Merge branch 'master' into test

This commit is contained in:
Axel Uhl committed 2011-06-14 19:27:11 +02:00
commit abe8a71d15
17 files changed
+386 -38

No files matched your search

Executable
+177
View File
@@ -0,0 +1,177 @@
This file explains the typical administrative tasks to be performed on
the SAP Sailing server. For an explanation of what this server does,
please refer to the README file stored next to this ADMIN file.
Emercengy Startup After Reboot
------------------------------
When for some reason the server re-booted, a number of manual steps
need to be performed to get back up and running. Proceed as follows:
- "ssh -A -L 5911:localhost:5902 trac@kielweek.web4sap.com"
- "vncserver -depth 24 -geometry 1600x900 :2"
Connect with your VNC viewer to localhost:11 and open six console
windows. Perform the steps "Launching Readily-built Java Server
Instances" for the <instance> names dev, test, prod1 and prod2 in a
separate console window each.
Perform the steps "Launch MongoDB" and "Launch Python Server"
described below. Use one of the two spare consoles in VNC to perform
the step "Launch UDP Mirror" described below.
Launching Readily-built Java Server Instances
---------------------------------------------
We usually launch, manage and observe the Java server instances using
a VNC viewer which connects to port 5902 of the server. We have a
console window there for each server instance, and the console
windows' title bars indicate by the current working directory which
window represents which instance. This section describes how to
initially start a server instance. See below for how to update and
restart an already running instance.
Port 5902 is blocked by the firewall, so you have to establish an SSH
tunnel, e.g., by
- ssh -A -L 5911:localhost:22 trac@kielweek.web4sap.com
You can then have your VNC viewer connect to you localhost:11. In the
console for the server instance you want to launch, ensure you're in
the correct directory, if not already there:
- "cd servers/<instance>" where <instance> is one of
dev/test/prod1/prod2
Then launch the server:
- ./start
This should start an OSGi console with the latest version of the
bundles deployed to ~trac/servers/<instance>/plugins.
Launch MongoDB
--------------
The MongoDB is used to store wind information and general
leaderboard-related information required by the Python web
application.
- log in as user "web"
- "cd project/dev/python"
- "bin/supervisord"
This will launch the MongoDB server, listening on port 10200. You can
check whether the MongoDB server started successfully by issuing the
following command:
- "bin/supervisorctl"
Launch Python Server
---------------------
The Python Server implements the web applications used by the
moderator as well as the iPhone/iPad web application.
- log in as user "web"
- "cd project/dev/python"
- nohup bin/debug.sh
Launch UDP Mirror
-----------------
The two production instances shall share the same wind
information. Therefore, it is necessary to launch a "UDP mirror" that
distributes UDP packets received on the single inbound UDP port for
the production instances to the two Java server instances.
In the VNC session, use a separate console window for user "trac" and
do the following:
- "cd ~/servers/prod1"
- "./udpmirror -v 2012 localhost 2013 localhost 2014"
The "-v" argument ensures that UDP packets received will be dumped to
the console. The process will listen for inbound UDP packets on port
2012 and forward anything received on that port to localhost:2013 as
well as localhost:2014. See also the list of ports as documented in
the README file.
Re-Building the Java Server
---------------------------
If, e.g., after a bug fix, it is necessary to re-build and re-deploy
the Java server, you should consider doing this first on the "master"
branch of the git versioning system. The master branch contains the
sources for the "dev" server instance. The git branch to server
instance mappings are as follows:
git branch server instance
---------- ---------------
master dev
test test
prod prod1 / prod2
First, check out the branch you want to re-build:
- log in as user "trac"
- ensure that your SSH key is loaded / unlocked, either by logging in
using SSH with the -A argument, or by invoking the alias "sa" and
entering the password for the trac user's SSH key
- ensure there is an ssh tunnel with port forward from port 12347 to
port 22, e.g., by running the following command:
"ssh -A -L 12347:localhost:22 trac@localhost"
- "cd git/java"
- "git checkout -f <branchname>" where <branchname> is either one of
master, test or prod
- ensure that there is an ssh tunnel to localhost that
- "mvn deploy"
This will compile the sources, bundle them up in to OSGi bundle JAR
files, run all tests which required online access to the TracTrac
servers, and, if successful, deploy the new JAR files to
maven-repositories/<instancename> where <instancename> is one of dev,
test or prod.
Note that the running server(s) are not updated automatically by
deploying the new bundle versions to the maven-repositories
subdirectory. See next topic.
Updating an OSGi Server Instance
--------------------------------
We usually have four OSGi consoles running with a terminal window
each, visible at the VNC server running on por 5902. The title bar
shows the current working directory which should be something like
"~/servers/<instancename>" where <instancename> is one of dev, test,
prod1 and prod2.
At the "osgi>" prompt of the OSGi console you can type
- "exit"
to terminate the particular Java server instance. To update the server
instance from its respective maven repository (located under
~/maven-repositories/...) you can issue
- "./update"
To start the server instance again, type
- "./start"
and the server should welcome you again with the "osgi>" prompt after
a successful start.
Executable
+64
View File
@@ -0,0 +1,64 @@
This is a short readme file outlining the architecture of the SAP
Sailing server. For hints for how to perform typical administrative
tasks, please see the ADMIN file which should be stored right next to
this README file.
The architecture mainly consists of
- A 64-bit Linux server running the following services.
- Apache web server handling inbound HTTP requests on port 80 (see
hostname configurations in /etc/httpd/conf.d/kiel.conf)
- dev/test/prod1/prod2 OSGi server instances running the Java
component
- UDP mirror process that duplicates UDP packets received for "the"
production instance and forwards them to the two inbound UDP ports
for prod1 and prod2, respectively.
- dev/test/prod Python servers running the web application for
browser, iPhone and iPad that connect to a Java OSGi server to
complete its requests
- a Pound load balancer that does alive checks for the prod1/prod2
Java instances to enable quick fail-over
- a number of MongoDB instances for dev/test/prod1/prod2 that store
leaderboard information for the Python application as well as wind
information for the Java component
We have a VNC server running on port 5902 with a KDE window
manager. There, we operate console windows for the various Java
instances and the UDP mirror.
Inbound Port Assignments
------------------------
- TCP
22: ssh
80: apache
5902: vnc
8026: Python "dev" instance
8886: servlet container of "dev" Java instance
8887: servlet container of "test" Java instance
8888: servlet container of "prod1" Java instance
8889: servlet container of "prod2" Java instance
10200: MongoDB "dev" instance
12347: SSH forward to localhost:22 required for "mvn deploy"
- UDP
2010: wind input for "dev" Java instance
2011: wind input for "test" Java instance
2012: wind input for "prod" (mirrored to 2013/2014)
2013: wind input for "prod1" Java instance
2014: wind input for "prod2" Java instance
Java
----
We use Equinox as an OSGi container into which we deploy a set of
bundles that implement TracTrac connectivity, Expedition wind
connectivity, sailing domain knowledge, race tracking capabilities as
well as servlets with RESTful APIs for use by web clients.
The
@@ -16,5 +16,5 @@
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.domain.test"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -XX:+UseParallelGC"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -XX:+UseParallelGC -Dtractrac.tunnel=true"/>
</launchConfiguration>
@@ -46,13 +46,15 @@ public abstract class AbstractTracTracLiveTest implements Listener {
// for stored race, non-real-time simulation:
paramUrl = new URL("http://germanmaster.traclive.dk/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=bd8c778e-7c65-11e0-8236-406186cbf87c");
// tunneled:
//liveUri = new URI("tcp://localhost:4412");
//storedUri = new URI("tcp://localhost:4413");
//no tunnel:
liveUri = new URI("tcp://germanmaster.traclive.dk:4400");
storedUri = new URI("tcp://germanmaster.traclive.dk:4401");
if (Boolean.valueOf(System.getProperty("tractrac.tunnel", "false"))) {
// tunnel
liveUri = new URI("tcp://localhost:4412");
storedUri = new URI("tcp://localhost:4413");
} else {
//no tunnel:
liveUri = new URI("tcp://germanmaster.traclive.dk:4400");
storedUri = new URI("tcp://germanmaster.traclive.dk:4401");
}
receivers = new HashSet<Receiver>();
}
@@ -22,8 +22,14 @@ public interface Track<FixType extends Timed> {
FixType getFirstFixAfter(TimePoint timePoint);
/**
* The first fix in this track or <code>null</code> if the track is empty
*/
FixType getFirstFix();
/**
* The last fix in this track or <code>null</code> if the track is empty
*/
FixType getLastFix();
/**
@@ -80,7 +80,7 @@ public interface TrackedRace {
* @return a sequential number counting the updates that occurred to this tracked race. Callers may use this to ask
* for updates newer than such a sequence number.
*/
int getUpdateCount();
long getUpdateCount();
int getRankDifference(Competitor competitor, Leg leg, TimePoint timePoint);
@@ -74,13 +74,21 @@ public abstract class TrackImpl<FixType extends Timed> implements Track<FixType>
@SuppressWarnings("unchecked")
@Override
public FixType getFirstFix() {
return (FixType) fixes.first();
if (fixes.isEmpty()) {
return null;
} else {
return (FixType) fixes.first();
}
}
@SuppressWarnings("unchecked")
@Override
public FixType getLastFix() {
return (FixType) fixes.last();
if (fixes.isEmpty()) {
return null;
} else {
return (FixType) fixes.last();
}
}
@Override
@@ -47,7 +47,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
private TimePoint finish;
private TimePoint timePointOfNewestEvent;
private TimePoint timePointOfLastEvent;
private int updateCount;
private long updateCount;
private final Map<TimePoint, TreeSet<Competitor>> competitorRankings;
@@ -216,7 +216,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
}
@Override
public int getUpdateCount() {
public long getUpdateCount() {
return updateCount;
}
@@ -242,18 +242,18 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
@Override
public int getRank(Competitor competitor, TimePoint timePoint) throws NoWindException {
try {
synchronized (competitorRankings) {
TreeSet<Competitor> rankedCompetitors = competitorRankings.get(timePoint);
if (rankedCompetitors == null) {
RaceRankComparator comparator = new RaceRankComparator(this, timePoint);
rankedCompetitors = new TreeSet<Competitor>(comparator);
for (Competitor c : getRace().getCompetitors()) {
rankedCompetitors.add(c);
synchronized (competitorRankings) {
TreeSet<Competitor> rankedCompetitors = competitorRankings.get(timePoint);
if (rankedCompetitors == null) {
RaceRankComparator comparator = new RaceRankComparator(this, timePoint);
rankedCompetitors = new TreeSet<Competitor>(comparator);
for (Competitor c : getRace().getCompetitors()) {
rankedCompetitors.add(c);
}
competitorRankings.put(timePoint, rankedCompetitors);
}
competitorRankings.put(timePoint, rankedCompetitors);
return rankedCompetitors.headSet(competitor, /* inclusive */true).size();
}
return rankedCompetitors.headSet(competitor, /* inclusive */ true).size();
}
} catch (NoWindError e) {
throw e.getCause();
}
@@ -37,7 +37,7 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
}
@Override
public synchronized void add(Wind wind) {
public void add(Wind wind) {
getInternalFixes().add(wind);
notifyListenersAboutReceive(wind);
}
@@ -99,7 +99,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public int getUpdateCount() {
public long getUpdateCount() {
// TODO Auto-generated method stub
return 0;
}
@@ -1,6 +1,7 @@
package com.sap.sailing.expeditionconnector.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -164,6 +165,37 @@ public class UDPExpeditionReceiverTest {
assertTrue(cal.get(Calendar.SECOND) == 46 || cal.get(Calendar.SECOND) == 45);
}
/**
* If no timestamp is received in a message, by default the time the message was received is used to fill it in.
*/
@Test
public void testTimeStampCompletionFromCurrentTime() throws IOException, InterruptedException {
receiver.addListener(listener, /* validMessagesOnly */ true);
sendAndWaitABit(new String[] { "#0,9,318.0*0E" });
assertEquals(1, messages.size());
assertFalse(messages.get(0).hasValue(ExpeditionMessage.ID_GPS_TIME));
assertEquals(messages.get(0).getCreatedAt(), messages.get(0).getTimePoint());
}
/**
* If no timestamp is received in a message, by default the time the message was received is used to fill it in.
*/
@Test
public void testTimeStampCompletionFromLastTimePointReceived() throws IOException, InterruptedException {
receiver.addListener(listener, /* validMessagesOnly */ true);
sendAndWaitABit(validLines);
assertEquals(validLines.length, messages.size());
assertTrue(messages.get(0).hasValue(ExpeditionMessage.ID_GPS_TIME));
assertTrue(messages.get(10).hasValue(ExpeditionMessage.ID_GPS_TIME));
TimePoint m0Time = messages.get(0).getTimePoint();
TimePoint m10Time = messages.get(10).getTimePoint();
for (int i=1; i<=9; i++) {
TimePoint m_iTime = messages.get(i).getTimePoint();
assertTrue(m_iTime.compareTo(m0Time) >= 0);
assertTrue(m_iTime.compareTo(m10Time) <= 0);
}
}
@Test
public void sendAndValidateSomeInvalidDatagrams() throws IOException, InterruptedException {
receiver.addListener(listener, /* validMessagesOnly */ true);
@@ -102,4 +102,6 @@ public interface ExpeditionMessage {
Bearing getCourseOverGround();
TimePoint getTimePoint();
TimePoint getCreatedAt();
}
@@ -10,6 +10,8 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.sap.sailing.domain.base.TimePoint;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.expeditionconnector.impl.ExpeditionMessageImpl;
/**
@@ -35,6 +37,12 @@ public class UDPExpeditionReceiver implements Runnable {
* Maximum IP packet length
*/
private static final int MAX_PACKET_SIZE = 65536;
/**
* Remembers, per boat ID, the milliseconds difference between the time the message was received
* and the GPS time stamp provided by the message.
*/
private final Map<Integer, Long> timeStampOfLastMessageReceived;
/**
* Launches a listener and dumps messages received to the console
@@ -61,6 +69,7 @@ public class UDPExpeditionReceiver implements Runnable {
udpSocket = new DatagramSocket(listeningOnPort);
listeners = new HashMap<ExpeditionListener, Boolean>();
this.listeningOnPort = listeningOnPort;
this.timeStampOfLastMessageReceived = new HashMap<Integer, Long>();
}
public void stop() throws SocketException, IOException {
@@ -110,6 +119,16 @@ public class UDPExpeditionReceiver implements Runnable {
String variableValuePairs = m.group(2).trim().substring(",".length()); // skip the leading ","
Map<Integer, Double> values = new HashMap<Integer, Double>();
String[] variablesAndValuesInterleaved = variableValuePairs.split(",");
long now = System.currentTimeMillis();
Long diff = timeStampOfLastMessageReceived.get(boatID);
TimePoint defaultForMessageTimePoint;
if (diff != null) {
// compute a reasonable default for a time stamp in case message doesn't provide one
// by subtracting the last diff from now
defaultForMessageTimePoint = new MillisecondsTimePoint(now - diff);
} else {
defaultForMessageTimePoint = MillisecondsTimePoint.now();
}
for (int i = 0; i < variablesAndValuesInterleaved.length; i++) {
int variableID = Integer.valueOf(variablesAndValuesInterleaved[i++]);
double variableValue = Double.valueOf(variablesAndValuesInterleaved[i]);
@@ -117,7 +136,12 @@ public class UDPExpeditionReceiver implements Runnable {
}
int checksum = Integer.valueOf(m.group(m.groupCount()), 16);
valid = valid && checksumOk(checksum, packetAsString);
return new ExpeditionMessageImpl(boatID, values, valid);
ExpeditionMessageImpl result = new ExpeditionMessageImpl(boatID, values, valid, defaultForMessageTimePoint);
if (result.hasValue(ExpeditionMessage.ID_GPS_TIME)) {
// an original GPS time stamp; then remember the difference between now and the time stamp
timeStampOfLastMessageReceived.put(boatID, now-result.getTimePoint().asMillis());
}
return result;
} else {
System.err.println("Unparsable expedition message: " + packetAsString);
return null; // couldn't even parse
@@ -28,6 +28,18 @@ public class ExpeditionMessageImpl implements ExpeditionMessage {
private final long createdAtMillis;
private final TimePoint timePoint;
private static final TimeZone UTC = TimeZone.getTimeZone("UTC") == null ? TimeZone.getTimeZone("GMT") : TimeZone.getTimeZone("UTC");
private static final GregorianCalendar cal = new GregorianCalendar(UTC);
static {
cal.set(1899, 11, 30, 0, 0, 0);
}
/**
* Creates a message instance based on <code>values</code>. If there is no timestamp delivered by
* <code>values</code>, the {@link System#currentTimeMillis() current time} is used as the message's
* {@link #getTimePoint() time point}.
*/
public ExpeditionMessageImpl(int boatID, Map<Integer, Double> values, boolean valid) {
this.boatID = boatID;
// ensure that nobody can manipulate the map used by this message object from outside
@@ -35,12 +47,6 @@ public class ExpeditionMessageImpl implements ExpeditionMessage {
this.valid = valid;
this.createdAtMillis = System.currentTimeMillis();
if (hasValue(ID_GPS_TIME)) {
TimeZone UTC = TimeZone.getTimeZone("UTC");
if (UTC == null) {
UTC = TimeZone.getTimeZone("GMT");
}
GregorianCalendar cal = new GregorianCalendar(UTC);
cal.set(1899, 11, 30, 0, 0, 0);
timePoint = new MillisecondsTimePoint((long)
(getValue(ID_GPS_TIME)*24*3600*1000) + // this is the milliseconds since 31.12.1899 0:00:00 UTC
cal.getTimeInMillis());
@@ -49,6 +55,29 @@ public class ExpeditionMessageImpl implements ExpeditionMessage {
}
}
/**
* @param defaultTimePoint
* a non-<code>null</code> default time point to use in case the message received does not carry a time
* stamp
*/
public ExpeditionMessageImpl(int boatID, Map<Integer, Double> values, boolean valid, TimePoint defaultTimePoint) {
if (defaultTimePoint == null) {
throw new IllegalArgumentException("defaultTimePoint for ExpeditionMessageImpl constructor must not be null");
}
this.boatID = boatID;
// ensure that nobody can manipulate the map used by this message object from outside
this.values = new HashMap<Integer, Double>(values);
this.valid = valid;
this.createdAtMillis = System.currentTimeMillis();
if (hasValue(ID_GPS_TIME)) {
timePoint = new MillisecondsTimePoint((long)
(getValue(ID_GPS_TIME)*24*3600*1000) + // this is the milliseconds since 31.12.1899 0:00:00 UTC
cal.getTimeInMillis());
} else {
timePoint = defaultTimePoint;
}
}
@Override
public boolean isValid() {
return valid;
@@ -91,6 +120,11 @@ public class ExpeditionMessageImpl implements ExpeditionMessage {
return timePoint;
}
@Override
public TimePoint getCreatedAt() {
return new MillisecondsTimePoint(createdAtMillis);
}
@Override
public GPSFixMoving getGPSFixMoving() {
if (hasValue(ID_GPS_LAT) && hasValue(ID_GPS_LNG)) {
@@ -11,7 +11,6 @@
<booleanAttribute key="default" value="true"/>
<booleanAttribute key="default_auto_start" value="true"/>
<intAttribute key="default_start_level" value="4"/>
<stringAttribute key="deselected_workspace_plugins" value="ucar.grib.osgi"/>
<booleanAttribute key="includeOptional" value="true"/>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
@@ -23,9 +22,9 @@
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dorg.osgi.service.http.port=8888"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="org.eclipse.equinox.http.servlet@default:default,org.eclipse.osgi@-1:true,org.apache.ant@default:default,org.hamcrest.core@default:default,org.eclipse.net4j.jms.api@default:default,javax.activation@default:default,org.junit*4.8.1.v4_8_1_v20100427-1100@default:default,org.eclipse.equinox.http.jetty@default:default,javax.transaction@default:false,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.jobs@default:default,org.apache.jasper@default:default,org.mortbay.jetty.util@default:default,org.junit4@default:default,ch.qos.logback.classic@default:default,org.eclipse.osgi.services@default:default,ch.qos.logback.core@default:default,org.eclipse.equinox.util@default:default,org.apache.commons.el@default:default,org.mortbay.jetty.server@default:default,org.eclipse.osgi.util@default:default,javax.servlet.jsp@default:default,org.eclipse.equinox.common@2:true,org.slf4j.api@default:default,ch.qos.logback.slf4j@default:false,org.junit*3.8.2.v3_8_2_v20100427-1100@default:default,javax.servlet@default:default,org.eclipse.equinox.registry@default:default,org.apache.commons.logging@default:default,org.eclipse.equinox.http.registry@default:default"/>
<stringAttribute key="target_bundles" value="javax.servlet.jsp@default:default,javax.servlet@default:default,org.apache.ant@default:default,org.apache.commons.el@default:default,org.apache.commons.logging@default:default,org.apache.jasper@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.equinox.common@2:true,org.eclipse.equinox.http.jetty@default:default,org.eclipse.equinox.http.registry@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.util@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi.util@default:default,org.eclipse.osgi@-1:true,org.hamcrest.core@default:default,org.junit*3.8.2.v3_8_2_v20100427-1100@default:default,org.junit4@default:default,org.mortbay.jetty.server@default:default,org.mortbay.jetty.util@default:default"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="true"/>
<stringAttribute key="workspace_bundles" value="com.sap.sailing.declination@default:default,com.sap.sailing.declination.test@default:default,com.sap.sailing.expeditionconnector.test@default:default,com.sap.sailing.domain.tractracadapter@default:default,com.tractrac.resultapi@default:default,com.sap.sailing.server@default:default,com.tractrac.clientmodule@default:default,com.sap.sailing.domain.test@default:default,com.sap.sailing.domain@default:default,com.sap.sailing.expeditionconnector@default:default,org.json.simple@default:default"/>
<stringAttribute key="workspace_bundles" value="com.googlecode.java-diff-utils.test@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.declination.test@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.test@default:default,com.sap.sailing.domain.tractracadapter@default:default,com.sap.sailing.domain@default:default,com.sap.sailing.expeditionconnector.test@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.mongodb.test@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.server.test@default:default,com.sap.sailing.server@default:default,com.tractrac.clientmodule@default:default,com.tractrac.resultapi@default:default,org.json.simple@default:default"/>
</launchConfiguration>
@@ -20,9 +20,9 @@
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dhttp.proxyHost=proxy.wdf.sap.corp -Dhttp.proxyPort=8080&#13;&#10;-Dorg.osgi.service.http.port=8888"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="org.mortbay.jetty.server@default:default,ch.qos.logback.core@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.equinox.http.servlet@default:default,org.apache.jasper@default:default,ch.qos.logback.classic@default:default,org.apache.ant@default:default,org.eclipse.net4j.jms.api@default:default,org.eclipse.equinox.common@2:true,javax.servlet@default:default,org.eclipse.osgi.services@default:default,org.eclipse.equinox.http.jetty@default:default,org.eclipse.osgi@-1:true,org.eclipse.equinox.http.registry@default:default,org.eclipse.core.jobs@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.update.configurator@3:true,javax.servlet.jsp@default:default,javax.transaction@default:false,org.apache.commons.logging@default:default,org.eclipse.equinox.weaving.hook@default:false,org.slf4j.api@default:default,javax.activation@default:default,org.apache.commons.el@default:default,ch.qos.logback.slf4j@default:false,org.mortbay.jetty.util@default:default"/>
<stringAttribute key="target_bundles" value="javax.servlet.jsp@default:default,javax.servlet@default:default,org.apache.ant@default:default,org.apache.commons.el@default:default,org.apache.commons.logging@default:default,org.apache.jasper@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.equinox.common@2:true,org.eclipse.equinox.http.jetty@default:default,org.eclipse.equinox.http.registry@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.update.configurator@3:true,org.mortbay.jetty.server@default:default,org.mortbay.jetty.util@default:default"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
<stringAttribute key="workspace_bundles" value="com.sap.sailing.declination@default:default,com.mongodb.driver@default:default,com.sap.sailing.server@default:default,com.sap.sailing.domain@default:default,com.tractrac.clientmodule@default:default,com.sap.sailing.expeditionconnector@default:default,org.json.simple@default:default,com.sap.sailing.mongodb.test@default:default,com.sap.sailing.expeditionconnector.test@default:default,com.tractrac.resultapi@default:default,com.sap.sailing.domain.test@default:default,com.sap.sailing.domain.tractracadapter@default:default,com.sap.sailing.mongodb@default:default"/>
<stringAttribute key="workspace_bundles" value="com.googlecode.java-diff-utils.test@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.declination.test@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.test@default:default,com.sap.sailing.domain.tractracadapter@default:default,com.sap.sailing.domain@default:default,com.sap.sailing.expeditionconnector.test@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.mongodb.test@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.server.test@default:default,com.sap.sailing.server@default:default,com.tractrac.clientmodule@default:default,com.tractrac.resultapi@default:default,org.json.simple@default:default"/>
</launchConfiguration>
@@ -186,9 +186,9 @@ public class ModeratorApp extends Servlet {
trackedRace.getTimePointOfLastEvent()==null?MillisecondsTimePoint.now():trackedRace.getTimePointOfLastEvent());
String sinceUpdateString = req.getParameter(PARAM_NAME_SINCE_UPDATE);
if (sinceUpdateString != null) {
System.out.println("Blocking...");
int sinceUpdate = Integer.valueOf(sinceUpdateString);
// block until there is new data:
System.out.println("Blocking at "+trackedRace.getUpdateCount()+" waiting for "+sinceUpdate);
trackedRace.waitForNextUpdate(sinceUpdate);
}
JSONObject jsonRace = new JSONObject();