mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-10 14:20:55 +00:00
Merge branch 'bug1666'
This commit is contained in:
commit
18d3935ba6
21 files changed
+375
-198
No files matched your search
+4
@@ -2,6 +2,8 @@ package com.sap.sailing.domain.persistence;
|
||||
|
||||
|
||||
import com.sap.sailing.domain.persistence.impl.MongoRaceLogStoreFactoryImpl;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
|
||||
public interface MongoRaceLogStoreFactory {
|
||||
@@ -12,4 +14,6 @@ public interface MongoRaceLogStoreFactory {
|
||||
* and mongo.dbName[=<contents of constant {@link #DEFAULT_DB_NAME}>] specified in the bundle context
|
||||
*/
|
||||
RaceLogStore getMongoRaceLogStore(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory);
|
||||
|
||||
RaceLogEventVisitor getMongoRaceLogStoreVisitor(RaceLogIdentifier identifier, MongoObjectFactory mongoObjectFactory);
|
||||
}
|
||||
+7
-1
@@ -1,9 +1,10 @@
|
||||
package com.sap.sailing.domain.persistence.impl;
|
||||
|
||||
|
||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
|
||||
public class MongoRaceLogStoreFactoryImpl implements MongoRaceLogStoreFactory {
|
||||
@@ -11,4 +12,9 @@ public class MongoRaceLogStoreFactoryImpl implements MongoRaceLogStoreFactory {
|
||||
public RaceLogStore getMongoRaceLogStore(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory) {
|
||||
return new MongoRaceLogStoreImpl(mongoObjectFactory, domainObjectFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceLogEventVisitor getMongoRaceLogStoreVisitor(RaceLogIdentifier identifier, MongoObjectFactory mongoObjectFactory) {
|
||||
return new MongoRaceLogStoreVisitor(identifier, mongoObjectFactory);
|
||||
}
|
||||
}
|
||||
+5
@@ -98,4 +98,9 @@ public interface RaceLog extends Track<RaceLogEvent>, WithID {
|
||||
* in this race log yet
|
||||
*/
|
||||
boolean load(RaceLogEvent event);
|
||||
|
||||
/**
|
||||
* Merges all events from the <code>other</code> race log into this.
|
||||
*/
|
||||
void merge(RaceLog other);
|
||||
}
|
||||
+5
@@ -210,4 +210,9 @@ public class NoAddingRaceLogWrapper implements RaceLog {
|
||||
public Duration getAverageIntervalBetweenRawFixes() {
|
||||
return innerRaceLog.getAverageIntervalBetweenRawFixes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void merge(RaceLog other) {
|
||||
innerRaceLog.merge(other);
|
||||
}
|
||||
}
|
||||
+45
@@ -5,6 +5,7 @@ import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableSet;
|
||||
@@ -278,4 +279,48 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
|
||||
edtc.addAll(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void merge(RaceLog other) {
|
||||
lockForWrite();
|
||||
other.lockForRead();
|
||||
try {
|
||||
RaceLogEventComparator comparator = RaceLogEventComparator.INSTANCE;
|
||||
Iterator<RaceLogEvent> thisIter = getRawFixes().iterator();
|
||||
Iterator<RaceLogEvent> otherIter = other.getRawFixes().iterator();
|
||||
RaceLogEvent thisEvent = null;
|
||||
RaceLogEvent otherEvent = null;
|
||||
while (otherIter.hasNext() || otherEvent != null) {
|
||||
if (thisEvent == null && thisIter.hasNext()) {
|
||||
thisEvent = thisIter.next();
|
||||
}
|
||||
if (otherEvent == null) {
|
||||
otherEvent = otherIter.next();
|
||||
}
|
||||
if (thisEvent == null) {
|
||||
// All events of this race log have been consumed; simply keep adding the events
|
||||
// from the other race log to this race log.
|
||||
// otherEvent has to be non-null because if thisIter didn't have a next, otherIter must have had a next
|
||||
add(otherEvent);
|
||||
otherEvent = null; // "consumed" otherEvent; try to grab next if a next element exists in otherIter
|
||||
} else {
|
||||
final int comparison = comparator.compare(thisEvent, otherEvent);
|
||||
if (comparison < 0) {
|
||||
thisEvent = null; // skip the "lesser" race log event on this race log
|
||||
} else if (comparison == 0) {
|
||||
// the race log event from the other log is already contained in this log; skip both
|
||||
thisEvent = null;
|
||||
otherEvent = null;
|
||||
} else {
|
||||
// comparison > 0; we skipped on this race log until we found a "greater" event on this race log; insert otherEvent
|
||||
add(otherEvent);
|
||||
otherEvent = null; // "consumed"
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
other.unlockAfterRead();
|
||||
unlockAfterWrite();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,11 +186,8 @@ public interface RaceColumn extends Named {
|
||||
|
||||
/**
|
||||
* Sets (or reloads) {@link RaceLog} for this column with the given fleet
|
||||
*
|
||||
* @param raceLogInformation
|
||||
* @param fleetImpl
|
||||
*/
|
||||
void setOrReloadRaceLogInformation(RaceLogInformation raceLogInformation, Fleet fleetImpl);
|
||||
void setOrReloadRaceLogInformation(RaceLogInformation raceLogInformation, Fleet fleet);
|
||||
|
||||
/**
|
||||
* Remove the association between a race and a column. This is different from
|
||||
|
||||
+9
-18
@@ -4,7 +4,6 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@@ -14,7 +13,6 @@ import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifierTemplate;
|
||||
import com.sap.sailing.domain.racelog.RaceLogInformation;
|
||||
@@ -176,29 +174,22 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrReloadRaceLogInformation(RaceLogInformation information, Fleet fleetImpl) {
|
||||
public void setOrReloadRaceLogInformation(RaceLogInformation information, Fleet fleet) {
|
||||
synchronized(raceLogs) {
|
||||
raceLogInformation = information;
|
||||
RaceLogStore store = information.getStore();
|
||||
HashSet<RaceLogEventVisitor> listeners = new HashSet<RaceLogEventVisitor>();
|
||||
RaceLog raceLogAvailable = raceLogs.get(fleetImpl);
|
||||
if (raceLogAvailable != null) {
|
||||
store.removeListenersAddedByStoreFrom(raceLogAvailable);
|
||||
listeners = raceLogAvailable.removeAllListeners();
|
||||
raceLogs.remove(fleetImpl);
|
||||
}
|
||||
|
||||
raceLogIdentifierTemplate = raceLogInformation.getIdentifierTemplate();
|
||||
RaceLogIdentifier identifier = raceLogIdentifierTemplate.compileRaceLogIdentifier(fleetImpl);
|
||||
RaceLog raceLog = store.getRaceLog(identifier, /*ignoreCache*/ true);
|
||||
|
||||
if (listeners.isEmpty()) {
|
||||
RaceLogIdentifier identifier = raceLogIdentifierTemplate.compileRaceLogIdentifier(fleet);
|
||||
RaceLog newOrLoadedRaceLog = store.getRaceLog(identifier, /*ignoreCache*/ true);
|
||||
RaceLog raceLogAvailable = raceLogs.get(fleet);
|
||||
if (raceLogAvailable == null) {
|
||||
RaceColumnRaceLogReplicator listener = new RaceColumnRaceLogReplicator(this, identifier);
|
||||
raceLog.addListener(listener);
|
||||
newOrLoadedRaceLog.addListener(listener);
|
||||
raceLogs.put(fleet, newOrLoadedRaceLog);
|
||||
} else {
|
||||
raceLog.addAllListeners(listeners);
|
||||
// now add all race log events from newOrLoadedRaceLog that are not already in raceLogAvailable
|
||||
raceLogAvailable.merge(newOrLoadedRaceLog);
|
||||
}
|
||||
raceLogs.put(fleetImpl, raceLog);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-7
@@ -9,29 +9,34 @@ import com.sap.sailing.domain.base.Fleet;
|
||||
* <p>
|
||||
* {LeaderboardName / RegattaName} + RaceColumnName + FleetName
|
||||
* <p>
|
||||
* As the components of the RaceLogIdentifier are not available on RaceColumn level, we have to propagate the
|
||||
* As the components of the RaceLogIdentifier are not available on RaceColumn level, we have to propagate the
|
||||
* information in this template data object.
|
||||
*
|
||||
*/
|
||||
public interface RaceLogIdentifierTemplate extends Serializable {
|
||||
|
||||
/**
|
||||
* This method returns the name of parent object of the {@link RaceColumn}. This can be a {@link FlexibleLeaderboard} or a {@link Regatta}.
|
||||
* This method returns the name of parent object of the {@link RaceColumn}. This can be a
|
||||
* {@link FlexibleLeaderboard} or a {@link Regatta}.
|
||||
*
|
||||
* @return the name of the parent object
|
||||
*/
|
||||
String getParentObjectName();
|
||||
|
||||
/**
|
||||
* Compiles the template with giving the last component, the {@link Fleet}, to a RaceLogIdentifier that is used to retrieve the
|
||||
* {@link RaceLogEvent}s from a RaceLogStore
|
||||
* @param fleet the fleet of the race
|
||||
* Compiles the template with giving the last component, the {@link Fleet}, to a RaceLogIdentifier that is used to
|
||||
* retrieve the {@link RaceLogEvent}s from a RaceLogStore
|
||||
*
|
||||
* @param fleet
|
||||
* the fleet of the race
|
||||
* @return the RaceLogIdentifier
|
||||
*/
|
||||
RaceLogIdentifier compileRaceLogIdentifier(Fleet fleet);
|
||||
|
||||
/**
|
||||
* Resolves this RaceLogIdentifier template for replication with the help of the given resolver.
|
||||
* @param resolver the resolver that resolves this template, either for {@link Leaderboard} or for {@link Regatta}.
|
||||
*
|
||||
* @param resolver
|
||||
* the resolver that resolves this template, either for {@link Leaderboard} or for {@link Regatta}.
|
||||
*/
|
||||
void resolve(RaceLogIdentifierTemplateResolver resolver);
|
||||
|
||||
|
||||
@@ -151,11 +151,9 @@ public class RaceColumnListeners implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyListenersAboutRaceLogEventAdded(RaceColumn raceColumn, RaceLogIdentifier raceLogIdentifier,
|
||||
RaceLogEvent event) {
|
||||
public void notifyListenersAboutRaceLogEventAdded(RaceColumn raceColumn, RaceLogIdentifier raceLogIdentifier, RaceLogEvent event) {
|
||||
for (RaceColumnListener listener : getRaceColumnListeners()) {
|
||||
listener.raceLogEventAdded(raceColumn, raceLogIdentifier, event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+16
-5
@@ -27,6 +27,7 @@ import com.rabbitmq.client.QueueingConsumer;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.impl.DomainFactoryImpl;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.PersistenceFactory;
|
||||
import com.sap.sailing.domain.persistence.media.MediaDBFactory;
|
||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
@@ -93,19 +94,19 @@ public abstract class AbstractServerReplicationTest {
|
||||
mongoDBService.getDB().dropDatabase();
|
||||
}
|
||||
resolveAgainst = DomainFactory.INSTANCE;
|
||||
final MongoObjectFactory mongoObjectFactory = PersistenceFactory.INSTANCE.getMongoObjectFactory(mongoDBService);
|
||||
mongoObjectFactory.getDatabase().requestStart();
|
||||
if (master != null) {
|
||||
this.master = master;
|
||||
} else {
|
||||
this.master = new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE
|
||||
.getMongoObjectFactory(mongoDBService), MediaDBFactory.INSTANCE.getMediaDB(mongoDBService), EmptyWindStore.INSTANCE);
|
||||
this.master = createNewMaster(mongoDBService, mongoObjectFactory);
|
||||
}
|
||||
if (replica != null) {
|
||||
this.replica = replica;
|
||||
} else {
|
||||
this.replica = new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(mongoDBService,
|
||||
// replica gets its own base DomainFactory:
|
||||
new DomainFactoryImpl()), PersistenceFactory.INSTANCE
|
||||
.getMongoObjectFactory(mongoDBService), MediaDBFactory.INSTANCE.getMediaDB(mongoDBService), EmptyWindStore.INSTANCE);
|
||||
new DomainFactoryImpl()), mongoObjectFactory, MediaDBFactory.INSTANCE.getMediaDB(mongoDBService), EmptyWindStore.INSTANCE);
|
||||
}
|
||||
ReplicationInstancesManager rim = new ReplicationInstancesManager();
|
||||
masterReplicator = new ReplicationServiceImpl(exchangeName, exchangeHost, rim, this.master);
|
||||
@@ -121,9 +122,19 @@ public abstract class AbstractServerReplicationTest {
|
||||
this.replicaReplicator = replicaReplicator;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected RacingEventServiceImpl createNewMaster(final MongoDBService mongoDBService,
|
||||
final MongoObjectFactory mongoObjectFactory) {
|
||||
return new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(mongoDBService,
|
||||
DomainFactory.INSTANCE), mongoObjectFactory, MediaDBFactory.INSTANCE.getMediaDB(mongoDBService),
|
||||
EmptyWindStore.INSTANCE);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
final MongoDBService mongoDBService = MongoDBService.INSTANCE;
|
||||
final MongoObjectFactory mongoObjectFactory = PersistenceFactory.INSTANCE.getMongoObjectFactory(mongoDBService);
|
||||
mongoObjectFactory.getDatabase().requestDone();
|
||||
masterReplicator.unregisterReplica(replicaDescriptor);
|
||||
masterDescriptor.stopConnection();
|
||||
try {
|
||||
|
||||
+82
-46
@@ -1,9 +1,12 @@
|
||||
package com.sap.sailing.server.replication.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -19,33 +22,49 @@ import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.impl.ControlPointWithTwoMarksImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseDataImpl;
|
||||
import com.sap.sailing.domain.base.impl.MarkImpl;
|
||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||
import com.sap.sailing.domain.common.Color;
|
||||
import com.sap.sailing.domain.common.MarkType;
|
||||
import com.sap.sailing.domain.common.PassingInstruction;
|
||||
import com.sap.sailing.domain.common.RegattaName;
|
||||
import com.sap.sailing.domain.common.dto.FleetDTO;
|
||||
import com.sap.sailing.domain.common.dto.RegattaCreationParametersDTO;
|
||||
import com.sap.sailing.domain.common.dto.SeriesCreationParametersDTO;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.PersistenceFactory;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.racelog.impl.RaceLogEventAuthorImpl;
|
||||
import com.sap.sailing.mongodb.MongoDBService;
|
||||
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.AddColumnToSeries;
|
||||
import com.sap.sailing.server.operationaltransformation.AddDefaultRegatta;
|
||||
import com.sap.sailing.server.operationaltransformation.AddSpecificRegatta;
|
||||
import com.sap.sailing.server.operationaltransformation.CreateFlexibleLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.CreateRegattaLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.RenameLeaderboard;
|
||||
import com.sap.sailing.server.replication.ReplicationMasterDescriptor;
|
||||
|
||||
public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
private static final String BOAT_CLASS_NAME_49er = "49er";
|
||||
|
||||
private Pair<ReplicationServiceTestImpl, ReplicationMasterDescriptor> replicationDescriptorPair;
|
||||
|
||||
private RaceLogEvent raceLogEvent;
|
||||
@@ -70,12 +89,9 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String seriesName = "Default";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
Regatta regatta = setupRegatta(regattaName);
|
||||
Regatta regatta = setupRegatta(regattaName, seriesName, fleetName, BOAT_CLASS_NAME_49er);
|
||||
RaceLog masterLog = setupRaceColumn(regatta, seriesName, raceColumnName, fleetName);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(seriesName, fleetName, raceColumnName, regatta);
|
||||
addAndValidateEventIds(masterLog, replicaLog);
|
||||
}
|
||||
@@ -86,13 +102,10 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String seriesName = "Default";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
Regatta masterRegatta = setupRegatta(regattaName);
|
||||
Regatta masterRegatta = setupRegatta(regattaName, seriesName, fleetName, BOAT_CLASS_NAME_49er);
|
||||
RaceLog masterLog = setupRaceColumn(masterRegatta, seriesName, raceColumnName, fleetName);
|
||||
masterLog.add(raceLogEvent);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(seriesName, fleetName, raceColumnName, masterRegatta);
|
||||
addAndValidateEventIds(masterLog, replicaLog);
|
||||
}
|
||||
@@ -103,12 +116,9 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String seriesName = "Default";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
Regatta masterRegatta = setupRegatta(regattaName);
|
||||
Regatta masterRegatta = setupRegatta(regattaName, seriesName, fleetName, BOAT_CLASS_NAME_49er);
|
||||
RaceLog masterLog = setupRaceColumn(masterRegatta, seriesName, raceColumnName, fleetName);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(seriesName, fleetName, raceColumnName, masterRegatta);
|
||||
addAndValidateEventIds(masterLog, replicaLog, raceLogEvent);
|
||||
}
|
||||
@@ -118,12 +128,9 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String leaderboardName = "Test";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
FlexibleLeaderboard masterLeaderboard = setupFlexibleLeaderboard(leaderboardName);
|
||||
RaceLog masterLog = setupRaceColumn(leaderboardName, fleetName, raceColumnName);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(fleetName, raceColumnName, masterLeaderboard);
|
||||
addAndValidateEventIds(masterLog, replicaLog, raceLogEvent);
|
||||
}
|
||||
@@ -134,13 +141,10 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String seriesName = "Default";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
Regatta masterRegatta = setupRegatta(regattaName);
|
||||
Regatta masterRegatta = setupRegatta(regattaName, seriesName, fleetName, BOAT_CLASS_NAME_49er);
|
||||
RaceLog masterLog = setupRaceColumn(masterRegatta, seriesName, raceColumnName, fleetName);
|
||||
masterLog.add(raceLogEvent);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(seriesName, fleetName, raceColumnName, masterRegatta);
|
||||
addAndValidateEventIds(masterLog, replicaLog, anotherRaceLogEvent);
|
||||
}
|
||||
@@ -151,20 +155,14 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String seriesName = "Default";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
Regatta masterRegatta = setupRegatta(regattaName);
|
||||
Regatta masterRegatta = setupRegatta(regattaName, seriesName, fleetName, BOAT_CLASS_NAME_49er);
|
||||
RaceLog masterLog = setupRaceColumn(masterRegatta, seriesName, raceColumnName, fleetName);
|
||||
|
||||
raceLogEvent = RaceLogEventFactory.INSTANCE.createCourseDesignChangedEvent(MillisecondsTimePoint.now(), author, 43, createCourseData());
|
||||
masterLog.add(raceLogEvent);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(seriesName, fleetName, raceColumnName, masterRegatta);
|
||||
|
||||
anotherRaceLogEvent = RaceLogEventFactory.INSTANCE.createCourseDesignChangedEvent(MillisecondsTimePoint.now(), author, 43, createCourseData());
|
||||
addAndValidateEventIds(masterLog, replicaLog, anotherRaceLogEvent);
|
||||
|
||||
compareReplicatedCourseDesignEvent(replicaLog, (RaceLogCourseDesignChangedEvent) anotherRaceLogEvent);
|
||||
}
|
||||
|
||||
@@ -173,13 +171,10 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String leaderboardName = "Test";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
FlexibleLeaderboard masterLeaderboard = setupFlexibleLeaderboard(leaderboardName);
|
||||
RaceLog masterLog = setupRaceColumn(leaderboardName, fleetName, raceColumnName);
|
||||
masterLog.add(raceLogEvent);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(fleetName, raceColumnName, masterLeaderboard);
|
||||
addAndValidateEventIds(masterLog, replicaLog, anotherRaceLogEvent);
|
||||
}
|
||||
@@ -189,15 +184,11 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String leaderboardName = "Test";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
FlexibleLeaderboard masterLeaderboard = setupFlexibleLeaderboard(leaderboardName);
|
||||
RaceLog masterLog = setupRaceColumn(leaderboardName, fleetName, raceColumnName);
|
||||
|
||||
raceLogEvent = RaceLogEventFactory.INSTANCE.createCourseDesignChangedEvent(MillisecondsTimePoint.now(), author, 43, createCourseData());
|
||||
masterLog.add(raceLogEvent);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(fleetName, raceColumnName, masterLeaderboard);
|
||||
anotherRaceLogEvent = RaceLogEventFactory.INSTANCE.createCourseDesignChangedEvent(MillisecondsTimePoint.now(), author, 43, createCourseData());
|
||||
addAndValidateEventIds(masterLog, replicaLog, anotherRaceLogEvent);
|
||||
@@ -224,36 +215,76 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
final String leaderboardName = "Test";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
|
||||
FlexibleLeaderboard masterLeaderboard = setupFlexibleLeaderboard(leaderboardName);
|
||||
RaceLog masterLog = setupRaceColumn(leaderboardName, fleetName, raceColumnName);
|
||||
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
|
||||
masterLog.add(raceLogEvent);
|
||||
|
||||
RenameLeaderboard renameOperation = new RenameLeaderboard(leaderboardName, leaderboardName + "new");
|
||||
master.apply(renameOperation);
|
||||
Thread.sleep(3000);
|
||||
|
||||
RaceLog replicaLog = getReplicaLog(fleetName, raceColumnName, masterLeaderboard);
|
||||
addAndValidateEventIds(masterLog, replicaLog, anotherRaceLogEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* See bug 1666; a race log reload operation may not properly have been replicating. This tests asserts that when a race log event
|
||||
* has been added to the DB and then race log is re-loaded on the master, the events added through the DB also show up on the replica.
|
||||
*/
|
||||
@Test
|
||||
public void testRaceLogReloadReplication() throws ClassNotFoundException, IOException, InterruptedException {
|
||||
final String regattaName = "Test";
|
||||
final String seriesName = "Default";
|
||||
final String fleetName = "Default";
|
||||
final String raceColumnName = "R1";
|
||||
Regatta masterRegatta = setupRegatta(regattaName, seriesName, fleetName, BOAT_CLASS_NAME_49er);
|
||||
RaceLog masterLog = setupRaceColumn(masterRegatta, seriesName, raceColumnName, fleetName);
|
||||
masterLog.add(raceLogEvent);
|
||||
replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB());
|
||||
RaceLog replicaLog = getReplicaLog(seriesName, fleetName, raceColumnName, masterRegatta);
|
||||
addAndValidateEventIds(masterLog, replicaLog);
|
||||
|
||||
final Series series = masterRegatta.getSeries().iterator().next();
|
||||
final MillisecondsTimePoint approximateRaceStatusEventCreationTimePoint = MillisecondsTimePoint.now();
|
||||
final RaceLogRaceStatusEvent raceStatusEvent = RaceLogEventFactory.INSTANCE.createRaceStatusEvent(approximateRaceStatusEventCreationTimePoint, author, 42,
|
||||
RaceLogRaceStatus.UNKNOWN);
|
||||
addEventToDB(series.getRaceColumnByName(raceColumnName).getRaceLogIdentifier(series.getFleetByName(fleetName)), raceStatusEvent, regattaName, raceColumnName, fleetName);
|
||||
RegattaLeaderboard leaderboard = master.apply(new CreateRegattaLeaderboard(
|
||||
masterRegatta.getRegattaIdentifier(), /* leaderboardDisplayName */ null, new int[0]));
|
||||
master.reloadRaceLog(leaderboard.getName(), raceColumnName, fleetName);
|
||||
Thread.sleep(3000);
|
||||
final RaceLog reloadedMasterLog = leaderboard.getRaceColumnByName(raceColumnName).getRaceLog(series.getFleetByName(fleetName));
|
||||
final RaceLogEvent lastEventReadFromMasterLog = reloadedMasterLog.getFirstRawFixAtOrAfter(approximateRaceStatusEventCreationTimePoint);
|
||||
assertNotNull(lastEventReadFromMasterLog);
|
||||
assertEqualsOnId(reloadedMasterLog, getReplicaLog(seriesName, fleetName, raceColumnName, masterRegatta));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses a new master that loads the existing regatta and race log to append an event to the race log. This will store it to the DB so that if the original
|
||||
* master re-loads the race log it should see the new race log event.
|
||||
*/
|
||||
private void addEventToDB(RaceLogIdentifier raceLogIdentifier, RaceLogRaceStatusEvent createRaceStatusEvent, String regattaName, String raceColumnName, String fleetName) {
|
||||
final MongoObjectFactory defaultMongoObjectFactory = PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory();
|
||||
defaultMongoObjectFactory.getDatabase().getLastError(); // wait for regatta write operation to complete
|
||||
final RacingEventServiceImpl temporaryMaster = createNewMaster(MongoDBService.INSTANCE, defaultMongoObjectFactory);
|
||||
Regatta regatta = temporaryMaster.getRegatta(new RegattaName(regattaName+" ("+BOAT_CLASS_NAME_49er+")"));
|
||||
Series series = regatta.getSeries().iterator().next();
|
||||
RaceLog masterLog = series.getRaceColumnByName(raceColumnName).getRaceLog(series.getFleetByName(fleetName));
|
||||
masterLog.add(createRaceStatusEvent);
|
||||
defaultMongoObjectFactory.getDatabase().getLastError(); // wait for write operation to complete
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation is done based only on the identifier and type of the {@link RaceLogEvent}s.
|
||||
*/
|
||||
private void addAndValidateEventIds(RaceLog masterLog, RaceLog replicaLog, RaceLogEvent... addedEvents) throws InterruptedException {
|
||||
// 1. Check state of replica after initial load...
|
||||
assertEqualsOnId(masterLog, replicaLog);
|
||||
|
||||
// 2. ... add all incoming events...
|
||||
for (RaceLogEvent event : addedEvents) {
|
||||
masterLog.add(event);
|
||||
}
|
||||
// 3. ... and give replication some time to deliver messages.
|
||||
Thread.sleep(3000);
|
||||
|
||||
assertEqualsOnId(masterLog, replicaLog);
|
||||
}
|
||||
|
||||
@@ -280,10 +311,8 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
private void assertEqualsOnId(Iterable<RaceLogEvent> expectedEvents, Iterable<RaceLogEvent> actualEvents) {
|
||||
List<RaceLogEvent> expectedCollection = new ArrayList<>();
|
||||
Util.addAll(expectedEvents, expectedCollection);
|
||||
|
||||
List<RaceLogEvent> actualCollection = new ArrayList<>();
|
||||
Util.addAll(actualEvents, actualCollection);
|
||||
|
||||
assertEquals(Util.size(expectedEvents), Util.size(actualEvents));
|
||||
for (int i = 0; i < expectedCollection.size(); i++) {
|
||||
assertEquals(expectedCollection.get(i).getClass(), actualCollection.get(i).getClass());
|
||||
@@ -306,9 +335,17 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
return replicaColumn.getRaceLog(replicaFleet);
|
||||
}
|
||||
|
||||
private Regatta setupRegatta(final String regattaName) {
|
||||
private Regatta setupRegatta(final String regattaName, String seriesName, String fleetName, String boatClassName) {
|
||||
LinkedHashMap<String, SeriesCreationParametersDTO> seriesCreationParameters = new LinkedHashMap<>();
|
||||
SeriesCreationParametersDTO creationParametersForDefaultSeries = new SeriesCreationParametersDTO(
|
||||
Arrays.asList(new FleetDTO[] { new FleetDTO(fleetName, 0, Color.BLACK), }), /* medal */false, /* startsWithZero */
|
||||
false, /* firstColumnIsNonDiscardableCarryForward */false, /* discardingThresholds */new int[0], /* hasSplitFleetContiguousScoring */
|
||||
false);
|
||||
seriesCreationParameters.put(seriesName, creationParametersForDefaultSeries);
|
||||
// 1. Install some race column on master...
|
||||
AddDefaultRegatta addRegattaOperation = new AddDefaultRegatta(regattaName, "49er", UUID.randomUUID());
|
||||
RegattaCreationParametersDTO regattaCreationParams = new RegattaCreationParametersDTO(seriesCreationParameters);
|
||||
AddSpecificRegatta addRegattaOperation = new AddSpecificRegatta(regattaName, boatClassName, /* regatta ID */ UUID.randomUUID(), regattaCreationParams, /* persistent */ true,
|
||||
new LowPoint(), /* default course area ID */ UUID.randomUUID());
|
||||
return master.apply(addRegattaOperation);
|
||||
}
|
||||
|
||||
@@ -336,7 +373,6 @@ public class RaceLogReplicationTest extends AbstractServerReplicationTest {
|
||||
|
||||
protected CourseBase createCourseData() {
|
||||
CourseBase course = new CourseDataImpl("Test Course");
|
||||
|
||||
course.addWaypoint(0, new WaypointImpl(new ControlPointWithTwoMarksImpl(UUID.randomUUID(),
|
||||
new MarkImpl(UUID.randomUUID(), "Black", MarkType.BUOY, "black", "round", "circle"),
|
||||
new MarkImpl(UUID.randomUUID(), "Green", MarkType.BUOY, "green", "round", "circle"),
|
||||
|
||||
@@ -28,7 +28,6 @@ public class RaceLogReplicator implements RaceColumnListener {
|
||||
@Override
|
||||
public void raceLogEventAdded(final RaceColumn raceColumn, final RaceLogIdentifier identifier, final RaceLogEvent event) {
|
||||
identifier.getTemplate().resolve(new RaceLogIdentifierTemplateResolver() {
|
||||
|
||||
@Override
|
||||
public void resolveOnRegattaIdentifierAndReplicate(RaceLogOnRegattaIdentifier identifierTemplate) {
|
||||
RacingEventServiceOperation<?> operation = new RecordRaceLogEventOnRegatta(
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
|
||||
public abstract class AbstractRaceLogEventOperation extends AbstractRaceLogOperation<RaceLogEvent> {
|
||||
private static final long serialVersionUID = -8559301422783375526L;
|
||||
private final RaceLogEvent event;
|
||||
|
||||
protected AbstractRaceLogEventOperation(String raceColumnName, String fleetName, RaceLogEvent event) {
|
||||
super(raceColumnName, fleetName);
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
protected RaceLogEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public abstract class AbstractRaceLogOnLeaderboardOperation<T> extends AbstractRaceLogOperation<T> {
|
||||
private static final long serialVersionUID = -5649159437859782663L;
|
||||
private final String leaderboardName;
|
||||
|
||||
public AbstractRaceLogOnLeaderboardOperation(String leaderboardName, String raceColumnName, String fleetName) {
|
||||
super(raceColumnName, fleetName);
|
||||
this.leaderboardName = leaderboardName;
|
||||
}
|
||||
|
||||
protected RaceColumn getRaceColumn(RacingEventService toState) {
|
||||
Leaderboard leaderboard = toState.getLeaderboardByName(leaderboardName);
|
||||
RaceColumn raceColumn = leaderboard.getRaceColumnByName(getRaceColumnName());
|
||||
return raceColumn;
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public abstract class AbstractRaceLogOnRegattaOperation<T> extends AbstractRaceLogOperation<T> {
|
||||
private static final long serialVersionUID = -7174569054572099191L;
|
||||
private final String regattaName;
|
||||
|
||||
public AbstractRaceLogOnRegattaOperation(String regattaName, String raceColumnName,
|
||||
String fleetName) {
|
||||
super(raceColumnName, fleetName);
|
||||
this.regattaName = regattaName;
|
||||
}
|
||||
|
||||
protected String getRegattaName() {
|
||||
return regattaName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RaceColumn getRaceColumn(RacingEventService toState) {
|
||||
Regatta regatta = toState.getRegattaByName(regattaName);
|
||||
RaceColumn raceColumn = null;
|
||||
for (Series series : regatta.getSeries()) {
|
||||
raceColumn = series.getRaceColumnByName(getRaceColumnName());
|
||||
if (raceColumn != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return raceColumn;
|
||||
}
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
|
||||
public abstract class AbstractRaceLogOperation<T> extends AbstractRacingEventServiceOperation<T> {
|
||||
private static final long serialVersionUID = 2140858355670664173L;
|
||||
|
||||
private final String raceColumnName;
|
||||
private final String fleetName;
|
||||
|
||||
public AbstractRaceLogOperation(String raceColumnName, String fleetName) {
|
||||
this.raceColumnName = raceColumnName;
|
||||
this.fleetName = fleetName;
|
||||
}
|
||||
|
||||
protected String getRaceColumnName() {
|
||||
return raceColumnName;
|
||||
}
|
||||
|
||||
protected String getFleetName() {
|
||||
return fleetName;
|
||||
}
|
||||
|
||||
abstract protected RaceColumn getRaceColumn(RacingEventService toState);
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
|
||||
public abstract class AbstractRecordRaceLogEvent extends AbstractRacingEventServiceOperation<RaceLogEvent> {
|
||||
private static final long serialVersionUID = 2140858355670664173L;
|
||||
|
||||
protected final String raceColumnName;
|
||||
private final String fleetName;
|
||||
private final RaceLogEvent event;
|
||||
|
||||
public AbstractRecordRaceLogEvent(String raceColumnName, String fleetName, RaceLogEvent event) {
|
||||
this.raceColumnName = raceColumnName;
|
||||
this.fleetName = fleetName;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the stored event to the race column's race log.
|
||||
* @param raceColumn to add to.
|
||||
* @param fleetName to resolve correct {@link RaceLog}.
|
||||
* @return <code>true</code> if add was successful.
|
||||
*/
|
||||
protected RaceLogEvent addEventTo(RaceColumn raceColumn) {
|
||||
if (raceColumn != null) {
|
||||
Fleet fleet = raceColumn.getFleetByName(fleetName);
|
||||
RaceLog raceLog = raceColumn.getRaceLog(fleet);
|
||||
raceLog.add(event);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
}
|
||||
+20
-29
@@ -3,7 +3,6 @@ package com.sap.sailing.server.operationaltransformation;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -35,8 +34,12 @@ import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
|
||||
import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
|
||||
import com.sap.sailing.domain.masterdataimport.TopLevelMasterData;
|
||||
import com.sap.sailing.domain.masterdataimport.WindTrackMasterData;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
@@ -103,7 +106,6 @@ public class ImportMasterDataOperation extends
|
||||
|
||||
private void createLeaderboardGroupWithAllRelatedObjects(final RacingEventService toState,
|
||||
LeaderboardGroup leaderboardGroup) {
|
||||
Map<RaceColumn, Map<Fleet, Iterable<RaceLogEvent>>> raceLogEvents = extractRaceLogEvents(leaderboardGroup);
|
||||
Map<String, Leaderboard> existingLeaderboards = toState.getLeaderboards();
|
||||
List<String> leaderboardNames = new ArrayList<String>();
|
||||
createCourseAreasAndEvents(toState, leaderboardGroup);
|
||||
@@ -136,7 +138,7 @@ public class ImportMasterDataOperation extends
|
||||
}
|
||||
if (leaderboard != null) {
|
||||
toState.addLeaderboard(leaderboard);
|
||||
addRaceLogEvents(leaderboard, raceLogEvents);
|
||||
storeRaceLogEvents(leaderboard, toState.getMongoObjectFactory());
|
||||
creationCount.addOneLeaderboard(leaderboard.getName());
|
||||
relinkTrackedRacesIfPossible(toState, leaderboard);
|
||||
}
|
||||
@@ -189,39 +191,28 @@ public class ImportMasterDataOperation extends
|
||||
}
|
||||
}
|
||||
|
||||
private void addRaceLogEvents(Leaderboard leaderboard,
|
||||
Map<RaceColumn, Map<Fleet, Iterable<RaceLogEvent>>> raceLogEvents) {
|
||||
/**
|
||||
* Ensures that the race log events are stored to the receiving instance's database. The race logs have been received
|
||||
* in serialized form on the {@link RaceColumn} objects, but the database doesn't yet know about them. This method uses
|
||||
* a <code>MongoRaceLogStoreVisitor</code> to store all race log events to the database.
|
||||
*/
|
||||
private void storeRaceLogEvents(Leaderboard leaderboard, MongoObjectFactory mongoObjectFactory) {
|
||||
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
for (Fleet fleet : raceColumn.getFleets()) {
|
||||
RaceLog log = raceColumn.getRaceLog(fleet);
|
||||
Iterable<RaceLogEvent> raceLogsForColumnAndFleet = raceLogEvents.get(raceColumn).get(fleet);
|
||||
for (RaceLogEvent event : raceLogsForColumnAndFleet) {
|
||||
log.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<RaceColumn, Map<Fleet, Iterable<RaceLogEvent>>> extractRaceLogEvents(LeaderboardGroup group) {
|
||||
Map<RaceColumn, Map<Fleet, Iterable<RaceLogEvent>>> raceLogEvents = new HashMap<RaceColumn, Map<Fleet, Iterable<RaceLogEvent>>>();
|
||||
for (Leaderboard leaderboard : group.getLeaderboards()) {
|
||||
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
HashMap<Fleet, Iterable<RaceLogEvent>> raceLogEventsForRaceColumn = new HashMap<Fleet, Iterable<RaceLogEvent>>();
|
||||
raceLogEvents.put(raceColumn, raceLogEventsForRaceColumn);
|
||||
for (Fleet fleet : raceColumn.getFleets()) {
|
||||
RaceLog raceLog = raceColumn.getRaceLog(fleet);
|
||||
raceLog.lockForRead();
|
||||
try {
|
||||
Iterable<RaceLogEvent> fixes = raceLog.getRawFixes();
|
||||
raceLogEventsForRaceColumn.put(fleet, fixes);
|
||||
} finally {
|
||||
raceLog.unlockAfterRead();
|
||||
RaceLogIdentifier identifier = raceColumn.getRaceLogIdentifier(fleet);
|
||||
RaceLogEventVisitor storeVisitor = MongoRaceLogStoreFactory.INSTANCE.getMongoRaceLogStoreVisitor(identifier, mongoObjectFactory);
|
||||
log.lockForRead();
|
||||
try {
|
||||
for (RaceLogEvent event : log.getRawFixes()) {
|
||||
event.accept(storeVisitor);
|
||||
}
|
||||
} finally {
|
||||
log.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
return raceLogEvents;
|
||||
|
||||
}
|
||||
|
||||
private void relinkTrackedRacesIfPossible(RacingEventService toState, Leaderboard newLeaderboard) {
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
|
||||
public class RaceLogEventRecorder implements Serializable {
|
||||
private static final long serialVersionUID = -5426128599743917274L;
|
||||
private final String fleetName;
|
||||
private final RaceLogEvent event;
|
||||
|
||||
public RaceLogEventRecorder(String fleetName, RaceLogEvent event) {
|
||||
this.fleetName = fleetName;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
private String getFleetName() {
|
||||
return fleetName;
|
||||
}
|
||||
|
||||
private RaceLogEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the stored event to the race column's race log.
|
||||
*
|
||||
* @param raceColumn
|
||||
* to add to.
|
||||
* @param fleetName
|
||||
* to resolve correct {@link RaceLog}.
|
||||
* @return <code>true</code> if add was successful.
|
||||
*/
|
||||
RaceLogEvent addEventTo(RaceColumn raceColumn) {
|
||||
if (raceColumn != null) {
|
||||
Fleet fleet = raceColumn.getFleetByName(getFleetName());
|
||||
RaceLog raceLog = raceColumn.getRaceLog(fleet);
|
||||
raceLog.add(getEvent());
|
||||
}
|
||||
return getEvent();
|
||||
}
|
||||
}
|
||||
+6
-21
@@ -1,37 +1,22 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
|
||||
public class RecordRaceLogEventOnLeaderboard extends AbstractRecordRaceLogEvent {
|
||||
public class RecordRaceLogEventOnLeaderboard extends AbstractRaceLogOnLeaderboardOperation<RaceLogEvent> {
|
||||
private static final long serialVersionUID = 1008913415922358665L;
|
||||
private final RaceLogEvent event;
|
||||
|
||||
private final String leaderboardName;
|
||||
|
||||
public RecordRaceLogEventOnLeaderboard(String leaderboardName, String raceColumnName,
|
||||
String fleetName, RaceLogEvent event) {
|
||||
super(raceColumnName, fleetName, event);
|
||||
this.leaderboardName = leaderboardName;
|
||||
super(leaderboardName, raceColumnName, fleetName);
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceLogEvent internalApplyTo(RacingEventService toState) throws Exception {
|
||||
Leaderboard leaderboard = toState.getLeaderboardByName(leaderboardName);
|
||||
RaceColumn raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
|
||||
return addEventTo(raceColumn);
|
||||
RaceColumn raceColumn = getRaceColumn(toState);
|
||||
return new RaceLogEventRecorder(getFleetName(), event).addEventTo(raceColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+6
-27
@@ -1,44 +1,23 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
|
||||
public class RecordRaceLogEventOnRegatta extends AbstractRecordRaceLogEvent {
|
||||
public class RecordRaceLogEventOnRegatta extends AbstractRaceLogOnRegattaOperation<RaceLogEvent> {
|
||||
private static final long serialVersionUID = 8092146834280389864L;
|
||||
|
||||
private final String regattaName;
|
||||
private final RaceLogEvent event;
|
||||
|
||||
public RecordRaceLogEventOnRegatta(String regattaName, String raceColumnName,
|
||||
String fleetName, RaceLogEvent event) {
|
||||
super(raceColumnName, fleetName, event);
|
||||
this.regattaName = regattaName;
|
||||
super(regattaName, raceColumnName, fleetName);
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceLogEvent internalApplyTo(RacingEventService toState) throws Exception {
|
||||
Regatta regatta = toState.getRegattaByName(regattaName);
|
||||
RaceColumn raceColumn = null;
|
||||
for (Series series : regatta.getSeries()) {
|
||||
raceColumn = series.getRaceColumnByName(raceColumnName);
|
||||
if (raceColumn != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return addEventTo(raceColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
|
||||
return null;
|
||||
RaceColumn raceColumn = getRaceColumn(toState);
|
||||
return new RaceLogEventRecorder(getFleetName(), event).addEventTo(raceColumn);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user