Merge remote-tracking branch 'origin/ribdashboard' into ribdashboard

This commit is contained in:
Alexander Ries committed 2015-04-01 10:25:52 +02:00
commit a46f2a6b80
13 files changed
+552 -504

No files matched your search

@@ -42,7 +42,11 @@ public interface RaceTracker {
/** /**
* Stops tracking the races. * Stops tracking the races.
* @param preemptive TODO *
* @param preemptive
* if <code>false</code>, the tracker will continue to process data already received but will stop
* receiving new data. If <code>true</code>, the tracker will stop processing data immediately, ignoring
* (dropping) all data already received but not yet processed.
*/ */
void stop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException; void stop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException;
@@ -260,7 +260,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
* these race states can be garbage-collected when the race log is no longer attached. The race states are created * these race states can be garbage-collected when the race log is no longer attached. The race states are created
* lazily, synchronizing on this weak hash map. * lazily, synchronizing on this weak hash map.
*/ */
protected final transient WeakHashMap<RaceLog, ReadonlyRaceState> raceStates; protected transient WeakHashMap<RaceLog, ReadonlyRaceState> raceStates;
protected transient ConcurrentHashMap<Serializable, RegattaLog> attachedRegattaLogs; protected transient ConcurrentHashMap<Serializable, RegattaLog> attachedRegattaLogs;
@@ -497,6 +497,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
*/ */
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException, PatchFailedException { private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException, PatchFailedException {
ois.defaultReadObject(); ois.defaultReadObject();
raceStates = new WeakHashMap<>();
attachedRaceLogs = new ConcurrentHashMap<>(); attachedRaceLogs = new ConcurrentHashMap<>();
markPassingsTimes = new ArrayList<com.sap.sse.common.Util.Pair<Waypoint, com.sap.sse.common.Util.Pair<TimePoint, TimePoint>>>(); markPassingsTimes = new ArrayList<com.sap.sse.common.Util.Pair<Waypoint, com.sap.sse.common.Util.Pair<TimePoint, TimePoint>>>();
// The short time wind cache needs to be there before operations such as maneuver recalculation try to access it // The short time wind cache needs to be there before operations such as maneuver recalculation try to access it
@@ -3158,26 +3159,30 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
if (!legs.isEmpty()) { if (!legs.isEmpty()) {
if (allMarksHavePositions && numberOfMarks == 2) { if (allMarksHavePositions && numberOfMarks == 2) {
final TrackedLeg legDeterminingDirection = getLegDeterminingDirectionInWhichToPassWaypoint(waypoint); final TrackedLeg legDeterminingDirection = getLegDeterminingDirectionInWhichToPassWaypoint(waypoint);
Distance crossTrackErrorOfMark0OnLineFromMark1ToNextWaypoint = markPositions.get(0) if (legDeterminingDirection == null) {
.crossTrackError(markPositions.get(1), legDeterminingDirection.getLegBearing(timePoint)); result = null;
final Position portMarkPositionWhileApproachingLine;
final Position starboardMarkPositionWhileApproachingLine;
final Mark starboardMarkWhileApproachingLine;
final Mark portMarkWhileApproachingLine;
if (crossTrackErrorOfMark0OnLineFromMark1ToNextWaypoint.getMeters() < 0) {
portMarkWhileApproachingLine = Util.get(waypoint.getMarks(), 0);
portMarkPositionWhileApproachingLine = markPositions.get(0);
starboardMarkWhileApproachingLine = Util.get(waypoint.getMarks(), 1);
starboardMarkPositionWhileApproachingLine = markPositions.get(1);
} else { } else {
portMarkWhileApproachingLine = Util.get(waypoint.getMarks(), 1); Distance crossTrackErrorOfMark0OnLineFromMark1ToNextWaypoint = markPositions.get(0)
portMarkPositionWhileApproachingLine = markPositions.get(1); .crossTrackError(markPositions.get(1), legDeterminingDirection.getLegBearing(timePoint));
starboardMarkWhileApproachingLine = Util.get(waypoint.getMarks(), 0); final Position portMarkPositionWhileApproachingLine;
starboardMarkPositionWhileApproachingLine = markPositions.get(0); final Position starboardMarkPositionWhileApproachingLine;
final Mark starboardMarkWhileApproachingLine;
final Mark portMarkWhileApproachingLine;
if (crossTrackErrorOfMark0OnLineFromMark1ToNextWaypoint.getMeters() < 0) {
portMarkWhileApproachingLine = Util.get(waypoint.getMarks(), 0);
portMarkPositionWhileApproachingLine = markPositions.get(0);
starboardMarkWhileApproachingLine = Util.get(waypoint.getMarks(), 1);
starboardMarkPositionWhileApproachingLine = markPositions.get(1);
} else {
portMarkWhileApproachingLine = Util.get(waypoint.getMarks(), 1);
portMarkPositionWhileApproachingLine = markPositions.get(1);
starboardMarkWhileApproachingLine = Util.get(waypoint.getMarks(), 0);
starboardMarkPositionWhileApproachingLine = markPositions.get(0);
}
result = new LineMarksWithPositions(portMarkPositionWhileApproachingLine,
starboardMarkPositionWhileApproachingLine, starboardMarkWhileApproachingLine,
portMarkWhileApproachingLine);
} }
result = new LineMarksWithPositions(portMarkPositionWhileApproachingLine,
starboardMarkPositionWhileApproachingLine, starboardMarkWhileApproachingLine,
portMarkWhileApproachingLine);
} else { } else {
result = null; // either the position(s) or one or more marks is/are unknown, or the waypoint is not a two-mark waypoint result = null; // either the position(s) or one or more marks is/are unknown, or the waypoint is not a two-mark waypoint
} }
+444 -451
View File
@@ -1,454 +1,447 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<feature <feature
id="com.sap.sailing.feature" id="com.sap.sailing.feature"
label="SAP Sailing Server" label="SAP Sailing Server"
version="1.0.0.qualifier" version="1.0.0.qualifier"
provider-name="SAP"> provider-name="SAP">
<description url="http://www.sap.com"> <description url="http://www.sap.com">
The SAP Sailing Server. The SAP Sailing Server.
Provides connectivity to a TracTrac live GPS feed as well as a live feed from an Expedition system. Provides connectivity to a TracTrac live GPS feed as well as a live feed from an Expedition system.
Computes leaderboard information for sailing races and offers RESTful APIs to all of this. Computes leaderboard information for sailing races and offers RESTful APIs to all of this.
</description> </description>
<copyright url="http://www.example.com/copyright"> <copyright url="http://www.example.com/copyright">
[Enter Copyright Description here.] [Enter Copyright Description here.]
</copyright> </copyright>
<license url="http://www.example.com/license"> <license url="http://www.example.com/license">
[Enter License Description here.] [Enter License Description here.]
</license> </license>
<requires> <requires>
<import plugin="com.googlecode.java-diff-utils" version="1.3.0" match="greaterOrEqual"/> <import plugin="com.googlecode.java-diff-utils" version="1.3.0" match="greaterOrEqual"/>
<import plugin="org.eclipse.osgi" version="3.10.1" match="greaterOrEqual"/> <import plugin="org.eclipse.osgi" version="3.10.1" match="greaterOrEqual"/>
<import plugin="javax.servlet" version="3.1.0" match="greaterOrEqual"/> <import plugin="javax.servlet" version="3.1.0" match="greaterOrEqual"/>
<import plugin="com.mongodb.driver" version="2.6.2" match="greaterOrEqual"/> <import plugin="org.mongodb.mongo-java-driver" version="2.13.0" match="greaterOrEqual"/>
<import plugin="com.google.gwt.osgi" version="2.6.1" match="greaterOrEqual"/> <import plugin="com.google.gwt.osgi" version="2.7.0" match="greaterOrEqual"/>
<import plugin="org.json.simple" version="1.1.0" match="greaterOrEqual"/> <import plugin="org.json.simple" version="1.1.0" match="greaterOrEqual"/>
<import plugin="org.moxieapps.gwt.highcharts" version="1.1.4" match="greaterOrEqual"/> <import plugin="org.moxieapps.gwt.highcharts" version="1.6.0" match="greaterOrEqual"/>
<import plugin="org.apache.geronimo.specs.geronimo-jms_1.1_spec"/> <import plugin="org.apache.geronimo.specs.geronimo-jms_1.1_spec"/>
<import plugin="com.rabbitmq.client"/> <import plugin="com.rabbitmq.client"/>
<import plugin="org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec"/> <import plugin="org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec"/>
</requires> </requires>
<plugin <plugin
id="com.sap.sailing.geocoding" id="com.sap.sailing.geocoding"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.common" id="com.sap.sailing.domain.common"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain" id="com.sap.sailing.domain"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.tractracadapter" id="com.sap.sailing.domain.tractracadapter"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.expeditionconnector" id="com.sap.sailing.expeditionconnector"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.server" id="com.sap.sailing.server"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.server.gateway" id="com.sap.sailing.server.gateway"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.server.gateway.ess40" id="com.sap.sailing.server.gateway.ess40"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.tractrac.clientmodule" id="com.tractrac.clientmodule"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.declination" id="com.sap.sailing.declination"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.persistence" id="com.sap.sailing.domain.persistence"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.swisstimingadapter" id="com.sap.sailing.domain.swisstimingadapter"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.swisstimingadapter.persistence" id="com.sap.sailing.domain.swisstimingadapter.persistence"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.swisstimingreplayadapter" id="com.sap.sailing.domain.swisstimingreplayadapter"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.tractracadapter.persistence" id="com.sap.sailing.domain.tractracadapter.persistence"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.gwt" id="com.sap.sse.gwt"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.security" id="com.sap.sse.security"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.security.ui" id="com.sap.sse.security.ui"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.security.userstore.mongodb" id="com.sap.sse.security.userstore.mongodb"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.gwt.ui" id="com.sap.sailing.gwt.ui"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.udpconnector" id="com.sap.sailing.udpconnector"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.xmlexport" id="com.sap.sailing.xmlexport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.simulator" id="com.sap.sailing.simulator"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.www" id="com.sap.sailing.www"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0"/> version="0.0.0"/>
<plugin <plugin
id="com.sap.sailing.www.events" id="com.sap.sailing.www.events"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0"/> version="0.0.0"/>
<plugin <plugin
id="com.sap.sailing.resultimport" id="com.sap.sailing.resultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.kiworesultimport" id="com.sap.sailing.kiworesultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.ess40.resultimport" id="com.sap.sailing.ess40.resultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.freg.resultimport" id="com.sap.sailing.freg.resultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.barbados.resultimport" id="com.sap.sailing.barbados.resultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.sailwave.resultimport" id="com.sap.sailing.sailwave.resultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.manage2sail.resultimport" id="com.sap.sailing.manage2sail.resultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.velum.resultimport" id="com.sap.sailing.velum.resultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.monitoring" id="com.sap.sailing.monitoring"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.xrr.resultimport" id="com.sap.sailing.xrr.resultimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.igtimiadapter" id="com.sap.sailing.domain.igtimiadapter"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.igtimiadapter.persistence" id="com.sap.sailing.domain.igtimiadapter.persistence"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.racelogtrackingadapter" id="com.sap.sailing.domain.racelogtrackingadapter"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.domain.deckmanadapter" id="com.sap.sailing.domain.deckmanadapter"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.autoload" id="com.sap.sailing.autoload"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse" id="com.sap.sse"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.common" id="com.sap.sse.common"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.datamining" id="com.sap.sse.datamining"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.datamining.shared" id="com.sap.sse.datamining.shared"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.gateway" id="com.sap.sse.gwt.adminconsole"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.gwt.adminconsole" id="com.sap.sse.mongodb"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.mongodb" id="com.sap.sse.operationaltransformation"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.operationaltransformation" id="com.sap.sse.replication"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.replication" id="com.sap.sailing.xrr.structureimport"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.xrr.structureimport" id="com.sap.sailing.server.gateway.serialization.shared.android"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.server.gateway.serialization.shared.android" id="com.sap.sailing.server.gateway.serialization"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.server.gateway.serialization" id="com.sap.sse.filestorage"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.filestorage" id="com.sap.sse.shared.android"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.shared.android" id="com.sap.sailing.dashboards.gwt"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.dashboards.gwt" id="com.sap.sse.mail"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sse.mail" id="com.sap.sailing.dashboards.gwt"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.dashboards.gwt" id="com.sap.sailing.datamining"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.datamining" id="com.sap.sailing.datamining.shared"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin <plugin
id="com.sap.sailing.datamining.shared" id="com.sap.sse.threadmanager"
download-size="0" download-size="0"
install-size="0" install-size="0"
version="0.0.0" version="0.0.0"
unpack="false"/> unpack="false"/>
<plugin </feature>
id="com.sap.sse.threadmanager"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>
@@ -140,7 +140,7 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth,
int numberOfFixes, double latDeg, double lngDeg, Collection<String> windSources) throws NoWindException; int numberOfFixes, double latDeg, double lngDeg, Collection<String> windSources) throws NoWindException;
Boolean getPolarResults(RegattaAndRaceIdentifier raceIdentifier); boolean getPolarResults(RegattaAndRaceIdentifier raceIdentifier);
SimulatorResultsDTO getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime); SimulatorResultsDTO getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime);
@@ -1423,13 +1423,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
} }
@Override @Override
public Boolean getPolarResults(RegattaAndRaceIdentifier raceIdentifier) { public boolean getPolarResults(RegattaAndRaceIdentifier raceIdentifier) {
final boolean result;
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier); TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
BoatClass boatClass = trackedRace.getRace().getBoatClass(); if (trackedRace == null) {
PolarDataService polarData = getService().getPolarDataService(); result = false;
PolarDiagram polarDiagram = new PolarDiagramGPS(boatClass, polarData); } else {
return new Boolean(polarDiagram != null); BoatClass boatClass = trackedRace.getRace().getBoatClass();
}; PolarDataService polarData = getService().getPolarDataService();
PolarDiagram polarDiagram = new PolarDiagramGPS(boatClass, polarData);
result = polarDiagram != null;
}
return result;
}
@Override @Override
public SimulatorResultsDTO getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime) { public SimulatorResultsDTO getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime) {
@@ -190,7 +190,7 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl
replicationDescriptorPair.getA().initialLoad(); replicationDescriptorPair.getA().initialLoad();
replicator.setSuspended(false); replicator.setSuspended(false);
synchronized (replicator) { synchronized (replicator) {
while (!replicator.isQueueEmpty()) { while (!replicator.isQueueEmptyOrStopped()) {
replicator.wait(); replicator.wait();
} }
} }
@@ -60,7 +60,7 @@ public class PrematureOperationReceiptTest extends AbstractServerReplicationTest
} }
replicator.setSuspended(false); replicator.setSuspended(false);
synchronized (replicator) { synchronized (replicator) {
while (!replicator.isQueueEmpty()) { while (!replicator.isQueueEmptyOrStopped()) {
replicator.wait(); replicator.wait();
} }
} }
@@ -129,6 +129,7 @@ public class TrackRaceReplicationTest extends AbstractServerReplicationTest {
@Test @Test
public void testReassignmentToLeaderboardReplication() throws Exception { public void testReassignmentToLeaderboardReplication() throws Exception {
logger.info("Running testReassignmentToLeaderboardReplication()");
final String leaderboardName = "Test Leaderboard"; final String leaderboardName = "Test Leaderboard";
Leaderboard masterLeaderboard = master.apply(new CreateFlexibleLeaderboard(leaderboardName, null, new int[0], new LowPoint(), null)); Leaderboard masterLeaderboard = master.apply(new CreateFlexibleLeaderboard(leaderboardName, null, new int[0], new LowPoint(), null));
final String columnName = "R1"; final String columnName = "R1";
@@ -153,10 +154,12 @@ public class TrackRaceReplicationTest extends AbstractServerReplicationTest {
RaceColumn column = replicaLeaderboard.getRaceColumnByName(columnName); RaceColumn column = replicaLeaderboard.getRaceColumnByName(columnName);
assertNotNull(column); assertNotNull(column);
assertSame(replicaTrackedRace, column.getTrackedRace(defaultFleet)); assertSame(replicaTrackedRace, column.getTrackedRace(defaultFleet));
logger.info("Done running testReassignmentToLeaderboardReplication()");
} }
@Test @Test
public void testRaceTimeReplication() throws InterruptedException, Exception { public void testRaceTimeReplication() throws InterruptedException, Exception {
logger.info("Running testRaceTimeReplication()");
startTracking(); startTracking();
// now wait at least until the start of tracking time has been received on the master copy // now wait at least until the start of tracking time has been received on the master copy
boolean receivedStartAndEndOfTracking = master.getTrackedRace(raceIdentifier).getStartOfTracking() != null && boolean receivedStartAndEndOfTracking = master.getTrackedRace(raceIdentifier).getStartOfTracking() != null &&
@@ -176,21 +179,27 @@ public class TrackRaceReplicationTest extends AbstractServerReplicationTest {
((DynamicTrackedRace) masterTrackedRace).setStartTimeReceived(now); ((DynamicTrackedRace) masterTrackedRace).setStartTimeReceived(now);
Thread.sleep(1000); Thread.sleep(1000);
assertEquals(now, replicaTrackedRace.getStartOfRace()); assertEquals(now, replicaTrackedRace.getStartOfRace());
logger.info("Done running testRaceTimeReplication()");
} }
@Test @Test
public void testWindSourcesToExcludeReplication() throws InterruptedException, Exception { public void testWindSourcesToExcludeReplication() throws InterruptedException, Exception {
startTracking(); try {
Thread.sleep(1000); logger.info("Running testWindSourcesToExcludeReplication()");
TrackedRace replicaTrackedRace = replica.getTrackedRace(raceIdentifier); startTracking();
assertTrue(Util.isEmpty(masterTrackedRace.getWindSourcesToExclude())); Thread.sleep(1000);
assertTrue(Util.isEmpty(replicaTrackedRace.getWindSourcesToExclude())); TrackedRace replicaTrackedRace = replica.getTrackedRace(raceIdentifier);
masterTrackedRace.setWindSourcesToExclude(Collections.singleton(new WindSourceImpl(WindSourceType.WEB))); assertTrue(Util.isEmpty(masterTrackedRace.getWindSourcesToExclude()));
assertEquals(1, Util.size(masterTrackedRace.getWindSourcesToExclude())); assertTrue(Util.isEmpty(replicaTrackedRace.getWindSourcesToExclude()));
assertEquals(WindSourceType.WEB, masterTrackedRace.getWindSourcesToExclude().iterator().next().getType()); masterTrackedRace.setWindSourcesToExclude(Collections.singleton(new WindSourceImpl(WindSourceType.WEB)));
Thread.sleep(1000); assertEquals(1, Util.size(masterTrackedRace.getWindSourcesToExclude()));
assertEquals(1, Util.size(replicaTrackedRace.getWindSourcesToExclude())); assertEquals(WindSourceType.WEB, masterTrackedRace.getWindSourcesToExclude().iterator().next().getType());
assertEquals(WindSourceType.WEB, replicaTrackedRace.getWindSourcesToExclude().iterator().next().getType()); Thread.sleep(1000);
assertEquals(1, Util.size(replicaTrackedRace.getWindSourcesToExclude()));
assertEquals(WindSourceType.WEB, replicaTrackedRace.getWindSourcesToExclude().iterator().next().getType());
} finally {
logger.info("Done running testWindSourcesToExcludeReplication()");
}
} }
@After @After
@@ -379,6 +379,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
.withInitial(() -> false); .withInitial(() -> false);
private final Set<ClassLoader> masterDataClassLoaders = new HashSet<ClassLoader>(); private final Set<ClassLoader> masterDataClassLoaders = new HashSet<ClassLoader>();
private final JoinedClassLoader joinedClassLoader;
/** /**
* Constructs a {@link DomainFactory base domain factory} that uses this object's {@link #competitorStore competitor * Constructs a {@link DomainFactory base domain factory} that uses this object's {@link #competitorStore competitor
@@ -457,6 +459,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
TypeBasedServiceFinderFactory serviceFinderFactory) { TypeBasedServiceFinderFactory serviceFinderFactory) {
logger.info("Created " + this); logger.info("Created " + this);
this.masterDataClassLoaders.add(this.getClass().getClassLoader()); this.masterDataClassLoaders.add(this.getClass().getClassLoader());
joinedClassLoader = new JoinedClassLoader(masterDataClassLoaders);
this.operationsSentToMasterForReplication = new HashSet<>(); this.operationsSentToMasterForReplication = new HashSet<>();
if (windStore == null) { if (windStore == null) {
try { try {
@@ -2291,7 +2294,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
@Override @Override
public ClassLoader getDeserializationClassLoader() { public ClassLoader getDeserializationClassLoader() {
return getCombinedMasterDataClassLoader(); return joinedClassLoader;
} }
@Override @Override
@@ -179,6 +179,16 @@ public abstract class AbstractServerReplicationTestSetUp<ReplicableInterface ext
* original exception propagate */ * original exception propagate */
logger.log(Level.SEVERE, "Exception trying to connect to initial load test servlet to STOP it", ex); logger.log(Level.SEVERE, "Exception trying to connect to initial load test servlet to STOP it", ex);
} }
final ReplicationReceiver replicaReplicatorReplicator = replicaReplicator.getReplicator();
if (replicaReplicatorReplicator != null) {
synchronized (replicaReplicatorReplicator) {
while (!replicaReplicatorReplicator.isQueueEmptyOrStopped()) {
logger.info("Waiting for replication queue to drain...");
replicaReplicatorReplicator.wait();
}
}
}
logger.info("Replication queue has been drained...");
} }
/** /**
@@ -215,6 +225,11 @@ public abstract class AbstractServerReplicationTestSetUp<ReplicableInterface ext
ReplicationMasterDescriptor getMasterDescriptor() { ReplicationMasterDescriptor getMasterDescriptor() {
return masterDescriptor; return masterDescriptor;
} }
@Override
public ReplicationReceiver getReplicator() {
return super.getReplicator();
}
private Thread startInitialLoadTransmissionServlet() throws InterruptedException { private Thread startInitialLoadTransmissionServlet() throws InterruptedException {
final boolean[] listening = new boolean[] { false }; final boolean[] listening = new boolean[] { false };
@@ -322,7 +337,7 @@ public abstract class AbstractServerReplicationTestSetUp<ReplicableInterface ext
public void waitUntilQueueIsEmpty() throws InterruptedException, IllegalAccessException { public void waitUntilQueueIsEmpty() throws InterruptedException, IllegalAccessException {
synchronized (getReplicator()) { synchronized (getReplicator()) {
while (!getReplicator().isQueueEmpty()) { while (!getReplicator().isQueueEmptyOrStopped()) {
getReplicator().wait(); getReplicator().wait();
} }
} }
@@ -7,6 +7,8 @@ import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
@@ -19,6 +21,8 @@ import com.sap.sse.replication.Replicable;
import com.sap.sse.replication.ReplicationMasterDescriptor; import com.sap.sse.replication.ReplicationMasterDescriptor;
public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescriptor { public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescriptor {
private static final Logger logger = Logger.getLogger(ReplicationMasterDescriptorImpl.class.getName());
private static final String REPLICATION_SERVLET = "/replication/replication"; private static final String REPLICATION_SERVLET = "/replication/replication";
private final String masterServletHostname; private final String masterServletHostname;
private final String exchangeName; private final String exchangeName;
@@ -161,7 +165,7 @@ public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescrip
} catch (Exception ex) { } catch (Exception ex) {
// ignore any exception during abort. close can yield a broad // ignore any exception during abort. close can yield a broad
// number of exceptions that we don't want to know or to log. // number of exceptions that we don't want to know or to log.
ex.printStackTrace(); logger.log(Level.SEVERE, "Exception while closing replication channel consumer", ex);
} }
} }
@@ -147,7 +147,6 @@ public class ReplicationReceiver implements Runnable {
*/ */
@Override @Override
public void run() { public void run() {
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
long messageCount = 0; long messageCount = 0;
long operationCount = 0; long operationCount = 0;
final boolean logsFine = logger.isLoggable(Level.FINE); final boolean logsFine = logger.isLoggable(Level.FINE);
@@ -156,6 +155,11 @@ public class ReplicationReceiver implements Runnable {
Delivery delivery = consumer.nextDelivery(); Delivery delivery = consumer.nextDelivery();
messageCount++; messageCount++;
if (_queue != null) { if (_queue != null) {
synchronized (this) {
if (getInboundMessageQueue().isEmpty()) {
notifyAll(); // wake up anyone waiting for isQueueEmpty()
}
}
if (logsFine || messageCount % 10l == 0) { if (logsFine || messageCount % 10l == 0) {
try { try {
logger.log(messageCount%10l==0 ? Level.INFO : Level.FINE, logger.log(messageCount%10l==0 ? Level.INFO : Level.FINE,
@@ -174,7 +178,6 @@ public class ReplicationReceiver implements Runnable {
String replicableIdAsString = new DataInputStream(uncompressedInputStream).readUTF(); String replicableIdAsString = new DataInputStream(uncompressedInputStream).readUTF();
Replicable<?, ?> replicable = replicableProvider.getReplicable(replicableIdAsString, /* wait */ false); Replicable<?, ?> replicable = replicableProvider.getReplicable(replicableIdAsString, /* wait */ false);
if (replicable != null) { if (replicable != null) {
Thread.currentThread().setContextClassLoader(replicable.getClass().getClassLoader());
ObjectInputStream ois = new ObjectInputStream(uncompressedInputStream); // no special stream required; only reading a generic byte[] ObjectInputStream ois = new ObjectInputStream(uncompressedInputStream); // no special stream required; only reading a generic byte[]
int operationsInMessage = 0; int operationsInMessage = 0;
try { try {
@@ -248,11 +251,13 @@ public class ReplicationReceiver implements Runnable {
} catch (Exception e) { } catch (Exception e) {
logger.info("Exception while processing replica: "+e.getMessage()); logger.info("Exception while processing replica: "+e.getMessage());
logger.log(Level.SEVERE, "run", e); logger.log(Level.SEVERE, "run", e);
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
} }
} }
logger.info("Stopped replicator thread. This server will no longer receive events from a master."); logger.info("Stopped replicator thread. This server will no longer receive events from a master.");
synchronized (this) {
stopped = true;
notifyAll();
}
} }
/** /**
@@ -313,9 +318,6 @@ public class ReplicationReceiver implements Runnable {
queue = new ArrayList<>(); queue = new ArrayList<>();
queueByReplicableIdAsString.put(replicableIdAsString, queue); queueByReplicableIdAsString.put(replicableIdAsString, queue);
} }
if (queue.isEmpty()) {
notifyAll();
}
queue.add(new Pair<String, OperationWithResult<?, ?>>(replicable.getId().toString(), operation)); queue.add(new Pair<String, OperationWithResult<?, ?>>(replicable.getId().toString(), operation));
assert !queue.isEmpty(); assert !queue.isEmpty();
} }
@@ -359,6 +361,7 @@ public class ReplicationReceiver implements Runnable {
logger.info("Signaled Replicator thread to stop asap."); logger.info("Signaled Replicator thread to stop asap.");
stopped = true; stopped = true;
master.stopConnection(); master.stopConnection();
notifyAll(); // notify those waiting for stopped
} }
public synchronized boolean isBeingStopped() { public synchronized boolean isBeingStopped() {
@@ -374,8 +377,9 @@ public class ReplicationReceiver implements Runnable {
/** /**
* @return <code>true</code> if all queues for all replicables are empty * @return <code>true</code> if all queues for all replicables are empty
*/ */
public boolean isQueueEmpty() throws IllegalAccessException { public boolean isQueueEmptyOrStopped() throws IllegalAccessException {
return (_queue == null || getInboundMessageQueue().isEmpty()) && !queueByReplicableIdAsString.values().stream().anyMatch(q->!q.isEmpty()); return isBeingStopped() ||
(_queue == null || getInboundMessageQueue().isEmpty()) && !queueByReplicableIdAsString.values().stream().anyMatch(q->!q.isEmpty());
} }
} }
@@ -246,7 +246,12 @@ public class ReplicationServiceImpl implements ReplicationService {
replicator = null; replicator = null;
serverUUID = UUID.randomUUID(); serverUUID = UUID.randomUUID();
logger.info("Setting " + serverUUID.toString() + " as unique replication identifier."); logger.info("Setting " + serverUUID.toString() + " as unique replication identifier.");
}
@Override
protected void finalize() {
logger.info("terminating timer "+timer);
timer.cancel();
} }
protected ServiceTracker<Replicable<?, ?>, Replicable<?, ?>> getReplicableTracker() { protected ServiceTracker<Replicable<?, ?>, Replicable<?, ?>> getReplicableTracker() {