proxy progress

This commit is contained in:
rusefi 2020-07-18 22:50:32 -04:00
parent d649dce37a
commit 7e6022b551
9 changed files with 111 additions and 94 deletions

View File

@ -197,7 +197,7 @@ jobs:
if: always() if: always()
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: primary console junit name: console primary junit
path: ./java_console/build/*.txt path: ./java_console/build/*.txt
- name: Upload primary bundle - name: Upload primary bundle

View File

@ -13,6 +13,7 @@ import com.rusefi.io.tcp.TcpConnector;
import com.rusefi.io.tcp.TcpIoStream; import com.rusefi.io.tcp.TcpIoStream;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.Closeable;
import java.net.Socket; import java.net.Socket;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
@ -24,7 +25,7 @@ import java.util.concurrent.*;
* @author Andrey Belomutskiy * @author Andrey Belomutskiy
* 3/3/14 * 3/3/14
*/ */
public class LinkManager { public class LinkManager implements Closeable {
@NotNull @NotNull
public static LogLevel LOG_LEVEL = LogLevel.INFO; public static LogLevel LOG_LEVEL = LogLevel.INFO;
@ -263,7 +264,8 @@ public class LinkManager {
connector.restart(); connector.restart();
} }
public void stop() { @Override
public void close() {
connector.stop(); connector.stop();
} }

View File

@ -11,6 +11,7 @@ public class SessionDetails {
private static final String ONE_TIME_TOKEN = "oneTime"; private static final String ONE_TIME_TOKEN = "oneTime";
private static final String AUTH_TOKEN = "authToken"; private static final String AUTH_TOKEN = "authToken";
private static final String CONTROLLER = "controller"; private static final String CONTROLLER = "controller";
private static final String HARDCODED_ONE_TIME_CODE = System.getProperty("ONE_TIME_CODE");
private final ControllerInfo controllerInfo; private final ControllerInfo controllerInfo;
@ -26,7 +27,7 @@ public class SessionDetails {
} }
public static int createOneTimeCode() { 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() { public int getOneTimeToken() {

View File

@ -55,7 +55,7 @@ public class ServerTest {
CountDownLatch allClientsDisconnected = new CountDownLatch(1); CountDownLatch allClientsDisconnected = new CountDownLatch(1);
CountDownLatch onConnected = new CountDownLatch(2); CountDownLatch onConnected = new CountDownLatch(2);
Backend backend = new Backend(userDetailsResolver, httpPort, logger) { try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) {
@Override @Override
public void register(ControllerConnectionState clientConnectionState) { public void register(ControllerConnectionState clientConnectionState) {
super.register(clientConnectionState); super.register(clientConnectionState);
@ -68,25 +68,26 @@ public class ServerTest {
if (getCount() == 0) if (getCount() == 0)
allClientsDisconnected.countDown(); allClientsDisconnected.countDown();
} }
}; }) {
backend.runControllerConnector(serverPortForControllers, parameter -> serverCreated.countDown()); backend.runControllerConnector(serverPortForControllers, parameter -> serverCreated.countDown());
assertTrue(serverCreated.await(30, TimeUnit.SECONDS)); assertTrue(serverCreated.await(30, TimeUnit.SECONDS));
assertEquals(0, backend.getCount()); assertEquals(0, backend.getCount());
new MockRusEfiDevice(MockRusEfiDevice.TEST_TOKEN_1, "rusEFI 2020.07.06.frankenso_na6.2468827536", 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); 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<ControllerConnectionState> clients = backend.getClients(); List<ControllerConnectionState> clients = backend.getClients();
assertEquals(2, clients.size()); assertEquals(2, clients.size());
List<UserDetails> onlineUsers = ProxyClient.getOnlineUsers(httpPort); List<UserDetails> onlineUsers = ProxyClient.getOnlineUsers(httpPort);
assertEquals(2, onlineUsers.size()); assertEquals(2, onlineUsers.size());
assertTrue("allClientsDisconnected", allClientsDisconnected.await(30, TimeUnit.SECONDS)); assertTrue("allClientsDisconnected", allClientsDisconnected.await(30, TimeUnit.SECONDS));
}
} }
@Test @Test
@ -95,24 +96,24 @@ public class ServerTest {
int httpPort = 8001; int httpPort = 8001;
int serverPortForRemoteUsers = 6801; int serverPortForRemoteUsers = 6801;
CountDownLatch disconnectedCountDownLatch = new CountDownLatch(1); CountDownLatch disconnectedCountDownLatch = new CountDownLatch(1);
Backend backend = new Backend(userDetailsResolver, httpPort, logger) { try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) {
@Override @Override
protected void onDisconnectApplication() { protected void onDisconnectApplication() {
super.onDisconnectApplication(); super.onDisconnectApplication();
disconnectedCountDownLatch.countDown(); disconnectedCountDownLatch.countDown();
} }
}; }) {
CountDownLatch applicationServerCreated = new CountDownLatch(1); CountDownLatch applicationServerCreated = new CountDownLatch(1);
backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown()); backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown());
assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS));
// start authenticator // start authenticator
IoStream authenticatorToProxyStream = TestHelper.secureConnectToLocalhost(serverPortForRemoteUsers, logger); IoStream authenticatorToProxyStream = TestHelper.secureConnectToLocalhost(serverPortForRemoteUsers, logger);
new HelloCommand(logger, "hello").handle(authenticatorToProxyStream); new HelloCommand(logger, "hello").handle(authenticatorToProxyStream);
assertTrue(disconnectedCountDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(disconnectedCountDownLatch.await(30, TimeUnit.SECONDS));
backend.close(); }
} }
@Test @Test
@ -124,28 +125,28 @@ public class ServerTest {
CountDownLatch disconnectedCountDownLatch = new CountDownLatch(1); CountDownLatch disconnectedCountDownLatch = new CountDownLatch(1);
Backend backend = new Backend(userDetailsResolver, httpPort, logger) { try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) {
@Override @Override
protected void onDisconnectApplication() { protected void onDisconnectApplication() {
super.onDisconnectApplication(); super.onDisconnectApplication();
disconnectedCountDownLatch.countDown(); disconnectedCountDownLatch.countDown();
} }
}; }) {
CountDownLatch applicationServerCreated = new CountDownLatch(1); CountDownLatch applicationServerCreated = new CountDownLatch(1);
backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown()); backend.runApplicationConnector(serverPortForRemoteUsers, parameter -> applicationServerCreated.countDown());
assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS));
SessionDetails sessionDetails = MockRusEfiDevice.createTestSession(MockRusEfiDevice.TEST_TOKEN_1, Fields.TS_SIGNATURE); SessionDetails sessionDetails = MockRusEfiDevice.createTestSession(MockRusEfiDevice.TEST_TOKEN_1, Fields.TS_SIGNATURE);
ApplicationRequest applicationRequest = new ApplicationRequest(sessionDetails, 123); ApplicationRequest applicationRequest = new ApplicationRequest(sessionDetails, 123);
// start authenticator // start authenticator
IoStream authenticatorToProxyStream = TestHelper.secureConnectToLocalhost(serverPortForRemoteUsers, logger); IoStream authenticatorToProxyStream = TestHelper.secureConnectToLocalhost(serverPortForRemoteUsers, logger);
LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(logger, applicationRequest); LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(logger, applicationRequest);
localApplicationProxy.run(authenticatorToProxyStream); localApplicationProxy.run(authenticatorToProxyStream);
assertTrue(disconnectedCountDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(disconnectedCountDownLatch.await(30, TimeUnit.SECONDS));
backend.close(); }
} }
@Test @Test
@ -158,75 +159,72 @@ public class ServerTest {
UserDetailsResolver userDetailsResolver = authToken -> new UserDetails(authToken.substring(0, 5), userId); UserDetailsResolver userDetailsResolver = authToken -> new UserDetails(authToken.substring(0, 5), userId);
int httpPort = 8001; int httpPort = 8001;
Backend backend = new Backend(userDetailsResolver, httpPort, logger) { try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) {
@Override @Override
protected void onRegister(ControllerConnectionState controllerConnectionState) { protected void onRegister(ControllerConnectionState controllerConnectionState) {
super.onRegister(controllerConnectionState); super.onRegister(controllerConnectionState);
controllerRegistered.countDown(); controllerRegistered.countDown();
} }
}; }; LinkManager clientManager = new LinkManager(logger)) {
int serverPortForControllers = 7001; int serverPortForControllers = 7001;
int serverPortForRemoteUsers = 7003; int serverPortForRemoteUsers = 7003;
// first start backend server // first start backend server
CountDownLatch controllerServerCreated = new CountDownLatch(1); CountDownLatch controllerServerCreated = new CountDownLatch(1);
CountDownLatch applicationServerCreated = 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(controllerServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS));
assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS));
// create virtual controller to which "rusEFI network connector" connects to // create virtual controller to which "rusEFI network connector" connects to
int controllerPort = 7002; int controllerPort = 7002;
ConfigurationImage controllerImage = prepareImage(value, createIniField(Fields.CYLINDERSCOUNT)); ConfigurationImage controllerImage = prepareImage(value, createIniField(Fields.CYLINDERSCOUNT));
CountDownLatch controllerCreated = new CountDownLatch(1); CountDownLatch controllerCreated = new CountDownLatch(1);
TestHelper.createVirtualController(controllerImage, controllerPort, parameter -> controllerCreated.countDown(), logger); TestHelper.createVirtualController(controllerImage, controllerPort, parameter -> controllerCreated.countDown(), logger);
assertTrue(controllerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); 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 // 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); 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()); SessionDetails authenticatorSessionDetails = new SessionDetails(deviceSessionDetails.getControllerInfo(), MockRusEfiDevice.TEST_TOKEN_3, deviceSessionDetails.getOneTimeToken());
ApplicationRequest applicationRequest = new ApplicationRequest(authenticatorSessionDetails, userId); ApplicationRequest applicationRequest = new ApplicationRequest(authenticatorSessionDetails, userId);
// start authenticator // start authenticator
int authenticatorPort = 7004; // local port on which authenticator accepts connections from Tuner Studio int authenticatorPort = 7004; // local port on which authenticator accepts connections from Tuner Studio
LocalApplicationProxy.startAndRun(logger, serverPortForRemoteUsers, applicationRequest, authenticatorPort); 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 // connect to proxy and read virtual controller through it
LinkManager clientManager = new LinkManager(logger); clientManager.startAndConnect(ProxyClient.LOCALHOST + ":" + authenticatorPort, new ConnectionStateListener() {
clientManager.startAndConnect(ProxyClient.LOCALHOST + ":" + authenticatorPort, new ConnectionStateListener() { @Override
@Override public void onConnectionEstablished() {
public void onConnectionEstablished() { connectionEstablishedCountDownLatch.countDown();
connectionEstablishedCountDownLatch.countDown(); }
}
@Override @Override
public void onConnectionFailed() { public void onConnectionFailed() {
System.out.println("Failed"); System.out.println("Failed");
} }
}); });
assertTrue("Connection established", connectionEstablishedCountDownLatch.await(30, TimeUnit.SECONDS)); assertTrue("Connection established", connectionEstablishedCountDownLatch.await(30, TimeUnit.SECONDS));
BinaryProtocol clientStreamState = clientManager.getCurrentStreamState(); BinaryProtocol clientStreamState = clientManager.getCurrentStreamState();
Objects.requireNonNull(clientStreamState, "clientStreamState"); Objects.requireNonNull(clientStreamState, "clientStreamState");
ConfigurationImage clientImage = clientStreamState.getControllerConfiguration(); ConfigurationImage clientImage = clientStreamState.getControllerConfiguration();
String clientValue = iniField.getValue(clientImage); String clientValue = iniField.getValue(clientImage);
assertEquals(Double.toString(value), clientValue); assertEquals(Double.toString(value), clientValue);
}
backend.close();
clientManager.stop();
} }
} }

View File

@ -82,7 +82,7 @@ public class TcpCommunicationIntegrationTest {
String clientValue = iniField.getValue(clientImage); String clientValue = iniField.getValue(clientImage);
assertEquals(Double.toString(value), clientValue); assertEquals(Double.toString(value), clientValue);
clientManager.stop(); clientManager.close();
} }
@Test @Test
@ -118,7 +118,7 @@ public class TcpCommunicationIntegrationTest {
}); });
assertTrue("Connection established", connectionEstablishedCountDownLatch.await(30, TimeUnit.SECONDS)); assertTrue("Connection established", connectionEstablishedCountDownLatch.await(30, TimeUnit.SECONDS));
clientManager.stop(); clientManager.close();
} }
} }

View File

@ -55,7 +55,7 @@ public class NetworkConnector {
private static SessionDetails runNetworkConnector(int serverPortForControllers, LinkManager linkManager, final Logger logger, String authToken) throws IOException { private static SessionDetails runNetworkConnector(int serverPortForControllers, LinkManager linkManager, final Logger logger, String authToken) throws IOException {
IoStream targetEcuSocket = linkManager.getConnector().getBinaryProtocol().getStream(); IoStream targetEcuSocket = linkManager.getConnector().getBinaryProtocol().getStream();
HelloCommand.send(targetEcuSocket, logger); 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(); ConfigurationImage image = linkManager.getConnector().getBinaryProtocol().getControllerConfiguration();
String vehicleName = Fields.VEHICLENAME.getStringValue(image); String vehicleName = Fields.VEHICLENAME.getStringValue(image);

View File

@ -3,6 +3,7 @@ package com.rusefi.server;
import javax.json.Json; import javax.json.Json;
import javax.json.JsonObject; import javax.json.JsonObject;
import javax.json.JsonReader; import javax.json.JsonReader;
import javax.json.stream.JsonParsingException;
import java.io.StringReader; import java.io.StringReader;
import java.util.Objects; import java.util.Objects;
@ -37,7 +38,12 @@ public class ApplicationRequest {
public static ApplicationRequest valueOf(String jsonString) { public static ApplicationRequest valueOf(String jsonString) {
JsonReader reader = Json.createReader(new StringReader(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); int targetUserId = jsonObject.getInt(USER_ID);
SessionDetails session = SessionDetails.valueOf(jsonObject.getString(SESSION)); SessionDetails session = SessionDetails.valueOf(jsonObject.getString(SESSION));

View File

@ -19,13 +19,14 @@ import org.takes.rs.RsJson;
import javax.json.Json; import javax.json.Json;
import javax.json.JsonArrayBuilder; import javax.json.JsonArrayBuilder;
import javax.json.JsonObject; import javax.json.JsonObject;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function; import java.util.function.Function;
public class Backend { public class Backend implements Closeable {
public static final String VERSION_PATH = "/version"; public static final String VERSION_PATH = "/version";
public static final String BACKEND_VERSION = "0.0001"; public static final String BACKEND_VERSION = "0.0001";
public static final int SERVER_PORT_FOR_APPLICATIONS = 8002; public static final int SERVER_PORT_FOR_APPLICATIONS = 8002;
@ -62,7 +63,11 @@ public class Backend {
new FkRegex("/", new RsHtml("<html><body>\n" + new FkRegex("/", new RsHtml("<html><body>\n" +
"<a href='https://rusefi.com/online/'>rusEFI Online</a>\n" + "<a href='https://rusefi.com/online/'>rusEFI Online</a>\n" +
"<br/>\n" + "<br/>\n" +
"<a href='/status'>Status</a>\n" + "<a href='" + Monitoring.STATUS + "'>Status</a>\n" +
"<br/>\n" +
"<a href='" + ProxyClient.LIST_PATH + "'>List</a>\n" +
"<br/>\n" +
"<br/>\n" +
"</body></html>\n")) "</body></html>\n"))
), httpPort ), httpPort
).start(() -> isClosed); ).start(() -> isClosed);
@ -171,6 +176,9 @@ public class Backend {
.add(UserDetails.USER_ID, client.getUserDetails().getUserId()) .add(UserDetails.USER_ID, client.getUserDetails().getUserId())
.add(UserDetails.USERNAME, client.getUserDetails().getUserName()) .add(UserDetails.USERNAME, client.getUserDetails().getUserName())
.add(ControllerInfo.SIGNATURE, client.getSessionDetails().getControllerInfo().getSignature()) .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(); .build();
builder.add(clientObject); builder.add(clientObject);
} }
@ -219,6 +227,7 @@ public class Backend {
} }
} }
@Override
public void close() { public void close() {
isClosed = true; isClosed = true;
} }

View File

@ -11,7 +11,8 @@ import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean; import java.lang.management.OperatingSystemMXBean;
public class Monitoring { 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()); (Take) req -> Monitoring.getStatus());