mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-24 14:38:45 +00:00
some improvements of the WindStatusServlet regarding user accounts and live connection information
This commit is contained in:
+4
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.domain.igtimiadapter;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public interface LiveDataConnection {
|
||||
/**
|
||||
* Disconnects this connection. Afterwards, the connection will no longer feed live data to its listener(s).
|
||||
@@ -18,4 +20,6 @@ public interface LiveDataConnection {
|
||||
void addListener(BulkFixReceiver listener);
|
||||
|
||||
void removeListener(BulkFixReceiver listener);
|
||||
|
||||
InetSocketAddress getRemoteAddress();
|
||||
}
|
||||
|
||||
+4
@@ -132,6 +132,10 @@ public class IgtimiConnectionFactoryImpl implements IgtimiConnectionFactory {
|
||||
return new ArrayList<Account>(accountsByEmail.values());
|
||||
}
|
||||
|
||||
public IgtimiConnection getConnectionOfAccount(Account account) {
|
||||
return connectionsByAccount.get(account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IgtimiConnection connect(Account account) {
|
||||
IgtimiConnection connection;
|
||||
|
||||
+7
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.domain.igtimiadapter.websocket;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import com.sap.sailing.domain.igtimiadapter.BulkFixReceiver;
|
||||
import com.sap.sailing.domain.igtimiadapter.LiveDataConnection;
|
||||
|
||||
@@ -45,4 +47,9 @@ public class LiveDataConnectionWrapper implements LiveDataConnection {
|
||||
LiveDataConnection getActualConnection() {
|
||||
return actualConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress() {
|
||||
return actualConnection.getRemoteAddress();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.igtimiadapter.websocket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -150,7 +151,7 @@ public class WebSocketConnectionManager extends WebSocketAdapter implements Live
|
||||
public com.sap.sse.common.Util.Pair<TimePoint, TimePoint> getIgtimiServerTimePointAndWhenItWasReceived() {
|
||||
return new com.sap.sse.common.Util.Pair<TimePoint, TimePoint>(igtimiServerTimepoint, localTimepointWhenServerTimepointWasReceived);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addListener(BulkFixReceiver listener) {
|
||||
listeners.put(listener, listener);
|
||||
@@ -250,4 +251,9 @@ public class WebSocketConnectionManager extends WebSocketAdapter implements Live
|
||||
throw lastException;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress() {
|
||||
return getSession().getRemoteAddress();
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -8,6 +8,7 @@ import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
@@ -16,6 +17,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sap.sailing.domain.igtimiadapter.BulkFixReceiver;
|
||||
import com.sap.sailing.domain.igtimiadapter.IgtimiWindListener;
|
||||
import com.sap.sailing.domain.igtimiadapter.LiveDataConnection;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
@@ -43,6 +45,18 @@ public class WindStatusHtmlServlet extends WindStatusServlet implements IgtimiWi
|
||||
out.println("<body>");
|
||||
out.println("<p>Reload wind connectors with parameter <a href=\"/sailingserver/windStatus?reloadWindReceiver=true\">reloadWindReceiver=true</a>. This will force a connection reset and a reloading of the wind receivers.</p>");
|
||||
out.println("<h3>Igtimi Wind Status ("+getIgtimiMessagesRawCount()+" raw messages received)</h3>");
|
||||
Map<LiveDataConnection, IgtimiConnectionInfo> igtimiConnections = getIgtimiConnections();
|
||||
if (!igtimiConnections.isEmpty()) {
|
||||
out.println("<h4>Igtimi accounts used</h4>");
|
||||
for (Map.Entry<LiveDataConnection, IgtimiConnectionInfo> entry: igtimiConnections.entrySet()) {
|
||||
IgtimiConnectionInfo igtimiConnectionInfo = entry.getValue();
|
||||
int deviceCount = igtimiConnectionInfo.deviceIDs.size();
|
||||
out.println("<b>Account " + igtimiConnectionInfo.accountName + "</b><br/>");
|
||||
out.println(deviceCount + " devices " + igtimiConnectionInfo.deviceIDs.toString() + "<br/>");
|
||||
out.println("Connection used is " + igtimiConnectionInfo.remoteAddress.toString() + "<br/><br/>");
|
||||
}
|
||||
out.println("<br/>");
|
||||
}
|
||||
if (getLastIgtimiMessages() != null && !getLastIgtimiMessages().isEmpty()) {
|
||||
for(Entry<String, Deque<IgtimiMessageInfo>> deviceAndMessagesList: getLastIgtimiMessages().entrySet()) {
|
||||
final Deque<IgtimiMessageInfo> copyOfLastIgtimiMessages;
|
||||
|
||||
+47
-100
@@ -1,7 +1,6 @@
|
||||
package com.sap.sailing.server.gateway.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
@@ -10,15 +9,9 @@ import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
@@ -37,7 +30,7 @@ import com.sap.sailing.expeditionconnector.ExpeditionMessage;
|
||||
import com.sap.sailing.expeditionconnector.ExpeditionWindTrackerFactory;
|
||||
import com.sap.sailing.expeditionconnector.UDPExpeditionReceiver;
|
||||
import com.sap.sailing.server.gateway.SailingServerHttpServlet;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* Shows the state of wind receivers regardless of them being attached to a race. Currently Expedition and Igtimi are supported.
|
||||
@@ -45,7 +38,7 @@ import com.sap.sse.common.TimePoint;
|
||||
* @author Simon Marcel Pamies
|
||||
*
|
||||
*/
|
||||
public class WindStatusServlet extends SailingServerHttpServlet implements IgtimiWindListener, BulkFixReceiver {
|
||||
public abstract class WindStatusServlet extends SailingServerHttpServlet implements IgtimiWindListener, BulkFixReceiver {
|
||||
private static final long serialVersionUID = -6791613843435003810L;
|
||||
|
||||
protected static final String PARAM_RELOAD_WIND_RECEIVER="reloadWindReceiver";
|
||||
@@ -64,8 +57,8 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
private static int igtimiRawMessageCount;
|
||||
private static Map<String, Deque<IgtimiMessageInfo>> lastIgtimiMessages;
|
||||
private static IgtimiWindReceiver igtimiWindReceiver;
|
||||
private static LiveDataConnection liveDataConnection;
|
||||
|
||||
private static Map<LiveDataConnection, IgtimiConnectionInfo> igtimiConnections;
|
||||
|
||||
private static boolean isExpeditionListenerRegistered;
|
||||
private static boolean isIgtimiListenerRegistered;
|
||||
|
||||
@@ -73,6 +66,7 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
super();
|
||||
isExpeditionListenerRegistered = false;
|
||||
isIgtimiListenerRegistered = false;
|
||||
igtimiConnections = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
protected int getIgtimiMessagesRawCount() {
|
||||
@@ -97,14 +91,21 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
synchronized (lock) {
|
||||
if (!isIgtimiListenerRegistered || reinitialize) {
|
||||
if (reinitialize) {
|
||||
try {
|
||||
if (liveDataConnection != null) {
|
||||
liveDataConnection.stop();
|
||||
liveDataConnection.removeListener(igtimiWindReceiver);
|
||||
liveDataConnection.removeListener(this);
|
||||
if (!igtimiConnections.isEmpty()) {
|
||||
for (Map.Entry<LiveDataConnection, IgtimiConnectionInfo> entry: igtimiConnections.entrySet()) {
|
||||
LiveDataConnection igtimiConnection = entry.getKey();
|
||||
try {
|
||||
if (igtimiConnection != null) {
|
||||
igtimiConnection.stop();
|
||||
igtimiConnection.removeListener(igtimiWindReceiver);
|
||||
igtimiConnection.removeListener(this);
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
igtimiConnections.clear();
|
||||
}
|
||||
}
|
||||
isIgtimiListenerRegistered = registerIgtimiListener();
|
||||
@@ -114,77 +115,6 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String reinitializeWindReceiverParameter = req.getParameter(PARAM_RELOAD_WIND_RECEIVER);
|
||||
initializeWindReceiver(reinitializeWindReceiverParameter != null && reinitializeWindReceiverParameter.equalsIgnoreCase("true"));
|
||||
resp.setContentType("text/html");
|
||||
PrintWriter out = resp.getWriter();
|
||||
out.println("<html>");
|
||||
out.println("<head>");
|
||||
out.println("<title>Wind Status</title>");
|
||||
out.println("<meta http-equiv=refresh content='10; url="+req.getRequestURI()+"'>");
|
||||
out.println("</head>");
|
||||
out.println("<body>");
|
||||
out.println("<p>Reload wind connectors with parameter <a href=\"/sailingserver/windStatus?reloadWindReceiver=true\">reloadWindReceiver=true</a>. This will force a connection reset and a reloading of the wind receivers.</p>");
|
||||
out.println("<h3>Igtimi Wind Status ("+igtimiRawMessageCount+" raw messages received)</h3>");
|
||||
if (lastIgtimiMessages != null && !lastIgtimiMessages.isEmpty()) {
|
||||
for(Entry<String, Deque<IgtimiMessageInfo>> deviceAndMessagesList: lastIgtimiMessages.entrySet()) {
|
||||
final Deque<IgtimiMessageInfo> copyOfLastIgtimiMessages;
|
||||
synchronized (deviceAndMessagesList.getValue()) {
|
||||
copyOfLastIgtimiMessages = new ArrayDeque<>(deviceAndMessagesList.getValue());
|
||||
}
|
||||
out.println("Windbot: <b>" + deviceAndMessagesList.getKey() + "</b>");
|
||||
if(copyOfLastIgtimiMessages.size() > 0) {
|
||||
TimePoint latestTimePoint = copyOfLastIgtimiMessages.peek().wind.getTimePoint();
|
||||
long lastFixDiffInMs = System.currentTimeMillis() - latestTimePoint.asMillis();
|
||||
out.println(" Last fix:");
|
||||
if(lastFixDiffInMs / 1000 < 60) {
|
||||
out.println(lastFixDiffInMs / 1000 +"s ago");
|
||||
} else {
|
||||
out.println("<span style=\"color:red;\">" + lastFixDiffInMs / 1000 +"min ago</span>");
|
||||
}
|
||||
}
|
||||
out.println("<br/>");
|
||||
Iterator<IgtimiMessageInfo> messageIt = copyOfLastIgtimiMessages.iterator();
|
||||
while (messageIt.hasNext()){
|
||||
IgtimiMessageInfo message = messageIt.next();
|
||||
out.println(message);
|
||||
out.println("<br/>");
|
||||
}
|
||||
out.println("<br/>");
|
||||
}
|
||||
} else {
|
||||
if (igtimiRawMessageCount == 0) {
|
||||
out.println("<i>No Igtimi messages received so far!</i>");
|
||||
} else {
|
||||
out.println("<i>"+igtimiRawMessageCount+" Igtimi message bunch has been received but not enough messages to generate wind information.</i>");
|
||||
}
|
||||
}
|
||||
out.println("<h3>Expedition Wind Status</h3>");
|
||||
if (lastExpeditionMessages != null && !lastExpeditionMessages.isEmpty()) {
|
||||
final List<ExpeditionMessageInfo> copyOfLastExpeditionMessages;
|
||||
synchronized (lastExpeditionMessages) {
|
||||
copyOfLastExpeditionMessages = new ArrayList<>(WindStatusServlet.lastExpeditionMessages);
|
||||
}
|
||||
int expeditionMsgCounter = 0;
|
||||
for (ListIterator<ExpeditionMessageInfo> iterator = copyOfLastExpeditionMessages.listIterator(copyOfLastExpeditionMessages.size()); iterator.hasPrevious();) {
|
||||
expeditionMsgCounter++;
|
||||
ExpeditionMessageInfo message = iterator.previous();
|
||||
out.println(message);
|
||||
out.println("<br/>");
|
||||
if (expeditionMsgCounter >= NUMBER_OF_MESSAGES_TO_SHOW) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.println("<i>No Expedition messages received so far!</i>");
|
||||
}
|
||||
out.println("</body>");
|
||||
out.println("</html>");
|
||||
out.close();
|
||||
}
|
||||
|
||||
private boolean registerIgtimiListener() {
|
||||
boolean result = false;
|
||||
ServiceTracker<IgtimiConnectionFactory, IgtimiConnectionFactory> igtimiServiceTracker = new ServiceTracker<IgtimiConnectionFactory, IgtimiConnectionFactory>(getContext(), IgtimiConnectionFactory.class, null);
|
||||
@@ -196,9 +126,16 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
if (account.getUser() != null) {
|
||||
IgtimiConnection igtimiConnection = igtimiConnectionFactory.connect(account);
|
||||
try {
|
||||
liveDataConnection = igtimiConnection.getOrCreateLiveConnection(igtimiConnection.getWindDevices());
|
||||
liveDataConnection.addListener(igtimiWindReceiver);
|
||||
liveDataConnection.addListener(this);
|
||||
LiveDataConnection newIgtimiConnection = igtimiConnection.getOrCreateLiveConnection(igtimiConnection.getWindDevices());
|
||||
newIgtimiConnection.addListener(igtimiWindReceiver);
|
||||
newIgtimiConnection.addListener(this);
|
||||
|
||||
IgtimiConnectionInfo newIgtimiConnectionInfo = new IgtimiConnectionInfo();
|
||||
newIgtimiConnectionInfo.remoteAddress = newIgtimiConnection.getRemoteAddress();
|
||||
newIgtimiConnectionInfo.accountName = account.getUser().getEmail();
|
||||
Util.addAll(igtimiConnection.getWindDevices(), newIgtimiConnectionInfo.deviceIDs);
|
||||
igtimiConnections.put(newIgtimiConnection, newIgtimiConnectionInfo);
|
||||
|
||||
result = true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -236,7 +173,13 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected class IgtimiConnectionInfo {
|
||||
InetSocketAddress remoteAddress;
|
||||
String accountName;
|
||||
List<String> deviceIDs = new ArrayList<>();
|
||||
}
|
||||
|
||||
protected class ExpeditionMessageInfo {
|
||||
Integer boatID;
|
||||
ExpeditionMessage message;
|
||||
@@ -296,20 +239,24 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (liveDataConnection != null) {
|
||||
for (Map.Entry<LiveDataConnection, IgtimiConnectionInfo> entry: igtimiConnections.entrySet()) {
|
||||
LiveDataConnection igtimiConnection = entry.getKey();
|
||||
try {
|
||||
liveDataConnection.stop();
|
||||
igtimiConnection.stop();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
liveDataConnection = null;
|
||||
isIgtimiListenerRegistered = false;
|
||||
}
|
||||
}
|
||||
igtimiConnections.clear();
|
||||
isIgtimiListenerRegistered = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void received(Iterable<Fix> fixes) {
|
||||
igtimiRawMessageCount += 1;
|
||||
}
|
||||
|
||||
public static Map<LiveDataConnection, IgtimiConnectionInfo> getIgtimiConnections() {
|
||||
return igtimiConnections;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user