Merge branch 'master' into bug2842

This commit is contained in:
Daniel Lisunkin committed 2019-08-01 13:29:40 +02:00
commit 039cc2a039
60 files changed
+309 -193

No files matched your search

+2 -1
View File
@@ -1,7 +1,8 @@
#!/bin/bash
AWS=/root/.local/bin/aws
REGION=eu-west-1
HUDSON_SLAVE_AMI_ID=ami-09f0f1f11364aeddb
#HUDSON_SLAVE_AMI_ID=ami-09f0f1f11364aeddb
HUDSON_SLAVE_AMI_ID=ami-027eed1bdca18b979
echo Launching instance...
instanceid=`$AWS ec2 run-instances --image-id $HUDSON_SLAVE_AMI_ID --count 1 --instance-type c5d.4xlarge --key-name Axel --security-groups "Sailing Analytics App" --region $REGION --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=Hudson Ubuntu Slave}]' --instance-initiated-shutdown-behavior terminate | tee /tmp/slavelaunch.out | jq .Instances[0].InstanceId | sed -e 's/"//g'`
if [ "$instanceid" = "" ]; then
@@ -313,7 +313,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
this.baseDomainFactory = baseDomainFactory;
this.legacyCompetitorWithBoatDeserializer = LegacyCompetitorWithContainedBoatJsonDeserializer.create(baseDomainFactory);
this.competitorWithBoatRefDeserializer = CompetitorWithBoatRefJsonDeserializer.create(baseDomainFactory);
this.boatDeserializer = BoatJsonDeserializer.create(baseDomainFactory);
this.boatDeserializer = BoatJsonDeserializer.create(baseDomainFactory, /* storeDeserializedBoatPersistently */ false);
this.database = db;
}
@@ -1746,7 +1746,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
final String sailId = ""+(secondLeagueBoatCounter++ % 6 + 1);
final String auxiliaryBoatId = "b2567e08-26d9-45c1-b5e0-8c410c8db18b#"+sailId;
final Boat auxiliaryBoat = baseDomainFactory.getCompetitorAndBoatStore().getOrCreateBoat(auxiliaryBoatId, sailId,
baseDomainFactory.getOrCreateBoatClass(BoatClassMasterdata.J70.getDisplayName()), sailId, /* color */ null);
baseDomainFactory.getOrCreateBoatClass(BoatClassMasterdata.J70.getDisplayName()), sailId, /* color */ null, /* storePersistently */ true);
return createRaceLogRegisterCompetitorEventImpl(createdAt, author, logicalTimePoint, id, passId, auxiliaryBoat, competitor);
}
@@ -121,6 +121,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.BoatClassJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.BoatJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CompetitorJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CompetitorWithBoatRefJsonSerializer;
@@ -145,8 +146,9 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
private static Logger logger = Logger.getLogger(MongoObjectFactoryImpl.class.getName());
private final MongoDatabase database;
private final CompetitorWithBoatRefJsonSerializer competitorWithBoatRefSerializer = CompetitorWithBoatRefJsonSerializer.create();
private final CompetitorJsonSerializer competitorSerializer = CompetitorJsonSerializer.create(/* serialize boat */ true, /* serializeNonPublicCompetitorFields */ true);
private final BoatJsonSerializer boatSerializer = BoatJsonSerializer.create();
private final CompetitorJsonSerializer competitorSerializer = CompetitorJsonSerializer.create(
/* serialize boat */ true, /* serializeNonPublicCompetitorFields */ true, /* verboseBoatClassSerializer */ false);
private final BoatJsonSerializer boatSerializer = new BoatJsonSerializer(new BoatClassJsonSerializer(/* verbose */ false));
private final TypeBasedServiceFinder<DeviceIdentifierMongoHandler> deviceIdentifierServiceFinder;
private final TypeBasedServiceFinder<RaceTrackingConnectivityParametersHandler> raceTrackingConnectivityParamsServiceFinder;
@@ -62,8 +62,8 @@ public class AbstractGPSFixStoreTest extends RaceLogTrackingTestHelper {
protected RegattaLog regattaLog;
protected SensorFixStore store;
protected final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
protected final Boat boat = DomainFactory.INSTANCE.getOrCreateBoat("boat", "boat", boatClass, "GER 234", null);
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
protected final Boat boat = DomainFactory.INSTANCE.getOrCreateBoat("boat", "boat", boatClass, "GER 234", null, /* storePersistently */ true);
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
@@ -200,7 +200,7 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
// add a mapping and one fix in, one out of mapping
Boat boat1 = new BoatImpl("id12345", "boat1", boatClass, /* sailID */ null);
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", "c", null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
DeviceIdentifier dev1 = new SmartphoneImeiIdentifier("dev1");
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), t(), author, 0, comp1, dev1, t(0), t(10)));
addFixes0(dev1);
@@ -281,7 +281,7 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
// add a mapping and one fix in, one out of mapping
Boat boat1 = new BoatImpl("id12345", "boat1", boatClass, /* sailID */ null);
CompetitorWithBoat comp1 = DomainFactory.INSTANCE.getOrCreateCompetitorWithBoat("comp1", "comp1", "c1", null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, (DynamicBoat) boat1);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, (DynamicBoat) boat1, /* storePersistently */ true);
DeviceIdentifier dev1 = new SmartphoneImeiIdentifier("dev1");
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), t(), author, UUID.randomUUID(), comp1, dev1,
t(0), t(10)));
@@ -32,7 +32,7 @@ public class DeviceMappingsAndSensorFixStoreLockingTest extends AbstractGPSFixSt
@Test
public void deviceMappingsAndSensorFixStoreShouldNotCauseADeadlock() {
final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null,
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
@@ -72,9 +72,9 @@ public class RaceLogFixTrackerManagerTest {
protected RegattaLog regattaLog;
protected SensorFixStore store;
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", "c2", null, null, null,
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
protected final Boat boat = DomainFactory.INSTANCE.getOrCreateBoat("boat", "boat", boatClass, "USA 123", null);
protected final Boat boat = DomainFactory.INSTANCE.getOrCreateBoat("boat", "boat", boatClass, "USA 123", null, /* storePersistently */ true);
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
protected final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
@@ -125,14 +125,14 @@ public class SensorFixStoreAndLoadTest {
protected RegattaLog regattaLog;
protected SensorFixStore store;
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null,
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
protected final Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null,
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
protected final Boat boat1 = DomainFactory.INSTANCE.getOrCreateBoat("Boat1", "Boat1", boatClass, "GER 1", null);
protected final Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("Boat2", "Boat2", boatClass, "GER 2", null);
protected final Boat boat1 = DomainFactory.INSTANCE.getOrCreateBoat("Boat1", "Boat1", boatClass, "GER 1", null, /* storePersistently */ true);
protected final Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("Boat2", "Boat2", boatClass, "GER 2", null, /* storePersistently */ true);
private final Competitor compNotPartOfRace = DomainFactory.INSTANCE.getOrCreateCompetitor("comp3", "comp3", null, null, null, null,
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
protected final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
@@ -52,8 +52,8 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
private final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
private final Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null,
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
private final Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
private final Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null, /* storePersistently */ true);
private final Course course = new CourseImpl("course", Arrays.asList(new WaypointImpl(mark), new WaypointImpl(mark2)));
private RaceDefinition raceDefinition;
@@ -64,8 +64,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
public void testStartTimeInferencePrecedenceOrder() throws TransformationException,
NoCorrespondingServiceRegisteredException, InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null, /* storePersistently */ true);
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(comp, boat);
competitorsAndBoats.put(comp2, boat2);
@@ -143,8 +143,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
public void testStartTimeChangeNotificationForFirstUpdateThroughRaceLog() throws TransformationException,
NoCorrespondingServiceRegisteredException, InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null, /* storePersistently */ true);
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(comp, boat);
competitorsAndBoats.put(comp2, boat2);
@@ -187,8 +187,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
public void testStartTimeChangeNotificationForFirstUpdateThroughStartMarkPassing() throws TransformationException,
NoCorrespondingServiceRegisteredException, InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null, /* storePersistently */ true);
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(comp, boat);
competitorsAndBoats.put(comp2, boat2);
@@ -234,8 +234,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
public void testStartAndEndTrackingTimeInferencePrecedenceOrderTriggersListener() throws TransformationException,
NoCorrespondingServiceRegisteredException, InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null, /* storePersistently */ true);
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(comp, boat);
competitorsAndBoats.put(comp2, boat2);
@@ -350,8 +350,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
public void testStartAndEndOfTrackingTimeChangeNotificationForFirstUpdateThroughRaceLog() throws TransformationException,
NoCorrespondingServiceRegisteredException, InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null, /* storePersistently */ true);
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(comp, boat);
competitorsAndBoats.put(comp2, boat2);
@@ -24,5 +24,5 @@ public interface BoatFactory {
*/
boolean isBoatToUpdateDuringGetOrCreate(Boat result);
DynamicBoat getOrCreateBoat(Serializable id, String name, BoatClass boatClass, String sailId, Color color);
DynamicBoat getOrCreateBoat(Serializable id, String name, BoatClass boatClass, String sailId, Color color, boolean storePersistently);
}
@@ -87,16 +87,24 @@ public interface CompetitorAndBoatStore extends CompetitorFactory, BoatFactory {
Iterable<Competitor> getCompetitorsWithoutBoat();
/**
* Updates the competitor with {@link Competitor#getId() ID} <code>id</code> by setting the name, sail ID and nationality to
* the values provided. Doing so will not fire any events nor will it replicate this change from a master to any replicas.
* The calling client has to make sure that the changes applied will reach replicas and all other interested clients. It will
* be sufficient to ensure that subsequent DTOs produced from the competitor modified will reflect the changes.<p>
* Updates the competitor with {@link Competitor#getId() ID} <code>id</code> by setting the name, sail ID and
* nationality to the values provided. Doing so will not fire any events nor will it replicate this change from a
* master to any replicas. The calling client has to make sure that the changes applied will reach replicas and all
* other interested clients. It will be sufficient to ensure that subsequent DTOs produced from the competitor
* modified will reflect the changes.
* <p>
*
* If no competitor with the ID requested is found, the call is a no-op, doing nothing, not even throwing an exception.
* If no competitor with the ID requested is found, the call is a no-op, doing nothing, not even throwing an
* exception.
*
* @param storePersistently
* if {@code true}, updates and creations will be store durably in the database; otherwise it is assumed
* that the "creation" is caused by the loading process that fetches the objects from the persistence
* layer; no need then to store them back to the DB. See also bug5106
*/
Competitor updateCompetitor(String idAsString, String newName, String newShortName, Color newDisplayColor, String newEmail,
Nationality newNationality, URI newTeamImageUri, URI newFlagImageUri,
Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag);
Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, boolean storePersistently);
void addNewCompetitors(Iterable<DynamicCompetitor> competitors);
@@ -33,15 +33,20 @@ public interface CompetitorFactory {
boolean isCompetitorToUpdateDuringGetOrCreate(Competitor result);
DynamicCompetitor getOrCreateCompetitor(Serializable competitorId, String name, String shortName, Color displayColor, String email,
URI flagImageURI, DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag);
URI flagImageURI, DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, boolean storePersistently);
/**
* Updates only the competitor fields; the {@code boat} parameter is used only when the competitor needs to be
* created because it doesn't exist yet. In this case the boat is assigned to the new competitor and stored in the
* competitor and boat store. If changes to an existing competitor's {@link Boat} object shall be stored, use
* {@link CompetitorAndBoatStore#getOrCreateBoat(Serializable, String, BoatClass, String, Color)}.
* {@link CompetitorAndBoatStore#getOrCreateBoat(Serializable, String, BoatClass, String, Color, boolean)}.
*
* @param storePersistently
* if {@code true}, updates and creations will be store durably in the database; otherwise it is assumed
* that the "creation" is caused by the loading process that fetches the objects from the persistence
* layer; no need then to store them back to the DB. See also bug5106
*/
DynamicCompetitorWithBoat getOrCreateCompetitorWithBoat(Serializable competitorId, String name, String shortName, Color displayColor, String email,
URI flagImageURI, DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat);
URI flagImageURI, DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat, boolean storePersistently);
}
@@ -99,7 +99,7 @@ public class BoatImpl extends RenamableImpl implements DynamicBoat {
@Override
public Boat resolve(SharedDomainFactory domainFactory) {
return domainFactory.getOrCreateBoat(getId(), getName(), getBoatClass(), getSailID(), getColor());
return domainFactory.getOrCreateBoat(getId(), getName(), getBoatClass(), getSailID(), getColor(), /* storePersistently */ true);
}
@Override
@@ -131,7 +131,7 @@ public class CompetitorImpl implements DynamicCompetitor {
public Competitor resolve(SharedDomainFactory domainFactory) {
Competitor result = domainFactory
.getOrCreateCompetitor(getId(), getName(), getShortName(), getColor(), getEmail(), getFlagImage(), getTeam(),
getTimeOnTimeFactor(), getTimeOnDistanceAllowancePerNauticalMile(), searchTag);
getTimeOnTimeFactor(), getTimeOnDistanceAllowancePerNauticalMile(), searchTag, /* storePersistently */ true);
return result;
}
@@ -46,7 +46,7 @@ public class CompetitorWithBoatImpl extends CompetitorImpl implements DynamicCom
} else {
result = domainFactory.getOrCreateCompetitorWithBoat(getId(), getName(), getShortName(), getColor(),
getEmail(), getFlagImage(), getTeam(), getTimeOnTimeFactor(),
getTimeOnDistanceAllowancePerNauticalMile(), getSearchTag(), getBoat());
getTimeOnDistanceAllowancePerNauticalMile(), getSearchTag(), getBoat(), /* storePersistently */ true);
}
return result;
}
@@ -375,23 +375,23 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
@Override
public DynamicCompetitor getOrCreateCompetitor(Serializable competitorId, String name, String shortname, Color displayColor, String email,
URI flagImage, DynamicTeam team, Double timeOnTimeFactor,
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) {
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, boolean storePersistently) {
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "getting or creating competitor "+name+" with ID "+competitorId+" in domain factory "+this);
}
return getCompetitorAndBoatStore().getOrCreateCompetitor(competitorId, name, shortname, displayColor, email, flagImage, team,
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag);
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, storePersistently);
}
@Override
public DynamicCompetitorWithBoat getOrCreateCompetitorWithBoat(Serializable competitorId, String name, String shortName,
Color displayColor, String email, URI flagImageURI, DynamicTeam team, Double timeOnTimeFactor,
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat) {
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat, boolean storePersistently) {
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "getting or creating competitor "+name+" with ID "+competitorId+" in domain factory "+this);
}
return getCompetitorAndBoatStore().getOrCreateCompetitorWithBoat(competitorId, name, shortName, displayColor, email, flagImageURI, team,
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat);
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat, storePersistently);
}
@Override
@@ -405,8 +405,8 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
}
@Override
public DynamicBoat getOrCreateBoat(Serializable id, String name, BoatClass boatClass, String sailId, Color color) {
return getCompetitorAndBoatStore().getOrCreateBoat(id, name, boatClass, sailId, color);
public DynamicBoat getOrCreateBoat(Serializable id, String name, BoatClass boatClass, String sailId, Color color, boolean storePersistently) {
return getCompetitorAndBoatStore().getOrCreateBoat(id, name, boatClass, sailId, color, storePersistently);
}
@Override
@@ -99,10 +99,10 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
}
private DynamicCompetitor createCompetitor(Serializable id, String name, String shortName, Color displayColor, String email, URI flagImage,
DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) {
DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, boolean storePersistently) {
DynamicCompetitor result = new CompetitorImpl(id, name, shortName, displayColor, email, flagImage, team,
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag);
addNewCompetitor(result);
addNewCompetitor(result, storePersistently);
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "Created competitor "+name+" with ID "+id, new Exception("Here is where it happened"));
}
@@ -130,8 +130,13 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
* {@link IllegalArgumentException} will be thrown. This is necessary because there is a rule in place saying each
* competitor entity can be represented in the scope of the VM by at most one Java {@link Competitor} object, and
* replacing an object in this store would leave us with at least two.
*
* @param storePersistently
* ignored here; only subclasses may deal with persistence. If this flag is {@code false}, a subclass
* shall not store the competitor persistently because it can assume that the competitor object has just
* been loaded from the persistent store.
*/
protected void addNewCompetitor(DynamicCompetitor competitor) {
protected void addNewCompetitor(DynamicCompetitor competitor, boolean storePersistently) {
LockUtil.lockForWrite(lock);
try {
final Competitor existingCompetitorWithEqualId = competitorCache.put(competitor.getId(), competitor);
@@ -158,7 +163,7 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
@Override
public DynamicCompetitor getOrCreateCompetitor(Serializable competitorId, String name, String shortName, Color displayColor, String email,
URI flagImage, DynamicTeam team, Double timeOnTimeFactor,
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) {
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, boolean storePersistently) {
DynamicCompetitor result = getExistingCompetitorById(competitorId); // avoid synchronization for successful read access
if (result == null) {
LockUtil.lockForWrite(lock);
@@ -166,14 +171,14 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
result = getExistingCompetitorById(competitorId); // try again, now while holding the write lock
if (result == null) {
result = createCompetitor(competitorId, name, shortName, displayColor, email, flagImage, team,
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag);
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, /* storePersistently */ storePersistently);
}
} finally {
LockUtil.unlockAfterWrite(lock);
}
} else if (isCompetitorToUpdateDuringGetOrCreate(result)) {
updateCompetitor(result.getId().toString(), name, shortName, displayColor, email, team.getNationality(),
team.getImage(), flagImage, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag);
team.getImage(), flagImage, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, /* storePersistently */ storePersistently);
competitorNoLongerToUpdateDuringGetOrCreate(result);
}
return result;
@@ -323,7 +328,7 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
@Override
public Competitor updateCompetitor(String idAsString, String newName, String newShortName, Color newDisplayColor, String newEmail,
Nationality newNationality, URI newTeamImageUri, URI newFlagImageUri,
Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String newSearchTag) {
Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String newSearchTag, boolean storePersistently) {
DynamicCompetitor competitor = getExistingCompetitorByIdAsString(idAsString);
if (competitor != null) {
LockUtil.lockForWrite(lock);
@@ -398,24 +403,24 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
@Override
public void addNewCompetitors(Iterable<DynamicCompetitor> competitors) {
for (DynamicCompetitor competitor : competitors) {
addNewCompetitor(competitor);
addNewCompetitor(competitor, /* storePersistently */ true);
}
}
@Override
public void addNewCompetitorsWithBoat(Iterable<DynamicCompetitorWithBoat> competitors) {
for (DynamicCompetitorWithBoat competitor : competitors) {
addNewBoat(competitor.getBoat()); // create the boat before the competitor because the competitor references the boat
addNewCompetitor(competitor);
addNewBoat(competitor.getBoat(), /* storePersistently */ true); // create the boat before the competitor because the competitor references the boat
addNewCompetitor(competitor, /* storePersistently */ true);
}
}
private DynamicCompetitorWithBoat createCompetitorWithBoat(Serializable id, String name, String shortName, Color displayColor, String email, URI flagImage,
DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat) {
DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat, boolean storePersistently) {
DynamicCompetitorWithBoat competitor = new CompetitorWithBoatImpl(id, name, shortName, displayColor, email, flagImage, team,
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat);
addNewBoat(boat); // create the boat before the competitor because the competitor references the boat
addNewCompetitor(competitor);
addNewBoat(boat, /* storePersistently */ storePersistently); // create the boat before the competitor because the competitor references the boat
addNewCompetitor(competitor, /* storePersistently */ storePersistently);
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "Created competitor "+name+" with ID "+id, new Exception("Here is where it happened"));
}
@@ -425,7 +430,7 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
@Override
public DynamicCompetitorWithBoat getOrCreateCompetitorWithBoat(Serializable competitorId, String name, String shortName, Color displayColor, String email,
URI flagImage, DynamicTeam team, Double timeOnTimeFactor,
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat) {
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat, boolean storePersistently) {
DynamicCompetitorWithBoat result = null;
result = getExistingCompetitorWithBoatById(competitorId); // avoid synchronization for successful read access
if (result == null) {
@@ -434,7 +439,7 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
result = getExistingCompetitorWithBoatById(competitorId); // try again, now while holding the write lock
if (result == null) {
result = createCompetitorWithBoat(competitorId, name, shortName, displayColor, email, flagImage, team,
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat);
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat, /* storePersistently */ storePersistently);
}
} finally {
LockUtil.unlockAfterWrite(lock);
@@ -442,7 +447,7 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
} else if (isCompetitorToUpdateDuringGetOrCreate(result)) {
assert result.getBoat() == boat;
updateCompetitor(result.getId().toString(), name, shortName, displayColor, email, team.getNationality(),
team.getImage(), flagImage, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag);
team.getImage(), flagImage, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, /* storePersistently */ storePersistently);
competitorNoLongerToUpdateDuringGetOrCreate(result);
}
return result;
@@ -460,9 +465,9 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
boatUpdateListeners.remove(listener);
}
private DynamicBoat createBoat(Serializable id, String name, BoatClass boatClass, String sailID, Color color) {
private DynamicBoat createBoat(Serializable id, String name, BoatClass boatClass, String sailID, Color color, boolean storePersistently) {
DynamicBoat boat = new BoatImpl(id, name, boatClass, sailID, color);
addNewBoat(boat);
addNewBoat(boat, /* storePersistently */ storePersistently);
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "Created boat "+name+" with ID "+id, new Exception("Here is where it happened"));
}
@@ -474,7 +479,7 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
* {@link #getExistingBoatById(Serializable)}. Subclasses may override in case they need to take additional
* measures such as durably storing the boat. Overriding implementations must call this implementation.
*/
protected void addNewBoat(DynamicBoat boat) {
protected void addNewBoat(DynamicBoat boat, boolean storePersistently) {
LockUtil.lockForWrite(lock);
try {
final Boat existingBoatWithEqualId = boatCache.put(boat.getId(), boat);
@@ -494,14 +499,14 @@ public class TransientCompetitorAndBoatStoreImpl implements CompetitorAndBoatSto
}
@Override
public DynamicBoat getOrCreateBoat(Serializable id, String name, BoatClass boatClass, String sailId, Color color) {
public DynamicBoat getOrCreateBoat(Serializable id, String name, BoatClass boatClass, String sailId, Color color, boolean storePersistently) {
DynamicBoat result = getExistingBoatById(id); // avoid synchronization for successful read access
if (result == null) {
LockUtil.lockForWrite(lock);
try {
result = getExistingBoatById(id); // try again, now while holding the write lock
if (result == null) {
result = createBoat(id, name, boatClass, sailId, color);
result = createBoat(id, name, boatClass, sailId, color, storePersistently);
}
} finally {
LockUtil.unlockAfterWrite(lock);
@@ -285,7 +285,7 @@ public class DomainFactoryImpl implements DomainFactory {
private Competitor getOrCreateCompetitor(ICompetitor competitor, RaceTrackingHandler raceTrackingHandler) {
Competitor result = getOrCreateCompetitor(competitor.getId(), competitor.getNationality(), competitor.getName(),
competitor.getShortName(), competitor.getHandicapToT(), competitor.getHandicapToD(), null,
competitor.getShortName(), competitor.getHandicapToT(), competitor.getHandicapToD(), /* searchTag */ null,
raceTrackingHandler);
return result;
}
@@ -316,10 +316,9 @@ public class DomainFactoryImpl implements DomainFactory {
nationality = null;
logger.log(Level.SEVERE, "Unknown nationality "+nationalityAsString+" for competitor "+name+"; leaving null", iae);
}
// TODO bug2822: if only boat is to be updated then this would currently fail here; consider competitorStore.isBoatToUpdateDuringGetOrCreate(...)
DynamicTeam team = createTeam(name, nationality, competitorId);
DynamicBoat boat = (DynamicBoat) competitorStore.getOrCreateBoat(domainCompetitor == null ? UUID.randomUUID() : domainCompetitor.getBoat().getId(),
null /* no boat name available */, boatClass, sailId, /* color */ null);
null /* no boat name available */, boatClass, sailId, /* color */ null, /* storePersistently */ true);
domainCompetitor = raceTrackingHandler.getOrCreateCompetitorWithBoat(competitorStore, competitorId, name,
shortName, null /* displayColor */,
null /* email */, null /* flagImag */, team, (double) timeOnTimeFactor,
@@ -816,7 +815,7 @@ public class DomainFactoryImpl implements DomainFactory {
rc.getCompetitor().getShortName(), competitorToUse.getColor(),
competitorToUse.getEmail(), competitorToUse.getNationality(), competitorToUse.getTeam().getImage(),
competitorToUse.getFlagImage(), competitorToUse.getTimeOnTimeFactor(),
competitorToUse.getTimeOnDistanceAllowancePerNauticalMile(), competitorToUse.getSearchTag());
competitorToUse.getTimeOnDistanceAllowancePerNauticalMile(), competitorToUse.getSearchTag(), /* storePersistently */ true);
if (savedIsCompetitorToUpdateDuringGetOrCreate) {
competitorAndBoatStore.allowCompetitorResetToDefaults(competitorToUse);
}
@@ -13,7 +13,7 @@ public interface DynamicCompetitorStore extends CompetitorAndBoatStore {
@Override
DynamicCompetitor getOrCreateCompetitor(Serializable competitorId, String name, String shortName, Color displayColor, String email, URI flagImage,
DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag);
DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, boolean storePersistently);
@Override
Iterable<? extends DynamicCompetitor> getAllCompetitors();
@@ -77,7 +77,7 @@ public interface RaceTrackingHandler {
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) {
return competitorStore.getOrCreateCompetitor(competitorId, name, shortName, displayColor, email,
flagImageURI, team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile,
searchTag);
searchTag, /* storePersistently */ true);
}
@Override
@@ -86,13 +86,13 @@ public interface RaceTrackingHandler {
URI flagImageURI, DynamicTeam team, Double timeOnTimeFactor,
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat) {
return competitorStore.getOrCreateCompetitorWithBoat(competitorId, name, shortName, displayColor, email,
flagImageURI, team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat);
flagImageURI, team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat, /* storePersistently */ true);
}
@Override
public DynamicBoat getOrCreateBoat(CompetitorAndBoatStore competitorAndBoatStore, Serializable id, String name,
BoatClass boatClass, String sailId, Color color) {
return competitorAndBoatStore.getOrCreateBoat(id, name, boatClass, sailId, color);
return competitorAndBoatStore.getOrCreateBoat(id, name, boatClass, sailId, color, /* storePersistently */ true);
}
}
}
@@ -5936,7 +5936,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
competitor.getFlagImageURL() == null ? null : new URI(competitor.getFlagImageURL()),
team, competitor.getTimeOnTimeFactor(),
competitor.getTimeOnDistanceAllowancePerNauticalMile(), competitor.getSearchTag(),
boat));
boat, /* storePersistently */ true));
} else {
SecurityUtils.getSubject().checkPermission(SecuredDomainType.COMPETITOR.getStringPermissionForTypeRelativeIdentifier(
DefaultActions.UPDATE, CompetitorImpl.getTypeRelativeObjectIdentifier(competitor.getId())));
@@ -5973,7 +5973,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
competitor.getShortName(), competitor.getColor(), competitor.getEmail(),
competitor.getFlagImageURL() == null ? null : new URI(competitor.getFlagImageURL()),
team, competitor.getTimeOnTimeFactor(),
competitor.getTimeOnDistanceAllowancePerNauticalMile(), competitor.getSearchTag()));
competitor.getTimeOnDistanceAllowancePerNauticalMile(), competitor.getSearchTag(), /* storePersistently */ true));
} else {
SecurityUtils.getSubject().checkPermission(
SecuredDomainType.COMPETITOR.getStringPermissionForTypeRelativeIdentifier(DefaultActions.UPDATE,
@@ -6078,7 +6078,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
BoatClass boatClass = getBaseDomainFactory().getOrCreateBoatClass(boat.getBoatClass().getName());
result = getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError(
SecuredDomainType.BOAT, BoatImpl.getTypeRelativeObjectIdentifier(boatUUID), boat.getName(),
() -> getBaseDomainFactory().getOrCreateBoat(boatUUID, boat.getName(), boatClass, boat.getSailId(), boat.getColor()));
() -> getBaseDomainFactory().getOrCreateBoat(boatUUID, boat.getName(), boatClass, boat.getSailId(), boat.getColor(), /* storePersistently */ true));
} else {
SecurityUtils.getSubject().checkPermission(
SecuredDomainType.BOAT.getStringPermissionForTypeRelativeIdentifier(DefaultActions.UPDATE,
@@ -75,7 +75,7 @@ public class StoreAndLoadDeviceIdentifierTest extends AbstractMongoDBTest {
private DeviceIdentifier storeAndLoad(DeviceIdentifier device, TypeBasedServiceFinderFactory forStoring, TypeBasedServiceFinderFactory forLoading) {
createFactories(forStoring);
Competitor c = DomainFactory.INSTANCE.getOrCreateCompetitor("a", "a", "a", null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Competitor c = DomainFactory.INSTANCE.getOrCreateCompetitor("a", "a", "a", null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(now(), now(), author, 0,
c, device, now(), now()));
createFactories(forLoading);
@@ -199,8 +199,8 @@ public class StoreAndLoadRaceLogEventsTest extends AbstractMongoDBTest {
RaceLogRegisterCompetitorEvent expectedEvent = new RaceLogRegisterCompetitorEventImpl(expectedEventTime,
expectedEventTime, author, expectedId, expectedPassId, DomainFactory.INSTANCE.getOrCreateCompetitor(
"comp", "comp", "c", null, null, null, null,
/* timeOnTimeFactor */null, /* timeOnDistanceAllowancePerNauticalMile */null, null),
DomainFactory.INSTANCE.getOrCreateBoat("boat", "b", boatClass, null, null));
/* timeOnTimeFactor */null, /* timeOnDistanceAllowancePerNauticalMile */null, null, /* storePersistently */ true),
DomainFactory.INSTANCE.getOrCreateBoat("boat", "b", boatClass, null, null, /* storePersistently */ true));
Document dbObject = mongoFactory.storeRaceLogEntry(logIdentifier, expectedEvent);
RaceLogRegisterCompetitorEvent actualEvent = loadEvent(dbObject);
@@ -360,8 +360,8 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
DynamicBoat boat = (DynamicBoat) domainFactory.getOrCreateBoat("boat", "Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
DynamicBoat boat = (DynamicBoat) domainFactory.getOrCreateBoat("boat", "Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null, null, /* storePersistently */ true);
CompetitorWithBoat competitorWithBoat = new CompetitorWithBoatImpl(competitor, boat);
TrackedRace raceWithOneCompetitor1 = new MockedTrackedRaceWithFixedRank(competitorWithBoat, /* rank */ 1, /* started */ true);
TrackedRace raceWithOneCompetitor2 = new MockedTrackedRaceWithFixedRank(competitorWithBoat, /* rank */ 2, /* started */ true);
@@ -308,9 +308,9 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
public void testStoreAndRetrieveSimpleLeaderboardWithRaceLogFinishPositioningConfirmedEvent() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", "SAP",
Color.RED, "someone@nowhere.de", null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
storedPositioningList.add(new CompetitorResultImpl(storedCompetitor.getId(), storedCompetitor.getName(), storedCompetitor.getShortName(),
storedBoat.getName(), storedBoat.getSailID(), /* rank */ 1, MaxPointsReason.NONE, /* score */ null, /* finishingTimePoint */null,
@@ -335,9 +335,9 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
public void testStoreAndRetrieveSimpleLeaderboardWithRaceLogFinishPositioningConfirmedEventWithContents() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", "SAP",
Color.RED, "someone@nowhere.de", null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
final TimePoint finishingTimePoint = MillisecondsTimePoint.now();
final String comment = "This is a comment";
@@ -406,9 +406,9 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
@Test
public void testStoreAndRetrieveSimpleLeaderboardWithRaceLogFinishPositioningListChangeEvent() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", "SAP", Color.RED,
"someone@nowhere.de", null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
"someone@nowhere.de", null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
storedPositioningList.add(new CompetitorResultImpl(storedCompetitor.getId(), storedCompetitor.getName(), storedCompetitor.getShortName(),
storedBoat.getName(), storedBoat.getSailID(), /* rank */ 1, MaxPointsReason.NONE, /* score */ null, /* finishingTimePoint */null,
@@ -208,9 +208,9 @@ public class TestStoringAndRetrievingRaceLogInRegatta extends AbstractTestStorin
@Test
public void testStoreAndRetrieveRegattaWithRaceLogFinishPositioningListChangeEvent() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", "SAP", Color.RED,
"someone@nowhere.de", null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
"someone@nowhere.de", null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
storedPositioningList.add(new CompetitorResultImpl(storedCompetitor.getId(), storedCompetitor.getName(), storedCompetitor.getShortName(),
storedBoat.getName(), storedBoat.getSailID(), /* rank */ 1, MaxPointsReason.NONE, /* score */ null, /* finishingTime */ null,
@@ -236,9 +236,9 @@ public class TestStoringAndRetrievingRaceLogInRegatta extends AbstractTestStorin
@Test
public void testStoreAndRetrieveRegattaWithRaceLogFinishPositioningConfirmedEvent() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", "SAP", Color.RED,
"someone@nowhere.de", null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
"someone@nowhere.de", null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
storedPositioningList.add(new CompetitorResultImpl(storedCompetitor.getId(), storedCompetitor.getName(), storedCompetitor.getShortName(),
storedBoat.getName(), storedBoat.getSailID(), /* rank */ 1, MaxPointsReason.NONE, /* score */ null, /* finishingTime */ null,
@@ -18,12 +18,10 @@ public class BoatClassJsonDeserializer implements JsonDeserializer<BoatClass> {
public BoatClass deserialize(JSONObject object) throws JsonDeserializationException {
String name = (String) object.get(BoatClassJsonSerializer.FIELD_NAME);
if (object.containsKey(BoatClassJsonSerializer.FIELD_TYPICALLY_STARTS_UPWIND)) {
boolean typicallyStartsUpwind = Boolean.parseBoolean(object.get(BoatClassJsonSerializer.FIELD_TYPICALLY_STARTS_UPWIND).toString());
return domainFactory.getOrCreateBoatClass(name, typicallyStartsUpwind);
}
return domainFactory.getOrCreateBoatClass(name);
}
@@ -24,14 +24,34 @@ public class BoatJsonDeserializer implements JsonDeserializer<DynamicBoat> {
private final BoatClassJsonDeserializer boatClassDeserializer;
private final BoatFactory boatFactory;
/**
* An instance of this deserializer class may be used to load competitors and their boats
* from the persistent store. In this case, when creating the {@link Competitor} object,
* the new object shall <em>not</em> be stored / updated again to the persistent store
* because it just came from there. This behavior can be accomplished by setting this
* property to {@code false} by means of using a corresponding constructor.<p>
*
* See also bug 5106.
*/
private final boolean storeDeserializedCompetitorsPersistently;
public static BoatJsonDeserializer create(SharedDomainFactory baseDomainFactory, boolean storeDeserializedCompetitorsPersistently) {
return new BoatJsonDeserializer(baseDomainFactory, new BoatClassJsonDeserializer(baseDomainFactory), storeDeserializedCompetitorsPersistently);
}
public static BoatJsonDeserializer create(SharedDomainFactory baseDomainFactory) {
return new BoatJsonDeserializer(baseDomainFactory, new BoatClassJsonDeserializer(baseDomainFactory));
return create(baseDomainFactory, /* storeDeserializedCompetitorsPersistently */ true);
}
public BoatJsonDeserializer(BoatFactory boatFactory, BoatClassJsonDeserializer boatClassDeserializer) {
this(boatFactory, boatClassDeserializer, /* storeDeserializedCompetitorsPersistently */ true);
}
public BoatJsonDeserializer(BoatFactory boatFactory, BoatClassJsonDeserializer boatClassDeserializer, boolean storeDeserializedCompetitorsPersistently) {
super();
this.boatFactory = boatFactory;
this.boatClassDeserializer = boatClassDeserializer;
this.storeDeserializedCompetitorsPersistently = storeDeserializedCompetitorsPersistently;
}
@Override
@@ -78,7 +98,7 @@ public class BoatJsonDeserializer implements JsonDeserializer<DynamicBoat> {
String colorAsString = (String) object.get(BoatJsonSerializer.FIELD_COLOR);
final Color color = colorAsString == null || colorAsString.isEmpty() ? null
: new RGBColor(colorAsString);
DynamicBoat boat = (DynamicBoat) boatFactory.getOrCreateBoat(boatId, name, boatClass, sailId, color);
DynamicBoat boat = (DynamicBoat) boatFactory.getOrCreateBoat(boatId, name, boatClass, sailId, color, storeDeserializedCompetitorsPersistently);
return boat;
} catch (Exception e) {
throw new JsonDeserializationException(e);
@@ -27,6 +27,18 @@ public class CompetitorJsonDeserializer implements JsonDeserializer<DynamicCompe
private final CompetitorFactory competitorWithBoatFactory;
private final JsonDeserializer<DynamicTeam> teamJsonDeserializer;
private final BoatJsonDeserializer boatJsonDeserializer;
/**
* An instance of this deserializer class may be used to load competitors and their boats
* from the persistent store. In this case, when creating the {@link Competitor} object,
* the new object shall <em>not</em> be stored / updated again to the persistent store
* because it just came from there. This behavior can be accomplished by setting this
* property to {@code false} by means of using a corresponding constructor.<p>
*
* See also bug 5106.
*/
private final boolean storeDeserializedCompetitorsPersistently;
private static final Logger logger = Logger.getLogger(CompetitorJsonDeserializer.class.getName());
public static CompetitorJsonDeserializer create(SharedDomainFactory baseDomainFactory) {
@@ -38,10 +50,23 @@ public class CompetitorJsonDeserializer implements JsonDeserializer<DynamicCompe
this(competitorWithBoatFactory, null, /* boatDeserializer */ null);
}
public CompetitorJsonDeserializer(CompetitorFactory competitorWithBoatFactory, JsonDeserializer<DynamicTeam> teamJsonDeserializer, BoatJsonDeserializer boatDeserializer) {
public CompetitorJsonDeserializer(CompetitorFactory competitorWithBoatFactory, boolean storeDeserializedCompetitorsPersistently) {
this(competitorWithBoatFactory, null, /* boatDeserializer */ null, storeDeserializedCompetitorsPersistently);
}
public CompetitorJsonDeserializer(CompetitorFactory competitorWithBoatFactory,
JsonDeserializer<DynamicTeam> teamJsonDeserializer, BoatJsonDeserializer boatDeserializer) {
this(competitorWithBoatFactory, teamJsonDeserializer, boatDeserializer,
/* storeDeserializedCompetitorsPersistently */ true);
}
public CompetitorJsonDeserializer(CompetitorFactory competitorWithBoatFactory,
JsonDeserializer<DynamicTeam> teamJsonDeserializer, BoatJsonDeserializer boatDeserializer,
boolean storeDeserializedCompetitorsPersistently) {
this.competitorWithBoatFactory = competitorWithBoatFactory;
this.teamJsonDeserializer = teamJsonDeserializer;
this.boatJsonDeserializer = boatDeserializer;
this.storeDeserializedCompetitorsPersistently = storeDeserializedCompetitorsPersistently;
}
@Override
@@ -93,12 +118,12 @@ public class CompetitorJsonDeserializer implements JsonDeserializer<DynamicCompe
result = competitorWithBoatFactory.getOrCreateCompetitor(competitorId, name, shortName, displayColor, email,
flagImageURI, team, timeOnTimeFactor,
timeOnDistanceAllowanceInSecondsPerNauticalMile == null ? null :
new MillisecondsDurationImpl((long) (timeOnDistanceAllowanceInSecondsPerNauticalMile*1000)), searchTag);
new MillisecondsDurationImpl((long) (timeOnDistanceAllowanceInSecondsPerNauticalMile*1000)), searchTag, storeDeserializedCompetitorsPersistently);
} else {
result = competitorWithBoatFactory.getOrCreateCompetitorWithBoat(competitorId, name, shortName, displayColor, email,
flagImageURI, team, timeOnTimeFactor,
timeOnDistanceAllowanceInSecondsPerNauticalMile == null ? null :
new MillisecondsDurationImpl((long) (timeOnDistanceAllowanceInSecondsPerNauticalMile*1000)), searchTag, boat);
new MillisecondsDurationImpl((long) (timeOnDistanceAllowanceInSecondsPerNauticalMile*1000)), searchTag, boat, storeDeserializedCompetitorsPersistently);
}
return result;
} catch (Exception e) {
@@ -8,6 +8,7 @@ import java.util.UUID;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.BoatFactory;
import com.sap.sailing.domain.base.CompetitorAndBoatStore;
import com.sap.sailing.domain.base.CompetitorFactory;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.impl.DynamicBoat;
@@ -16,6 +17,14 @@ import com.sap.sailing.domain.common.tracking.impl.CompetitorJsonConstants;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sse.util.impl.UUIDHelper;
/**
* A competitor de-serializer that does not store the competitors it loads back to the DB because it assumes
* that the competitors are just being loaded from the DB. The boats are loaded as IDs ("by reference") only
* and are then looked up by that ID in the {@link CompetitorAndBoatStore}.
*
* @author Axel Uhl (D043530)
*
*/
public class CompetitorWithBoatRefJsonDeserializer extends CompetitorJsonDeserializer {
private final BoatFactory boatFactory;
@@ -29,7 +38,8 @@ public class CompetitorWithBoatRefJsonDeserializer extends CompetitorJsonDeseria
}
public CompetitorWithBoatRefJsonDeserializer(CompetitorFactory competitorFactory, BoatFactory boatFactory, JsonDeserializer<DynamicTeam> teamJsonDeserializer) {
super(competitorFactory, teamJsonDeserializer, /* boat deserializer */ null);
// see also bug 5106: competitors de-serialized by this object are not to be stored (again) in the DB
super(competitorFactory, teamJsonDeserializer, /* boat deserializer */ null, /* storeDeserializedCompetitorsPersistently */ false);
this.boatFactory = boatFactory;
}
@@ -60,7 +60,6 @@ public class LegacyCompetitorWithContainedBoatJsonDeserializer implements JsonDe
String displayColorAsString = (String) object.get(CompetitorJsonConstants.FIELD_DISPLAY_COLOR);
String email = (String) object.get(CompetitorJsonConstants.FIELD_EMAIL);
String searchTag = (String) object.get(CompetitorJsonConstants.FIELD_SEARCHTAG);
URI flagImageURI = null;
String flagImageURIAsString = (String) object.get(CompetitorJsonConstants.FIELD_FLAG_IMAGE_URI);
if (flagImageURIAsString != null) {
@@ -70,7 +69,6 @@ public class LegacyCompetitorWithContainedBoatJsonDeserializer implements JsonDe
logger.warning("Illegal flag image URI " + e.getMessage());
}
}
final Color displayColor;
if (displayColorAsString == null || displayColorAsString.isEmpty()) {
displayColor = null;
@@ -94,7 +92,6 @@ public class LegacyCompetitorWithContainedBoatJsonDeserializer implements JsonDe
flagImageURI, team, timeOnTimeFactor,
timeOnDistanceAllowanceInSecondsPerNauticalMile == null ? null :
new MillisecondsDurationImpl((long) (timeOnDistanceAllowanceInSecondsPerNauticalMile*1000)), searchTag, boat);
return competitorWithBoat;
} catch (Exception e) {
throw new JsonDeserializationException(e);
@@ -7,6 +7,7 @@ import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.common.BoatClassMasterdata;
import com.sap.sailing.server.gateway.deserialization.impl.BoatClassJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class BoatClassJsonSerializer implements JsonSerializer<BoatClass> {
@@ -18,6 +19,27 @@ public class BoatClassJsonSerializer implements JsonSerializer<BoatClass> {
public static final String FIELD_ALIAS_NAMES = "aliasNames";
public static final String FIELD_ICON_URL = "iconUrl";
/**
* Tells whether properties beyond {@link #FIELD_NAME} and {@link #FIELD_TYPICALLY_STARTS_UPWIND} shall
* be serialized by this serializer. Non-verbose serialization still has everything that the complementary
* {@link BoatClassJsonDeserializer} requires.
*/
private final boolean verbose;
/**
* Creates a {@link #verbose} boat serializer.
*/
public BoatClassJsonSerializer() {
this(/* verbose */ true);
}
/**
* Creates a boat serializer that is {@link #verbose} if the {@code verbose} parameter is {@code true}
*/
public BoatClassJsonSerializer(boolean verbose) {
this.verbose = verbose;
}
@Override
public JSONObject serialize(BoatClass boatClass) {
JSONObject result = new JSONObject();
@@ -26,19 +48,21 @@ public class BoatClassJsonSerializer implements JsonSerializer<BoatClass> {
if (boatClass.getHullLength() != null) {
result.put(FIELD_HULL_LENGTH_IN_METERS, boatClass.getHullLength().getMeters());
}
if (boatClass.getHullBeam() != null) {
result.put(FIELD_HULL_BEAM_IN_METERS, boatClass.getHullBeam().getMeters());
}
final JSONArray aliasNames = new JSONArray();
if (boatClass.getDisplayName() != null) {
result.put(FIELD_DISPLAY_NAME, boatClass.getDisplayName());
final BoatClassMasterdata masterData = BoatClassMasterdata.resolveBoatClass(boatClass.getDisplayName());
if (masterData != null) {
result.put(FIELD_ICON_URL, "/gwt/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/"+masterData.name().replaceAll("^_", "")+".png");
aliasNames.addAll(Arrays.asList(masterData.getAlternativeNames()));
if (verbose) {
if (boatClass.getHullBeam() != null) {
result.put(FIELD_HULL_BEAM_IN_METERS, boatClass.getHullBeam().getMeters());
}
final JSONArray aliasNames = new JSONArray();
if (boatClass.getDisplayName() != null) {
result.put(FIELD_DISPLAY_NAME, boatClass.getDisplayName());
final BoatClassMasterdata masterData = BoatClassMasterdata.resolveBoatClass(boatClass.getDisplayName());
if (masterData != null) {
result.put(FIELD_ICON_URL, "/gwt/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/"+masterData.name().replaceAll("^_", "")+".png");
aliasNames.addAll(Arrays.asList(masterData.getAlternativeNames()));
}
}
result.put(FIELD_ALIAS_NAMES, aliasNames);
}
result.put(FIELD_ALIAS_NAMES, aliasNames);
return result;
}
}
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.base.CompetitorWithBoat;
import com.sap.sailing.domain.base.Nationality;
import com.sap.sailing.domain.base.Team;
import com.sap.sailing.domain.common.tracking.impl.CompetitorJsonConstants;
import com.sap.sailing.server.gateway.deserialization.impl.BoatClassJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sse.common.Color;
import com.sap.sse.common.CountryCode;
@@ -63,10 +64,25 @@ public class CompetitorJsonSerializer implements JsonSerializer<Competitor> {
/**
* Creates a serializer for {@link Competitor} objects which if {@code serializeBoat==true} and if the competitor
* {@link Competitor#hasBoat() has a boat attached} will serialize the boat in the
* {@link CompetitorJsonConstants#FIELD_BOAT} field of the resulting document.
* {@link CompetitorJsonConstants#FIELD_BOAT} field of the resulting document. The boat class will be
* serialized in verbose format. See also {@link #create(boolean, boolean, boolean)}.
*/
public static CompetitorJsonSerializer create(boolean serializeBoat, boolean serializeNonPublicCompetitorFields) {
return new CompetitorJsonSerializer(TeamJsonSerializer.create(), serializeBoat?BoatJsonSerializer.create():null,
return create(serializeBoat, serializeNonPublicCompetitorFields, /* verboseBoatClassSerializer */ true);
}
/**
* Creates a serializer for {@link Competitor} objects which if {@code serializeBoat==true} and if the competitor
* {@link Competitor#hasBoat() has a boat attached} will serialize the boat in the
* {@link CompetitorJsonConstants#FIELD_BOAT} field of the resulting document. If {@code verboseBoatClassSerializer}
* is {@code true}, a verbose set of fields describing the boat class is serialized with every boat. If
* {@code false}, the serialized boat class will still have enough information to be de-serialized by
* {@link BoatClassJsonDeserializer}.
*/
public static CompetitorJsonSerializer create(boolean serializeBoat, boolean serializeNonPublicCompetitorFields,
boolean verboseBoatClassSerializer) {
return new CompetitorJsonSerializer(TeamJsonSerializer.create(),
serializeBoat ? new BoatJsonSerializer(new BoatClassJsonSerializer(verboseBoatClassSerializer)) : null,
serializeNonPublicCompetitorFields);
}
@@ -243,14 +243,14 @@ public class RaceLogEventSerializerTest {
public void testRegisterCompetitorEventSerializer() {
// we use the real event type here because we do not want to re-implement the dispatching.
Competitor c = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", "c", null, null, null, null,
/* timeOnTimeFactor */null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Boat b = DomainFactory.INSTANCE.getOrCreateBoat("boat", "b", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null, null);
/* timeOnTimeFactor */null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
Boat b = DomainFactory.INSTANCE.getOrCreateBoat("boat", "b", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null, null, /* storePersistently */ true);
RaceLogEvent event = new RaceLogRegisterCompetitorEventImpl(null, author, 0, c, b);
serializer.serialize(event);
verify(registerCompetitorEventSerializer).serialize(event);
Boat b2 = new BoatImpl("boat", "b", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null, null);
CompetitorWithBoat c2 = DomainFactory.INSTANCE.getOrCreateCompetitorWithBoat("comp2", "comp", "c", null, null,
null, null, /* timeOnTimeFactor */null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, (DynamicBoat) b2);
null, null, /* timeOnTimeFactor */null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, (DynamicBoat) b2, /* storePersistently */ true);
RaceLogEvent event2 = new RaceLogRegisterCompetitorEventImpl(null, author, 0, c2, b2);
serializer.serialize(event2);
verify(registerCompetitorEventSerializer).serialize(event2);
@@ -72,7 +72,7 @@ public class RaceLogFinishPositioningConfirmedEventSerializerTest {
@Test
public void testSerializeAndDeserializeRaceLogFinishPositioningConfirmedEvent() throws JsonDeserializationException {
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
positioningList.add(new CompetitorResultImpl(UUID.randomUUID(), "SAP Extreme", "SAP Ext", storedBoat.getName(),
storedBoat.getSailID(), /* rank */ 1, MaxPointsReason.NONE, /* score */ null, /* finishingTime */ null,
/* comment */ null, MergeState.OK));
@@ -23,7 +23,7 @@ public class BoatResourceTest extends AbstractJaxRsApiTest {
@Before
public void setUp() throws Exception {
super.setUp();
racingEventService.getBaseDomainFactory().getOrCreateBoat(id, boatName, boatClass, sailId, null);
racingEventService.getBaseDomainFactory().getOrCreateBoat(id, boatName, boatClass, sailId, null, /* storePersistently */ true);
}
@Test
@@ -46,7 +46,7 @@ public class CompetitorsResourceTeamImageTest extends AbstractJaxRsApiTest {
DynamicTeam team = new TeamImpl(null, Collections.singleton(new PersonImpl(null, new NationalityImpl(
nationality), null, null)), null);
racingEventService.getBaseDomainFactory().getOrCreateCompetitor(id, name, null, null, null, null, team,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
}
@Test
@@ -26,7 +26,7 @@ public class CompetitorsResourceTest extends AbstractJaxRsApiTest {
public void setUp() throws Exception {
super.setUp();
DynamicTeam team = new TeamImpl(null, Collections.singleton(new PersonImpl(null, new NationalityImpl(nationality), null, null)), null);
racingEventService.getBaseDomainFactory().getOrCreateCompetitor(id, name, shortName, null, null, null, team, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
racingEventService.getBaseDomainFactory().getOrCreateCompetitor(id, name, shortName, null, null, null, team, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
}
@Test
@@ -54,10 +54,10 @@ public class LeaderboardsResourceCheckinAndOutTest extends AbstractJaxRsApiTest
public void setUp() throws Exception {
super.setUp();
Competitor c = createCompetitors(1).get(0);
Boat boat = racingEventService.getBaseDomainFactory().getOrCreateBoat("boat", "boat", boatClass, "GER1", null);
Boat boat = racingEventService.getBaseDomainFactory().getOrCreateBoat("boat", "boat", boatClass, "GER1", null, /* storePersistently */ true);
competitor = racingEventService.getBaseDomainFactory().getOrCreateCompetitorWithBoat(c.getId(), c.getName(), c.getShortName(),
c.getColor(), c.getEmail(), c.getFlagImage(), (DynamicTeam) c.getTeam(),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, (DynamicBoat) boat);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, (DynamicBoat) boat, /* storePersistently */ true);
regatta = new RegattaImpl("regatta", boatClass, /* canBoatsOfCompetitorsChangePerRace */ false, CompetitorRegistrationType.CLOSED,
MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), Collections.singleton(new SeriesImpl("series", false, /* isFleetsCanRunInParallel */ true, Collections
.singleton(new FleetImpl("fleet")), Arrays.asList("column"), racingEventService)), false,
@@ -191,7 +191,7 @@ public class CompetitorsResource extends AbstractSailingServerResource {
competitor.getColor(), competitor.getEmail(),
competitor.getTeam().getNationality(), imageUri, competitor.getFlagImage(),
/* timeOnTimeFactor */ competitor.getTimeOnTimeFactor(),
/* timeOnDistanceAllowancePerNauticalMile */ competitor.getTimeOnDistanceAllowancePerNauticalMile(), competitor.getSearchTag());
/* timeOnDistanceAllowancePerNauticalMile */ competitor.getTimeOnDistanceAllowancePerNauticalMile(), competitor.getSearchTag(), /* storePersistently */ true);
logger.log(Level.INFO, "Set team image for competitor " + competitor.getName());
JSONObject result = new JSONObject();
result.put(DeviceMappingConstants.JSON_TEAM_IMAGE_URI, imageUri.toString());
@@ -514,7 +514,7 @@ public class RegattasResource extends AbstractSailingServerResource {
timeOnDistanceAllowancePerNauticalMileAsMillis == null ? null
: new MillisecondsDurationImpl(
timeOnDistanceAllowancePerNauticalMileAsMillis),
searchTag, boat);
searchTag, boat, /* storePersistently */ true);
}
});
} else {
@@ -522,7 +522,7 @@ public class RegattasResource extends AbstractSailingServerResource {
name, shortName, color, email, flagImageURI, team, timeOnTimeFactor,
timeOnDistanceAllowancePerNauticalMileAsMillis == null ? null
: new MillisecondsDurationImpl(timeOnDistanceAllowancePerNauticalMileAsMillis),
searchTag, boat);
searchTag, boat, /* storePersistently */ true);
getSecurityService().setOwnership(competitor.getIdentifier(),
(User) regattaOwnerShipAnnotation.getAnnotation().getUserOwner(),
regattaOwnerShipAnnotation.getAnnotation().getTenantOwner(), name);
@@ -36,7 +36,7 @@ public class CreateBoat extends AbstractRacingEventServiceOperation<Boat> {
@Override
public Boat internalApplyTo(RacingEventService toState) throws Exception {
BoatClass boatClass = toState.getBaseDomainFactory().getOrCreateBoatClass(boatClassName);
Boat result = toState.getBaseDomainFactory().getCompetitorAndBoatStore().getOrCreateBoat(boatId, name, boatClass, sailId, color);
Boat result = toState.getBaseDomainFactory().getCompetitorAndBoatStore().getOrCreateBoat(boatId, name, boatClass, sailId, color, /* storePersistently */ true);
return result;
}
@@ -21,9 +21,9 @@ import com.sap.sse.common.Duration;
/**
* Creates a {@link Competitor} if {@link #boatId} is {@code null}, or a {@link CompetitorWithBoat} otherwise. See also
* {@link CompetitorAndBoatStore#getOrCreateCompetitor(Serializable, String, String, Color, String, URI, DynamicTeam, Double, Duration, String)}
* {@link CompetitorAndBoatStore#getOrCreateCompetitor(Serializable, String, String, Color, String, URI, DynamicTeam, Double, Duration, String, boolean)}
* and
* {@link CompetitorAndBoatStore#getOrCreateCompetitorWithBoat(Serializable, String, String, Color, String, URI, DynamicTeam, Double, Duration, String, com.sap.sailing.domain.base.impl.DynamicBoat)},
* {@link CompetitorAndBoatStore#getOrCreateCompetitorWithBoat(Serializable, String, String, Color, String, URI, DynamicTeam, Double, Duration, String, com.sap.sailing.domain.base.impl.DynamicBoat, boolean)},
* respectively. This operation assumes that the boat creation has been replicated before the competitor creation in
* case a non-{@code null} boat ID has been provided, so the boat is expected to be found by a
* {@link CompetitorAndBoatStore#getExistingBoatById(Serializable) lookup by ID}.
@@ -79,7 +79,7 @@ public class CreateCompetitor extends AbstractRacingEventServiceOperation<Compet
if (boatId == null) {
result = toState.getBaseDomainFactory().getCompetitorAndBoatStore()
.getOrCreateCompetitor(competitorId, name, shortName, displayColor, email, flagImageUri,
team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag);
team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, /* storePersistently */ true);
} else {
final DynamicBoat boat = toState.getBaseDomainFactory().getCompetitorAndBoatStore().getExistingBoatById(boatId);
if (boat == null) {
@@ -87,7 +87,7 @@ public class CreateCompetitor extends AbstractRacingEventServiceOperation<Compet
}
result = toState.getBaseDomainFactory().getCompetitorAndBoatStore()
.getOrCreateCompetitorWithBoat(competitorId, name, shortName, displayColor, email, flagImageUri,
team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat);
team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat, /* storePersistently */ true);
}
return result;
}
@@ -61,7 +61,7 @@ public class UpdateCompetitor extends AbstractRacingEventServiceOperation<Compet
public Competitor internalApplyTo(RacingEventService toState) throws Exception {
Competitor result = toState.getBaseDomainFactory().getCompetitorAndBoatStore()
.updateCompetitor(idAsString, newName, newShortName, newDisplayColor, newEmail, newNationality,
newTeamImageUri, newFlagImageUri, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, newSearchTag);
newTeamImageUri, newFlagImageUri, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, newSearchTag, /* storePersistently */ true);
return result;
}
@@ -88,8 +88,8 @@ public class BoatReplicationTest extends AbstractServerReplicationTest {
new TeamImpl("STG", Collections.singleton(new PersonImpl("comp1", new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous name")), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"), /* dateOfBirth */null, "This is Rigo, the coach")),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
Boat boat = master.getBaseDomainFactory().getOrCreateBoat(UUID.randomUUID(), "Kielboat", boatClass, "GER 123", Color.RED);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat = master.getBaseDomainFactory().getOrCreateBoat(UUID.randomUUID(), "Kielboat", boatClass, "GER 123", Color.RED, /* storePersistently */ true);
Map<Competitor,Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(competitor, boat);
final String raceName = "Test Race";
@@ -147,7 +147,7 @@ public class BoatReplicationTest extends AbstractServerReplicationTest {
final String boatName = "Kielzugvogel 123";
BoatClass boatClass = new BoatClassImpl("Kielzugvogel", true);
Boat boat = master.getBaseDomainFactory().getOrCreateBoat(123, boatName, boatClass, "GER 123", null);
Boat boat = master.getBaseDomainFactory().getOrCreateBoat(123, boatName, boatClass, "GER 123", null, /* storePersistently */ true);
Thread.sleep(1000);
assertTrue(StreamSupport.stream(replica.getBaseDomainFactory().getCompetitorAndBoatStore().getBoats().spliterator(), /* parallel */ false).anyMatch(
b-> b.getId().equals(boat.getId())));
@@ -98,7 +98,7 @@ public class CompetitorReplicationTest extends AbstractServerReplicationTest {
/* dateOfBirth */null, "This is famous " + competitorName)), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat = new BoatImpl(competitor.getId(), competitorName + "'s boat", boatClass, /* sailID */ null);
Map<Competitor,Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(competitor, boat);
@@ -142,7 +142,7 @@ public class CompetitorReplicationTest extends AbstractServerReplicationTest {
// modify the competitor on the master "from below" without an UpdateCompetitor operation, only locally:
master.getBaseDomainFactory().getCompetitorAndBoatStore().updateCompetitor(competitor.getId().toString(), competitorName, competitorShortName, Color.RED, competitor.getEmail(),
competitor.getTeam().getNationality(), competitor.getTeam().getImage(), competitor.getFlagImage(),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true);
final RegattaAndRaceIdentifier raceIdentifier = masterRegatta.getRaceIdentifier(raceDefinition);
DynamicTrackedRace trackedRace = (DynamicTrackedRace) master.apply(new CreateTrackedRace(raceIdentifier,
EmptyWindStore.INSTANCE, /* delayToLiveInMillis */ 3000,
@@ -167,7 +167,7 @@ public class CompetitorReplicationTest extends AbstractServerReplicationTest {
new TeamImpl("STG", Collections.singleton(new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous " + competitorName)), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"), /* dateOfBirth */null, "This is Rigo, the coach")),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
Thread.sleep(1000);
Competitor[] replicaCompetitor = new Competitor[1];
StreamSupport.stream(replica.getBaseDomainFactory().getCompetitorAndBoatStore().getAllCompetitors().spliterator(), /* parallel */ false).filter(
@@ -181,13 +181,13 @@ public class CompetitorReplicationTest extends AbstractServerReplicationTest {
final String competitorName = "Der mit dem Kiel zieht";
final String shortCcompetitorName = "Kiel";
URI flagImageURI = new URI("http://www.sapsailing.com");
DynamicBoat boat = master.getBaseDomainFactory().getOrCreateBoat(234, "The Boat", master.getBaseDomainFactory().getOrCreateBoatClass("49er"), "234", null);
DynamicBoat boat = master.getBaseDomainFactory().getOrCreateBoat(234, "The Boat", master.getBaseDomainFactory().getOrCreateBoatClass("49er"), "234", null, /* storePersistently */ true);
CompetitorWithBoat competitor = master.getBaseDomainFactory().getOrCreateCompetitorWithBoat(
123, competitorName, shortCcompetitorName, Color.RED, "someone@nowhere.de", flagImageURI,
new TeamImpl("STG", Collections.singleton(new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous " + competitorName)), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"), /* dateOfBirth */null, "This is Rigo, the coach")),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, boat);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, boat, /* storePersistently */ true);
Thread.sleep(1000);
Competitor[] replicaCompetitor = new Competitor[1];
StreamSupport.stream(replica.getBaseDomainFactory().getCompetitorAndBoatStore().getAllCompetitors().spliterator(), /* parallel */ false).filter(
@@ -80,9 +80,9 @@ public class TrackedRaceContentsReplicationTest extends AbstractServerReplicatio
(List<PersonImpl>) Arrays.asList(new PersonImpl[] { new PersonImpl("Tina Lutz", masterDomainFactory.getOrCreateNationality("GER"), null, null),
new PersonImpl("Tina Lutz", masterDomainFactory.getOrCreateNationality("GER"), null, null) }),
new PersonImpl("Rigo de Mas", masterDomainFactory.getOrCreateNationality("NED"), null, null)),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat = masterDomainFactory.getCompetitorAndBoatStore().getOrCreateBoat("boat123", "boat123",
masterDomainFactory.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true), "GER 61", null);
masterDomainFactory.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true), "GER 61", null, /* storePersistently */ true);
Map<Competitor, Boat> competitorAndBoats = new HashMap<>();
competitorAndBoats.put(competitor, boat);
final String baseEventName = "Test Event";
@@ -83,8 +83,8 @@ public class TrackedRaceWithSensorFixStoreContentsReplicationTest extends Abstra
(List<PersonImpl>) Arrays.asList(new PersonImpl[] { new PersonImpl("Tina Lutz", DomainFactory.INSTANCE.getOrCreateNationality("GER"), null, null),
new PersonImpl("Tina Lutz", DomainFactory.INSTANCE.getOrCreateNationality("GER"), null, null) }),
new PersonImpl("Rigo de Mas", DomainFactory.INSTANCE.getOrCreateNationality("NED"), null, null)),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
Boat boat = masterDomainFactory.getCompetitorAndBoatStore().getOrCreateBoat("boat", "GER 61", boatClass470, "GER 61", null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
Boat boat = masterDomainFactory.getCompetitorAndBoatStore().getOrCreateBoat("boat", "GER 61", boatClass470, "GER 61", null, /* storePersistently */ true);
final String baseEventName = "Test Event";
AddDefaultRegatta addEventOperation = new AddDefaultRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
/*startDate*/ null, /*endDate*/ null, UUID.randomUUID());
@@ -57,7 +57,7 @@ public class StatisticsTest {
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
private final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", "c", null, null, null, null,
/* timeOnTimeFactor */ null,
/* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
/* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
private final Boat boat = new BoatImpl("boat", "b", boatClass, "DE 12345");
private final Mark mark1 = DomainFactory.INSTANCE.getOrCreateMark("mark1");
private final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
@@ -93,7 +93,7 @@ public class ApplyScoresFromRaceLogTest extends LeaderboardScoringAndRankingTest
/* dateOfBirth */ null, "This is famous "+competitorName)),
new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null));
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true));
}
regatta = createRegatta(/* qualifying */0, new String[] { "Default" }, /* final */1,
new String[] { "Default" },
@@ -181,7 +181,7 @@ public class ApplyScoresFromRaceLogTest extends LeaderboardScoringAndRankingTest
int oneBasedRank = 1;
final CompetitorResults results = new CompetitorResultsImpl();
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
for (final Competitor c : competitors) {
final MaxPointsReason mpr = new MaxPointsReason[] { null, MaxPointsReason.NONE, MaxPointsReason.DNF, MaxPointsReason.OCS }[oneBasedRank%4];
final Double score = oneBasedRank%5 == 0 ? null : 20*Math.random();
@@ -319,7 +319,7 @@ public class ApplyScoresFromRaceLogTest extends LeaderboardScoringAndRankingTest
private void setResultForCompetitor(final Competitor competitor, int oneBasedRank,
final CompetitorResults results, MaxPointsReason maxPointsReason, Double explicitScore) {
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
results.add(new CompetitorResultImpl(competitor.getId(), competitor.getName(),
competitor.getShortName(), storedBoat.getName(), storedBoat.getSailID(), oneBasedRank,
maxPointsReason, explicitScore, /* finishingTime */ null, /* comment */ null, MergeState.OK));
@@ -32,19 +32,19 @@ public class CompetitorStoreTest {
CompetitorAndBoatStore transientStore = new TransientCompetitorAndBoatStoreImpl();
DynamicCompetitor template = (DynamicCompetitor) AbstractLeaderboardTest.createCompetitor("Test Competitor");
Competitor competitor = transientStore.getOrCreateCompetitor(template.getId(), template.getName(), template.getShortName(), template.getColor(), template.getEmail(), template.getFlagImage(), template.getTeam(),
/* timeOnTimeFactor */ 1.234, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(730), null);
/* timeOnTimeFactor */ 1.234, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(730), null, /* storePersistently */ true);
assertTrue(competitor != template);
Competitor competitor2 = transientStore.getOrCreateCompetitor(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), template.getTeam(),
/* timeOnTimeFactor */ 1.345,
/* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(750.2), null);
/* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(750.2), null, /* storePersistently */ true);
assertSame(competitor, competitor2);
assertEquals(DomainFactory.INSTANCE.getOrCreateNationality("GER"), competitor.getTeam().getNationality());
DynamicTeam differentTeam = (DynamicTeam) AbstractLeaderboardTest.createCompetitor("Test Competitor").getTeam();
differentTeam.setNationality(DomainFactory.INSTANCE.getOrCreateNationality("GHA")); // Ghana
Competitor competitor3 = transientStore.getOrCreateCompetitor(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), differentTeam, /* timeOnTimeFactor */
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null);
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null, /* storePersistently */ true);
assertSame(competitor, competitor3); // use existing competitor despite the different team
assertSame(competitor.getTeam(), competitor3.getTeam());
@@ -52,7 +52,7 @@ public class CompetitorStoreTest {
transientStore.allowCompetitorResetToDefaults(competitor);
Competitor competitor4 = transientStore.getOrCreateCompetitor(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), differentTeam, /* timeOnTimeFactor */
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null);
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null, /* storePersistently */ true);
assertSame(competitor, competitor4); // expecting an in-place update
assertEquals(differentTeam.getNationality(), competitor4.getTeam().getNationality());
}
@@ -64,7 +64,7 @@ public class CompetitorStoreTest {
DynamicCompetitor template = (DynamicCompetitor) AbstractLeaderboardTest.createCompetitor("Test Competitor");
Competitor competitor = persistentStore1.getOrCreateCompetitor(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), template.getTeam(),
/* timeOnTimeFactor */ 1.234, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(730), null);
/* timeOnTimeFactor */ 1.234, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(730), null, /* storePersistently */ true);
CompetitorAndBoatStore persistentStore2 = new PersistentCompetitorAndBoatStore(
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), /* clearStore */false, null, /* raceLogResolver */ (srlid)->null);
@@ -79,7 +79,7 @@ public class CompetitorStoreTest {
differentTeam.setNationality(DomainFactory.INSTANCE.getOrCreateNationality("GHA")); // Ghana
Competitor competitor3 = persistentStore2.getOrCreateCompetitor(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), differentTeam, /* timeOnTimeFactor */
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null);
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null, /* storePersistently */ true);
assertSame(competitor2, competitor3); // use existing competitor despite the different team
assertNotSame(differentTeam, competitor2.getTeam()); // team expected to remain unchanged
assertEquals(competitor.getTeam().getNationality(), competitor3.getTeam().getNationality()); // no updatability requested; nationality
@@ -88,7 +88,7 @@ public class CompetitorStoreTest {
persistentStore2.allowCompetitorResetToDefaults(competitor2);
Competitor competitor4 = persistentStore2.getOrCreateCompetitor(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), differentTeam, /* timeOnTimeFactor */
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null);
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null, /* storePersistently */ true);
assertSame(competitor2, competitor4); // expecting an in-place update
assertEquals(differentTeam.getNationality(), competitor4.getTeam().getNationality());
}
@@ -100,7 +100,7 @@ public class CompetitorStoreTest {
DynamicCompetitorWithBoat template = (DynamicCompetitorWithBoat) AbstractLeaderboardTest.createCompetitorWithBoat("Test Competitor");
CompetitorWithBoat competitor = persistentStore1.getOrCreateCompetitorWithBoat(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), template.getTeam(),
/* timeOnTimeFactor */ 1.234, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(730), null, template.getBoat());
/* timeOnTimeFactor */ 1.234, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(730), null, template.getBoat(), /* storePersistently */ true);
CompetitorAndBoatStore persistentStore2 = new PersistentCompetitorAndBoatStore(
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), /* clearStore */false, null, /* raceLogResolver */ (srlid)->null);
@@ -115,7 +115,7 @@ public class CompetitorStoreTest {
differentTeam.setNationality(DomainFactory.INSTANCE.getOrCreateNationality("GHA")); // Ghana
DynamicCompetitorWithBoat competitor3 = persistentStore2.getOrCreateCompetitorWithBoat(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), differentTeam, /* timeOnTimeFactor */
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null, template.getBoat());
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null, template.getBoat(), /* storePersistently */ true);
assertSame(competitor2, competitor3); // use existing competitor despite the different team
assertNotSame(differentTeam, competitor2.getTeam()); // team expected to remain unchanged
assertEquals(competitor.getTeam().getNationality(), competitor3.getTeam().getNationality()); // no updatability requested; nationality
@@ -124,7 +124,7 @@ public class CompetitorStoreTest {
persistentStore2.allowCompetitorResetToDefaults(competitor2);
CompetitorWithBoat competitor4 = persistentStore2.getOrCreateCompetitorWithBoat(template.getId(), template.getName(), template.getShortName(),
template.getColor(), template.getEmail(), template.getFlagImage(), differentTeam, /* timeOnTimeFactor */
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null, competitor3.getBoat());
null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */null, null, competitor3.getBoat(), /* storePersistently */ true);
assertSame(competitor2, competitor4); // expecting an in-place update
assertEquals(differentTeam.getNationality(), competitor4.getTeam().getNationality());
}
@@ -136,7 +136,7 @@ public class CompetitorStoreTest {
DynamicBoat template = new BoatImpl("id-12345", "Morning Glory", new BoatClassImpl("505", /* typicallyStartsUpwind */ true),
"GER 1234", new RGBColor(255, 0, 0));
persistentStore1.getOrCreateBoat(template.getId(), template.getName(), template.getBoatClass(),
template.getSailID(), template.getColor());
template.getSailID(), template.getColor(), /* storePersistently */ true);
CompetitorAndBoatStore persistentStore2 = new PersistentCompetitorAndBoatStore(
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), /* clearStore */false, null, /* raceLogResolver */ (srlid)->null);
@@ -146,14 +146,14 @@ public class CompetitorStoreTest {
String differentSailId = "USA 1234";
Boat boat3 = persistentStore2.getOrCreateBoat(template.getId(), template.getName(), template.getBoatClass(),
differentSailId, template.getColor());
differentSailId, template.getColor(), /* storePersistently */ true);
assertSame(boat2, boat3); // use existing boat despite the different sailID
assertNotSame(differentSailId, boat2.getSailID()); // sailID expected to remain unchanged
// now mark the boat as to update from defaults
persistentStore2.allowBoatResetToDefaults(boat2);
Boat boat4 = persistentStore2.getOrCreateBoat(template.getId(), template.getName(), template.getBoatClass(),
differentSailId, template.getColor());
differentSailId, template.getColor(), /* storePersistently */ true);
assertSame(boat2, boat4); // expecting an in-place update
assertEquals(differentSailId, boat4.getSailID());
}
@@ -57,7 +57,7 @@ public class LeaderboardStorageTest extends TestCase {
DynamicTeam team = new TeamImpl("team", sailorList, null);
String competitorId = "testC";
Competitor competitor = service.getBaseDomainFactory().getOrCreateCompetitor(competitorId, "Test C", null, null,
null, null, team, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
null, null, team, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
double carriedPoints = 2.0;
leaderboard.setCarriedPoints(competitor, carriedPoints);
@@ -994,7 +994,7 @@ public class MasterDataImportTest {
BoatClass boatClass = new BoatClassImpl("H16", true);
Competitor competitor = sourceService.getBaseDomainFactory().getOrCreateCompetitor(competitorUUID, "Froderik", "F", Color.RED,
"noone@nowhere.de", null, team, /* timeOnTimeFactor */null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */
null, null);
null, null, /* storePersistently */ true);
competitors.add(competitor);
UUID competitor2UUID = UUID.randomUUID();
Set<DynamicPerson> sailors2 = new HashSet<DynamicPerson>();
@@ -1003,7 +1003,7 @@ public class MasterDataImportTest {
DynamicTeam team2 = new TeamImpl("Pros2", sailors2, coach2);
Competitor competitor2 = sourceService.getBaseDomainFactory().getCompetitorAndBoatStore().getOrCreateCompetitor(competitor2UUID,
"Froderik", "F", Color.RED, "noone@nowhere.de", null, team2, /* timeOnTimeFactor */null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */
null, null);
null, null, /* storePersistently */ true);
competitors.add(competitor2);
RaceColumn raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
TrackedRace trackedRace = new DummyTrackedRace(raceId, createCompetitorsAndBoatsMap(boatClass, competitors), regatta, null, sourceService.getWindStore());
@@ -1020,7 +1020,7 @@ public class MasterDataImportTest {
TimePoint logTimePoint2 = logTimePoint.plus(10);
CompetitorResults positionedCompetitors = new CompetitorResultsImpl();
Boat storedBoat = DomainFactory.INSTANCE.getOrCreateBoat(UUID.randomUUID(), "SAP Extreme Sailing Team",
new BoatClassImpl("X40", false), "123", Color.RED);
new BoatClassImpl("X40", false), "123", Color.RED, /* storePersistently */ true);
positionedCompetitors.add(new CompetitorResultImpl(
competitor.getId(), competitor.getName(), competitor.getShortName(), storedBoat.getName(),
storedBoat.getSailID(), /* rank */ 1, MaxPointsReason.DNS, /* score */ null, /* finishingTime */ null,
@@ -1459,7 +1459,7 @@ public class MasterDataImportTest {
String competitorOldName = "oldName";
Competitor competitorToOverride = domainFactory.getOrCreateCompetitor(competitorUUID, competitorOldName, "c",
Color.BLUE, "noone@nowhere.de", null, teamToOverride, /* timeOnTimeFactor */null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */
null, null);
null, null, /* storePersistently */ true);
competitorsToOverride.add(competitorToOverride);
Leaderboard leaderboardToOverride = destService.addRegattaLeaderboard(
@@ -92,7 +92,7 @@ public class RaceColumnReloadTest {
Boat boat = new BoatImpl("61", "GER 61", boatClass, "GER 61");
CompetitorWithBoat comp = masterDomainFactory.getOrCreateCompetitorWithBoat("GER 61", "Team", "T", Color.RED, "noone@nowhere.de",
null, new TeamImpl("Team", Arrays.asList(sailor), coach),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, (DynamicBoat) boat);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, (DynamicBoat) boat, /* storePersistently */ true);
service.apply(new CreateFlexibleLeaderboard(leaderboardName, "Test", new int[] { 1, 2 }, new LowPoint(), null));
raceColumn = service.apply(new AddColumnToLeaderboard("R1", leaderboardName, false));
@@ -115,8 +115,8 @@ public class WindByRaceLogTest {
Competitor competitor = masterDomainFactory.getOrCreateCompetitor("GER 61", "Sailor", "S", Color.RED, "noone@nowhere.de", null, new TeamImpl("Sailor",
(List<PersonImpl>) Arrays.asList(new PersonImpl[] { new PersonImpl("Sailor 1", DomainFactory.INSTANCE.getOrCreateNationality("GER"), null, null)}),
new PersonImpl("Sailor 2", DomainFactory.INSTANCE.getOrCreateNationality("NED"), null, null)),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
DynamicBoat boat = (DynamicBoat) masterDomainFactory.getOrCreateBoat("boat", "GER 61", boatClass, "GER 61", null);
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null, /* storePersistently */ true);
DynamicBoat boat = (DynamicBoat) masterDomainFactory.getOrCreateBoat("boat", "GER 61", boatClass, "GER 61", null, /* storePersistently */ true);
return new CompetitorWithBoatImpl(competitor, boat);
}
@@ -66,11 +66,11 @@ public class PersistentCompetitorAndBoatStore extends TransientCompetitorAndBoat
} else {
Collection<DynamicBoat> allBoats = loadFrom.loadAllBoats();
for (DynamicBoat boat : allBoats) {
super.addNewBoat(boat);
super.addNewBoat(boat, /* storePersistently */ false);
}
Collection<DynamicCompetitor> allCompetitors = loadFrom.loadAllCompetitors();
for (DynamicCompetitor competitor : allCompetitors) {
super.addNewCompetitor(competitor);
super.addNewCompetitor(competitor, /* storePersistently */ false);
}
}
}
@@ -130,9 +130,11 @@ public class PersistentCompetitorAndBoatStore extends TransientCompetitorAndBoat
}
@Override
protected void addNewCompetitor(DynamicCompetitor competitor) {
storeTo.storeCompetitor(competitor);
super.addNewCompetitor(competitor);
protected void addNewCompetitor(DynamicCompetitor competitor, boolean storePersistently) {
if (storePersistently) {
storeTo.storeCompetitor(competitor);
}
super.addNewCompetitor(competitor, storePersistently);
}
@Override
@@ -149,10 +151,12 @@ public class PersistentCompetitorAndBoatStore extends TransientCompetitorAndBoat
@Override
public Competitor updateCompetitor(String idAsString, String newName, String newShortName, Color newRgbDisplayColor, String newEmail,
Nationality newNationality, URI newTeamImageUri, URI newFlagImageUri, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile,
String searchTag) {
String searchTag, boolean storePersistently) {
Competitor result = super.updateCompetitor(idAsString, newName, newShortName, newRgbDisplayColor, newEmail, newNationality,
newTeamImageUri, newFlagImageUri, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag);
storeTo.storeCompetitor(result);
newTeamImageUri, newFlagImageUri, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, storePersistently);
if (storePersistently) {
storeTo.storeCompetitor(result);
}
return result;
}
@@ -163,9 +167,11 @@ public class PersistentCompetitorAndBoatStore extends TransientCompetitorAndBoat
}
@Override
protected void addNewBoat(DynamicBoat boat) {
storeTo.storeBoat(boat);
super.addNewBoat(boat);
protected void addNewBoat(DynamicBoat boat, boolean storePersistently) {
if (storePersistently) {
storeTo.storeBoat(boat);
}
super.addNewBoat(boat, storePersistently);
}
@Override
@@ -3299,12 +3299,12 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
dynamicCompetitor.getColor(), dynamicCompetitor.getEmail(), dynamicCompetitor.getFlagImage(),
dynamicCompetitor.getTeam(), dynamicCompetitor.getTimeOnTimeFactor(),
dynamicCompetitor.getTimeOnDistanceAllowancePerNauticalMile(), dynamicCompetitor.getSearchTag(),
((DynamicCompetitorWithBoat) dynamicCompetitor).getBoat());
((DynamicCompetitorWithBoat) dynamicCompetitor).getBoat(), /* storePersistently */ true);
} else {
competitorAndBoatStore.getOrCreateCompetitor(dynamicCompetitor.getId(), dynamicCompetitor.getName(), dynamicCompetitor.getShortName(),
dynamicCompetitor.getColor(), dynamicCompetitor.getEmail(), dynamicCompetitor.getFlagImage(),
dynamicCompetitor.getTeam(), dynamicCompetitor.getTimeOnTimeFactor(),
dynamicCompetitor.getTimeOnDistanceAllowancePerNauticalMile(), dynamicCompetitor.getSearchTag());
dynamicCompetitor.getTimeOnDistanceAllowancePerNauticalMile(), dynamicCompetitor.getSearchTag(), /* storePersistently */ true);
}
}
logoutput.append("Received " + competitorAndBoatStore.getCompetitorsCount() + " NEW competitors\n");
@@ -4639,11 +4639,11 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
DynamicPerson sailor = new PersonImpl(competitorDescriptor.getName(), nationality, null, null);
DynamicTeam team = new TeamImpl(competitorDescriptor.getName(), Collections.singleton(sailor), null);
BoatClass boatClass = getBaseDomainFactory().getOrCreateBoatClass(competitorDescriptor.getBoatClassName());
DynamicBoat boat = getCompetitorAndBoatStore().getOrCreateBoat(competitorUUID, competitorDescriptor.getBoatName(), boatClass, competitorDescriptor.getSailNumber(), /* color */ null);
DynamicBoat boat = getCompetitorAndBoatStore().getOrCreateBoat(competitorUUID, competitorDescriptor.getBoatName(), boatClass, competitorDescriptor.getSailNumber(), /* color */ null, /* storePersistently */ true);
DynamicCompetitorWithBoat competitorWithBoat = getCompetitorAndBoatStore().getOrCreateCompetitorWithBoat(boatUUID,
competitorDescriptor.getName(), competitorDescriptor.getShortName(), /* color */ null, /* eMail */ null,
/* flag image */ null, team, competitorDescriptor.getTimeOnTimeFactor(),
competitorDescriptor.getTimeOnDistanceAllowancePerNauticalMile(), searchTag, boat);
competitorDescriptor.getTimeOnDistanceAllowancePerNauticalMile(), searchTag, boat, /* storePersistently */ true);
return competitorWithBoat;
}
@@ -124,7 +124,7 @@ public class PermissionAwareRaceTrackingHandler extends DefaultRaceTrackingHandl
Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) {
final DynamicCompetitor competitor = competitorStore.getOrCreateCompetitor(competitorId, name, shortName,
displayColor, email, flagImageURI, team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile,
searchTag);
searchTag, /* storePersistently */ true);
createOwnershipIfMissing(competitor.getIdentifier());
return competitor;
}
@@ -136,7 +136,7 @@ public class PermissionAwareRaceTrackingHandler extends DefaultRaceTrackingHandl
Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, DynamicBoat boat) {
final DynamicCompetitorWithBoat competitorWithBoat = competitorStore.getOrCreateCompetitorWithBoat(competitorId,
name, shortName, displayColor, email, flagImageURI,
team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat);
team, timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag, boat, /* storePersistently */ true);
createOwnershipIfMissing(competitorWithBoat.getIdentifier());
createOwnershipIfMissing(competitorWithBoat.getBoat().getIdentifier());
return competitorWithBoat;
@@ -145,7 +145,7 @@ public class PermissionAwareRaceTrackingHandler extends DefaultRaceTrackingHandl
@Override
public DynamicBoat getOrCreateBoat(CompetitorAndBoatStore competitorAndBoatStore, Serializable id, String name,
BoatClass boatClass, String sailId, Color color) {
final DynamicBoat boat = competitorAndBoatStore.getOrCreateBoat(id, name, boatClass, sailId, color);
final DynamicBoat boat = competitorAndBoatStore.getOrCreateBoat(id, name, boatClass, sailId, color, /* storePersistently */ true);
createOwnershipIfMissing(boat.getIdentifier());
return boat;
}
@@ -224,7 +224,7 @@ public class StructureImporter {
BoatAndTeam boatAndTeam = getBoatAndTeam(idAsString, name, nationality, boatClass);
this.baseDomainFactory.convertToCompetitorDTO(this.baseDomainFactory.getOrCreateCompetitor(
UUID.fromString(idAsString), name, shortName, color, email, flagImage, boatAndTeam.getTeam(),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null));
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, /* storePersistently */ true));
} else {
break;
}