From c2523fe87945140e016aac1f2a4ab12ea9b196f1 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 22 Jan 2014 01:33:53 +0100 Subject: [PATCH 1/7] fixed the clear() method in TransientCompetitorStoreImpl which now clears all internal structures consistently --- .../sailing/domain/base/impl/TransientCompetitorStoreImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/TransientCompetitorStoreImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/TransientCompetitorStoreImpl.java index 82e71541d9f..84d77198394 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/TransientCompetitorStoreImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/TransientCompetitorStoreImpl.java @@ -135,6 +135,8 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab LockUtil.lockForWrite(lock); try { competitorCache.clear(); + competitorsByIdAsString.clear(); + competitorsToUpdateDuringGetOrCreate.clear(); } finally { LockUtil.unlockAfterWrite(lock); } From 38178a26b8f7e907134ff095435ff5ab93b07fbd Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 22 Jan 2014 01:34:30 +0100 Subject: [PATCH 2/7] added test support for creating competitors through a CompetitorStore/DomainFactory --- .../sailing/domain/test/AbstractLeaderboardTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractLeaderboardTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractLeaderboardTest.java index 90f3ddccd9c..d914b3bf679 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractLeaderboardTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractLeaderboardTest.java @@ -3,6 +3,8 @@ package com.sap.sailing.domain.test; import java.io.Serializable; import java.util.Collections; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorFactory; import com.sap.sailing.domain.base.impl.BoatClassImpl; import com.sap.sailing.domain.base.impl.BoatImpl; import com.sap.sailing.domain.base.impl.CompetitorImpl; @@ -21,6 +23,15 @@ public abstract class AbstractLeaderboardTest { new BoatClassImpl("505", /* typicallyStartsUpwind */ true), /* sailID */ null)); } + public static Competitor createCompetitor(String competitorName, CompetitorFactory competitorFactory) { + return competitorFactory.getOrCreateCompetitor(123, competitorName, Color.RED, 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")), new BoatImpl(competitorName + "'s boat", + new BoatClassImpl("505", /* typicallyStartsUpwind */ true), /* sailID */ null)); + } + public static CompetitorImpl createCompetitor(String competitorName, Serializable id) { return new CompetitorImpl(id, competitorName, Color.RED, new TeamImpl("STG", Collections.singleton( new PersonImpl(competitorName, new NationalityImpl("GER"), From 0d2e02bda220f276994a1ad2714c6047ed2aec8a Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 22 Jan 2014 01:35:06 +0100 Subject: [PATCH 3/7] fixed replication test for delayed score corrections after those are now handled slightly differently with a filled competitor store; The delayed leaderboard corrections are now resolved immediately upon loading if competitors are already known in the domain factory and its competitor store. To preserve the test's behavior, this commit ensures that well-defined, new domain factories and competitor stores are used for master and replica instance. --- ...LeaderboardCorrectionsReplicationTest.java | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/DelayedLeaderboardCorrectionsReplicationTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/DelayedLeaderboardCorrectionsReplicationTest.java index b4c68d84c15..0e0417e5b29 100755 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/DelayedLeaderboardCorrectionsReplicationTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/DelayedLeaderboardCorrectionsReplicationTest.java @@ -15,6 +15,8 @@ import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.RaceColumnListener; +import com.sap.sailing.domain.base.impl.DomainFactoryImpl; +import com.sap.sailing.domain.base.impl.DynamicCompetitor; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaNameAndRaceName; @@ -66,8 +68,9 @@ public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServer // then start initial load, wait until finished; then link a tracked race to leaderboard's RaceColumn on master and // verify that on the replica it is associated to the RaceColumn as well, and the DelayedLeaderboardCorrections are // resolved properly on the replica. - BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */ true); - Competitor hasso = AbstractLeaderboardTest.createCompetitor("Dr. Hasso Plattner"); + final DomainFactory domainFactory = DomainFactory.INSTANCE; + BoatClass boatClass = domainFactory.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */ true); + DynamicCompetitor hasso = AbstractLeaderboardTest.createCompetitor("Dr. Hasso Plattner"); // don't create competitor using CompetitorStore final DynamicTrackedRace q2YellowTrackedRace = new MockedTrackedRaceWithFixedRank(hasso, /* rank */ 1, /* started */ false, boatClass) { private static final long serialVersionUID = 1234L; @Override @@ -75,7 +78,7 @@ public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServer return new RegattaNameAndRaceName("Kieler Woche (5o5)", "Yellow Race 2"); } }; - master = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace); + master = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace, domainFactory); final String leaderboardName = "My new leaderboard"; final int[] discardThresholds = new int[] { 19, 44 }; CreateFlexibleLeaderboard createTestLeaderboard = new CreateFlexibleLeaderboard(leaderboardName, null, discardThresholds, new LowPoint(), null); @@ -92,11 +95,14 @@ public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServer masterLeaderboard.getRaceColumnByName(Q2), MillisecondsTimePoint.now())); // re-load new master from persistence - master = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace); - replica = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace); + master = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace, domainFactory); + DomainFactoryImpl replicaDomainFactory = new DomainFactoryImpl(); + replica = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace, replicaDomainFactory); final Leaderboard masterLeaderboardReloaded = master.getLeaderboardByName(leaderboardName); assertNotNull(masterLeaderboardReloaded); - // expecting the correction to only be in the DelayedLeaderboardCorrection object but not the leaderboard itself + // expecting the correction to not be in the leaderboard because the competitor was not found in the + // domain factory's competitor store while loading and therefore the score correction could not immediately + // be applied to the leaderboard's real score correction assertEquals(MaxPointsReason.NONE, masterLeaderboardReloaded.getMaxPointsReason(hasso, masterLeaderboardReloaded.getRaceColumnByName(Q2), MillisecondsTimePoint.now())); @@ -104,13 +110,16 @@ public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServer Pair descriptors = basicSetUp(/* dropDB */ false, master, replica); replicaReplicator = descriptors.getA(); masterDescriptor = descriptors.getB(); + // starting to replicate will clear the competitor store used by the replica in this test; + // the competitor will have to be looked up again after it was received by the replica. replicaReplicator.startToReplicateFrom(masterDescriptor); Thread.sleep(1000); Leaderboard replicaLeaderboard = replica.getLeaderboardByName(leaderboardName); assertNotNull(replicaLeaderboard); assertNotNull(replicaLeaderboard.getRaceColumnByName(Q2)); - // so far, the replica should also only have the delayed corrections: + // so far, the replica should also only have the delayed corrections since during deserializing them the + // replicatedHasso competitor was not yet known to the replica's competitor store: assertEquals(MaxPointsReason.NONE, replicaLeaderboard.getMaxPointsReason(hasso, replicaLeaderboard.getRaceColumnByName(Q2), MillisecondsTimePoint.now())); @@ -126,8 +135,9 @@ public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServer replicaLeaderboard.getRaceColumnByName(Q2), MillisecondsTimePoint.now())); } - private RacingEventServiceImpl createRacingEventServiceWithOneMockedTrackedRace(final DynamicTrackedRace q2YellowTrackedRace) { - return new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(MongoDBService.INSTANCE, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE + private RacingEventServiceImpl createRacingEventServiceWithOneMockedTrackedRace(final DynamicTrackedRace q2YellowTrackedRace, + DomainFactory domainFactory) { + return new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(MongoDBService.INSTANCE, domainFactory), PersistenceFactory.INSTANCE .getMongoObjectFactory(MongoDBService.INSTANCE), MediaDBFactory.INSTANCE.getMediaDB(MongoDBService.INSTANCE), EmptyWindStore.INSTANCE) { @Override public DynamicTrackedRace getExistingTrackedRace(RegattaAndRaceIdentifier raceIdentifier) { From 049431e629f00eadf72bc76c830c86fecfb0e823 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 22 Jan 2014 08:06:14 +0100 Subject: [PATCH 4/7] fixed indentation --- .../deserialization/impl/NationalityJsonDeserializer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/NationalityJsonDeserializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/NationalityJsonDeserializer.java index 4711ba33fc0..c9820e527b1 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/NationalityJsonDeserializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/NationalityJsonDeserializer.java @@ -10,13 +10,13 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; import com.sap.sailing.server.gateway.serialization.impl.NationalityJsonSerializer; public class NationalityJsonDeserializer implements JsonDeserializer { - private final SharedDomainFactory domainFactory; + private final SharedDomainFactory domainFactory; public NationalityJsonDeserializer(SharedDomainFactory domainFactory) { - this.domainFactory = domainFactory; - } + this.domainFactory = domainFactory; + } - @Override + @Override public Nationality deserialize(JSONObject object) throws JsonDeserializationException { final Nationality result; if (object == null) { From 038585690212cf13eb7216d0bcb06d1dec663515 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 22 Jan 2014 10:45:28 +0100 Subject: [PATCH 5/7] use MongoDB WriteConcern.SAFE for all master data updates in the MongoObjectFactoryImpl; hopefully this will also have an effect on the so far failing test DelayedLeaderboardCorrectionReplicationTest which only fails on the central Hudson but seems ok for local execution on a laptop. --- .../impl/MongoObjectFactoryImpl.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java index c92e76930c8..d4a7f40c0e0 100755 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java @@ -13,6 +13,7 @@ import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; +import com.mongodb.WriteConcern; import com.mongodb.util.JSON; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.ControlPoint; @@ -216,7 +217,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { } storeColumnFactors(leaderboard, dbLeaderboard); storeLeaderboardCorrectionsAndDiscards(leaderboard, dbLeaderboard); - leaderboardCollection.update(query, dbLeaderboard, /* upsrt */ true, /* multi */ false); + leaderboardCollection.update(query, dbLeaderboard, /* upsrt */ true, /* multi */ false, WriteConcern.SAFE); } private void storeColumnFactors(Leaderboard leaderboard, BasicDBObject dbLeaderboard) { @@ -350,7 +351,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { DBCollection leaderboardCollection = database.getCollection(CollectionNames.LEADERBOARDS.name()); BasicDBObject query = new BasicDBObject(FieldNames.LEADERBOARD_NAME.name(), oldName); BasicDBObject renameUpdate = new BasicDBObject("$set", new BasicDBObject(FieldNames.LEADERBOARD_NAME.name(), newName)); - leaderboardCollection.update(query, renameUpdate); + leaderboardCollection.update(query, renameUpdate, /* upsert */ true, /* multi */ false, WriteConcern.SAFE); } @Override @@ -392,7 +393,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { dbLeaderboardIds.add(dbLeaderboardId); } dbLeaderboardGroup.put(FieldNames.LEADERBOARD_GROUP_LEADERBOARDS.name(), dbLeaderboardIds); - leaderboardGroupCollection.update(query, dbLeaderboardGroup, true, false); + leaderboardGroupCollection.update(query, dbLeaderboardGroup, true, false, WriteConcern.SAFE); } @Override @@ -407,7 +408,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { DBCollection leaderboardGroupCollection = database.getCollection(CollectionNames.LEADERBOARD_GROUPS.name()); BasicDBObject query = new BasicDBObject(FieldNames.LEADERBOARD_GROUP_NAME.name(), oldName); BasicDBObject update = new BasicDBObject("$set", new BasicDBObject(FieldNames.LEADERBOARD_GROUP_NAME.name(), newName)); - leaderboardGroupCollection.update(query, update); + leaderboardGroupCollection.update(query, update, /* upsert */ true, /* multi */ false, WriteConcern.SAFE); } @Override @@ -423,7 +424,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { eventDBObject.put(FieldNames.EVENT_IS_PUBLIC.name(), event.isPublic()); DBObject venueDBObject = getVenueAsDBObject(event.getVenue()); eventDBObject.put(FieldNames.VENUE.name(), venueDBObject); - eventCollection.update(query, eventDBObject, /* upsrt */ true, /* multi */ false); + eventCollection.update(query, eventDBObject, /* upsrt */ true, /* multi */ false, WriteConcern.SAFE); } @Override @@ -431,7 +432,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { DBCollection eventCollection = database.getCollection(CollectionNames.EVENTS.name()); BasicDBObject query = new BasicDBObject(FieldNames.EVENT_ID.name(), id); BasicDBObject renameUpdate = new BasicDBObject("$set", new BasicDBObject(FieldNames.EVENT_NAME.name(), newName)); - eventCollection.update(query, renameUpdate); + eventCollection.update(query, renameUpdate, /* upsert */ true, /* multi */ false, WriteConcern.SAFE); } @Override @@ -484,7 +485,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { dbRegatta.put(FieldNames.REGATTA_REGATTA_CONFIGURATION.name(), configurationObject); } - regattasCollection.update(query, dbRegatta, /* upsrt */ true, /* multi */ false); + regattasCollection.update(query, dbRegatta, /* upsrt */ true, /* multi */ false, WriteConcern.SAFE); } @Override @@ -546,7 +547,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { DBObject query = new BasicDBObject(FieldNames.RACE_ID_AS_STRING.name(), raceIDAsString); DBObject entry = new BasicDBObject(FieldNames.RACE_ID_AS_STRING.name(), raceIDAsString); entry.put(FieldNames.REGATTA_NAME.name(), regatta.getName()); - regattaForRaceIDCollection.update(query, entry, /* upsrt */ true, /* multi */ false); + regattaForRaceIDCollection.update(query, entry, /* upsrt */ true, /* multi */ false, WriteConcern.SAFE); } @Override @@ -900,7 +901,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { JSONObject json = competitorSerializer.serialize(competitor); DBObject query = (DBObject) JSON.parse(competitorSerializer.getCompetitorIdQuery(competitor).toString()); DBObject entry = (DBObject) JSON.parse(json.toString()); - collection.update(query, entry, /* upsrt */true, /* multi */false); + collection.update(query, entry, /* upsrt */true, /* multi */false, WriteConcern.SAFE); } @Override @@ -930,7 +931,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { entryObject.put(FieldNames.CONFIGURATION_MATCHER.name(), createDeviceConfigurationMatcherObject(matcher)); entryObject.put(FieldNames.CONFIGURATION_CONFIG.name(), createDeviceConfigurationObject(configuration)); - configurationsCollections.update(query, entryObject, /* upsrt */ true, /* multi */ false); + configurationsCollections.update(query, entryObject, /* upsrt */ true, /* multi */ false, WriteConcern.SAFE); } private DBObject createDeviceConfigurationMatcherObject(DeviceConfigurationMatcher matcher) { From d4ecfc1c39cc447a80981ae01f5f4a345592a464 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Wed, 22 Jan 2014 12:15:43 +0100 Subject: [PATCH 6/7] Added start line length and start_type for a race --- .../src/com/sap/sailing/xmlexport/LeaderboardData.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java index acfeb7a72fb..09069d44352 100644 --- a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java +++ b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java @@ -169,6 +169,7 @@ public class LeaderboardData extends ExportAction { addNamedElementWithValue(raceElement, "same_day_index", sameDayGroupIndex); raceElement.addContent(createDataConfidenceXML(raceConfidenceAndErrorMessages)); + addNamedElementWithValue(raceElement, "start_type", race.getTrackedLeg(race.getRace().getCourse().getFirstLeg()).getLegType(race.getStartOfRace()).name()); addNamedElementWithValue(raceElement, "delay_to_live_in_millis", race.getDelayToLiveInMillis()); addNamedElementWithValue(raceElement, "timepoint_of_last_event_as_millis", handleValue(race.getTimePointOfLastEvent())); @@ -180,8 +181,10 @@ public class LeaderboardData extends ExportAction { addNamedElementWithValue(raceElement, "start_of_tracking_time_as_millis", handleValue(race.getStartOfTracking())); addNamedElementWithValue(raceElement, "end_of_tracking_time_as_millis", handleValue(race.getEndOfTracking())); + LineLengthAndAdvantage start = race.getStartLine(race.getStartOfTracking()); + addNamedElementWithValue(raceElement, "start_line_length_in_meters", start.getLength().getMeters()); + addNamedElementWithValue(raceElement, "course_length_in_meters", race.getCourseLength().getMeters()); - raceElement.addContent(createWindXML("wind_", race.getAverageWindSpeedWithConfidence(/*resolutionInMillis*/ 5*60*1000))); final List allCompetitors = race.getCompetitorsFromBestToWorst(/*timePoint*/ race.getEndOfRace()); @@ -191,7 +194,6 @@ public class LeaderboardData extends ExportAction { for (Competitor competitor : allCompetitors) { Element competitorElement = createCompetitorXML(competitor, leaderboard, /*shortVersion*/ true, null); Element competitorRaceDataElement = new Element("competitor_race_data"); - LineLengthAndAdvantage start = race.getStartLine(race.getStartOfTracking()); addNamedElementWithValue(competitorRaceDataElement, "distance_to_start_line_on_race_start_in_meters", race.getDistanceToStartLine(competitor, race.getStartOfRace()).getMeters()); addNamedElementWithValue(competitorRaceDataElement, "distance_from_starboard_side_of_start_line_when_passing_start_in_meters", race.getDistanceFromStarboardSideOfStartLineWhenPassingStart(competitor).getMeters()); addNamedElementWithValue(competitorRaceDataElement, "speed_when_crossing_start_line_in_knots", race.getSpeedWhenCrossingStartLine(competitor).getKnots()); From a13eeb3c596db27ff96f707a444b02c680c222d3 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 22 Jan 2014 15:53:30 +0100 Subject: [PATCH 7/7] added some logging to understand why DelayedLeaderboardCorrectionsReplicationTest fails only on central Hudson --- ...layedLeaderboardCorrectionsReplicationTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/DelayedLeaderboardCorrectionsReplicationTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/DelayedLeaderboardCorrectionsReplicationTest.java index 0e0417e5b29..50568474924 100755 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/DelayedLeaderboardCorrectionsReplicationTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/DelayedLeaderboardCorrectionsReplicationTest.java @@ -3,9 +3,11 @@ package com.sap.sailing.server.replication.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.io.FileNotFoundException; import java.net.UnknownHostException; +import java.util.logging.Logger; import org.junit.Before; import org.junit.Test; @@ -21,9 +23,11 @@ import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaNameAndRaceName; import com.sap.sailing.domain.common.impl.MillisecondsTimePoint; +import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.leaderboard.DelayedLeaderboardCorrections; import com.sap.sailing.domain.leaderboard.Leaderboard; +import com.sap.sailing.domain.leaderboard.SettableScoreCorrection; import com.sap.sailing.domain.leaderboard.impl.LowPoint; import com.sap.sailing.domain.persistence.PersistenceFactory; import com.sap.sailing.domain.persistence.media.MediaDBFactory; @@ -42,6 +46,8 @@ import com.sap.sailing.server.replication.ReplicationMasterDescriptor; import com.sap.sailing.server.replication.ReplicationService; public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServerReplicationTest { + private static final Logger logger = Logger.getLogger(DelayedLeaderboardCorrectionsReplicationTest.class.getName()); + private static final String Q2 = "Q2"; private ReplicationService replicaReplicator; private ReplicationMasterDescriptor masterDescriptor; @@ -123,9 +129,17 @@ public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServer assertEquals(MaxPointsReason.NONE, replicaLeaderboard.getMaxPointsReason(hasso, replicaLeaderboard.getRaceColumnByName(Q2), MillisecondsTimePoint.now())); + Leaderboard newMasterLeaderboard = master.getLeaderboardByName(masterLeaderboard.getName()); + SettableScoreCorrection newMasterScoreCorrections = newMasterLeaderboard.getScoreCorrection(); + RaceColumn newMasterQ2 = newMasterLeaderboard.getRaceColumnByName(Q2); + newMasterScoreCorrections.getCompetitorsThatHaveCorrectionsIn(newMasterQ2); + assertTrue(Util.isEmpty(newMasterScoreCorrections.getCompetitorsThatHaveCorrectionsIn(newMasterQ2))); // no score corrections applied yet // now connect the tracked race again to the leaderboard column in the re-loaded environment master.apply(new ConnectTrackedRaceToLeaderboardColumn(masterLeaderboard.getName(), Q2, /* default fleet */ masterLeaderboard.getFleet(null).getName(), q2YellowTrackedRace.getRaceIdentifier())); + logger.info("hasso object ID hash: "+System.identityHashCode(hasso)); + logger.info("got score correction for competitor "+System.identityHashCode(newMasterScoreCorrections.getCompetitorsThatHaveCorrectionsIn(newMasterQ2).iterator().next())); + assertTrue(Util.contains(newMasterScoreCorrections.getCompetitorsThatHaveCorrectionsIn(newMasterQ2), hasso)); // now score corrections must have been applied from Delayed... // now the delayed corrections are expected to have been resolved: assertEquals(MaxPointsReason.DNF, master.getLeaderboardByName(leaderboardName).getMaxPointsReason(hasso, master.getLeaderboardByName(leaderboardName).getRaceColumnByName(Q2), MillisecondsTimePoint.now()));