From 3c701edaeb721f3bd72a252f1020cfc79cd518c0 Mon Sep 17 00:00:00 2001 From: rusefi Date: Sat, 18 Jul 2020 22:50:32 -0400 Subject: [PATCH] proxy progress --- .github/workflows/build-firmware.yaml | 2 +- .../main/java/com/rusefi/io/LinkManager.java | 6 +- .../com/rusefi/server/SessionDetails.java | 3 +- .../src/test/java/com/rusefi/ServerTest.java | 164 +++++++++--------- .../io/TcpCommunicationIntegrationTest.java | 4 +- .../com/rusefi/proxy/NetworkConnector.java | 2 +- .../com/rusefi/server/ApplicationRequest.java | 8 +- .../main/java/com/rusefi/server/Backend.java | 13 +- .../java/com/rusefi/server/Monitoring.java | 3 +- 9 files changed, 111 insertions(+), 94 deletions(-) diff --git a/.github/workflows/build-firmware.yaml b/.github/workflows/build-firmware.yaml index 8048527b14..71269b7d2a 100644 --- a/.github/workflows/build-firmware.yaml +++ b/.github/workflows/build-firmware.yaml @@ -197,7 +197,7 @@ jobs: if: always() uses: actions/upload-artifact@v2 with: - name: primary console junit + name: console primary junit path: ./java_console/build/*.txt - name: Upload primary bundle diff --git a/java_console/io/src/main/java/com/rusefi/io/LinkManager.java b/java_console/io/src/main/java/com/rusefi/io/LinkManager.java index 1ea8b9bf4e..5760283579 100644 --- a/java_console/io/src/main/java/com/rusefi/io/LinkManager.java +++ b/java_console/io/src/main/java/com/rusefi/io/LinkManager.java @@ -13,6 +13,7 @@ import com.rusefi.io.tcp.TcpConnector; import com.rusefi.io.tcp.TcpIoStream; import org.jetbrains.annotations.NotNull; +import java.io.Closeable; import java.net.Socket; import java.util.Arrays; import java.util.Objects; @@ -24,7 +25,7 @@ import java.util.concurrent.*; * @author Andrey Belomutskiy * 3/3/14 */ -public class LinkManager { +public class LinkManager implements Closeable { @NotNull public static LogLevel LOG_LEVEL = LogLevel.INFO; @@ -263,7 +264,8 @@ public class LinkManager { connector.restart(); } - public void stop() { + @Override + public void close() { connector.stop(); } diff --git a/java_console/io/src/main/java/com/rusefi/server/SessionDetails.java b/java_console/io/src/main/java/com/rusefi/server/SessionDetails.java index a35034efb9..ea44980088 100644 --- a/java_console/io/src/main/java/com/rusefi/server/SessionDetails.java +++ b/java_console/io/src/main/java/com/rusefi/server/SessionDetails.java @@ -11,6 +11,7 @@ public class SessionDetails { private static final String ONE_TIME_TOKEN = "oneTime"; private static final String AUTH_TOKEN = "authToken"; private static final String CONTROLLER = "controller"; + private static final String HARDCODED_ONE_TIME_CODE = System.getProperty("ONE_TIME_CODE"); private final ControllerInfo controllerInfo; @@ -26,7 +27,7 @@ public class SessionDetails { } public static int createOneTimeCode() { - return new Random().nextInt(60000); + return HARDCODED_ONE_TIME_CODE == null ? new Random().nextInt(100000) : Integer.parseInt(HARDCODED_ONE_TIME_CODE); } public int getOneTimeToken() { diff --git a/java_console/ui/src/test/java/com/rusefi/ServerTest.java b/java_console/ui/src/test/java/com/rusefi/ServerTest.java index 1bc7d40063..6b8d78d758 100644 --- a/java_console/ui/src/test/java/com/rusefi/ServerTest.java +++ b/java_console/ui/src/test/java/com/rusefi/ServerTest.java @@ -55,7 +55,7 @@ public class ServerTest { CountDownLatch allClientsDisconnected = new CountDownLatch(1); CountDownLatch onConnected = new CountDownLatch(2); - Backend backend = new Backend(userDetailsResolver, httpPort, logger) { + try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) { @Override public void register(ControllerConnectionState clientConnectionState) { super.register(clientConnectionState); @@ -68,25 +68,26 @@ public class ServerTest { if (getCount() == 0) allClientsDisconnected.countDown(); } - }; + }) { - backend.runControllerConnector(serverPortForControllers, parameter -> serverCreated.countDown()); - assertTrue(serverCreated.await(30, TimeUnit.SECONDS)); - assertEquals(0, backend.getCount()); + backend.runControllerConnector(serverPortForControllers, parameter -> serverCreated.countDown()); + assertTrue(serverCreated.await(30, TimeUnit.SECONDS)); + assertEquals(0, backend.getCount()); - new MockRusEfiDevice(MockRusEfiDevice.TEST_TOKEN_1, "rusEFI 2020.07.06.frankenso_na6.2468827536", logger).connect(serverPortForControllers); - new MockRusEfiDevice("12345678-1234-1234-1234-123456789012", "rusEFI 2020.07.11.proteus_f4.1986715563", logger).connect(serverPortForControllers); + new MockRusEfiDevice(MockRusEfiDevice.TEST_TOKEN_1, "rusEFI 2020.07.06.frankenso_na6.2468827536", logger).connect(serverPortForControllers); + new MockRusEfiDevice("12345678-1234-1234-1234-123456789012", "rusEFI 2020.07.11.proteus_f4.1986715563", logger).connect(serverPortForControllers); - assertTrue("onConnected", onConnected.await(30, TimeUnit.SECONDS)); + assertTrue("onConnected", onConnected.await(30, TimeUnit.SECONDS)); - List clients = backend.getClients(); - assertEquals(2, clients.size()); + List clients = backend.getClients(); + assertEquals(2, clients.size()); - List onlineUsers = ProxyClient.getOnlineUsers(httpPort); - assertEquals(2, onlineUsers.size()); + List onlineUsers = ProxyClient.getOnlineUsers(httpPort); + assertEquals(2, onlineUsers.size()); - assertTrue("allClientsDisconnected", allClientsDisconnected.await(30, TimeUnit.SECONDS)); + assertTrue("allClientsDisconnected", allClientsDisconnected.await(30, TimeUnit.SECONDS)); + } } @Test @@ -95,24 +96,24 @@ public class ServerTest { int httpPort = 8001; int serverPortForRemoteUsers = 6801; CountDownLatch disconnectedCountDownLatch = new CountDownLatch(1); - Backend backend = new Backend(userDetailsResolver, httpPort, logger) { + try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) { @Override protected void onDisconnectApplication() { super.onDisconnectApplication(); disconnectedCountDownLatch.countDown(); } - }; + }) { - CountDownLatch applicationServerCreated = new CountDownLatch(1); - backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown()); - assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); + CountDownLatch applicationServerCreated = new CountDownLatch(1); + backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown()); + assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); - // start authenticator - IoStream authenticatorToProxyStream = TestHelper.secureConnectToLocalhost(serverPortForRemoteUsers, logger); - new HelloCommand(logger, "hello").handle(authenticatorToProxyStream); + // start authenticator + IoStream authenticatorToProxyStream = TestHelper.secureConnectToLocalhost(serverPortForRemoteUsers, logger); + new HelloCommand(logger, "hello").handle(authenticatorToProxyStream); - assertTrue(disconnectedCountDownLatch.await(30, TimeUnit.SECONDS)); - backend.close(); + assertTrue(disconnectedCountDownLatch.await(30, TimeUnit.SECONDS)); + } } @Test @@ -124,28 +125,28 @@ public class ServerTest { CountDownLatch disconnectedCountDownLatch = new CountDownLatch(1); - Backend backend = new Backend(userDetailsResolver, httpPort, logger) { + try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) { @Override protected void onDisconnectApplication() { super.onDisconnectApplication(); disconnectedCountDownLatch.countDown(); } - }; + }) { - CountDownLatch applicationServerCreated = new CountDownLatch(1); - backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown()); - assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); + CountDownLatch applicationServerCreated = new CountDownLatch(1); + backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown()); + assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); - SessionDetails sessionDetails = MockRusEfiDevice.createTestSession(MockRusEfiDevice.TEST_TOKEN_1, Fields.TS_SIGNATURE); - ApplicationRequest applicationRequest = new ApplicationRequest(sessionDetails, 123); + SessionDetails sessionDetails = MockRusEfiDevice.createTestSession(MockRusEfiDevice.TEST_TOKEN_1, Fields.TS_SIGNATURE); + ApplicationRequest applicationRequest = new ApplicationRequest(sessionDetails, 123); - // start authenticator - IoStream authenticatorToProxyStream = TestHelper.secureConnectToLocalhost(serverPortForRemoteUsers, logger); - LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(logger, applicationRequest); - localApplicationProxy.run(authenticatorToProxyStream); + // start authenticator + IoStream authenticatorToProxyStream = TestHelper.secureConnectToLocalhost(serverPortForRemoteUsers, logger); + LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(logger, applicationRequest); + localApplicationProxy.run(authenticatorToProxyStream); - assertTrue(disconnectedCountDownLatch.await(30, TimeUnit.SECONDS)); - backend.close(); + assertTrue(disconnectedCountDownLatch.await(30, TimeUnit.SECONDS)); + } } @Test @@ -158,75 +159,72 @@ public class ServerTest { UserDetailsResolver userDetailsResolver = authToken -> new UserDetails(authToken.substring(0, 5), userId); int httpPort = 8001; - Backend backend = new Backend(userDetailsResolver, httpPort, logger) { + try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) { @Override protected void onRegister(ControllerConnectionState controllerConnectionState) { super.onRegister(controllerConnectionState); controllerRegistered.countDown(); } - }; - int serverPortForControllers = 7001; - int serverPortForRemoteUsers = 7003; + }; LinkManager clientManager = new LinkManager(logger)) { + int serverPortForControllers = 7001; + int serverPortForRemoteUsers = 7003; - // first start backend server - CountDownLatch controllerServerCreated = new CountDownLatch(1); - CountDownLatch applicationServerCreated = new CountDownLatch(1); + // first start backend server + CountDownLatch controllerServerCreated = new CountDownLatch(1); + CountDownLatch applicationServerCreated = new CountDownLatch(1); - backend.runControllerConnector(serverPortForControllers, parameter -> controllerServerCreated.countDown()); + backend.runControllerConnector(serverPortForControllers, parameter -> controllerServerCreated.countDown()); - backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown()); + backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown()); - assertTrue(controllerServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); - assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); + assertTrue(controllerServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); + assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); - // create virtual controller to which "rusEFI network connector" connects to - int controllerPort = 7002; - ConfigurationImage controllerImage = prepareImage(value, createIniField(Fields.CYLINDERSCOUNT)); - CountDownLatch controllerCreated = new CountDownLatch(1); - TestHelper.createVirtualController(controllerImage, controllerPort, parameter -> controllerCreated.countDown(), logger); - assertTrue(controllerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); + // create virtual controller to which "rusEFI network connector" connects to + int controllerPort = 7002; + ConfigurationImage controllerImage = prepareImage(value, createIniField(Fields.CYLINDERSCOUNT)); + CountDownLatch controllerCreated = new CountDownLatch(1); + TestHelper.createVirtualController(controllerImage, controllerPort, parameter -> controllerCreated.countDown(), logger); + assertTrue(controllerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); - // start "rusEFI network connector" to connect controller with backend since in real life controller has only local serial port it does not have network - SessionDetails deviceSessionDetails = NetworkConnector.runNetworkConnector(MockRusEfiDevice.TEST_TOKEN_1, ProxyClient.LOCALHOST + ":" + controllerPort, serverPortForControllers); + // start "rusEFI network connector" to connect controller with backend since in real life controller has only local serial port it does not have network + SessionDetails deviceSessionDetails = NetworkConnector.runNetworkConnector(MockRusEfiDevice.TEST_TOKEN_1, ProxyClient.LOCALHOST + ":" + controllerPort, serverPortForControllers); - assertTrue(controllerRegistered.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); + assertTrue(controllerRegistered.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); - SessionDetails authenticatorSessionDetails = new SessionDetails(deviceSessionDetails.getControllerInfo(), MockRusEfiDevice.TEST_TOKEN_3, deviceSessionDetails.getOneTimeToken()); - ApplicationRequest applicationRequest = new ApplicationRequest(authenticatorSessionDetails, userId); + SessionDetails authenticatorSessionDetails = new SessionDetails(deviceSessionDetails.getControllerInfo(), MockRusEfiDevice.TEST_TOKEN_3, deviceSessionDetails.getOneTimeToken()); + ApplicationRequest applicationRequest = new ApplicationRequest(authenticatorSessionDetails, userId); - // start authenticator + // start authenticator - int authenticatorPort = 7004; // local port on which authenticator accepts connections from Tuner Studio - LocalApplicationProxy.startAndRun(logger, serverPortForRemoteUsers, applicationRequest, authenticatorPort); + int authenticatorPort = 7004; // local port on which authenticator accepts connections from Tuner Studio + LocalApplicationProxy.startAndRun(logger, serverPortForRemoteUsers, applicationRequest, authenticatorPort); - CountDownLatch connectionEstablishedCountDownLatch = new CountDownLatch(1); + CountDownLatch connectionEstablishedCountDownLatch = new CountDownLatch(1); - // connect to proxy and read virtual controller through it - LinkManager clientManager = new LinkManager(logger); - clientManager.startAndConnect(ProxyClient.LOCALHOST + ":" + authenticatorPort, new ConnectionStateListener() { - @Override - public void onConnectionEstablished() { - connectionEstablishedCountDownLatch.countDown(); - } + // connect to proxy and read virtual controller through it + clientManager.startAndConnect(ProxyClient.LOCALHOST + ":" + authenticatorPort, new ConnectionStateListener() { + @Override + public void onConnectionEstablished() { + connectionEstablishedCountDownLatch.countDown(); + } - @Override - public void onConnectionFailed() { - System.out.println("Failed"); - } - }); - assertTrue("Connection established", connectionEstablishedCountDownLatch.await(30, TimeUnit.SECONDS)); + @Override + public void onConnectionFailed() { + System.out.println("Failed"); + } + }); + assertTrue("Connection established", connectionEstablishedCountDownLatch.await(30, TimeUnit.SECONDS)); - BinaryProtocol clientStreamState = clientManager.getCurrentStreamState(); - Objects.requireNonNull(clientStreamState, "clientStreamState"); - ConfigurationImage clientImage = clientStreamState.getControllerConfiguration(); - String clientValue = iniField.getValue(clientImage); - assertEquals(Double.toString(value), clientValue); - - backend.close(); - clientManager.stop(); + BinaryProtocol clientStreamState = clientManager.getCurrentStreamState(); + Objects.requireNonNull(clientStreamState, "clientStreamState"); + ConfigurationImage clientImage = clientStreamState.getControllerConfiguration(); + String clientValue = iniField.getValue(clientImage); + assertEquals(Double.toString(value), clientValue); + } } } diff --git a/java_console/ui/src/test/java/com/rusefi/io/TcpCommunicationIntegrationTest.java b/java_console/ui/src/test/java/com/rusefi/io/TcpCommunicationIntegrationTest.java index f75f3a743d..5377a20438 100644 --- a/java_console/ui/src/test/java/com/rusefi/io/TcpCommunicationIntegrationTest.java +++ b/java_console/ui/src/test/java/com/rusefi/io/TcpCommunicationIntegrationTest.java @@ -82,7 +82,7 @@ public class TcpCommunicationIntegrationTest { String clientValue = iniField.getValue(clientImage); assertEquals(Double.toString(value), clientValue); - clientManager.stop(); + clientManager.close(); } @Test @@ -118,7 +118,7 @@ public class TcpCommunicationIntegrationTest { }); assertTrue("Connection established", connectionEstablishedCountDownLatch.await(30, TimeUnit.SECONDS)); - clientManager.stop(); + clientManager.close(); } } diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/proxy/NetworkConnector.java b/java_tools/proxy_server/src/main/java/com/rusefi/proxy/NetworkConnector.java index 00be9475de..f104f7152b 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/proxy/NetworkConnector.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/proxy/NetworkConnector.java @@ -55,7 +55,7 @@ public class NetworkConnector { private static SessionDetails runNetworkConnector(int serverPortForControllers, LinkManager linkManager, final Logger logger, String authToken) throws IOException { IoStream targetEcuSocket = linkManager.getConnector().getBinaryProtocol().getStream(); HelloCommand.send(targetEcuSocket, logger); - String controllerSignature = HelloCommand.getHelloResponse(targetEcuSocket.getDataBuffer(), logger); + String controllerSignature = HelloCommand.getHelloResponse(targetEcuSocket.getDataBuffer(), logger).trim(); ConfigurationImage image = linkManager.getConnector().getBinaryProtocol().getControllerConfiguration(); String vehicleName = Fields.VEHICLENAME.getStringValue(image); diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/server/ApplicationRequest.java b/java_tools/proxy_server/src/main/java/com/rusefi/server/ApplicationRequest.java index 6080b08d80..ced6bf9740 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/server/ApplicationRequest.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/server/ApplicationRequest.java @@ -3,6 +3,7 @@ package com.rusefi.server; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonReader; +import javax.json.stream.JsonParsingException; import java.io.StringReader; import java.util.Objects; @@ -37,7 +38,12 @@ public class ApplicationRequest { public static ApplicationRequest valueOf(String jsonString) { JsonReader reader = Json.createReader(new StringReader(jsonString)); - JsonObject jsonObject = reader.readObject(); + JsonObject jsonObject; + try { + jsonObject = reader.readObject(); + } catch (JsonParsingException e) { + throw new IllegalStateException("While parsing [" + jsonString + "]", e); + } int targetUserId = jsonObject.getInt(USER_ID); SessionDetails session = SessionDetails.valueOf(jsonObject.getString(SESSION)); 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 89a6e22727..ae3d856eac 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 @@ -19,13 +19,14 @@ import org.takes.rs.RsJson; import javax.json.Json; import javax.json.JsonArrayBuilder; import javax.json.JsonObject; +import java.io.Closeable; import java.io.IOException; import java.net.Socket; import java.util.*; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; -public class Backend { +public class Backend implements Closeable { public static final String VERSION_PATH = "/version"; public static final String BACKEND_VERSION = "0.0001"; public static final int SERVER_PORT_FOR_APPLICATIONS = 8002; @@ -62,7 +63,11 @@ public class Backend { new FkRegex("/", new RsHtml("\n" + "rusEFI Online\n" + "
\n" + - "Status\n" + + "Status\n" + + "
\n" + + "List\n" + + "
\n" + + "
\n" + "\n")) ), httpPort ).start(() -> isClosed); @@ -171,6 +176,9 @@ public class Backend { .add(UserDetails.USER_ID, client.getUserDetails().getUserId()) .add(UserDetails.USERNAME, client.getUserDetails().getUserName()) .add(ControllerInfo.SIGNATURE, client.getSessionDetails().getControllerInfo().getSignature()) + .add(ControllerInfo.VEHICLE_NAME, client.getSessionDetails().getControllerInfo().getVehicleName()) + .add(ControllerInfo.ENGINE_MAKE, client.getSessionDetails().getControllerInfo().getEngineMake()) + .add(ControllerInfo.ENGINE_CODE, client.getSessionDetails().getControllerInfo().getEngineCode()) .build(); builder.add(clientObject); } @@ -219,6 +227,7 @@ public class Backend { } } + @Override public void close() { isClosed = true; } diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/server/Monitoring.java b/java_tools/proxy_server/src/main/java/com/rusefi/server/Monitoring.java index 14b618c175..90d8f74dca 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/server/Monitoring.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/server/Monitoring.java @@ -11,7 +11,8 @@ import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; public class Monitoring { - static final FkRegex showStatistics = new FkRegex("/status", + public static final String STATUS = "/status"; + static final FkRegex showStatistics = new FkRegex(STATUS, (Take) req -> Monitoring.getStatus());