Merge branch 'master' into prod

This commit is contained in:
Axel Uhl committed 2011-06-13 01:13:13 +02:00
commit 5812eeed95
19 files changed
+309 -98

No files matched your search

@@ -45,8 +45,14 @@ public abstract class AbstractTracTracLiveTest implements Listener {
// storedUri = new URI("tcp://sapsimulation.tracdev.dk:4421"); // or with tunneling: tcp://localhost:4421
// 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");
liveUri = new URI("tcp://localhost:4412");
storedUri = new URI("tcp://localhost:4413");
// 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");
receivers = new HashSet<Receiver>();
}
@@ -2,12 +2,14 @@ package com.sap.sailing.domain.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
@@ -15,15 +17,20 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.ControlPoint;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.CourseListener;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.BuoyImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.tracking.DynamicTrackedEvent;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.Receiver;
@@ -42,6 +49,7 @@ import difflib.Patch;
import difflib.PatchFailedException;
public class CourseUpdateTest extends AbstractTracTracLiveTest {
private RaceDefinition race;
private Course course;
private Event domainEvent;
private DynamicTrackedEvent trackedEvent;
@@ -73,10 +81,14 @@ public class CourseUpdateTest extends AbstractTracTracLiveTest {
}
});
addListenersForStoredDataAndStartController(receivers);
RaceDefinition race = domainFactory.getRaceDefinition(getEvent().getRaceList().iterator().next());
race = domainFactory.getRaceDefinition(getEvent().getRaceList().iterator().next());
course = race.getCourse();
assertNotNull(course);
assertEquals(3, Util.size(course.getWaypoints()));
// make sure leg is initialized correctly in CourseImpl
assertEquals("start/finish", course.getLegs().get(0).getFrom().getName());
assertEquals("top", course.getLegs().get(1).getFrom().getName());
}
@Test
@@ -189,6 +201,47 @@ public class CourseUpdateTest extends AbstractTracTracLiveTest {
assertTrue(result[0]);
}
@Test
public void testTrackedRacesTrackedLegsUpdatedProperly() throws InterruptedException, PatchFailedException {
final boolean[] result = new boolean[1];
final com.tractrac.clientmodule.ControlPoint cp1 = new com.tractrac.clientmodule.ControlPoint(
UUID.randomUUID(), "CP1", /* hasTwo */false) {
};
waitForRouteData();
final List<com.tractrac.clientmodule.ControlPoint> controlPoints = new ArrayList<com.tractrac.clientmodule.ControlPoint>(
routeData[0].getPoints());
controlPoints.add(cp1);
course.addCourseListener(new CourseListener() {
@Override
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
System.out.println("waypointAdded " + zeroBasedIndex + " / " + waypointThatGotAdded);
ControlPoint cp = domainFactory.getControlPoint(cp1);
result[0] = zeroBasedIndex == controlPoints.size() - 1 && waypointThatGotAdded.getControlPoint() == cp;
}
@Override
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
System.out.println("waypointRemoved " + zeroBasedIndex + " / " + waypointThatGotRemoved);
}
});
domainFactory.updateCourseWaypoints(course, controlPoints);
assertTrue(result[0]);
TrackedRace trackedRace = trackedEvent.getTrackedRace(race);
Iterator<Leg> legIter = course.getLegs().iterator();
for (TrackedLeg trackedLeg : trackedRace.getTrackedLegs()) {
assertTrue(legIter.hasNext());
Leg leg = legIter.next();
assertSame(leg, trackedLeg.getLeg());
}
// and again, this time for the TrackedLegOfCompetitors
for (Leg leg : course.getLegs()) {
for (Competitor competitor : race.getCompetitors()) {
TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, leg);
assertSame(leg, trackedLegOfCompetitor.getLeg());
}
}
}
@After
public void tearDown() {
routeData[0] = null;
@@ -133,6 +133,11 @@ public class DomainFactoryImpl implements DomainFactory {
Iterable<Waypoint> courseWaypoints = courseToUpdate.getWaypoints();
List<Waypoint> newWaypointList = new LinkedList<Waypoint>();
for (ControlPoint tractracControlPoint : controlPoints) {
// The following creates new waypoints; those using equal control points (equality controlled by their UUID)
// are considered equal. Therefore, the diff will try to construct a minimal set of changes where those
// old waypoints remain the same but where the patch may alter their positions. Deleted waypoints are trivial
// regarding ID retention. Waypoints added obtain a new ID during the createWaypoint and will be inserted
// with this new ID.
Waypoint waypoint = createWaypoint(tractracControlPoint);
newWaypointList.add(waypoint);
}
@@ -49,8 +49,8 @@ public class TracTracTrackedRaceImpl extends DynamicTrackedRaceImpl implements D
}
@Override
protected TrackedLeg createTrackedLeg(RaceDefinition race, Leg leg) {
return new TracTracTrackedLegImpl(this, leg, race.getCompetitors());
protected TrackedLeg createTrackedLeg(Leg leg) {
return new TracTracTrackedLegImpl(this, leg, getRace().getCompetitors());
}
@Override
@@ -36,12 +36,15 @@ public class CourseImpl extends NamedImpl implements Course {
if (waypointIter.hasNext()) {
Waypoint previous = waypointIter.next();
this.waypoints.add(previous);
waypointIndexes.put(previous, i++);
while (waypointIter.hasNext()) {
Waypoint current = waypointIter.next();
this.waypoints.add(current);
int indexOfStartWaypoint = i-1;
waypointIndexes.put(current, i++);
Leg leg = new LegImpl(this, i);
Leg leg = new LegImpl(this, indexOfStartWaypoint);
legs.add(leg);
previous = current;
}
@@ -58,7 +61,13 @@ public class CourseImpl extends NamedImpl implements Course {
@Override
public void addWaypoint(int zeroBasedPosition, Waypoint waypointToAdd) {
waypoints.add(zeroBasedPosition, waypointToAdd);
legs.add(new LegImpl(this, zeroBasedPosition));
int legStartWaypointIndex;
if (zeroBasedPosition == waypoints.size()-1) { // added to end
legStartWaypointIndex = zeroBasedPosition-1;
} else {
legStartWaypointIndex = zeroBasedPosition;
}
legs.add(new LegImpl(this, legStartWaypointIndex));
notifyListenersWaypointAdded(zeroBasedPosition, waypointToAdd);
}
@@ -182,7 +182,7 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
@Override
protected TrackedLeg createTrackedLeg(RaceDefinition race, Leg leg) {
return new TrackedLegImpl(this, leg, race.getCompetitors());
protected TrackedLeg createTrackedLeg(Leg leg) {
return new TrackedLegImpl(this, leg, getRace().getCompetitors());
}
}
@@ -97,7 +97,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
}
trackedLegs = new LinkedHashMap<Leg, TrackedLeg>();
for (Leg leg : race.getCourse().getLegs()) {
trackedLegs.put(leg, createTrackedLeg(race, leg));
trackedLegs.put(leg, createTrackedLeg(leg));
}
markPassingsForCompetitor = new HashMap<Competitor, NavigableSet<MarkPassing>>();
tracks = new HashMap<Competitor, GPSFixTrack<Competitor, GPSFixMoving>>();
@@ -115,9 +115,13 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
}
currentWindSource = WindSource.EXPEDITION;
competitorRankings = new HashMap<TimePoint, TreeSet<Competitor>>();
getRace().getCourse().addCourseListener(this);
}
abstract protected TrackedLeg createTrackedLeg(RaceDefinition race, Leg leg);
/**
* Precondition: race has already been set, e.g., in constructor before this methocd is called
*/
abstract protected TrackedLeg createTrackedLeg(Leg leg);
@Override
public NavigableSet<MarkPassing> getMarkPassings(Competitor competitor) {
@@ -388,13 +392,35 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
buoyTracks.put(buoy, new DynamicTrackImpl<Buoy, GPSFix>(buoy, millisecondsOverWhichToAverageSpeed));
}
}
// TODO update trackedLegs
// a waypoint got added; this means that a leg got added as well; but we shouldn't claim we know where
// in the leg list of the course the leg was added; that's an implementation secret of CourseImpl. So try:
LinkedHashMap<Leg, TrackedLeg> reorderedTrackedLegs = new LinkedHashMap<Leg, TrackedLeg>();
for (Leg leg : getRace().getCourse().getLegs()) {
if (!trackedLegs.containsKey(leg)) {
// no tracked leg for leg yet:
TrackedLeg newTrackedLeg = createTrackedLeg(leg);
reorderedTrackedLegs.put(leg, newTrackedLeg);
} else {
reorderedTrackedLegs.put(leg, trackedLegs.get(leg));
}
}
// now ensure that the iteration order is in sync with the leg iteration order
trackedLegs.clear();
for (Map.Entry<Leg, TrackedLeg> entry : reorderedTrackedLegs.entrySet()) {
trackedLegs.put(entry.getKey(), entry.getValue());
}
updated(/* time point*/ null);
}
@Override
public synchronized void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
// TODO update trackedLegs
TrackedLeg toRemove;
if (zeroBasedIndex > trackedLegs.size()) { // last waypoint removed
toRemove = getTrackedLegFinishingAt(waypointThatGotRemoved);
} else {
toRemove = getTrackedLegStartingAt(waypointThatGotRemoved);
}
trackedLegs.remove(toRemove.getLeg());
updated(/* time point*/ null);
}
}
@@ -22,19 +22,30 @@ public class UDPMirror {
if (args.length == 0) {
usage();
} else {
int listeningOnPort = Integer.valueOf(args[0]);
int c = 0;
boolean verbose = false;
if (args[c].equals("-v")) {
c++;
verbose = true;
}
int listeningOnPort = Integer.valueOf(args[c++]);
byte[] buf = new byte[65536];
DatagramSocket udpSocket = new DatagramSocket(listeningOnPort);
DatagramPacket received = new DatagramPacket(buf, buf.length);
DatagramSocket[] sendingSockets = new DatagramSocket[(args.length - 1) / 2];
DatagramPacket[] mirroredPackets = new DatagramPacket[(args.length - 1) / 2];
for (int i = 1; i < args.length - 1; i += 2) {
sendingSockets[(i - 1) / 2] = new DatagramSocket();
mirroredPackets[(i - 1) / 2] = new DatagramPacket(buf, buf.length, InetAddress.getByName(args[i]),
Integer.valueOf(args[i + 1]));
while (c < args.length - 1) {
sendingSockets[(c - 1) / 2] = new DatagramSocket();
mirroredPackets[(c - 1) / 2] = new DatagramPacket(buf, buf.length, InetAddress.getByName(args[c]),
Integer.valueOf(args[c + 1]));
c += 2;
}
while (true) {
udpSocket.receive(received);
if (verbose) {
String packetAsString = new String(received.getData(), received.getOffset(), received.getLength()).trim();
System.out.println(packetAsString);
}
for (int i = 0; i < mirroredPackets.length; i++) {
mirroredPackets[i].setLength(received.getLength());
sendingSockets[i].send(mirroredPackets[i]);
@@ -44,6 +55,7 @@ public class UDPMirror {
}
private static void usage() {
System.out.println("Usage: java "+UDPMirror.class.getName()+" <listeningport> hostname1 port1 [hostname2 port2]*");
System.out.println("Usage: java "+UDPMirror.class.getName()+" [-v] <listeningport> hostname1 port1 [hostname2 port2]*");
System.out.println(" -v\tPrint packets received to stdout");
}
}
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.pde.ui.EquinoxLauncher">
<booleanAttribute key="append.args" value="true"/>
<booleanAttribute key="automaticAdd" value="true"/>
<booleanAttribute key="automaticValidate" value="false"/>
<stringAttribute key="bad_container_name" value="\com.sap."/>
<stringAttribute key="bootstrap" value=""/>
<stringAttribute key="checked" value="[NONE]"/>
<booleanAttribute key="clearConfig" value="false"/>
<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/SailingServer (No Proxy, No Tests)"/>
<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="com.googlecode.java-diff-utils.test,com.sap.sailing.declination.test,com.sap.sailing.domain.test,com.sap.sailing.expeditionconnector.test,com.sap.sailing.mongodb.test"/>
<booleanAttribute key="includeOptional" value="true"/>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-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="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.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.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.tractracadapter@default:default,com.sap.sailing.domain@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.server@default:default,com.tractrac.clientmodule@default:default,com.tractrac.resultapi@default:default,org.json.simple@default:default"/>
</launchConfiguration>
@@ -219,7 +219,9 @@ public class ModeratorApp extends Servlet {
for (TrackedLeg leg : trackedRace.getTrackedLegs()) {
JSONObject jsonLeg = new JSONObject();
jsonLeg.put("from", leg.getLeg().getFrom().getName());
jsonLeg.put("fromwaypointid", leg.getLeg().getFrom().getId());
jsonLeg.put("to", leg.getLeg().getTo().getName());
jsonLeg.put("towaypointid", leg.getLeg().getTo().getId());
try {
jsonLeg.put("upordownwindleg", leg.isUpOrDownwindLeg(timePoint));
} catch (NoWindException e) {
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
jar=`find plugins -name 'com.sap.sailing.expeditionconnector-*.jar' | sort | tail -1`
echo Using JAR file $jar
java -cp "$jar" com.sap.sailing.expeditionconnector.UDPMirror $*