Initially implemented the possibility to intercept TrackedRace creation

through RaceTrackers
This commit is contained in:
Steffen Schaefer
2018-12-05 17:11:32 +01:00
parent fef963a219
commit 1bdb7dfcfd
42 changed files with 271 additions and 111 deletions
@@ -65,6 +65,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.impl.RacingEventServiceImpl;
@@ -228,7 +229,8 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
}
private TrackedRace trackAndGetRace(RaceColumn column) throws NotDenotedForRaceLogTrackingException, Exception {
final RaceHandle raceHandle = adapter.startTracking(service, leaderboard, column, fleet, /* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ false);
final RaceHandle raceHandle = adapter.startTracking(service, leaderboard, column, fleet, /* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ false,
new DefaultRaceTrackingHandler());
raceHandle.getRace();
return WaitForTrackedRaceUtil.waitForTrackedRace(column, fleet, 10);
}
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.racelogtracking.impl.RaceLogRaceTracker;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.common.Util.Pair;
@@ -40,7 +41,8 @@ public interface RaceLogTrackingAdapter {
* <li>Is a {@link RaceLogStartTrackingEvent} present in the racelog? If not, add one</li>
* </ul>
*/
RaceHandle startTracking(RacingEventService service, Leaderboard leaderboard, RaceColumn raceColumn, Fleet fleet, boolean trackWind, boolean correctWindDirectionByMagneticDeclination)
RaceHandle startTracking(RacingEventService service, Leaderboard leaderboard, RaceColumn raceColumn, Fleet fleet, boolean trackWind, boolean correctWindDirectionByMagneticDeclination,
RaceTrackingHandler raceTrackingHandler)
throws NotDenotedForRaceLogTrackingException, Exception;
RaceLogTrackingState getRaceLogTrackingState(RacingEventService service, RaceColumn raceColumn, Fleet fleet);
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
import com.sap.sailing.domain.regattalike.HasRegattaLike;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.impl.AbstractRaceTrackingConnectivityParameters;
@@ -65,13 +66,16 @@ public class RaceLogConnectivityParams extends AbstractRaceTrackingConnectivityP
@Override
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) {
return createRaceTracker(regatta, trackedRegattaRegistry, windStore, raceLogResolver, leaderboardGroupResolver, timeoutInMilliseconds);
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler) {
return createRaceTracker(regatta, trackedRegattaRegistry, windStore, raceLogResolver, leaderboardGroupResolver, timeoutInMilliseconds,
raceTrackingHandler);
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) {
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler) {
if (regatta == null) {
BoatClass boatClass = new RaceInformationFinder(getRaceLog()).analyze().getBoatClass();
regatta = service.getOrCreateDefaultRegatta(
@@ -82,7 +86,8 @@ public class RaceLogConnectivityParams extends AbstractRaceTrackingConnectivityP
throw new RaceNotCreatedException("No regatta for race-log tracked race");
}
DynamicTrackedRegatta trackedRegatta = trackedRegattaRegistry.getOrCreateTrackedRegatta(regatta);
return new RaceLogRaceTracker(trackedRegatta, this, windStore, raceLogResolver, this, trackedRegattaRegistry);
return new RaceLogRaceTracker(trackedRegatta, this, windStore, raceLogResolver, this, trackedRegattaRegistry,
raceTrackingHandler);
}
@Override
@@ -64,6 +64,7 @@ import com.sap.sailing.domain.tracking.AbstractRaceTrackerBaseImpl;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
@@ -99,15 +100,18 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
private final TrackedRegattaRegistry trackedRegattaRegistry;
private volatile DynamicTrackedRace trackedRace;
private final RaceTrackingHandler raceTrackingHandler;
public RaceLogRaceTracker(DynamicTrackedRegatta regatta, RaceLogConnectivityParams params, WindStore windStore,
RaceLogResolver raceLogResolver, RaceLogConnectivityParams connectivityParams, TrackedRegattaRegistry trackedRegattaRegistry) {
RaceLogResolver raceLogResolver, RaceLogConnectivityParams connectivityParams,
TrackedRegattaRegistry trackedRegattaRegistry, RaceTrackingHandler raceTrackingHandler) {
super(connectivityParams);
this.trackedRegattaRegistry = trackedRegattaRegistry;
this.params = params;
this.windStore = windStore;
this.trackedRegatta = regatta;
this.raceLogResolver = raceLogResolver;
this.raceTrackingHandler = raceTrackingHandler;
// add log listeners
for (AbstractLog<?, ?> log : params.getLogHierarchy()) {
@@ -304,7 +308,7 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
// set race definition, so race is linked to leaderboard automatically
trackedRegatta.getRegatta().addRace(raceDef);
raceColumn.setRaceIdentifier(fleet, trackedRegatta.getRegatta().getRaceIdentifier(raceDef));
trackedRace = trackedRegatta.createTrackedRace(raceDef, sidelines, windStore,
trackedRace = raceTrackingHandler.createTrackedRace(trackedRegatta, raceDef, sidelines, windStore,
params.getDelayToLiveInMillis(), WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
boatClass.getApproximateManeuverDurationInMilliseconds(), null, /*useMarkPassingCalculator*/ true, raceLogResolver,
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty());
@@ -55,6 +55,7 @@ import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.racelogtracking.PingDeviceIdentifierImpl;
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
@@ -79,7 +80,8 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
@Override
public RaceHandle startTracking(RacingEventService service, Leaderboard leaderboard, RaceColumn raceColumn,
Fleet fleet, boolean trackWind, boolean correctWindDirectionByMagneticDeclination)
Fleet fleet, boolean trackWind, boolean correctWindDirectionByMagneticDeclination,
RaceTrackingHandler raceTrackingHandler)
throws NotDenotedForRaceLogTrackingException, Exception {
RaceLog raceLog = raceColumn.getRaceLog(fleet);
RaceLogTrackingState raceLogTrackingState = new RaceLogTrackingStateAnalyzer(raceLog).analyze();
@@ -95,7 +97,7 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
final RaceHandle result;
if (!isRaceLogRaceTrackerAttached(service, raceLog)) {
result = addTracker(service, regatta, leaderboard, raceColumn, fleet, -1, trackWind,
correctWindDirectionByMagneticDeclination);
correctWindDirectionByMagneticDeclination, raceTrackingHandler);
} else {
result = null;
}
@@ -110,14 +112,14 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
*/
private RaceHandle addTracker(RacingEventService service, RegattaIdentifier regattaToAddTo, Leaderboard leaderboard,
RaceColumn raceColumn, Fleet fleet, long timeoutInMilliseconds, boolean trackWind,
boolean correctWindDirectionByMagneticDeclination) throws RaceLogRaceTrackerExistsException, Exception {
boolean correctWindDirectionByMagneticDeclination, RaceTrackingHandler raceTrackingHandler) throws RaceLogRaceTrackerExistsException, Exception {
RaceLog raceLog = raceColumn.getRaceLog(fleet);
assert !isRaceLogRaceTrackerAttached(service, raceLog) : new RaceLogRaceTrackerExistsException(
leaderboard.getName() + " - " + raceColumn.getName() + " - " + fleet.getName());
Regatta regatta = regattaToAddTo == null ? null : service.getRegatta(regattaToAddTo);
RaceLogConnectivityParams params = new RaceLogConnectivityParams(service, regatta, raceColumn, fleet,
leaderboard, delayToLiveInMillis, domainFactory, trackWind, correctWindDirectionByMagneticDeclination);
return service.addRace(regattaToAddTo, params, timeoutInMilliseconds);
return service.addRace(regattaToAddTo, params, timeoutInMilliseconds, raceTrackingHandler);
}
@Override
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.regattalog.RegattaLogStore;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sailing.xrr.schema.RegattaResults;
@@ -29,7 +30,8 @@ public interface SwissTimingAdapter {
*/
RaceHandle addSwissTimingRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, String raceID,
String raceName, String raceDescription, BoatClass boatClass, String hostname, int port,
StartList startList, RaceLogStore logStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, String updateURL, String updateUsername, String updatePassword)
StartList startList, RaceLogStore logStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, String updateURL, String updateUsername, String updatePassword,
RaceTrackingHandler raceTrackingHandler)
throws InterruptedException, UnknownHostException, IOException, ParseException, Exception;
StartList readStartListForRace(String raceId, RegattaResults regattaResults);
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.swisstimingadapter.impl.SwissTimingFactoryImpl;
import com.sap.sailing.domain.swisstimingadapter.impl.SwissTimingRaceTrackerImpl;
import com.sap.sailing.domain.swisstimingadapter.impl.SwissTimingTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
@@ -55,11 +56,13 @@ public interface SwissTimingFactory {
SwissTimingConfiguration createSwissTimingConfiguration(String name, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword);
SwissTimingRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore,
DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams)
DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams,
RaceTrackingHandler raceTrackingHandler)
throws InterruptedException, UnknownHostException, IOException, ParseException, URISyntaxException;
RaceTracker createRaceTracker(Regatta regatta, WindStore windStore, DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams)
RaceLogResolver raceLogResolver, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams,
RaceTrackingHandler raceTrackingHandler)
throws UnknownHostException, InterruptedException, IOException, ParseException, URISyntaxException;
Race createRace(String raceId, String raceName, String description, BoatClass boatClass);
@@ -24,6 +24,7 @@ import com.sap.sailing.domain.swisstimingadapter.StartList;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapter;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sailing.xrr.resultimport.ParserFactory;
import com.sap.sailing.xrr.schema.Boat;
@@ -70,13 +71,13 @@ public class SwissTimingAdapterImpl implements SwissTimingAdapter {
String raceName, String raceDescription, BoatClass boatClass, String hostname, int port,
StartList startList, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds,
boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination,
String updateURL, String updateUsername, String updatePassword) throws Exception {
String updateURL, String updateUsername, String updatePassword, RaceTrackingHandler raceTrackingHandler) throws Exception {
return trackerManager.addRace(regattaToAddTo,
swissTimingDomainFactory.createTrackingConnectivityParameters(hostname, port, raceID, raceName,
raceDescription, boatClass, startList, DEFAULT_SWISSTIMING_LIVE_DELAY_IN_MILLISECONDS,
swissTimingFactory, swissTimingDomainFactory, raceLogStore, regattaLogStore,
useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination, updateURL, updateUsername, updatePassword),
timeoutInMilliseconds);
timeoutInMilliseconds, raceTrackingHandler);
}
@Override
@@ -24,6 +24,7 @@ import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessageParser;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingRaceTracker;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sse.common.Util;
@@ -91,19 +92,21 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory {
@Override
public SwissTimingRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams)
RaceLogResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams,
RaceTrackingHandler raceTrackingHandler)
throws InterruptedException, UnknownHostException, IOException, ParseException, URISyntaxException {
return new SwissTimingRaceTrackerImpl(raceLogStore, regattaLogStore, windStore, domainFactory, this,
trackedRegattaRegistry, raceLogResolver, connectivityParams);
trackedRegattaRegistry, raceLogResolver, connectivityParams, raceTrackingHandler);
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, WindStore windStore, DomainFactory domainFactory,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams)
RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams,
RaceTrackingHandler raceTrackingHandler)
throws UnknownHostException, InterruptedException, IOException, ParseException, URISyntaxException {
return new SwissTimingRaceTrackerImpl(regatta, windStore, domainFactory, this, trackedRegattaRegistry,
raceLogStore, regattaLogStore, raceLogResolver, connectivityParams);
raceLogStore, regattaLogStore, raceLogResolver, connectivityParams, raceTrackingHandler);
}
@Override
@@ -57,6 +57,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
@@ -123,22 +124,26 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
private final String updateUsername;
private final String updatePassword;
private final RaceTrackingHandler raceTrackingHandler;
protected SwissTimingRaceTrackerImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, DomainFactory domainFactory, SwissTimingFactory factory,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
SwissTimingTrackingConnectivityParameters connectivityParams)
SwissTimingTrackingConnectivityParameters connectivityParams, RaceTrackingHandler raceTrackingHandler)
throws InterruptedException, UnknownHostException, IOException, ParseException, URISyntaxException {
this(/* regatta */ null, windStore, domainFactory, factory, trackedRegattaRegistry, raceLogStore, regattaLogStore, raceLogResolver, connectivityParams);
this(/* regatta */ null, windStore, domainFactory, factory, trackedRegattaRegistry, raceLogStore,
regattaLogStore, raceLogResolver, connectivityParams, raceTrackingHandler);
}
protected SwissTimingRaceTrackerImpl(Regatta regatta, WindStore windStore, DomainFactory domainFactory,
SwissTimingFactory factory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, RaceLogResolver raceLogResolver,
SwissTimingTrackingConnectivityParameters connectivityParams)
SwissTimingTrackingConnectivityParameters connectivityParams, RaceTrackingHandler raceTrackingHandler)
throws InterruptedException, UnknownHostException, IOException, ParseException, URISyntaxException {
super(connectivityParams);
this.raceLogResolver = raceLogResolver;
this.raceTrackingHandler = raceTrackingHandler;
this.tmdMessageQueue = new TMDMessageQueue(this);
final Regatta effectiveRegatta;
// Try to find a pre-associated event based on the Race ID
@@ -472,7 +477,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
competitorsByBoatId.put(c.getBoatID(), existingCompetitor);
}
}
trackedRace = getTrackedRegatta().createTrackedRace(race, Collections.<Sideline> emptyList(), windStore,
trackedRace = raceTrackingHandler.createTrackedRace(getTrackedRegatta(), race, Collections.<Sideline> emptyList(), windStore,
delayToLiveInMillis,
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
/* time over which to average speed */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
import com.sap.sailing.domain.swisstimingadapter.StartList;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.impl.AbstractRaceTrackingConnectivityParameters;
@@ -66,16 +67,18 @@ public class SwissTimingTrackingConnectivityParameters extends AbstractRaceTrack
@Override
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception {
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler) throws Exception {
return swissTimingFactory.createRaceTracker(raceLogStore, regattaLogStore, windStore, domainFactory, trackedRegattaRegistry, raceLogResolver,
this);
this, raceTrackingHandler);
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception {
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler) throws Exception {
return swissTimingFactory.createRaceTracker(regatta, windStore, domainFactory, trackedRegattaRegistry, raceLogResolver, raceLogStore,
regattaLogStore, this);
regattaLogStore, this, raceTrackingHandler);
}
@Override
@@ -7,7 +7,8 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Fragment-Host: com.sap.sailing.domain.swisstimingreplayadapter
Import-Package: org.json.simple,
Import-Package: com.sap.sailing.domain.tracking,
org.json.simple,
org.json.simple.parser
Require-Bundle: com.sap.sailing.domain.test,
org.junit;bundle-version="4.8.2",
@@ -29,6 +29,7 @@ import com.sap.sailing.domain.swisstimingreplayadapter.impl.SwissTimingReplayPar
import com.sap.sailing.domain.swisstimingreplayadapter.impl.SwissTimingReplayServiceImpl;
import com.sap.sailing.domain.swisstimingreplayadapter.impl.SwissTimingReplayToDomainAdapter;
import com.sap.sailing.domain.test.DummyTrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.Distance;
import com.sap.sse.common.Util;
@@ -185,7 +186,8 @@ public class SwissTimingReplayAdapterServiceTest {
public void testRaceData_SAW010955_20120802_WithDomainAdapter() throws Exception {
SwissTimingReplayToDomainAdapter replayListener = new SwissTimingReplayToDomainAdapter(null, /* raceName */ "SAW005906",
"SAW005906", /* boatClass */ null, DomainFactory.INSTANCE, new DummyTrackedRegattaRegistry(), /* useInternalMarkPassingAlgorithm */ false,
mock(RaceLogResolver.class), EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, /* tracker creator */ null);
mock(RaceLogResolver.class), EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, /* tracker creator */ null,
new DefaultRaceTrackingHandler());
new SwissTimingReplayParserImpl().readData(getClass().getResourceAsStream("/SAW005906.20120805.replay"), replayListener);
Iterable<? extends TrackedRace> trackedRaces = replayListener.getTrackedRaces();
assertFalse(Util.isEmpty(trackedRaces));
@@ -200,7 +202,7 @@ public class SwissTimingReplayAdapterServiceTest {
public void testStartPerformanceDetection() throws Exception {
SwissTimingReplayToDomainAdapter replayListener = new SwissTimingReplayToDomainAdapter(null, /* raceName */ "SAW005905",
"SAW005905", /* boatClass */ null, DomainFactory.INSTANCE, new DummyTrackedRegattaRegistry(), /* useInternalMarkPassingAlgorithm */ false,
mock(RaceLogResolver.class), EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, /* tracker creator */ null);
mock(RaceLogResolver.class), EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, /* tracker creator */ null, new DefaultRaceTrackingHandler());
new SwissTimingReplayParserImpl().readData(getClass().getResourceAsStream("/SAW005905.20120805.replay"), replayListener);
Iterable<? extends TrackedRace> trackedRaces = replayListener.getTrackedRaces();
TrackedRace trackedRace = trackedRaces.iterator().next();
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.regattalog.RegattaLogStore;
import com.sap.sailing.domain.swisstimingreplayadapter.impl.SwissTimingRaceConfig;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.TrackerManager;
@@ -45,7 +46,8 @@ public interface SwissTimingReplayService {
*/
void loadRaceData(RegattaIdentifier regattaToAddTo, String link, String raceName, String raceID,
String boatClassName, TrackerManager trackerManager, TrackedRegattaRegistry trackedRegattaRegistry,
boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore)
boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
RaceTrackingHandler raceTrackingHandler)
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
/**
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.tracking.AbstractRaceTrackerImpl;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.impl.AbstractRaceTrackingConnectivityParameters;
@@ -133,22 +134,26 @@ public class SwissTimingReplayConnectivityParameters extends AbstractRaceTrackin
@Override
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, final WindStore windStore,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception {
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler) throws Exception {
SwissTimingReplayToDomainAdapter listener = new SwissTimingReplayToDomainAdapter(/* regatta */ null, raceName,
raceID, domainFactory.getBaseDomainFactory().getOrCreateBoatClass(boatClassName), domainFactory,
trackedRegattaRegistry, useInternalMarkPassingAlgorithm, raceLogResolver, raceLogStore,
regattaLogStore, l->new SwissTimingReplayRaceTracker(windStore, l, this));
regattaLogStore, l->new SwissTimingReplayRaceTracker(windStore, l, this),
raceTrackingHandler);
replayService.loadRaceData(link, listener);
return listener.getTracker();
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception {
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler) throws Exception {
SwissTimingReplayToDomainAdapter listener = new SwissTimingReplayToDomainAdapter(regatta, raceName,
raceID, domainFactory.getBaseDomainFactory().getOrCreateBoatClass(boatClassName),
domainFactory, trackedRegattaRegistry, useInternalMarkPassingAlgorithm, raceLogResolver,
raceLogStore, regattaLogStore, l->new SwissTimingReplayRaceTracker(windStore, l, this));
raceLogStore, regattaLogStore, l->new SwissTimingReplayRaceTracker(windStore, l, this),
raceTrackingHandler);
replayService.loadRaceData(link, listener);
return listener.getTracker();
}
@@ -28,6 +28,7 @@ import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
import com.sap.sailing.domain.swisstimingreplayadapter.SwissTimingReplayListener;
import com.sap.sailing.domain.swisstimingreplayadapter.SwissTimingReplayRace;
import com.sap.sailing.domain.swisstimingreplayadapter.SwissTimingReplayService;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sse.util.ByteArrayOutputStreamWithVisibleBuffer;
@@ -151,9 +152,11 @@ public class SwissTimingReplayServiceImpl implements SwissTimingReplayService {
@Override
public void loadRaceData(RegattaIdentifier regattaToAddTo, String link, String raceName, String raceID,
String boatClassName, TrackerManager trackerManager, TrackedRegattaRegistry trackedRegattaRegistry,
boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore)
boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
RaceTrackingHandler raceTrackingHandler)
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception {
trackerManager.addRace(regattaToAddTo, new SwissTimingReplayConnectivityParameters(link, raceName, raceID,
boatClassName, useInternalMarkPassingAlgorithm, domainFactory, this, raceLogStore, regattaLogStore), /* timeout */ -1);
boatClassName, useInternalMarkPassingAlgorithm, domainFactory, this, raceLogStore, regattaLogStore), /* timeout */ -1,
raceTrackingHandler);
}
}
@@ -49,6 +49,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
@@ -159,6 +160,8 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
private final DynamicRaceDefinitionSet dynamicRaceDefinitionSet;
private final SwissTimingReplayRaceTracker tracker;
private final RaceTrackingHandler raceTrackingHandler;
@FunctionalInterface
public static interface TrackerConstructor {
@@ -180,7 +183,8 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
public SwissTimingReplayToDomainAdapter(Regatta regatta, String raceName, String raceIdForRaceDefinition,
BoatClass boatClass, DomainFactory domainFactory,
TrackedRegattaRegistry trackedRegattaRegistry, boolean useInternalMarkPassingAlgorithm, RaceLogResolver raceLogResolver,
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, TrackerConstructor trackerConstructor) {
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, TrackerConstructor trackerConstructor,
RaceTrackingHandler raceTrackingHandler) {
this.tracker = trackerConstructor == null ? null : trackerConstructor.createTracker(this);
this.raceLogResolver = raceLogResolver;
// when the race is created, notify the tracker's race creation listeners
@@ -211,6 +215,7 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
lastNextMark = new HashMap<>();
this.domainFactory = domainFactory;
this.useInternalMarkPassingAlgorithm = useInternalMarkPassingAlgorithm;
this.raceTrackingHandler = raceTrackingHandler;
}
public RaceTracker getTracker() {
@@ -396,8 +401,8 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
racePerRaceIdForRaceDefinition.put(raceIdForRaceDefinition, race);
racePerRaceIdForRaceDefinition.notifyAll();
}
DynamicTrackedRace trackedRace = getTrackedRegatta().
createTrackedRace(race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
DynamicTrackedRace trackedRace = raceTrackingHandler.createTrackedRace(getTrackedRegatta(),
race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
TrackedRace.DEFAULT_LIVE_DELAY_IN_MILLISECONDS,
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
@@ -45,6 +45,7 @@ import com.sap.sailing.domain.tracking.RaceTracker;
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.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -96,7 +97,8 @@ public class CourseUpdateTest extends AbstractTracTracLiveTest {
},
/* delayToLiveInMillis */0l, /* millisecondsOverWhichToAverageWind */30000, /* simulator */null, /* courseDesignUpdateURI */
null, /* tracTracUsername */null, /* tracTracPassword */null, getEventSubscriber(), getRaceSubscriber(),
/*ignoreTracTracMarkPassings*/false, mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS) {
/*ignoreTracTracMarkPassings*/false, mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler()) {
@Override
protected void handleEvent(Triple<IControlRoute, Long, Void> event) {
super.handleEvent(event);
@@ -19,6 +19,7 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.TracTracConnectionConstants;
@@ -57,25 +58,29 @@ public class MultipleClassesInRegattaTest {
EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE, new DummyTrackedRegattaRegistry(),
mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), createConnectivityParams(httpAndHost, liveURI, storedURI, courseDesignUpdateURI,
tracTracUsername, tracTracPassword, "cce678c8-97e6-11e0-9aed-406186cbf87c"), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
tracTracUsername, tracTracPassword, "cce678c8-97e6-11e0-9aed-406186cbf87c"), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler());
kiwotest2 = domainFactory
.createRaceTracker(
EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE, new DummyTrackedRegattaRegistry(),
mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), createConnectivityParams(httpAndHost, liveURI, storedURI, courseDesignUpdateURI,
tracTracUsername, tracTracPassword, "11290bd6-97e7-11e0-9aed-406186cbf87c"), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
tracTracUsername, tracTracPassword, "11290bd6-97e7-11e0-9aed-406186cbf87c"), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler());
kiwotest3 = domainFactory
.createRaceTracker(
EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE, new DummyTrackedRegattaRegistry(),
mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), createConnectivityParams(httpAndHost, liveURI, storedURI, courseDesignUpdateURI,
tracTracUsername, tracTracPassword, "39635b24-97e7-11e0-9aed-406186cbf87c"), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
tracTracUsername, tracTracPassword, "39635b24-97e7-11e0-9aed-406186cbf87c"), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler());
weym470may112014_2 = domainFactory
.createRaceTracker(
EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE, new DummyTrackedRegattaRegistry(),
mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), createConnectivityParams(httpAndHost, liveURI, storedURI, courseDesignUpdateURI,
tracTracUsername, tracTracPassword, "04498426-7dfd-11e0-8236-406186cbf87c"), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
tracTracUsername, tracTracPassword, "04498426-7dfd-11e0-8236-406186cbf87c"), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler());
assertEquals("STG", kiwotest1.getRegatta().getBoatClass().getName());
assertEquals("5O5", kiwotest2.getRegatta().getBoatClass().getName());
@@ -38,6 +38,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
@@ -126,7 +127,8 @@ public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest i
for (Receiver r : domainFactory.getUpdateReceivers(trackedRegatta, getTracTracRace(), EmptyWindStore.INSTANCE, /* delayToLiveInMillis */0l, /* simulator */null, createRaceDefinitionSet(),
/* trackedRegattaRegistry */null,
mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), /* courseDesignUpdateURI */null, /* tracTracUsername */null, /* tracTracPassword */
null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, receiverTypes)) {
null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler(), receiverTypes)) {
receivers.add(r);
}
getRaceSubscriber().subscribeConnectionStatus(new IConnectionStatusListener() {
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -121,7 +122,8 @@ public class ReceiveMarkPassingDataTest extends AbstractTracTracLiveTest {
}
}, /* trackedRegattaRegistry */null,
mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), /* courseDesignUpdateURI */null, /* tracTracUsername */null, /* tracTracPassword */
null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, ReceiverType.RACECOURSE,
null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler(), ReceiverType.RACECOURSE,
ReceiverType.MARKPOSITIONS, ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS)) {
receivers.add(r);
addReceiverToStopDuringTearDown(r);
@@ -27,6 +27,7 @@ import com.sap.sailing.domain.tracking.RaceChangeListener;
import com.sap.sailing.domain.tracking.RaceListener;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
@@ -88,7 +89,8 @@ public class ReceiveTrackingDataTest extends AbstractTracTracLiveTest {
}
},
/* trackedRegattaRegistry */null, mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), getTracTracRace(), /* courseDesignUpdateURI */
null, /* tracTracUsername */null, /* tracTracPassword */null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS)) {
null, /* tracTracUsername */null, /* tracTracPassword */null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler())) {
receiver.subscribe();
getRaceSubscriber().start();
addReceiverToStopDuringTearDown(receiver);
@@ -101,7 +103,8 @@ public class ReceiveTrackingDataTest extends AbstractTracTracLiveTest {
public void addRaceDefinition(RaceDefinition race, DynamicTrackedRace trackedRace) {
}
}, /* trackedRegattaRegistry */null, mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class), getTracTracRace(), /* courseDesignUpdateURI */
null, /* tracTracUsername */null, /* tracTracPassword */null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS));
null, /* tracTracUsername */null, /* tracTracPassword */null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler()));
}
@Test
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.TracTracConnectionConstants;
@@ -71,7 +72,8 @@ public class UnicodeCharactersInCompetitorNamesTest {
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, domainFactory,
"tracTest", "tracTest", "", "", /* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ true,
/* preferReplayIfAvailable */ false, /* timeoutInMillis */ (int) RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS),
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler());
Iterable<Competitor> competitors = fourtyninerYellow_2.getRaceHandle().getRace().getCompetitors();
for (Competitor competitor : competitors) {
@@ -37,6 +37,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
@@ -139,15 +140,19 @@ public interface DomainFactory {
TracTracRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
LeaderboardGroupResolver leaderboardGroupResolver,
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds)
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler)
throws URISyntaxException, SubscriberInitializationException, IOException, InterruptedException;
/**
* Same as {@link #createRaceTracker(URL, URI, URI, URI, TimePoint, TimePoint, WindStore, TrackedRegattaRegistry)},
* only that a predefined {@link Regatta} is used to hold the resulting races.
*/
RaceTracker createRaceTracker(Regatta regatta, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds)
RaceTracker createRaceTracker(Regatta regatta, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
LeaderboardGroupResolver leaderboardGroupResolver,
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler)
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
SubscriberInitializationException, IOException, InterruptedException;
@@ -172,7 +177,8 @@ public interface DomainFactory {
Simulator simulator, WindStore windStore, DynamicRaceDefinitionSet raceDefinitionSetToUpdate, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, IRace tractracRace,
URI courseDesignUpdateURI, String tracTracUsername, String tracTracPassword,
IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean useInternalMarkPassingAlgorithm, long timeoutInMilliseconds);
IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean useInternalMarkPassingAlgorithm, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler);
/**
* Creates a {@link RaceDefinition} from a TracTrac {@link IRace} and a domain {@link Course} definition. The
@@ -203,7 +209,8 @@ public interface DomainFactory {
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, URI courseDesignUpdateURI, UUID tracTracEventUuid,
String tracTracUsername, String tracTracPassword, boolean ignoreTracTracMarkPassings,
RaceLogResolver raceLogResolver, Consumer<DynamicTrackedRace> runBeforeExposingRace, IRace tractracRace);
RaceLogResolver raceLogResolver, Consumer<DynamicTrackedRace> runBeforeExposingRace, IRace tractracRace,
RaceTrackingHandler raceTrackingHandler);
/**
* The record may be for a single mark or a gate. If for a gate, the {@link ControlPointPositionData#getIndex()
@@ -221,7 +228,8 @@ public interface DomainFactory {
Iterable<Receiver> getUpdateReceivers(DynamicTrackedRegatta trackedRegatta, IRace tractracRace, WindStore windStore,
long delayToLiveInMillis, Simulator simulator, DynamicRaceDefinitionSet raceDefinitionSetToUpdate, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, URI courseDesignUpdateURI,
String tracTracUsername, String tracTracPassword, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean ignoreTracTracMarkPassings, long timeoutInMilliseconds, ReceiverType... types);
String tracTracUsername, String tracTracPassword, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean ignoreTracTracMarkPassings, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler, ReceiverType... types);
JSONService parseJSONURLWithRaceRecords(URL jsonURL, boolean loadClientParams) throws IOException, ParseException, org.json.simple.parser.ParseException, URISyntaxException;
@@ -15,6 +15,7 @@ import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.regattalog.RegattaLogStore;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tractracadapter.impl.Simulator;
@@ -52,7 +53,8 @@ public interface TracTracAdapter {
RaceHandle addTracTracRace(TrackerManager trackerManager, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
long timeoutInMilliseconds, String tracTracUsername, String tracTracPassword, String raceStatus,
String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, int timeoutInMillis)
String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, int timeoutInMillis,
RaceTrackingHandler raceTrackingHandler)
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
/**
@@ -79,7 +81,8 @@ public interface TracTracAdapter {
URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint trackingStartTime,
TimePoint trackingEndTime, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
long timeoutForReceivingRaceDefinitionInMilliseconds, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination)
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination,
RaceTrackingHandler raceTrackingHandler)
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
/**
@@ -70,6 +70,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
@@ -487,7 +488,7 @@ public class DomainFactoryImpl implements DomainFactory {
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
URI courseDesignUpdateURI, String tracTracUsername, String tracTracPassword,
IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean useInternalMarkPassingAlgorithm,
long timeoutInMilliseconds, ReceiverType... types) {
long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, ReceiverType... types) {
IEvent tractracEvent = tractracRace.getEvent();
Collection<Receiver> result = new ArrayList<Receiver>();
for (ReceiverType type : types) {
@@ -497,7 +498,8 @@ public class DomainFactoryImpl implements DomainFactory {
raceDefinitionSetToUpdate, delayToLiveInMillis,
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND, simulator, courseDesignUpdateURI,
tracTracUsername, tracTracPassword, eventSubscriber, raceSubscriber,
useInternalMarkPassingAlgorithm, raceLogResolver, leaderboardGroupResolver, timeoutInMilliseconds));
useInternalMarkPassingAlgorithm, raceLogResolver, leaderboardGroupResolver, timeoutInMilliseconds,
raceTrackingHandler));
break;
case MARKPOSITIONS:
result.add(new MarkPositionReceiver(
@@ -531,11 +533,11 @@ public class DomainFactoryImpl implements DomainFactory {
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
LeaderboardGroupResolver leaderboardGroupResolver, IRace tractracRace, URI courseDesignUpdateURI,
String tracTracUsername, String tracTracPassword, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber,
boolean useInternalMarkPassingAlgorithm, long timeoutInMilliseconds) {
boolean useInternalMarkPassingAlgorithm, long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler) {
return getUpdateReceivers(trackedRegatta, tractracRace, windStore, delayToLiveInMillis, simulator,
raceDefinitionSetToUpdate, trackedRegattaRegistry, raceLogResolver, leaderboardGroupResolver, courseDesignUpdateURI,
tracTracUsername, tracTracPassword, eventSubscriber, raceSubscriber,
useInternalMarkPassingAlgorithm, timeoutInMilliseconds, ReceiverType.RACECOURSE,
useInternalMarkPassingAlgorithm, timeoutInMilliseconds, raceTrackingHandler, ReceiverType.RACECOURSE,
ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS,
ReceiverType.SENSORDATA);
}
@@ -591,7 +593,7 @@ public class DomainFactoryImpl implements DomainFactory {
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, URI tracTracUpdateURI, UUID tracTracEventUuid,
String tracTracUsername, String tracTracPassword, boolean ignoreTracTracMarkPassings, RaceLogResolver raceLogResolver,
Consumer<DynamicTrackedRace> runBeforeExposingRace, IRace tractracRace) {
Consumer<DynamicTrackedRace> runBeforeExposingRace, IRace tractracRace, RaceTrackingHandler raceTrackingHandler) {
synchronized (raceCache) {
RaceDefinition raceDefinition = raceCache.get(raceId);
if (raceDefinition == null) {
@@ -607,7 +609,7 @@ public class DomainFactoryImpl implements DomainFactory {
trackedRegatta.getRegatta().addRace(raceDefinition);
trackedRace = createTrackedRace(trackedRegatta, raceDefinition, sidelines, windStore,
delayToLiveInMillis, millisecondsOverWhichToAverageWind, raceDefinitionSetToUpdate, ignoreTracTracMarkPassings,
raceLogResolver);
raceLogResolver, raceTrackingHandler);
logger.info("Added race " + raceDefinition + " to regatta " + trackedRegatta.getRegatta());
if (runBeforeExposingRace != null) {
logger.fine("Running callback for tracked race creation for "+trackedRace.getRace());
@@ -697,8 +699,8 @@ public class DomainFactoryImpl implements DomainFactory {
private DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta, RaceDefinition race,
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
boolean useMarkPassingCalculator, RaceLogResolver raceLogResolver) {
return trackedRegatta.createTrackedRace(race, sidelines,
boolean useMarkPassingCalculator, RaceLogResolver raceLogResolver, RaceTrackingHandler raceTrackingHandler) {
return raceTrackingHandler.createTrackedRace(trackedRegatta, race, sidelines,
windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
raceDefinitionSetToUpdate, useMarkPassingCalculator, raceLogResolver, Optional.empty());
@@ -958,21 +960,22 @@ public class DomainFactoryImpl implements DomainFactory {
public TracTracRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
LeaderboardGroupResolver leaderboardGroupResolver,
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds)
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler)
throws URISyntaxException, SubscriberInitializationException, IOException, InterruptedException {
return new TracTracRaceTrackerImpl(this, raceLogStore, regattaLogStore, windStore, trackedRegattaRegistry,
raceLogResolver, leaderboardGroupResolver, connectivityParams, timeoutInMilliseconds);
raceLogResolver, leaderboardGroupResolver, connectivityParams, timeoutInMilliseconds, raceTrackingHandler);
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
LeaderboardGroupResolver leaderboardGroupResolver,
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds)
throws URISyntaxException, CreateModelException, SubscriberInitializationException, IOException,
InterruptedException {
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler) throws URISyntaxException, CreateModelException,
SubscriberInitializationException, IOException, InterruptedException {
return new TracTracRaceTrackerImpl(regatta, this, raceLogStore, regattaLogStore, windStore, trackedRegattaRegistry,
raceLogResolver, leaderboardGroupResolver, connectivityParams, timeoutInMilliseconds);
raceLogResolver, leaderboardGroupResolver, connectivityParams, timeoutInMilliseconds, raceTrackingHandler);
}
@Override
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -70,19 +71,23 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue<IControlRoute,
private final boolean useInternalMarkPassingAlgorithm;
private final RaceLogResolver raceLogResolver;
private final LeaderboardGroupResolver leaderboardGroupResolver;
private final RaceTrackingHandler raceTrackingHandler;
public RaceCourseReceiver(DomainFactory domainFactory, DynamicTrackedRegatta trackedRegatta, IEvent tractracEvent,
IRace tractracRace, WindStore windStore, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, Simulator simulator,
URI courseDesignUpdateURI, String tracTracUsername, String tracTracPassword,
IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean useInternalMarkPassingAlgorithm,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) {
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler) {
super(domainFactory, tractracEvent, trackedRegatta, simulator, eventSubscriber, raceSubscriber, timeoutInMilliseconds);
this.tractracRace = tractracRace;
this.raceLogResolver = raceLogResolver;
this.leaderboardGroupResolver = leaderboardGroupResolver;
this.millisecondsOverWhichToAverageWind = millisecondsOverWhichToAverageWind;
this.delayToLiveInMillis = delayToLiveInMillis;
this.raceTrackingHandler = raceTrackingHandler;
if (simulator == null) {
this.windStore = windStore;
} else {
@@ -176,7 +181,8 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue<IControlRoute,
getTrackedRegatta(), tractracRace.getId(), tractracRace.getName(),
dominantBoatClass, competitorAndBoats, course, sidelines, windStore, delayToLiveInMillis,
millisecondsOverWhichToAverageWind, raceDefinitionSetToUpdate, tracTracUpdateURI,
getTracTracEvent().getId(), tracTracUsername, tracTracPassword, useInternalMarkPassingAlgorithm, raceLogResolver, tr->updateRaceTimes(tractracRace, tr), tractracRace);
getTracTracEvent().getId(), tracTracUsername, tracTracPassword, useInternalMarkPassingAlgorithm, raceLogResolver, tr->updateRaceTimes(tractracRace, tr), tractracRace,
raceTrackingHandler);
addAllMarksFromCourseArea(trackedRace);
if (getSimulator() != null) {
getSimulator().setTrackedRace(trackedRace);
@@ -253,7 +259,7 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue<IControlRoute,
private DynamicTrackedRace createTrackedRace(RaceDefinition race, Iterable<Sideline> sidelines,
Consumer<DynamicTrackedRace> runAfterCreatingTrackedRace) {
DynamicTrackedRace trackedRace = getTrackedRegatta().createTrackedRace(race, sidelines, windStore,
DynamicTrackedRace trackedRace = raceTrackingHandler.createTrackedRace(getTrackedRegatta(), race, sidelines, windStore,
delayToLiveInMillis, millisecondsOverWhichToAverageWind,
/* time over which to average speed: */ race.getBoatClass()
.getApproximateManeuverDurationInMilliseconds(),
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.regattalog.RegattaLogStore;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.impl.AbstractRaceTrackingConnectivityParameters;
@@ -117,18 +118,21 @@ public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTracking
@Override
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
long timeoutInMilliseconds) throws URISyntaxException, CreateModelException,
SubscriberInitializationException, IOException, InterruptedException {
long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler) throws URISyntaxException,
CreateModelException, SubscriberInitializationException, IOException, InterruptedException {
RaceTracker tracker = domainFactory.createRaceTracker(raceLogStore, regattaLogStore, windStore,
trackedRegattaRegistry, raceLogResolver, leaderboardGroupResolver, this, timeoutInMilliseconds);
trackedRegattaRegistry, raceLogResolver, leaderboardGroupResolver, this, timeoutInMilliseconds,
raceTrackingHandler);
return tracker;
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception {
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler) throws Exception {
RaceTracker tracker = domainFactory.createRaceTracker(regatta, raceLogStore, regattaLogStore, windStore,
trackedRegattaRegistry, raceLogResolver, leaderboardGroupResolver, this, timeoutInMilliseconds);
trackedRegattaRegistry, raceLogResolver, leaderboardGroupResolver, this, timeoutInMilliseconds,
raceTrackingHandler);
return tracker;
}
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.regattalog.RegattaLogStore;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -49,7 +50,8 @@ public class TracTracAdapterImpl implements TracTracAdapter {
public RaceHandle addTracTracRace(TrackerManager trackerManager, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
long timeoutInMilliseconds, String tracTracUsername, String tracTracPassword, String raceStatus,
String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, int timeoutInMillis) throws Exception {
String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, int timeoutInMillis,
RaceTrackingHandler raceTrackingHandler) throws Exception {
return trackerManager.addRace(
/* regattaToAddTo */null,
getTracTracDomainFactory().createTrackingConnectivityParameters(paramURL, liveURI, storedURI,
@@ -58,7 +60,7 @@ public class TracTracAdapterImpl implements TracTracAdapter {
/* endOfTracking */null, delayToLiveInMillis, /* offsetToStartTimeOfSimulatedRace */null, /* ignoreTracTracMarkPassings */ false,
raceLogStore, regattaLogStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackWind, correctWindDirectionByMagneticDeclination,
/* preferReplayIfAvailable */ false, timeoutInMillis),
timeoutInMilliseconds);
timeoutInMilliseconds, raceTrackingHandler);
}
@Override
@@ -67,14 +69,14 @@ public class TracTracAdapterImpl implements TracTracAdapter {
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility, boolean trackWind,
boolean correctWindDirectionByMagneticDeclination) throws Exception {
boolean correctWindDirectionByMagneticDeclination,RaceTrackingHandler raceTrackingHandler) throws Exception {
return trackerManager.addRace(
regattaToAddTo,
getTracTracDomainFactory().createTrackingConnectivityParameters(paramURL, liveURI, storedURI,
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, tracTracUsername, tracTracPassword,
raceStatus, raceVisibility, trackWind, correctWindDirectionByMagneticDeclination, /* preferReplayIfAvailable */ false,
(int) timeoutInMilliseconds), timeoutInMilliseconds);
(int) timeoutInMilliseconds), timeoutInMilliseconds, raceTrackingHandler);
}
@Override
@@ -36,6 +36,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackedRegatta;
@@ -261,10 +262,12 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
*/
TracTracRaceTrackerImpl(DomainFactory domainFactory, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds)
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler)
throws URISyntaxException, SubscriberInitializationException, IOException, InterruptedException {
this(/* regatta */ null, domainFactory, raceLogStore, regattaLogStore, windStore, trackedRegattaRegistry,
raceLogResolver, leaderboardGroupResolver, connectivityParams, timeoutInMilliseconds);
raceLogResolver, leaderboardGroupResolver, connectivityParams, timeoutInMilliseconds,
raceTrackingHandler);
}
/**
@@ -283,7 +286,8 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
*/
TracTracRaceTrackerImpl(final Regatta regatta, DomainFactory domainFactory, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds)
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler)
throws URISyntaxException, SubscriberInitializationException, IOException, InterruptedException {
super(connectivityParams);
final URL paramURL = connectivityParams.getParamURL();
@@ -399,7 +403,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
for (Receiver receiver : domainFactory.getUpdateReceivers(getTrackedRegatta(), delayToLiveInMillis,
simulator, windStore, this, trackedRegattaRegistry, raceLogResolver, leaderboardGroupResolver, tractracRace,
tracTracUpdateURI, tracTracUsername, tracTracPassword, eventSubscriber, raceSubscriber,
useInternalMarkPassingAlgorithm, timeoutInMilliseconds)) {
useInternalMarkPassingAlgorithm, timeoutInMilliseconds, raceTrackingHandler)) {
receivers.add(receiver);
}
addListenersForStoredDataAndStartController(receivers);
@@ -40,7 +40,8 @@ public interface RaceTrackingConnectivityParameters {
* tracker.
*/
RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception;
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler) throws Exception;
/**
* Starts a {@link RaceTracker}, associating the resulting races with the {@link Regatta} passed as argument instead
@@ -54,7 +55,8 @@ public interface RaceTrackingConnectivityParameters {
* {@link TrackedRegattaRegistry#removeRace(Regatta, com.sap.sailing.domain.base.RaceDefinition)}.
*/
RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception;
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler) throws Exception;
/**
* Deliver an ID object equal to that of the {@link RaceTracker#getID()} delivered by the {@link RaceTracker}
@@ -0,0 +1,36 @@
package com.sap.sailing.domain.tracking;
import java.util.Optional;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sse.util.ThreadLocalTransporter;
/**
* There are cases where extra work needs to be done when creating {@link TrackedRace TrackedRaces}. Due to the fact
* that several trackers do not know race Ids or any other specific information before receiving signals to create
* {@link TrackedRace TrackedRaces} which can in fact occur asynchronously. In this case, extra work (e.g. security
* checks) can not be done in the direct user interaction. This interface allows to implement custom generic logic to
* hook into {@link TrackedRace} creation on a {@link TrackedRegatta}.
*/
public interface RaceTrackingHandler {
DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta, RaceDefinition raceDefinition,
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingCalculator,
RaceLogResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter);
public class DefaultRaceTrackingHandler implements RaceTrackingHandler {
@Override
public DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta, RaceDefinition raceDefinition,
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingCalculator,
RaceLogResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter) {
return trackedRegatta.createTrackedRace(raceDefinition, sidelines, windStore, delayToLiveInMillis,
millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed, raceDefinitionSetToUpdate,
useMarkPassingCalculator, raceLogResolver, threadLocalTransporter);
}
}
}
@@ -29,7 +29,8 @@ public interface TrackerManager {
* if -1 then loading doesn't time out; otherwise, if the {@link RaceDefinition} hasn't been received
* after so many milliseconds then the tracker will be {@link RaceTracker#stop(boolean) stopped}.
*/
RaceHandle addRace(RegattaIdentifier regattaToAddTo, RaceTrackingConnectivityParameters params, long timeoutInMilliseconds)
RaceHandle addRace(RegattaIdentifier regattaToAddTo, RaceTrackingConnectivityParameters params, long timeoutInMilliseconds,
RaceTrackingHandler raceTrackingHandler)
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
}
@@ -22,6 +22,7 @@ import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapterFactory;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory;
import com.sap.sailing.domain.swisstimingreplayadapter.SwissTimingReplayService;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sailing.domain.tractracadapter.TracTracAdapterFactory;
import com.sap.sailing.gwt.ui.server.SailingServiceImpl;
@@ -75,7 +76,8 @@ public class SailingServiceImplMock extends SailingServiceImpl {
public RaceHandle addSwissTimingRace(TrackerManager trackerManager,
RegattaIdentifier regattaToAddTo, String raceID, String raceName, String raceDescription,
BoatClass boatClass, String hostname, int port, StartList startList, RaceLogStore logStore,
RegattaLogStore regattaLogStore, long timeoutInMilliseconds, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, String updateURL, String updateUsername, String updatePassword) throws InterruptedException,
RegattaLogStore regattaLogStore, long timeoutInMilliseconds, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, String updateURL, String updateUsername, String updatePassword,
RaceTrackingHandler raceTrackingHandler) throws InterruptedException,
UnknownHostException, IOException, ParseException, Exception {
// TODO Auto-generated method stub
return null;
@@ -362,6 +362,7 @@ import com.sap.sailing.domain.tracking.Maneuver;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
@@ -1379,7 +1380,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
getRegattaLogStore(), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, tracTracUsername,
tracTracPassword, record.getRaceStatus(), record.getRaceVisibility(), trackWind,
correctWindByDeclination);
correctWindByDeclination, new DefaultRaceTrackingHandler());
} catch (Exception e) {
logger.log(Level.SEVERE, "Error trying to load race " + rrs+". Continuing with remaining races...", e);
}
@@ -3122,7 +3123,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
rr.raceId, rr.getName(), raceDescription, boatClass, hostname, port, startList,
getRaceLogStore(), getRegattaLogStore(),
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, useInternalMarkPassingAlgorithm, trackWind,
correctWindByDeclination, updateURL, updateUsername, updatePassword);
correctWindByDeclination, updateURL, updateUsername, updatePassword, new DefaultRaceTrackingHandler());
}
}
@@ -3163,7 +3164,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
boatClassName = null;
}
getSwissTimingReplayService().loadRaceData(regattaIdentifier, replayRaceDTO.link, replayRaceDTO.getName(),
replayRaceDTO.race_id, boatClassName, getService(), getService(), useInternalMarkPassingAlgorithm, getRaceLogStore(), getRegattaLogStore());
replayRaceDTO.race_id, boatClassName, getService(), getService(), useInternalMarkPassingAlgorithm, getRaceLogStore(), getRegattaLogStore(),
new DefaultRaceTrackingHandler());
} catch (Exception e) {
logger.log(Level.SEVERE, "Error trying to load SwissTimingReplay race " + replayRaceDTO, e);
}
@@ -6881,7 +6883,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
Leaderboard leaderboard = getLeaderboardByName(leaderboardName);
RaceColumn raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
Fleet fleet = raceColumn.getFleetByName(fleetName);
getRaceLogTrackingAdapter().startTracking(getService(), leaderboard, raceColumn, fleet, trackWind, correctWindByDeclination);
getRaceLogTrackingAdapter().startTracking(getService(), leaderboard, raceColumn, fleet, trackWind, correctWindByDeclination,
new DefaultRaceTrackingHandler());
}
@Override
@@ -8343,7 +8346,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
raceLog.add(new RaceLogStartTrackingEventImpl(startTrackingTimePoint, author, raceLog.getCurrentPassId()));
try {
final RaceHandle raceHandle = getRaceLogTrackingAdapter().startTracking(getService(), regattaLeaderboard,
raceColumn, fleet, /* trackWind */ true, /* correctWindDirectionByMagneticDeclination */ true);
raceColumn, fleet, /* trackWind */ true, /* correctWindDirectionByMagneticDeclination */ true,
new DefaultRaceTrackingHandler());
// wait for the RaceDefinition to be created
raceHandle.getRace();
@@ -42,6 +42,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.Receiver;
@@ -92,7 +93,8 @@ public class TestStoringAndRetrievingWindTracksTest extends AbstractTracTracLive
public void addRaceDefinition(RaceDefinition race, DynamicTrackedRace trackedRace) {
}
}, /* trackedRegattaRegistry */ null, mock(RaceLogResolver.class), mock(LeaderboardGroupResolver.class),
/*courseDesignUpdateURI*/ null, /*tracTracUsername*/ null, /*tracTracPassword*/ null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, ReceiverType.RACECOURSE);
/*courseDesignUpdateURI*/ null, /*tracTracUsername*/ null, /*tracTracPassword*/ null, getEventSubscriber(), getRaceSubscriber(), /*ignoreTracTracMarkPassings*/ false, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler(), ReceiverType.RACECOURSE);
addListenersForStoredDataAndStartController(typeControllers);
for (final Receiver receiver : typeControllers) {
addReceiverToStopDuringTearDown(receiver);
@@ -106,6 +106,7 @@ import com.sap.sailing.domain.tracking.GPSFixTrack;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.FlatGPSFixJsonDeserializer;
@@ -617,7 +618,8 @@ public class LeaderboardsResource extends AbstractLeaderboardsResource {
leaderboardAndRaceColumnAndFleetAndResponse.getRaceColumn(),
leaderboardAndRaceColumnAndFleetAndResponse.getFleet(),
trackWind == null ? true : trackWind,
correctWindDirectionByMagneticDeclination == null ? true : correctWindDirectionByMagneticDeclination);
correctWindDirectionByMagneticDeclination == null ? true : correctWindDirectionByMagneticDeclination,
new DefaultRaceTrackingHandler());
jsonResult.put("regatta", raceHandle.getRegatta().getName());
result = Response.ok(jsonResult.toJSONString()).build();
} else {
@@ -72,6 +72,7 @@ import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
import com.sap.sailing.domain.trackimport.GPSFixImporter;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.geocoding.ReverseGeocoder;
@@ -677,7 +678,8 @@ public class ExpeditionAllInOneImporter {
final Fleet fleet) throws NotDenotedForRaceLogTrackingException, Exception {
DynamicTrackedRace trackedRace;
final RaceHandle raceHandle = adapter.startTracking(service, regattaLeaderboard, raceColumn, fleet,
/* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ true);
/* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ true,
new DefaultRaceTrackingHandler());
// wait for the RaceDefinition to be created
raceHandle.getRace();
trackedRace = WaitForTrackedRaceUtil.waitForTrackedRace(raceColumn, fleet, 10);
@@ -32,6 +32,7 @@ import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tractracadapter.impl.DomainFactoryImpl;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.operationaltransformation.CreateTrackedRace;
@@ -109,7 +110,8 @@ public class TrackRaceBoatCompetitorMetadataReplicationTest extends AbstractServ
/* resultDiscardingThresholds */ null, /* startsWithZeroScore */ false, /* firstColumnIsNonDiscardableCarryForward */ false,
/* hasSplitFleetContiguousScoring */ false, /* maximumNumberOfDiscards */ null,
Arrays.asList(new FleetDTO("Red", 0, Color.RED), new FleetDTO("Green", 0, Color.GREEN), new FleetDTO("Blue", 0, Color.BLUE))));
racesHandle = master.addRace(/* regattaToAddTo */ regattaIdentifier, trackingParams, /* timeoutInMilliseconds */ 60000);
racesHandle = master.addRace(/* regattaToAddTo */ regattaIdentifier, trackingParams, /* timeoutInMilliseconds */ 60000,
new DefaultRaceTrackingHandler());
}
private void waitForTrackRaceReplicationTrigger() throws InterruptedException, IllegalAccessException {
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard;
import com.sap.sailing.server.operationaltransformation.ConnectTrackedRaceToLeaderboardColumn;
@@ -102,7 +103,8 @@ public class TrackRaceReplicationTest extends AbstractServerReplicationTest {
}
private void startTrackingOnMaster() throws Exception {
racesHandle = master.addRace(/* regattaToAddTo */ null, trackingParams, /* timeoutInMilliseconds */ 60000);
racesHandle = master.addRace(/* regattaToAddTo */ null, trackingParams, /* timeoutInMilliseconds */ 60000,
new DefaultRaceTrackingHandler());
}
private void waitForTrackRaceReplicationTrigger() throws InterruptedException, IllegalAccessException {
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.tracking.RaceListener;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tractracadapter.TracTracConnectionConstants;
import com.sap.sailing.domain.tractracadapter.impl.TracTracAdapterFactoryImpl;
import com.sap.sailing.server.impl.RacingEventServiceImpl;
@@ -76,7 +77,8 @@ public class RaceTrackerTest {
EmptyRegattaLogStore.INSTANCE, /* timeoutInMilliseconds */60000, tracTracUsername, tracTracPassword,
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
/* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ false,
/* timeoutInMillis */ (int) RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
/* timeoutInMillis */ (int) RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler());
logger.info("Calling raceHandle.getRaces()");
RaceDefinition race = raceHandle.getRace(); // wait for RaceDefinition to be completely wired in Regatta
logger.info("Obtained race: "+race);
@@ -135,7 +137,8 @@ public class RaceTrackerTest {
EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, /* timeoutInMilliseconds */60000,
tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS,
TracTracConnectionConstants.ONLINE_VISIBILITY, /* trackWind */ false,
/* correctWindDirectionByMagneticDeclination */ false, /* timeoutInMillis */ (int) RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
/* correctWindDirectionByMagneticDeclination */ false, /* timeoutInMillis */ (int) RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler());
TrackedRegatta newTrackedRegatta = myRaceHandle.getTrackedRegatta();
assertNotSame(oldTrackedRegatta, newTrackedRegatta);
TrackedRace newTrackedRace = getTrackedRace(newTrackedRegatta);
@@ -164,7 +167,8 @@ public class RaceTrackerTest {
EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, /* timeoutInMilliseconds */60000,
tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS,
TracTracConnectionConstants.ONLINE_VISIBILITY, /* trackWind */ false,
/* correctWindDirectionByMagneticDeclination */ false, /* timeoutInMillis */ (int) RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
/* correctWindDirectionByMagneticDeclination */ false, /* timeoutInMillis */ (int) RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS,
new DefaultRaceTrackingHandler());
TrackedRegatta newTrackedEvent = myRaceHandle.getTrackedRegatta();
TrackedRace newTrackedRace = getTrackedRace(newTrackedEvent);
// expecting a new tracked race to be created when starting over with tracking
@@ -186,6 +186,7 @@ import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.RaceListener;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackedRegatta;
@@ -193,6 +194,7 @@ import com.sap.sailing.domain.tracking.TrackedRegattaListener;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTracker;
import com.sap.sailing.domain.tracking.WindTrackerFactory;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
@@ -855,7 +857,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
// server startup activities happening
numberOfTrackedRacesToRestore = getDomainObjectFactory().loadConnectivityParametersForRacesToRestore(params -> {
try {
final RaceHandle handle = addRace(/* addToRegatta==null means "default regatta" */ null, params, /* no timeout during mass loading */ -1);
final RaceHandle handle = addRace(/* addToRegatta==null means "default regatta" */ null, params, /* no timeout during mass loading */ -1,
new DefaultRaceTrackingHandler());
final RaceDefinition race = handle.getRace(RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); // try to not flood servers during restore by waiting for race to appear
if (race == null) {
logger.warning("Race for tracker " + handle.getRaceTracker() + " with ID "
@@ -1710,7 +1713,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
@Override
public RaceHandle addRace(RegattaIdentifier regattaToAddTo, RaceTrackingConnectivityParameters params,
long timeoutInMilliseconds) throws Exception {
long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler) throws Exception {
final Object trackerID = params.getTrackerID();
NamedReentrantReadWriteLock raceTrackersByIdLock = lockRaceTrackersById(trackerID);
try {
@@ -1719,10 +1722,12 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
Regatta regatta = regattaToAddTo == null ? null : getRegatta(regattaToAddTo);
if (regatta == null) {
// create tracker and use an existing or create a default regatta
tracker = params.createRaceTracker(this, windStore, /* raceLogResolver */ this, /* leaderboardGroupResolver */ this, timeoutInMilliseconds);
tracker = params.createRaceTracker(this, windStore, /* raceLogResolver */ this, /* leaderboardGroupResolver */ this, timeoutInMilliseconds,
raceTrackingHandler);
} else {
// use the regatta selected by the RaceIdentifier regattaToAddTo
tracker = params.createRaceTracker(regatta, this, windStore, /* raceLogResolver */ this, /* leaderboardGroupResolver */ this, timeoutInMilliseconds);
tracker = params.createRaceTracker(regatta, this, windStore, /* raceLogResolver */ this, /* leaderboardGroupResolver */ this, timeoutInMilliseconds,
raceTrackingHandler);
assert tracker.getRegatta() == regatta;
}
LockUtil.lockForWrite(raceTrackersByRegattaLock);