proxy progress
This commit is contained in:
parent
439ec69481
commit
811b44dae7
|
@ -12,16 +12,15 @@ import com.opensr5.io.DataListener;
|
|||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.dfu.DfuLogic;
|
||||
import com.rusefi.io.ByteReader;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.serial.AbstractIoStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class AndroidSerial implements IoStream {
|
||||
public class AndroidSerial extends AbstractIoStream {
|
||||
private static final int ST_CDC = 0x5740;
|
||||
private final IncomingDataBuffer dataBuffer;
|
||||
|
||||
private boolean isClosed;
|
||||
private UsbSerialPort usbSerialPort;
|
||||
|
||||
static List<UsbSerialDriver> findUsbSerial(UsbManager usbManager) {
|
||||
|
@ -53,16 +52,6 @@ public class AndroidSerial implements IoStream {
|
|||
ByteReader.runReaderLoop("", listener, reader, Logger.CONSOLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
return isClosed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
isClosed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] bytes) throws IOException {
|
||||
usbSerialPort.write(bytes, 1000);
|
||||
|
|
|
@ -4,12 +4,14 @@ import com.opensr5.Logger;
|
|||
import com.rusefi.Timeouts;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.serial.AbstractIoStream;
|
||||
import etch.util.CircularByteBuffer;
|
||||
import net.jcip.annotations.ThreadSafe;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.rusefi.binaryprotocol.IoHelper.*;
|
||||
|
||||
|
@ -28,15 +30,17 @@ public class IncomingDataBuffer {
|
|||
*/
|
||||
private final CircularByteBuffer cbb;
|
||||
private final Logger logger;
|
||||
private final AbstractIoStream.StreamStats streamStats;
|
||||
|
||||
public IncomingDataBuffer(Logger logger) {
|
||||
public IncomingDataBuffer(Logger logger, AbstractIoStream.StreamStats streamStats) {
|
||||
this.streamStats = Objects.requireNonNull(streamStats, "streamStats");
|
||||
this.cbb = new CircularByteBuffer(BUFFER_SIZE);
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public static IncomingDataBuffer createDataBuffer(String loggingPrefix, IoStream stream, Logger logger) {
|
||||
IncomingDataBuffer.loggingPrefix = loggingPrefix;
|
||||
IncomingDataBuffer incomingData = new IncomingDataBuffer(logger);
|
||||
IncomingDataBuffer incomingData = new IncomingDataBuffer(logger, stream.getStreamStats());
|
||||
stream.setInputListener(incomingData::addData);
|
||||
return incomingData;
|
||||
}
|
||||
|
@ -71,6 +75,7 @@ public class IncomingDataBuffer {
|
|||
logger.trace(String.format("%x", actualCrc) + " vs " + String.format("%x", packetCrc));
|
||||
return null;
|
||||
}
|
||||
streamStats.onPacketArrived();
|
||||
logger.trace("packet " + Arrays.toString(packet) + ": crc OK");
|
||||
|
||||
return packet;
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.opensr5.io.WriteStream;
|
|||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.binaryprotocol.IoHelper;
|
||||
import com.rusefi.io.serial.AbstractIoStream;
|
||||
import com.rusefi.io.tcp.BinaryProtocolServer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
@ -64,6 +65,8 @@ public interface IoStream extends WriteStream {
|
|||
|
||||
boolean isClosed();
|
||||
|
||||
AbstractIoStream.StreamStats getStreamStats();
|
||||
|
||||
void close();
|
||||
|
||||
String getLoggingPrefix();
|
||||
|
|
|
@ -5,6 +5,13 @@ import com.rusefi.io.IoStream;
|
|||
public abstract class AbstractIoStream implements IoStream {
|
||||
private boolean isClosed;
|
||||
|
||||
protected StreamStats streamStats = new StreamStats();
|
||||
|
||||
@Override
|
||||
public StreamStats getStreamStats() {
|
||||
return streamStats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
isClosed = true;
|
||||
|
@ -14,4 +21,24 @@ public abstract class AbstractIoStream implements IoStream {
|
|||
public boolean isClosed() {
|
||||
return isClosed;
|
||||
}
|
||||
|
||||
public class StreamStats {
|
||||
private long previousPacketArrivalTime;
|
||||
private int maxPacketGap;
|
||||
|
||||
/**
|
||||
* @return maximum time in MS between full valid packets received via this stream
|
||||
*/
|
||||
public int getMaxPacketGap() {
|
||||
return maxPacketGap;
|
||||
}
|
||||
|
||||
public void onPacketArrived() {
|
||||
long now = System.currentTimeMillis();
|
||||
if (previousPacketArrivalTime != 0) {
|
||||
maxPacketGap = (int) Math.max(maxPacketGap, now - previousPacketArrivalTime);
|
||||
}
|
||||
previousPacketArrivalTime = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,14 +13,15 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public class ProxyClient {
|
||||
public static final String LIST_PATH = "/list_online";
|
||||
public static final String LIST_CONTROLLERS_PATH = "/list_controllers";
|
||||
public static final String LIST_APPLICATIONS_PATH = "/list_applications";
|
||||
|
||||
public static List<PublicSession> getOnlineUsers(int httpPort) throws IOException {
|
||||
return getOnlineUsers(HttpUtil.RUSEFI_PROXY_JSON_API_PREFIX + ":" + httpPort + LIST_PATH);
|
||||
public static List<PublicSession> getOnlineApplications(int httpPort) throws IOException {
|
||||
return getOnlineApplications(HttpUtil.RUSEFI_PROXY_JSON_API_PREFIX + ":" + httpPort + LIST_CONTROLLERS_PATH);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PublicSession> getOnlineUsers(String url) throws IOException {
|
||||
public static List<PublicSession> getOnlineApplications(String url) throws IOException {
|
||||
HttpResponse httpResponse = HttpUtil.executeGet(url);
|
||||
|
||||
List<PublicSession> userLists = new ArrayList<>();
|
||||
|
|
|
@ -99,6 +99,8 @@ public class FullServerTest {
|
|||
ConfigurationImage clientImage = clientStreamState.getControllerConfiguration();
|
||||
String clientValue = iniField.getValue(clientImage);
|
||||
assertEquals(Double.toString(value), clientValue);
|
||||
|
||||
// now let's test that application connector would be terminated by server due to inactivity
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package com.rusefi;
|
||||
|
||||
import com.opensr5.ConfigurationImage;
|
||||
import com.opensr5.Logger;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.commands.HelloCommand;
|
||||
import com.rusefi.proxy.NetworkConnector;
|
||||
import com.rusefi.server.*;
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import com.rusefi.tools.online.ProxyClient;
|
||||
|
@ -18,6 +20,7 @@ import java.util.List;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.rusefi.Timeouts.READ_IMAGE_TIMEOUT;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
@ -84,10 +87,10 @@ public class ServerTest {
|
|||
|
||||
assertTrue("onConnected", onConnected.await(30, TimeUnit.SECONDS));
|
||||
|
||||
List<ControllerConnectionState> clients = backend.getClients();
|
||||
List<ControllerConnectionState> clients = backend.getControllers();
|
||||
assertEquals(2, clients.size());
|
||||
|
||||
List<PublicSession> onlineUsers = ProxyClient.getOnlineUsers(HttpUtil.RUSEFI_PROXY_JSON_PROTOCOL + TestHelper.LOCALHOST + ":" + httpPort + ProxyClient.LIST_PATH);
|
||||
List<PublicSession> onlineUsers = ProxyClient.getOnlineApplications(HttpUtil.RUSEFI_PROXY_JSON_PROTOCOL + TestHelper.LOCALHOST + ":" + httpPort + ProxyClient.LIST_CONTROLLERS_PATH);
|
||||
assertEquals(2, onlineUsers.size());
|
||||
|
||||
allConnected.countDown();
|
||||
|
@ -97,17 +100,41 @@ public class ServerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testApplicationTimeout() throws InterruptedException {
|
||||
public void testApplicationTimeout() throws InterruptedException, IOException {
|
||||
int serverPortForRemoteUsers = 6999;
|
||||
int serverPortForControllers = 6997;
|
||||
int httpPort = 6998;
|
||||
int serverPortForControllers = 6997;
|
||||
int controllerPort = 6996;
|
||||
int userId = 7;
|
||||
|
||||
try (Backend backend = new Backend(createTestUserResolver(), httpPort, logger)) {
|
||||
|
||||
UserDetailsResolver userDetailsResolver = authToken -> new UserDetails(authToken.substring(0, 5), userId);
|
||||
|
||||
CountDownLatch controllerRegistered = new CountDownLatch(1);
|
||||
try (Backend backend = new Backend(userDetailsResolver, httpPort, logger) {
|
||||
@Override
|
||||
protected void onRegister(ControllerConnectionState controllerConnectionState) {
|
||||
super.onRegister(controllerConnectionState);
|
||||
controllerRegistered.countDown();
|
||||
}
|
||||
}) {
|
||||
|
||||
TestHelper.runApplicationConnectorBlocking(backend, serverPortForRemoteUsers);
|
||||
|
||||
TestHelper.runControllerConnectorBlocking(backend, serverPortForControllers);
|
||||
|
||||
// create virtual controller to which "rusEFI network connector" connects to
|
||||
TestHelper.createVirtualController(controllerPort, new ConfigurationImage(Fields.TOTAL_CONFIG_SIZE), logger);
|
||||
|
||||
// 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, TestHelper.LOCALHOST + ":" + controllerPort, serverPortForControllers);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,13 +35,16 @@ public class Backend implements Closeable {
|
|||
public static final String BACKEND_VERSION = "0.0001";
|
||||
public static final int SERVER_PORT_FOR_CONTROLLERS = 8003;
|
||||
|
||||
private final FkRegex showOnlineUsers = new FkRegex(ProxyClient.LIST_PATH,
|
||||
(Take) req -> getUsersOnline()
|
||||
private final FkRegex showOnlineControllers = new FkRegex(ProxyClient.LIST_CONTROLLERS_PATH,
|
||||
(Take) req -> getControllersOnline()
|
||||
);
|
||||
private final FkRegex showOnlineApplications = new FkRegex(ProxyClient.LIST_CONTROLLERS_PATH,
|
||||
(Take) req -> getControllersOnline()
|
||||
);
|
||||
private boolean isClosed;
|
||||
|
||||
// guarded by own monitor
|
||||
private final Set<ControllerConnectionState> clients = new HashSet<>();
|
||||
private final Set<ControllerConnectionState> controllers = new HashSet<>();
|
||||
// guarded by clients
|
||||
private HashMap<ControllerKey, ControllerConnectionState> byId = new HashMap<>();
|
||||
// private final int clientTimeout;
|
||||
|
@ -62,7 +65,7 @@ public class Backend implements Closeable {
|
|||
System.out.println("Starting http backend on " + httpPort);
|
||||
try {
|
||||
new FtBasic(
|
||||
new TkFork(showOnlineUsers,
|
||||
new TkFork(showOnlineControllers,
|
||||
new Monitoring(this).showStatistics,
|
||||
new FkRegex(VERSION_PATH, BACKEND_VERSION),
|
||||
new FkRegex("/", new RsHtml("<html><body>\n" +
|
||||
|
@ -70,7 +73,8 @@ public class Backend implements Closeable {
|
|||
"<br/>\n" +
|
||||
"<a href='" + Monitoring.STATUS + "'>Status</a>\n" +
|
||||
"<br/>\n" +
|
||||
"<a href='" + ProxyClient.LIST_PATH + "'>List</a>\n" +
|
||||
"<a href='" + ProxyClient.LIST_CONTROLLERS_PATH + "'>Controllers</a>\n" +
|
||||
"<a href='" + ProxyClient.LIST_APPLICATIONS_PATH + "'>Applications</a>\n" +
|
||||
"<br/>\n" +
|
||||
"<br/>\n" +
|
||||
"</body></html>\n"))
|
||||
|
@ -121,7 +125,7 @@ public class Backend implements Closeable {
|
|||
|
||||
ControllerKey controllerKey = new ControllerKey(applicationRequest.getTargetUserId(), applicationRequest.getSessionDetails().getControllerInfo());
|
||||
ControllerConnectionState state;
|
||||
synchronized (clients) {
|
||||
synchronized (controllers) {
|
||||
state = byId.get(controllerKey);
|
||||
}
|
||||
if (state == null) {
|
||||
|
@ -178,9 +182,9 @@ public class Backend implements Closeable {
|
|||
}
|
||||
|
||||
@NotNull
|
||||
private RsJson getUsersOnline() throws IOException {
|
||||
private RsJson getControllersOnline() throws IOException {
|
||||
JsonArrayBuilder builder = Json.createArrayBuilder();
|
||||
List<ControllerConnectionState> clients = getClients();
|
||||
List<ControllerConnectionState> clients = getControllers();
|
||||
for (ControllerConnectionState client : clients) {
|
||||
|
||||
JsonObject clientObject = Json.createObjectBuilder()
|
||||
|
@ -190,6 +194,7 @@ public class Backend implements Closeable {
|
|||
.add(ControllerInfo.VEHICLE_NAME, client.getSessionDetails().getControllerInfo().getVehicleName())
|
||||
.add(ControllerInfo.ENGINE_MAKE, client.getSessionDetails().getControllerInfo().getEngineMake())
|
||||
.add(ControllerInfo.ENGINE_CODE, client.getSessionDetails().getControllerInfo().getEngineCode())
|
||||
.add("MAX_PACKET_GAP", client.getStream().getStreamStats().getMaxPacketGap())
|
||||
.build();
|
||||
builder.add(clientObject);
|
||||
}
|
||||
|
@ -219,8 +224,8 @@ public class Backend implements Closeable {
|
|||
|
||||
public void register(ControllerConnectionState controllerConnectionState) {
|
||||
Objects.requireNonNull(controllerConnectionState.getControllerKey(), "ControllerKey");
|
||||
synchronized (clients) {
|
||||
clients.add(controllerConnectionState);
|
||||
synchronized (controllers) {
|
||||
controllers.add(controllerConnectionState);
|
||||
byId.put(controllerConnectionState.getControllerKey(), controllerConnectionState);
|
||||
}
|
||||
onRegister(controllerConnectionState);
|
||||
|
@ -231,9 +236,9 @@ public class Backend implements Closeable {
|
|||
|
||||
public void close(ControllerConnectionState inactiveClient) {
|
||||
inactiveClient.close();
|
||||
synchronized (clients) {
|
||||
synchronized (controllers) {
|
||||
// in case of exception in the initialization phase we do not even add client into the the collection
|
||||
clients.remove(inactiveClient);
|
||||
controllers.remove(inactiveClient);
|
||||
byId.remove(inactiveClient.getControllerKey());
|
||||
}
|
||||
}
|
||||
|
@ -243,15 +248,15 @@ public class Backend implements Closeable {
|
|||
isClosed = true;
|
||||
}
|
||||
|
||||
public List<ControllerConnectionState> getClients() {
|
||||
synchronized (clients) {
|
||||
return new ArrayList<>(clients);
|
||||
public List<ControllerConnectionState> getControllers() {
|
||||
synchronized (controllers) {
|
||||
return new ArrayList<>(controllers);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
synchronized (clients) {
|
||||
return clients.size();
|
||||
synchronized (controllers) {
|
||||
return controllers.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,11 +53,9 @@ public class RemoteTab {
|
|||
listDownloadExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String url = HttpUtil.RUSEFI_PROXY_JSON_API_PREFIX + "/list_online";
|
||||
|
||||
List<PublicSession> userDetails;
|
||||
try {
|
||||
userDetails = ProxyClient.getOnlineUsers(HttpUtil.HTTP_PORT);
|
||||
userDetails = ProxyClient.getOnlineApplications(HttpUtil.HTTP_PORT);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
Loading…
Reference in New Issue