bug5219: added logic to race log tracking that re-tracks race when competitors change;

this makes the test case green that was previously red
This commit is contained in:
Axel Uhl committed 2020-04-21 19:10:50 +02:00
1 parent f4dce2e775
commit c8c3f8da35
3 files changed
+78 -11

No files matched your search

@@ -20,6 +20,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder;
@@ -28,12 +29,18 @@ import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogEndOfTrackingEventImpl;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartOfTrackingEventImpl;
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent;
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceInformationFinder;
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogTrackingStateAnalyzer;
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RegisteredCompetitorsAndBoatsAnalyzer;
import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogRegisterCompetitorEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.impl.BaseRegattaLogEventVisitor;
import com.sap.sailing.domain.base.Boat;
import com.sap.sailing.domain.base.BoatClass;
@@ -146,6 +153,26 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
trackedRace.updateStartAndEndOfTracking(/* waitForGPSFixesToLoad */ false);
}
}
@Override
public void visit(RaceLogRevokeEvent event) {
if (event.getRevokedEventType().equals(RaceLogRegisterCompetitorEventImpl.class.getName())) {
try {
checkForChangeOfCompetitorSet();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Override
public void visit(RaceLogRegisterCompetitorEvent event) {
try {
checkForChangeOfCompetitorSet();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
visitors.put(log, visitor);
((RaceLog) log).addListener(visitor);
@@ -155,6 +182,26 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
public void visit(RegattaLogDefineMarkEvent event) {
RaceLogRaceTracker.this.onDefineMarkEvent(event);
}
@Override
public void visit(RegattaLogRevokeEvent event) {
if (event.getRevokedEventType().equals(RegattaLogRegisterCompetitorEventImpl.class.getName())) {
try {
checkForChangeOfCompetitorSet();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Override
public void visit(RegattaLogRegisterCompetitorEvent event) {
try {
checkForChangeOfCompetitorSet();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
visitors.put(log, visitor);
((RegattaLog) log).addListener(visitor);
@@ -168,6 +215,13 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
}
}
private void checkForChangeOfCompetitorSet() throws Exception {
final Map<Competitor, Boat> competitorsAndTheirBoats = new RegisteredCompetitorsAndBoatsAnalyzer(params.getRaceLog(), params.getRegattaLog()).analyze();
if (!Util.setEquals(competitorsAndTheirBoats.keySet(), getRace().getCompetitors())) {
trackedRegattaRegistry.updateRaceCompetitors(getRegatta(), getRace());
}
}
@Override
protected void onStop(boolean preemptive, boolean willBeRemoved) {
RaceLog raceLog = params.getRaceLog();
@@ -273,18 +327,18 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
}
private void startTracking(RaceLogStartTrackingEvent event) {
RaceLog raceLog = params.getRaceLog();
RaceColumn raceColumn = params.getRaceColumn();
Fleet fleet = params.getFleet();
RaceLogDenoteForTrackingEvent denoteEvent = new RaceInformationFinder(raceLog).analyze();
final RaceLog raceLog = params.getRaceLog();
final RaceColumn raceColumn = params.getRaceColumn();
final Fleet fleet = params.getFleet();
final RaceLogDenoteForTrackingEvent denoteEvent = new RaceInformationFinder(raceLog).analyze();
final Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> trackingTimes = new TrackingTimesFinder(raceLog).analyze();
if (!trackedRegatta.getRegatta().isControlTrackingFromStartAndFinishTimes() &&
(trackingTimes == null || trackingTimes.getA() == null || trackingTimes.getA().getTimePoint() == null)) {
// the start of tracking interval is unset or set to null; enter "now" as start of tracking into the race log
raceLog.add(new RaceLogStartOfTrackingEventImpl(MillisecondsTimePoint.now(), raceLogEventAuthor, raceLog.getCurrentPassId()));
}
BoatClass boatClass = denoteEvent.getBoatClass();
String raceName = denoteEvent.getRaceName();
final BoatClass boatClass = denoteEvent.getBoatClass();
final String raceName = denoteEvent.getRaceName();
CourseBase courseBase = new LastPublishedCourseDesignFinder(raceLog, /* onlyCoursesWithValidWaypointList */ true).analyze();
if (courseBase == null) {
courseBase = new CourseDataImpl("Default course for " + raceName);
@@ -303,8 +357,8 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
}
throw new RaceNotCreatedException(String.format("Race for racelog (%s) has already been created", raceLog));
}
Map<Competitor, Boat> competitorsAndTheirBoats = raceColumn.getAllCompetitorsAndTheirBoats(params.getFleet());
Serializable raceId = denoteEvent.getRaceId();
final Map<Competitor, Boat> competitorsAndTheirBoats = raceColumn.getAllCompetitorsAndTheirBoats(params.getFleet());
final Serializable raceId = denoteEvent.getRaceId();
try {
final RaceDefinition raceDef = raceTrackingHandler.createRaceDefinition(trackedRegatta.getRegatta(), raceName, course,
boatClass, competitorsAndTheirBoats, raceId);
@@ -208,7 +208,6 @@ public class AutomaticRetrackUponCompetitorSetChangeTest {
final RegattaAndRaceIdentifier raceIdentifier = trackedRace.getRaceIdentifier();
assertEquals(1, Util.size(trackedRace.getRace().getCompetitors()));
assertSame(firstCompetitor, trackedRace.getRace().getCompetitors().iterator().next());
regattaLog.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), service.getServerAuthor(), firstCompetitor));
// Now add a second competitor registration ("late-comer") to the regatta log and expect the race to reload:
regattaLog.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), service.getServerAuthor(), secondCompetitor));
final CompletableFuture<RaceTracker> raceTrackerFuture = new CompletableFuture<>();
@@ -764,8 +764,13 @@ public class Util {
}
public static <T> Set<T> asSet(Iterable<T> iterable) {
final Set<T> result = new HashSet<>();
addAll(iterable, result);
final Set<T> result;
if (iterable instanceof Set<?>) {
result = (Set<T>) iterable;
} else {
result = new HashSet<>();
addAll(iterable, result);
}
return result;
}
@@ -967,4 +972,13 @@ public class Util {
}
return result;
}
/**
* Compares two iterable sequences based on {@link Set} semantics. If both objects turn out to be {@link Set}s,
* the {@link Set#equals(Object)} method will be used. Otherwise, non-{@link Set} objects will be filled into
* temporary {@link Set} objects and then compared as sets.
*/
public static <T> boolean setEquals(Iterable<T> a, Iterable<T> b) {
return asSet(a).equals(asSet(b));
}
}