Merge branch 'master' into bug1018

Conflicts:
	java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java
This commit is contained in:
Axel Uhl committed 2015-05-08 18:27:39 +02:00
commit 1dfc055e34
17 files changed
+296 -27

No files matched your search

+19 -17
View File
@@ -190,6 +190,7 @@ if [[ $@ == "" ]]; then
exit 2
fi
rm $START_DIR/build.log
if [[ "$@" == "clean" ]]; then
./gradlew clean
@@ -202,7 +203,7 @@ if [[ "$@" == "clean" ]]; then
cd $PROJECT_HOME
echo "Using following command: mvn $extra -DargLine=\"$APP_PARAMETERS\" -fae -s $MAVEN_SETTINGS $clean"
echo "Maven version used: `mvn --version`"
mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean 2>&1 | tee $START_DIR/build.log
mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean 2>&1 | tee -a $START_DIR/build.log
MVN_EXIT_CODE=${PIPESTATUS[0]}
echo "Maven exit code is $MVN_EXIT_CODE"
exit 0
@@ -576,7 +577,7 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
#build local p2 repo
echo "Using following command (pwd: java/com.sap.sailing.targetplatform.base): mvn -fae -s $MAVEN_SETTINGS $clean compile"
echo "Maven version used: `mvn --version`"
(cd com.sap.$PROJECT_TYPE.targetplatform.base; mvn -fae -s $MAVEN_SETTINGS $clean compile 2>&1 | tee $START_DIR/build.log)
(cd com.sap.$PROJECT_TYPE.targetplatform.base; mvn -fae -s $MAVEN_SETTINGS $clean compile 2>&1 | tee -a $START_DIR/build.log)
# now get the exit status from mvn, and not that of tee which is what $? contains now
MVN_EXIT_CODE=${PIPESTATUS[0]}
echo "Maven exit code is $MVN_EXIT_CODE"
@@ -631,36 +632,37 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
echo "TRACKING_APP_VERSION=$TRACKING_APP_VERSION"
extra="$extra -Dtracking-app-version=$TRACKING_APP_VERSION"
NOW=$(date +"%s")
BUILD_TOOLS=22.0.0
TARGET_API=22
TEST_API=18
ANDROID_ABI=armeabi-v7a
AVD_NAME=androidTest
echo "Updating Android SDK (tools)..."
AVD_NAME="androidTest-${NOW}"
echo "Updating Android SDK (tools)..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter tools --no-ui --force --all > /dev/null
echo "Updating Android SDK (platform-tools)..."
echo "Updating Android SDK (platform-tools)..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter platform-tools --no-ui --force --all > /dev/null
echo "Updating Android SDK (build-tools-${BUILD_TOOLS})..."
echo "Updating Android SDK (build-tools-${BUILD_TOOLS})..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter build-tools-${BUILD_TOOLS} --no-ui --force --all > /dev/null
echo "Updating Android SDK (android-${TARGET_API})..."
echo "Updating Android SDK (android-${TARGET_API})..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter android-${TARGET_API} --no-ui --force --all > /dev/null
echo "Updating Android SDK (extra-android-m2repository)..."
echo "Updating Android SDK (extra-android-m2repository)..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter extra-android-m2repository --no-ui --force --all > /dev/null
echo "Updating Android SDK (extra-google-m2repository)..."
echo "Updating Android SDK (extra-google-m2repository)..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter extra-google-m2repository --no-ui --force --all > /dev/null
./gradlew clean build
./gradlew clean build | tee -a $START_DIR/build.log
if [[ $? != 0 ]]; then
exit 100
fi
# testing deactivated due to errors in hudson
if [ $testing -eq 2 ]; then
if [ $testing -eq 1 ]; then
adb emu kill
echo "Downloading image (sys-img-${ANDROID_ABI}-android-${TEST_API})..."
echo "Downloading image (sys-img-${ANDROID_ABI}-android-${TEST_API})..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter sys-img-${ANDROID_ABI}-android-${TEST_API} --no-ui --force --all > /dev/null
echo no | "$ANDROID" create avd --name ${AVD_NAME} --target android-${TEST_API} --abi ${ANDROID_ABI} --force
echo "Starting emulator..."
echo no | "$ANDROID" create avd --name ${AVD_NAME} --target android-${TEST_API} --abi ${ANDROID_ABI} --force -p ${START_DIR}/emulator
echo "Starting emulator..." | tee -a $START_DIR/build.log
emulator -avd ${AVD_NAME} -no-skin -no-audio -no-window &
echo "Waiting for startup..."
echo "Waiting for startup..." | tee -a $START_DIR/build.log
adb wait-for-device
sleep 60
$PROJECT_HOME/configuration/androidWaitForEmulator.sh
@@ -670,7 +672,7 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
exit 102
fi
adb shell input keyevent 82 &
./gradlew deviceCheck connectedCheck
./gradlew deviceCheck connectedCheck --debug --stacktrace | tee -a $START_DIR/build.log
if [[ $? != 0 ]]; then
adb emu kill
"$ANDROID" delete avd --name ${AVD_NAME}
@@ -695,7 +697,7 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
echo "Using following command: mvn $extra -DargLine=\"$APP_PARAMETERS\" -fae -s $MAVEN_SETTINGS $clean install"
echo "Maven version used: `mvn --version`"
mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean install 2>&1 | tee $START_DIR/build.log
mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean install 2>&1 | tee -a $START_DIR/build.log
# now get the exit status from mvn, and not that of tee which is what $? contains now
MVN_EXIT_CODE=${PIPESTATUS[0]}
echo "Maven exit code is $MVN_EXIT_CODE"
@@ -40,6 +40,7 @@ import com.sap.sse.common.TimeRange;
import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.common.TypeBasedServiceFinderFactory;
import com.sap.sse.common.Util;
import com.sap.sse.common.WithID;
import com.sap.sse.common.impl.TimeRangeImpl;
/**
@@ -196,6 +197,12 @@ public class MongoGPSFixStoreImpl implements MongoGPSFixStore {
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
}
@Override
public void loadTrack(DynamicGPSFixTrack<WithID, ?> track, DeviceMapping<WithID> mapping)
throws NoCorrespondingServiceRegisteredException, TransformationException {
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true);
}
private DBObject getDeviceQuery(DeviceIdentifier device)
throws TransformationException, NoCorrespondingServiceRegisteredException {
Object dbDeviceId = MongoObjectFactoryImpl.storeDeviceId(deviceServiceFinder, device);
@@ -228,4 +235,5 @@ public class MongoGPSFixStoreImpl implements MongoGPSFixStore {
}
return ((Number) result.get(FieldNames.NUM_FIXES.name())).longValue();
}
}
@@ -4,6 +4,8 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixImpl;
import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixMovingImpl;
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
@@ -21,8 +23,10 @@ public class MockGPSFixMongoServiceFinder implements TypeBasedServiceFinder<GPSF
@Override
public GPSFixMongoHandler findService(String fixType) {
if (fixType.equals(GPSFixMovingImpl.class.getName())) return movingHandler;
if (fixType.equals(GPSFixImpl.class.getName())) return handler;
if (fixType.equals(GPSFixMovingImpl.class.getName()) ||
fixType.equals(CompactGPSFixMovingImpl.class.getName())) return movingHandler;
if (fixType.equals(GPSFixImpl.class.getName()) ||
fixType.equals(CompactGPSFixImpl.class.getName())) return handler;
return null;
}
@@ -24,6 +24,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
import com.sap.sse.common.Color;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.concurrent.ConcurrentWeakHashMap;
import com.sap.sse.concurrent.LockUtil;
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
@@ -168,6 +169,17 @@ public class LeaderboardCacheManager {
public void isSuppressedChanged(Competitor competitor, boolean newIsSuppressed) {
removeFromCache(leaderboard);
}
@Override
public void timePointOfLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity,
TimePoint newTimePointOfLastCorrectionsValidity) {
removeFromCache(leaderboard);
}
@Override
public void commentChanged(String oldComment, String newComment) {
removeFromCache(leaderboard);
}
}
private final LeaderboardCache leaderboardCache;
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.leaderboard;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sse.common.TimePoint;
public interface ScoreCorrectionListener {
void correctedScoreChanced(Competitor competitor, RaceColumn raceColumn, Double oldCorrectedScore, Double newCorrectedScore);
@@ -12,4 +13,8 @@ public interface ScoreCorrectionListener {
void carriedPointsChanged(Competitor competitor, Double oldCarriedPoints, Double newCarriedPoints);
void isSuppressedChanged(Competitor competitor, boolean newIsSuppressed);
void timePointOfLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity, TimePoint newTimePointOfLastCorrectionsValidity);
void commentChanged(String oldComment, String newComment);
}
@@ -40,5 +40,8 @@ public interface SettableScoreCorrection extends ScoreCorrection {
void notifyListenersAboutCarriedPointsChange(Competitor competitor, Double oldCarriedPoints, Double newCarriedPoints);
void notifyListenersAboutIsSuppressedChange(Competitor competitor, boolean suppressed);
void notifyListenersAboutLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity, TimePoint newTimePointOfLastCorrectionsValidity);
void notifyListenersAboutCommentChanged(String oldComment, String newComment);
}
@@ -377,7 +377,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
@Override
public void setCarriedPoints(Competitor competitor, double carriedPoints) {
Double oldCarriedPoints = this.carriedPoints.put(competitor, carriedPoints);
getScoreCorrection().notifyListenersAboutCarriedPointsChange(competitor, oldCarriedPoints, carriedPoints);
if (!Util.equalsWithNull(oldCarriedPoints, carriedPoints)) {
getScoreCorrection().notifyListenersAboutCarriedPointsChange(competitor, oldCarriedPoints, carriedPoints);
}
}
@Override
@@ -394,7 +396,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
@Override
public void unsetCarriedPoints(Competitor competitor) {
Double oldCarriedPoints = carriedPoints.remove(competitor);
getScoreCorrection().notifyListenersAboutCarriedPointsChange(competitor, oldCarriedPoints, null);
if (oldCarriedPoints != null) {
getScoreCorrection().notifyListenersAboutCarriedPointsChange(competitor, oldCarriedPoints, null);
}
}
@Override
@@ -411,7 +415,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
public void setDisplayName(Competitor competitor, String displayName) {
String oldDisplayName = displayNames.get(competitor);
displayNames.put(competitor, displayName);
getRaceColumnListeners().notifyListenersAboutCompetitorDisplayNameChanged(competitor, oldDisplayName, displayName);
if (!Util.equalsWithNull(oldDisplayName, displayName)) {
getRaceColumnListeners().notifyListenersAboutCompetitorDisplayNameChanged(competitor, oldDisplayName, displayName);
}
}
@Override
@@ -124,6 +124,21 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
}
}
@Override
public void notifyListenersAboutLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity,
TimePoint newTimePointOfLastCorrectionsValidity) {
for (ScoreCorrectionListener listener : getScoreCorrectionListeners()) {
listener.timePointOfLastCorrectionsValidityChanged(oldTimePointOfLastCorrectionsValidity, newTimePointOfLastCorrectionsValidity);
}
}
@Override
public void notifyListenersAboutCommentChanged(String oldComment, String newComment) {
for (ScoreCorrectionListener listener : getScoreCorrectionListeners()) {
listener.commentChanged(oldComment, newComment);
}
}
@Override
public void setMaxPointsReason(Competitor competitor, RaceColumn raceColumn, MaxPointsReason reason) {
com.sap.sse.common.Util.Pair<Competitor, RaceColumn> key = raceColumn.getKey(competitor);
@@ -483,12 +498,20 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
@Override
public void setTimePointOfLastCorrectionsValidity(TimePoint timePointOfLastCorrectionsValidity) {
final TimePoint oldTimePointOfLastCorrectionsValidity = this.timePointOfLastCorrectionsValidity;
this.timePointOfLastCorrectionsValidity = timePointOfLastCorrectionsValidity;
if (!Util.equalsWithNull(oldTimePointOfLastCorrectionsValidity, timePointOfLastCorrectionsValidity)) {
notifyListenersAboutLastCorrectionsValidityChanged(oldTimePointOfLastCorrectionsValidity, timePointOfLastCorrectionsValidity);
}
}
@Override
public void setComment(String scoreCorrectionComment) {
final String oldComment = this.comment;
this.comment = scoreCorrectionComment;
if (!Util.equalsWithNull(oldComment, scoreCorrectionComment)) {
notifyListenersAboutCommentChanged(oldComment, scoreCorrectionComment);
}
}
protected Leaderboard getLeaderboard() {
@@ -87,6 +87,17 @@ public abstract class AbstractMetaLeaderboard extends AbstractSimpleLeaderboardI
public void isSuppressedChanged(Competitor competitor, boolean newIsSuppressed) {
getScoreCorrection().notifyListenersAboutIsSuppressedChange(competitor, newIsSuppressed);
}
@Override
public void timePointOfLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity,
TimePoint newTimePointOfLastCorrectionsValidity) {
getScoreCorrection().notifyListenersAboutLastCorrectionsValidityChanged(oldTimePointOfLastCorrectionsValidity, newTimePointOfLastCorrectionsValidity);
}
@Override
public void commentChanged(String oldComment, String newComment) {
getScoreCorrection().notifyListenersAboutCommentChanged(oldComment, newComment);
}
}
public AbstractMetaLeaderboard(String name, ScoringScheme scoringScheme,
@@ -8,7 +8,16 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDeviceMarkMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
import com.sap.sailing.domain.abstractlog.shared.events.DeviceMappingEvent;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.Fleet;
@@ -17,10 +26,21 @@ import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.media.MediaTrack;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.WithID;
import com.sap.sse.common.impl.TimeRangeImpl;
/**
* Holds all information needed for a master data import.
@@ -29,6 +49,8 @@ import com.sap.sailing.domain.tracking.TrackedRace;
*
*/
public class TopLevelMasterData implements Serializable {
private static final Logger logger = Logger.getLogger(TopLevelMasterData.class.getName());
private static final long serialVersionUID = 4820893865792553281L;
private final Map<RegattaIdentifier, Set<String>> raceIdStringsForRegatta;
@@ -36,14 +58,16 @@ public class TopLevelMasterData implements Serializable {
private final Set<LeaderboardGroup> leaderboardGroups;
private final Set<WindTrackMasterData> windTrackMasterData;
private final Map<LeaderboardGroup, Set<Event>> eventForLeaderboardGroup;
private final Map<DeviceIdentifier, Set<GPSFix>> raceLogTrackingFixes;
public TopLevelMasterData(final Set<LeaderboardGroup> groupsToExport, final Iterable<Event> allEvents,
final Map<String, Regatta> regattaForRaceIdString, final Collection<MediaTrack> allMediaTracks,
boolean exportWind) {
GPSFixStore gpsFixStore, boolean exportWind) {
this.raceIdStringsForRegatta = convertToRaceIdStringsForRegattaMap(regattaForRaceIdString);
this.allMediaTracks = new HashSet<MediaTrack>();
this.allMediaTracks.addAll(allMediaTracks);
this.leaderboardGroups = groupsToExport;
this.raceLogTrackingFixes = getAllRelevantRaceLogTrackingFixes(gpsFixStore);
if (exportWind) {
this.windTrackMasterData = fillWindMap(groupsToExport);
} else {
@@ -52,6 +76,88 @@ public class TopLevelMasterData implements Serializable {
this.eventForLeaderboardGroup = createEventMap(groupsToExport, allEvents);
}
private Map<DeviceIdentifier, Set<GPSFix>> getAllRelevantRaceLogTrackingFixes(GPSFixStore gpsFixStore) {
Map<DeviceIdentifier, Set<GPSFix>> relevantFixes = new HashMap<>();
//Add fixes for regatta log mappings
for (Regatta regatta : getAllRegattas()) {
RegattaLog regattaLog = regatta.getRegattaLog();
try {
regattaLog.lockForRead();
for (RegattaLogEvent logEvent : regattaLog.getRawFixes()) {
addAllFixesIfMappingEvent(gpsFixStore, relevantFixes, logEvent);
}
} finally {
regattaLog.unlockAfterRead();
}
}
//Add fixes for race log mapping
for (LeaderboardGroup group : leaderboardGroups) {
for (Leaderboard leaderboard : group.getLeaderboards()) {
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
for (Fleet fleet : raceColumn.getFleets()) {
RaceLog raceLog = raceColumn.getRaceLog(fleet);
try {
raceLog.lockForRead();
for (RaceLogEvent logEvent : raceLog.getRawFixes()) {
addAllFixesIfMappingEvent(gpsFixStore, relevantFixes, logEvent);
}
} finally {
raceLog.unlockAfterRead();
}
}
}
}
}
return relevantFixes;
}
private void addAllFixesIfMappingEvent(GPSFixStore gpsFixStore, Map<DeviceIdentifier, Set<GPSFix>> relevantFixes,
AbstractLogEvent<?> logEvent) {
if (logEvent instanceof DeviceMappingEvent<?,?>) {
DeviceMappingEvent<?,?> mappingEvent = (DeviceMappingEvent<?,?>) logEvent;
try {
addAllFixesForMappingEvent(gpsFixStore, relevantFixes, mappingEvent);
} catch (NoCorrespondingServiceRegisteredException | TransformationException e) {
logger.severe("Failed to add fixes to exportdata for mapping Event");
e.printStackTrace();
}
}
}
private void addAllFixesForMappingEvent(GPSFixStore gpsFixStore, Map<DeviceIdentifier, Set<GPSFix>> relevantFixes,
DeviceMappingEvent<?, ?> mappingEvent) throws NoCorrespondingServiceRegisteredException, TransformationException {
DynamicGPSFixTrack<WithID, ?> track;
if (isMarkMappingEvent(mappingEvent)) {
track = new DynamicGPSFixTrackImpl<WithID>(mappingEvent.getMappedTo(), 10000);
} else {
track = new DynamicGPSFixMovingTrackImpl<WithID>(mappingEvent.getMappedTo(), 1000);
}
DeviceIdentifier device = mappingEvent.getDevice();
gpsFixStore.loadTrack(track, new DeviceMappingImpl<WithID>(mappingEvent.getMappedTo(), device,
new TimeRangeImpl(mappingEvent.getFrom(), mappingEvent.getTo())));
if (!relevantFixes.containsKey(device)) {
relevantFixes.put(device, new HashSet<>());
}
Set<GPSFix> fixes = relevantFixes.get(device);
try {
track.lockForRead();
for (GPSFix fix : track.getRawFixes()) {
fixes.add(fix);
}
} finally {
track.unlockAfterRead();
}
}
private boolean isMarkMappingEvent(DeviceMappingEvent<?, ?> mappingEvent) {
boolean isMarkMappingEvent = false;
if (mappingEvent instanceof RaceLogDeviceMarkMappingEvent || mappingEvent instanceof RegattaLogDeviceMarkMappingEvent) {
isMarkMappingEvent = true;
}
return isMarkMappingEvent;
}
/**
* Workaround to look for the events connected to RegattaLeadeboards. There should be a proper connection between
* regatta and event soon. TODO
@@ -186,4 +292,8 @@ public class TopLevelMasterData implements Serializable {
}
return regattas;
}
public Map<DeviceIdentifier, Set<GPSFix>> getRaceLogTrackingFixes() {
return raceLogTrackingFixes;
}
}
@@ -3,12 +3,15 @@ package com.sap.sailing.domain.racelog.tracking;
import com.sap.sailing.domain.abstractlog.AbstractLog;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TimeRange;
import com.sap.sse.common.WithID;
public enum EmptyGPSFixStore implements GPSFixStore {
INSTANCE;
@@ -57,4 +60,10 @@ public enum EmptyGPSFixStore implements GPSFixStore {
public long getNumberOfFixes(DeviceIdentifier device) {
return 0;
}
@Override
public void loadTrack(DynamicGPSFixTrack<WithID, ?> track, DeviceMapping<WithID> mapping)
throws NoCorrespondingServiceRegisteredException, TransformationException {
}
}
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.racelogtracking.DeviceMapping;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TimeRange;
import com.sap.sse.common.WithID;
public interface GPSFixStore {
@@ -39,6 +40,12 @@ public interface GPSFixStore {
*/
void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping) throws TransformationException,
NoCorrespondingServiceRegisteredException;
/**
* Load all fixes for both marks and competitors according to the {@code mapping}.
*/
void loadTrack(DynamicGPSFixTrack<WithID, ?> track, DeviceMapping<WithID> mapping)
throws NoCorrespondingServiceRegisteredException, TransformationException;
void storeFix(DeviceIdentifier device, GPSFix fix) throws TransformationException, NoCorrespondingServiceRegisteredException;
@@ -75,7 +75,7 @@ public class MasterDataResource extends AbstractSailingServerResource {
}
final TopLevelMasterData masterData = new TopLevelMasterData(groupsToExport,
getService().getAllEvents(), getService().getPersistentRegattasForRaceIDs(), getService()
.getAllMediaTracks(), exportWind);
.getAllMediaTracks(), getService().getGPSFixStore(), exportWind);
final StreamingOutput streamingOutput;
if (compress) {
streamingOutput= new CompressingStreamingOutput(masterData, competitorIds, startTime);
@@ -19,7 +19,9 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sailing.domain.test,
org.mockito.mockito-core;bundle-version="1.10.14",
com.sap.sse.common,
org.eclipse.jetty.server;bundle-version="9.2.2"
org.eclipse.jetty.server;bundle-version="9.2.2",
com.sap.sailing.domain.shared.android,
com.sap.sailing.domain.racelogtrackingadapter.testsupport
Import-Package: com.sap.sailing.server.gateway.jaxrs,
com.sap.sailing.server.gateway.jaxrs.spi,
org.json.simple,
@@ -45,7 +45,9 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent;
import com.sap.sailing.domain.abstractlog.race.impl.CompetitorResultsImpl;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogEventFactoryImpl;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
@@ -88,6 +90,8 @@ import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.WindImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.domain.common.media.MediaTrack;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
@@ -100,6 +104,9 @@ import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
import com.sap.sailing.domain.persistence.PersistenceFactory;
import com.sap.sailing.domain.persistence.media.MediaDBFactory;
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindTrack;
@@ -167,7 +174,8 @@ public class MasterDataImportTest {
public void testMasterDataImportWithoutHttpStack() throws MalformedURLException, IOException, InterruptedException,
ClassNotFoundException {
// Setup source service
RacingEventService sourceService = new RacingEventServiceImpl();
MockSmartphoneImeiServiceFinderFactory serviceFinderFactory = new MockSmartphoneImeiServiceFinderFactory();
RacingEventService sourceService = new RacingEventServiceImpl(null, null, serviceFinderFactory);
Event event = sourceService.addEvent(TEST_EVENT_NAME, /* eventDescription */ null, eventStartDate, eventEndDate, "testVenue", false, eventUUID);
UUID courseAreaUUID = UUID.randomUUID();
CourseArea courseArea = new CourseAreaImpl("testArea", courseAreaUUID);
@@ -254,6 +262,18 @@ public class MasterDataImportTest {
RegattaLogRegisterCompetitorEvent registerEvent = new RegattaLogRegisterCompetitorEventImpl(regattaLogTimepoint,
author, regattaLogTimepoint, UUID.randomUUID(), competitor);
regatta.getRegattaLog().add(registerEvent);
// Add some racelogtracking stuff
TimePoint logTimePoint3 = new MillisecondsTimePoint(1372489210000L);
TimePoint logTimePoint4 = new MillisecondsTimePoint(1372489200020L);
DeviceIdentifier deviceIdentifier = new SmartphoneImeiIdentifier("a");
RegattaLogDeviceCompetitorMappingEvent mappingEvent = new RegattaLogDeviceCompetitorMappingEventImpl(
logTimePoint4, author, logTimePoint4, UUID.randomUUID(), competitor,
deviceIdentifier, logTimePoint, logTimePoint3);
regatta.getRegattaLog().add(mappingEvent);
GPSFix gpsFix = new GPSFixMovingImpl(new DegreePosition(54.333, 10.133), logTimePoint2,
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(90)));
sourceService.getGPSFixStore().storeFix(deviceIdentifier, gpsFix);
// Set score correction
double scoreCorrection = 12.0;
@@ -291,7 +311,7 @@ public class MasterDataImportTest {
// Delete all data above from the database, to allow recreating all of it on target server
deleteAllDataFromDatabase();
// Import in new service
destService = new RacingEventServiceImplMock(new DataImportProgressImpl(randomUUID));
destService = new RacingEventServiceImplMock(new DataImportProgressImpl(randomUUID), serviceFinderFactory);
domainFactory = destService.getBaseDomainFactory();
DB db = destService.getMongoObjectFactory().getDatabase();
db.setWriteConcern(WriteConcern.SAFE);
@@ -382,6 +402,9 @@ public class MasterDataImportTest {
Assert.assertNotNull(registerEventOnTarget);
Assert.assertEquals(registerEvent.getId(), registerEventOnTarget.getId());
Assert.assertEquals(competitor.getId(), registerEventOnTarget.getCompetitor().getId());
// Check for import of racelogtracking fix
Assert.assertTrue(destService.getGPSFixStore().getNumberOfFixes(deviceIdentifier) == 1);
// Check for persisting of race log events:
RacingEventService dest2 = new RacingEventServiceImplMock();
@@ -8,6 +8,7 @@ import com.sap.sailing.domain.common.impl.DataImportProgressImpl;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.server.impl.RacingEventServiceImpl;
import com.sap.sailing.server.masterdata.DataImportLockWithProgress;
import com.sap.sse.common.TypeBasedServiceFinderFactory;
public class RacingEventServiceImplMock extends RacingEventServiceImpl {
@@ -16,6 +17,12 @@ public class RacingEventServiceImplMock extends RacingEventServiceImpl {
public RacingEventServiceImplMock() {
super(false, null);
}
public RacingEventServiceImplMock(DataImportProgressImpl dataImportProgressImpl, TypeBasedServiceFinderFactory serviceFinderFactory) {
super(null, null, serviceFinderFactory);
lock = new DataImportLockWithProgress();
lock.addProgress(dataImportProgressImpl.getOperationId(), dataImportProgressImpl);
}
public RacingEventServiceImplMock(DataImportProgressImpl dataImportProgressImpl) {
lock = new DataImportLockWithProgress();
@@ -7,6 +7,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
@@ -28,6 +29,12 @@ import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.impl.MasterDataImportObjectCreationCountImpl;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixImpl;
import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixMovingImpl;
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
@@ -38,6 +45,8 @@ import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
import com.sap.sailing.domain.persistence.MongoRegattaLogStoreFactory;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.regattalike.HasRegattaLike;
import com.sap.sailing.domain.regattalike.IsRegattaLike;
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
@@ -50,6 +59,7 @@ import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sailing.server.masterdata.DataImportLockWithProgress;
import com.sap.sailing.server.masterdata.DummyTrackedRace;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.Util;
import com.sap.sse.concurrent.LockUtil;
@@ -110,6 +120,7 @@ public class ImportMasterDataOperation extends
progress.setOverAllProgressPct(0.5);
progress.setCurrentSubProgressPct(0);
createWindTracks(toState);
importRaceLogTrackingGPSFixes(toState);
dataImportLock.getProgress(importOperationId).setResult(creationCount);
return creationCount;
} catch (Exception e) {
@@ -348,6 +359,32 @@ public class ImportMasterDataOperation extends
progress.setOverAllProgressPct(0.5 + (0.5) * ((double) i / numOfWindTracks));
}
}
private void importRaceLogTrackingGPSFixes(RacingEventService toState) {
Map<DeviceIdentifier, Set<GPSFix>> raceLogTrackingFixes = masterData.getRaceLogTrackingFixes();
if (raceLogTrackingFixes != null) {
GPSFixStore store = toState.getGPSFixStore();
for (Entry<DeviceIdentifier, Set<GPSFix>> entry : raceLogTrackingFixes.entrySet()) {
DeviceIdentifier device = entry.getKey();
for (GPSFix fixToAdd : entry.getValue()) {
try {
if (fixToAdd instanceof CompactGPSFixMovingImpl) {
fixToAdd = new GPSFixMovingImpl(fixToAdd.getPosition(), fixToAdd.getTimePoint(),
((CompactGPSFixMovingImpl) fixToAdd).getSpeed());
} else if (fixToAdd instanceof CompactGPSFixImpl) {
fixToAdd = new GPSFixImpl(fixToAdd.getPosition(), fixToAdd.getTimePoint());
}
store.storeFix(device, fixToAdd);
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
logger.severe("Failed to store race log tracking fix while importing.");
e.printStackTrace();
}
}
}
}
}
private void createRegattas(RacingEventService toState, LeaderboardGroup leaderboardGroup) {
Iterable<Leaderboard> leaderboards = leaderboardGroup.getLeaderboards();