From 3b40bc6773fb7881dfb79609f280f4ac8fb5fe96 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 17 Nov 2011 14:42:16 +0100 Subject: [PATCH] added canSendRequests parameter to SailMasterConnectorImpl and refactored clients accordingly; fixed startTime --- .../SwissTimingAdapterPersistenceImpl.java | 11 +-- ...ActivelyConnectingStoreAndForwardTest.java | 2 +- .../EndToEndListeningStoreAndFowardTest.java | 35 +++++++++- .../test/ListeningStoreAndForwardTest.java | 2 +- ...rlappingStoredAndReceivedMessagesTest.java | 2 +- .../test/SailMasterConnectivityTest.java | 2 +- .../test/ScriptedStoreAndForwardTest.java | 2 +- .../test/SwissTimingSailMasterLiveTest.java | 3 +- .../SwissTimingFactory.java | 5 +- .../impl/SailMasterConnectorImpl.java | 70 +++++++++++++------ .../impl/SwissTimingFactoryImpl.java | 16 +++-- .../impl/SwissTimingRaceTrackerImpl.java | 4 +- .../sailing/gwt/ui/client/SailingService.java | 6 +- .../gwt/ui/client/SailingServiceAsync.java | 7 +- .../SwissTimingEventManagementPanel.java | 6 +- .../gwt/ui/server/SailingServiceImpl.java | 10 +-- .../sailing/server/RacingEventService.java | 6 +- .../server/RacingEventServiceImpl.java | 16 +++-- 18 files changed, 136 insertions(+), 69 deletions(-) diff --git a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java index bcd807c6eb4..917039217ed 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java @@ -217,16 +217,17 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers for (Race newRace : availableRaces) { storeRace(newRace); } - } else if(message.getRaceID() != null && cachedRaces.containsKey(message.getRaceID()) == false) { + } else if (message.getRaceID() != null && !cachedRaces.containsKey(message.getRaceID())) { // ah, we found a new raceID which is not in the list of known races // in order to have a more intelligent conflict resolver mechanism we will forward the resolution to a special thread later on boolean simpleResolution = true; - if(simpleResolution) { + if (simpleResolution) { // first check if the missing race has been created in the mean time - Race checkRace = getRace(message.getRaceID()); - if(checkRace != null) { - cachedRaces.put(checkRace.getRaceID(), checkRace); + Race raceFromDB = getRace(message.getRaceID()); + if (raceFromDB != null) { + cachedRaces.put(raceFromDB.getRaceID(), raceFromDB); } else { + logger.info("Didn't find race "+message.getRaceID()+" in race DB. Adding it."); Race newRace = SwissTimingFactory.INSTANCE.createRace(message.getRaceID(), null, null); storeRace(newRace); cachedRaces.put(newRace.getRaceID(), newRace); diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ActivelyConnectingStoreAndForwardTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ActivelyConnectingStoreAndForwardTest.java index c566f32447f..f030e8b13a9 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ActivelyConnectingStoreAndForwardTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ActivelyConnectingStoreAndForwardTest.java @@ -79,7 +79,7 @@ public class ActivelyConnectingStoreAndForwardTest { } swissTimingFactory = SwissTimingFactory.INSTANCE; transceiver = swissTimingFactory.createSailMasterTransceiver(); - connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", CLIENT_PORT, null); // will connect to RECEIVE_PORT + connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", CLIENT_PORT, null, /* canSendRequests */ true); // will connect to RECEIVE_PORT DBCollection lastMessageCountCollection = db.getCollection(CollectionNames.LAST_MESSAGE_COUNT.name()); lastMessageCountCollection.update(new BasicDBObject(), new BasicDBObject().append(FieldNames.LAST_MESSAGE_COUNT.name(), 0l), /* upsert */ true, /* multi */ false); diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/EndToEndListeningStoreAndFowardTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/EndToEndListeningStoreAndFowardTest.java index e324aba8ebe..cba8a13ffa6 100644 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/EndToEndListeningStoreAndFowardTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/EndToEndListeningStoreAndFowardTest.java @@ -92,7 +92,7 @@ public class EndToEndListeningStoreAndFowardTest { } @Test - public void testEndToEndScenario() throws IOException, InterruptedException, ParseException { + public void testSimpleRaceCreationScript() throws IOException, InterruptedException, ParseException { String[] racesToTrack = new String[] { "4711", "4712" }; String scriptName = "/InitMessagesScript.txt"; setUpUsingScript(racesToTrack, scriptName); @@ -119,14 +119,43 @@ public class EndToEndListeningStoreAndFowardTest { assertEquals(expectedRaceIDs, raceIDs); } + @Test + public void testLongRaceLog() throws IOException, InterruptedException, ParseException { + String[] racesToTrack = new String[] { "W4702" }; + String scriptName = "/InitMessagesScript.txt"; + setUpUsingScript(racesToTrack, scriptName); + + Set allTrackedRaces = new HashSet(); + Iterable allEvents = racingEventService.getAllEvents(); + for (Event event : allEvents) { + DynamicTrackedEvent trackedEvent = racingEventService.getTrackedEvent(event); + Iterable trackedRaces = trackedEvent.getTrackedRaces(); + for (TrackedRace trackedRace : trackedRaces) { + allTrackedRaces.add(trackedRace); + } + } + assertEquals(2, Util.size(allTrackedRaces)); + Set raceIDs = new HashSet(); + for (TrackedRace trackedRace : allTrackedRaces) { + RaceDefinition race = trackedRace.getRace(); + raceIDs.add(race.getName()); + } + Set expectedRaceIDs = new HashSet(); + for (String raceIDToTrack : new String[] { "Not such a wonderful race", "A wonderful test race" }) { + expectedRaceIDs.add(raceIDToTrack); + } + assertEquals(expectedRaceIDs, raceIDs); + } + private void setUpUsingScript(String[] racesToTrack, String... scriptNames) throws InterruptedException, UnknownHostException, IOException, ParseException { for(String raceToTrack: racesToTrack) { - RaceHandle raceHandle = racingEventService.addSwissTimingRace(raceToTrack, "localhost", CLIENT_PORT, emptyWindStore, -1); + RaceHandle raceHandle = racingEventService.addSwissTimingRace(raceToTrack, "localhost", CLIENT_PORT, /* canSendRequests */ + false, emptyWindStore, -1); raceHandles.add(raceHandle); if(connector == null) { connector = racingEventService.getSwissTimingFactory().getOrCreateSailMasterConnector("localhost", - CLIENT_PORT, swissTimingAdapterPersistence); + CLIENT_PORT, swissTimingAdapterPersistence, /* canSendRequests */ false); } } ScriptedMessagesReader scriptedMessagesReader = new ScriptedMessagesReader(); diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ListeningStoreAndForwardTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ListeningStoreAndForwardTest.java index 764b0fa235b..194640a16d4 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ListeningStoreAndForwardTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ListeningStoreAndForwardTest.java @@ -56,7 +56,7 @@ public class ListeningStoreAndForwardTest { sendingStream = sendingSocket.getOutputStream(); swissTimingFactory = SwissTimingFactory.INSTANCE; transceiver = swissTimingFactory.createSailMasterTransceiver(); - connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", CLIENT_PORT, null); + connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", CLIENT_PORT, null, /* canSendRequests */ false); DBCollection lastMessageCountCollection = db.getCollection(CollectionNames.LAST_MESSAGE_COUNT.name()); lastMessageCountCollection.update(new BasicDBObject(), new BasicDBObject().append(FieldNames.LAST_MESSAGE_COUNT.name(), 0l), /* upsert */ true, /* multi */ false); diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/OverlappingStoredAndReceivedMessagesTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/OverlappingStoredAndReceivedMessagesTest.java index 612d52145d4..c409f3001cc 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/OverlappingStoredAndReceivedMessagesTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/OverlappingStoredAndReceivedMessagesTest.java @@ -69,7 +69,7 @@ public class OverlappingStoredAndReceivedMessagesTest implements RaceSpecificMes }.start(); swissTimingFactory = SwissTimingFactory.INSTANCE; transceiver = swissTimingFactory.createSailMasterTransceiver(); - connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", PORT, this); + connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", PORT, this, /* canSendRequests */ false); synchronized (this) { while (sendingStream == null) { wait(); diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/SailMasterConnectivityTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/SailMasterConnectivityTest.java index 2d5e7f1875b..6be5fd7d881 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/SailMasterConnectivityTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/SailMasterConnectivityTest.java @@ -54,7 +54,7 @@ public class SailMasterConnectivityTest { Race race4712 = new RaceImpl("4712", "Not such a wonderful race"); swissTimingPersistence.storeRace(race4711); swissTimingPersistence.storeRace(race4712); - connector = SwissTimingFactory.INSTANCE.getOrCreateSailMasterConnector("localhost", port, swissTimingPersistence); + connector = SwissTimingFactory.INSTANCE.getOrCreateSailMasterConnector("localhost", port, swissTimingPersistence, /* canSendRequests */ true); connector.trackRace("W4702"); connector.trackRace(race4711.getRaceID()); connector.trackRace(race4712.getRaceID()); diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ScriptedStoreAndForwardTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ScriptedStoreAndForwardTest.java index f1a1dec6947..5ec3a0b0f43 100644 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ScriptedStoreAndForwardTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/ScriptedStoreAndForwardTest.java @@ -59,7 +59,7 @@ public class ScriptedStoreAndForwardTest { sendingStream = sendingSocket.getOutputStream(); swissTimingFactory = SwissTimingFactory.INSTANCE; transceiver = swissTimingFactory.createSailMasterTransceiver(); - connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", CLIENT_PORT, swissTimingAdapterPersistence); + connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", CLIENT_PORT, swissTimingAdapterPersistence, /* canSendRequests */ false); DBCollection lastMessageCountCollection = db.getCollection(CollectionNames.LAST_MESSAGE_COUNT.name()); lastMessageCountCollection.update(new BasicDBObject(), new BasicDBObject().append(FieldNames.LAST_MESSAGE_COUNT.name(), 0l), /* upsert */ true, /* multi */ false); diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/SwissTimingSailMasterLiveTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/SwissTimingSailMasterLiveTest.java index 2521fcdb0c8..e28dd975b74 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/SwissTimingSailMasterLiveTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/test/SwissTimingSailMasterLiveTest.java @@ -43,7 +43,8 @@ public class SwissTimingSailMasterLiveTest implements SailMasterListener { @Before public void connect() throws InterruptedException { - connector = SwissTimingFactory.INSTANCE.getOrCreateSailMasterConnector("gps.sportresult.com", 40300, SwissTimingAdapterPersistence.INSTANCE); + connector = SwissTimingFactory.INSTANCE.getOrCreateSailMasterConnector("gps.sportresult.com", 40300, + SwissTimingAdapterPersistence.INSTANCE, /* canSendRequests */true); } @After diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java index eb36f987a46..78427034e7d 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java @@ -34,14 +34,15 @@ public interface SwissTimingFactory { * {@link SailMasterConnector#trackRace} and {@link SailMasterConnector#stopTrackingRace} operations. * {@link MessageType#isRaceSpecific() Race-specific messages} for other races are ignored and not forwarded to any * listener. + * @param canSendRequests TODO */ - SailMasterConnector getOrCreateSailMasterConnector(String hostname, int port, RaceSpecificMessageLoader messageLoader) throws InterruptedException; + SailMasterConnector getOrCreateSailMasterConnector(String hostname, int port, RaceSpecificMessageLoader messageLoader, boolean canSendRequests) throws InterruptedException; SailMasterTransceiver createSailMasterTransceiver(); SwissTimingConfiguration createSwissTimingConfiguration(String name, String hostname, int port); - SwissTimingRaceTracker createRaceTracker(String raceID, String hostname, int port, WindStore windStore, RaceSpecificMessageLoader messageLoader, DomainFactory domainFactory, TrackedEventRegistry trackedEventRegistry) throws InterruptedException, UnknownHostException, IOException, ParseException; + SwissTimingRaceTracker createRaceTracker(String raceID, String hostname, int port, boolean canSendRequests, WindStore windStore, RaceSpecificMessageLoader messageLoader, DomainFactory domainFactory, TrackedEventRegistry trackedEventRegistry) throws InterruptedException, UnknownHostException, IOException, ParseException; Race createRace(String raceId, String description, TimePoint startTime); diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SailMasterConnectorImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SailMasterConnectorImpl.java index 24583318d47..6ae299481de 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SailMasterConnectorImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SailMasterConnectorImpl.java @@ -101,9 +101,11 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement * The only way known so far for how to find out the time zone relative to which the other time stamps * are to be interpreted is to start with the current default time zone's offset and wait for an * {@link MessageType#RPD RPD} event to be received. From this event, the time zone offset can be extracted - * and applied to all other time stamps. + * and applied to all other time stamps. It is stored using the race ID as key. */ - private String lastTimeZoneSuffix; + private final Map lastTimeZoneSuffixPerRaceID; + + private final Map startTimePerRaceID; /** * Used for the {@link #rendevouz(SailMasterMessage)} pattern. For each {@link MessageType} there @@ -118,20 +120,23 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement private final RaceSpecificMessageLoader messageLoader; - public SailMasterConnectorImpl(String host, int port, RaceSpecificMessageLoader messageLoader) throws InterruptedException { + private final boolean canSendRequests; + + public SailMasterConnectorImpl(String host, int port, RaceSpecificMessageLoader messageLoader, boolean canSendRequests) throws InterruptedException { super(); this.messageLoader = messageLoader; dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ"); idsOfTrackedRaces = new HashSet(); this.host = host; this.port = port; + this.canSendRequests = canSendRequests; this.listeners = new HashSet(); this.raceSpecificListeners = new HashMap>(); this.unprocessedMessagesByType = new HashMap>(); raceSpecificMessageBuffers = new HashMap>(); sequenceNumberOfLastMessageForRaceID = new HashMap(); - int offset = TimeZone.getDefault().getOffset(System.currentTimeMillis())/1000/3600; - lastTimeZoneSuffix = (offset<0?"-":"+") + new DecimalFormat("00").format(offset)+"00"; + lastTimeZoneSuffixPerRaceID = new HashMap(); + startTimePerRaceID = new HashMap(); receiverThread = new Thread(this, "SwissTiming SailMaster Receiver"); receiverThread.start(); synchronized (this) { @@ -437,9 +442,10 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement String[] sections = message.getSections(); String raceID = sections[1]; RaceStatus status = RaceStatus.values()[Integer.valueOf(sections[2])]; - TimePoint timePoint = new MillisecondsTimePoint(parseTimeAndDateISO(sections[3])); + TimePoint timePoint = new MillisecondsTimePoint(parseTimeAndDateISO(sections[3], raceID)); TimePoint startTimeEstimatedStartTime = sections[4].trim().length() == 0 ? null : new MillisecondsTimePoint( - parseTimePrefixedWithISOToday(sections[4])); + parseTimePrefixedWithISOToday(sections[4], raceID)); + startTimePerRaceID.put(raceID, startTimeEstimatedStartTime); Long millisecondsSinceRaceStart = sections[5].trim().length() == 0 ? null : parseHHMMSSToMilliseconds(sections[5]); Integer nextMarkIndexForLeader = sections[6].trim().length() == 0 ? null : Integer.valueOf(sections[6]); Distance distanceToNextMarkForLeader = sections[7].trim().length() == 0 ? null : new MeterDistance(Double.valueOf(sections[7])); @@ -576,12 +582,17 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement } } + private boolean canSendRequests() { + return canSendRequests; + } + @Override public Iterable getRaces() throws UnknownHostException, IOException, InterruptedException { - Iterable result; + Iterable result = null; if (messageLoader != null) { result = messageLoader.getRaces(); - } else { + } + if (result == null && canSendRequests()) { SailMasterMessage response = sendRequestAndGetResponse(MessageType.RAC); assertResponseType(MessageType.RAC, response); result = parseAvailableRacesMessage(response); @@ -620,17 +631,27 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement return new CourseImpl(courseConfigurationMessage.getSections()[1], marks); } - private String prefixTimeWithISOTodayAndSuffixWithTimezoneIndicator(String time) { + private String getLastTimeZoneSuffix(String raceID) { + String result = lastTimeZoneSuffixPerRaceID.get(raceID); + if (result == null) { + int offset = TimeZone.getDefault().getOffset(System.currentTimeMillis())/1000/3600; + result = (offset<0?"-":"+") + new DecimalFormat("00").format(offset)+"00"; + lastTimeZoneSuffixPerRaceID.put(raceID, result); + } + return result; + } + + private String prefixTimeWithISOTodayAndSuffixWithTimezoneIndicator(String time, String raceID) { synchronized (dateFormat) { - return dateFormat.format(new Date()).substring(0, "yyyy-mm-ddT".length())+time+lastTimeZoneSuffix; + return dateFormat.format(new Date()).substring(0, "yyyy-mm-ddT".length())+time+getLastTimeZoneSuffix(raceID); } } - private Date parseTimeAndDateISO(String timeAndDateISO) throws ParseException { + private Date parseTimeAndDateISO(String timeAndDateISO, String raceID) throws ParseException { char timeZoneIndicator = timeAndDateISO.charAt(timeAndDateISO.length()-6); if ((timeZoneIndicator == '+' || timeZoneIndicator == '-') && timeAndDateISO.charAt(timeAndDateISO.length()-3) == ':') { timeAndDateISO = timeAndDateISO.substring(0, timeAndDateISO.length()-3)+timeAndDateISO.substring(timeAndDateISO.length()-2); - lastTimeZoneSuffix = timeAndDateISO.substring(timeAndDateISO.length()-5); + lastTimeZoneSuffixPerRaceID.put(raceID, timeAndDateISO.substring(timeAndDateISO.length()-5)); } synchronized(dateFormat) { return dateFormat.parse(timeAndDateISO); @@ -698,16 +719,23 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement @Override public TimePoint getStartTime(String raceID) throws UnknownHostException, IOException, ParseException, InterruptedException { - SailMasterMessage response = sendRequestAndGetResponse(MessageType.STT, raceID); - String[] sections = response.getSections(); - assertResponseType(MessageType.STT, response); - assertRaceID(raceID, sections[1]); - return new MillisecondsTimePoint(parseTimePrefixedWithISOToday(sections[2])); + TimePoint result = null; + if (messageLoader != null) { + result = startTimePerRaceID.get(raceID); + } + if (result == null && canSendRequests()) { + SailMasterMessage response = sendRequestAndGetResponse(MessageType.STT, raceID); + String[] sections = response.getSections(); + assertResponseType(MessageType.STT, response); + assertRaceID(raceID, sections[1]); + result = new MillisecondsTimePoint(parseTimePrefixedWithISOToday(sections[2], raceID)); + } + return result; } - private Date parseTimePrefixedWithISOToday(String timeHHMMSS) throws ParseException { + private Date parseTimePrefixedWithISOToday(String timeHHMMSS, String raceID) throws ParseException { synchronized(dateFormat) { - return dateFormat.parse(prefixTimeWithISOTodayAndSuffixWithTimezoneIndicator(timeHHMMSS)); + return dateFormat.parse(prefixTimeWithISOTodayAndSuffixWithTimezoneIndicator(timeHHMMSS, raceID)); } } @@ -799,7 +827,7 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement String[] clockAtMarkDetail = clockAtMarkMessage.getSections()[3+i].split(";"); int markIndex = Integer.valueOf(clockAtMarkDetail[0]); TimePoint timePoint = clockAtMarkDetail.length <= 1 || clockAtMarkDetail[1].trim().length() == 0 ? null : - new MillisecondsTimePoint(parseTimePrefixedWithISOToday(clockAtMarkDetail[1])); + new MillisecondsTimePoint(parseTimePrefixedWithISOToday(clockAtMarkDetail[1], clockAtMarkMessage.getRaceID())); result.add(new Triple( markIndex, timePoint, clockAtMarkDetail.length <= 2 ? null : clockAtMarkDetail[2])); } diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java index fb0becfe065..59493bf199d 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java @@ -35,15 +35,15 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory { } @Override - public SailMasterConnector getOrCreateSailMasterConnector(String host, int port, RaceSpecificMessageLoader messageLoader) throws InterruptedException { + public SailMasterConnector getOrCreateSailMasterConnector(String host, int port, RaceSpecificMessageLoader messageLoader, boolean canSendRequests) throws InterruptedException { Triple key = new Triple(host, port, messageLoader); SailMasterConnector result = connectors.get(key); if (result == null) { - result = new SailMasterConnectorImpl(host, port, messageLoader); + result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests); connectors.put(key, result); // TODO how do connectors get stopped, terminated and removed from the connectors map again? } else if (result.isStopped()) { - result = new SailMasterConnectorImpl(host, port, messageLoader); + result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests); connectors.put(key, result); } return result; @@ -55,10 +55,12 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory { } @Override - public SwissTimingRaceTracker createRaceTracker(String raceID, String hostname, int port, WindStore windStore, - RaceSpecificMessageLoader messageLoader, DomainFactory domainFactory, TrackedEventRegistry trackedEventRegistry) - throws InterruptedException, UnknownHostException, IOException, ParseException { - return new SwissTimingRaceTrackerImpl(raceID, hostname, port, windStore, domainFactory, this, messageLoader, trackedEventRegistry); + public SwissTimingRaceTracker createRaceTracker(String raceID, String hostname, int port, boolean canSendRequests, + WindStore windStore, RaceSpecificMessageLoader messageLoader, DomainFactory domainFactory, TrackedEventRegistry trackedEventRegistry) + throws InterruptedException, UnknownHostException, IOException, + ParseException { + return new SwissTimingRaceTrackerImpl(raceID, hostname, port, windStore, domainFactory, this, messageLoader, + trackedEventRegistry, canSendRequests); } @Override diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java index d17fad9878e..62a2e00603b 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java @@ -67,8 +67,8 @@ public class SwissTimingRaceTrackerImpl implements SwissTimingRaceTracker, SailM protected SwissTimingRaceTrackerImpl(String raceID, String hostname, int port, WindStore windStore, DomainFactory domainFactory, SwissTimingFactory factory, RaceSpecificMessageLoader messageLoader, - TrackedEventRegistry trackedEventRegistry) throws InterruptedException, UnknownHostException, IOException, ParseException { - this.connector = factory.getOrCreateSailMasterConnector(hostname, port, messageLoader); + TrackedEventRegistry trackedEventRegistry, boolean canSendRequests) throws InterruptedException, UnknownHostException, IOException, ParseException { + this.connector = factory.getOrCreateSailMasterConnector(hostname, port, messageLoader, canSendRequests); this.domainFactory = domainFactory; this.raceID = raceID; this.messageLoader = messageLoader; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index 60caef829e7..12b39514f8f 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -108,10 +108,10 @@ public interface SailingService extends RemoteService { List getPreviousSwissTimingConfigurations(); - List listSwissTimingRaces(String hostname, int port) throws Exception; + List listSwissTimingRaces(String hostname, int port, boolean canSendRequests) throws Exception; void storeSwissTimingConfiguration(String a, String hostname, int port); - void trackWithSwissTiming(SwissTimingRaceRecordDAO rr, String hostname, int port, boolean trackWind, - boolean correctWindByDeclination) throws Exception; + void trackWithSwissTiming(SwissTimingRaceRecordDAO rr, String hostname, int port, boolean canSendRequests, + boolean trackWind, boolean correctWindByDeclination) throws Exception; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index bb69808451d..31aef3fa4ce 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -162,10 +162,11 @@ public interface SailingServiceAsync { void getPreviousSwissTimingConfigurations(AsyncCallback> asyncCallback); - void listSwissTimingRaces(String hostname, int port, AsyncCallback> asyncCallback); + void listSwissTimingRaces(String hostname, int port, boolean canSendRequests, + AsyncCallback> asyncCallback); void storeSwissTimingConfiguration(String a, String hostname, int port, AsyncCallback asyncCallback); - void trackWithSwissTiming(SwissTimingRaceRecordDAO rr, String hostname, int port, boolean trackWind, - boolean correctWindByDeclination, AsyncCallback asyncCallback); + void trackWithSwissTiming(SwissTimingRaceRecordDAO rr, String hostname, int port, boolean canSendRequests, + boolean trackWind, boolean correctWindByDeclination, AsyncCallback asyncCallback); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SwissTimingEventManagementPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SwissTimingEventManagementPanel.java index b56f3744483..1be07f1034c 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SwissTimingEventManagementPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SwissTimingEventManagementPanel.java @@ -267,7 +267,8 @@ public class SwissTimingEventManagementPanel extends FormPanel implements EventD private void fillRaces(final SailingServiceAsync sailingService) { final String hostname = hostnameTextbox.getValue(); final int port = portIntegerbox.getValue(); - sailingService.listSwissTimingRaces(hostname, port, new AsyncCallback>() { + sailingService.listSwissTimingRaces(hostname, port, /* TODO canSendRequests */ false, + new AsyncCallback>() { @Override public void onFailure(Throwable caught) { SwissTimingEventManagementPanel.this.errorReporter.reportError("Error trying to list races: " @@ -309,7 +310,8 @@ public class SwissTimingEventManagementPanel extends FormPanel implements EventD int port = portIntegerbox.getValue(); for (final SwissTimingRaceRecordDAO rr : raceList.getList()) { if (raceTable.getSelectionModel().isSelected(rr)) { - sailingService.trackWithSwissTiming(rr, hostname, port, trackWind, correctWindByDeclination, new AsyncCallback() { + sailingService.trackWithSwissTiming(rr, hostname, port, /* TODO canSendRequests */false, trackWind, + correctWindByDeclination, new AsyncCallback() { @Override public void onFailure(Throwable caught) { errorReporter.reportError("Error trying to register race " + rr.ID + " for tracking: " diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 13bfc4e16f8..7382bb428f4 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -1018,10 +1018,10 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS } @Override - public List listSwissTimingRaces(String hostname, int port) + public List listSwissTimingRaces(String hostname, int port, boolean canSendRequests) throws UnknownHostException, IOException, InterruptedException, ParseException { List result = new ArrayList(); - for (com.sap.sailing.domain.swisstimingadapter.RaceRecord rr : getService().getSwissTimingRaceRecords(hostname, port)) { + for (com.sap.sailing.domain.swisstimingadapter.RaceRecord rr : getService().getSwissTimingRaceRecords(hostname, port, canSendRequests)) { result.add(new SwissTimingRaceRecordDAO(rr.getRaceID(), rr.getDescription(), rr.getStartTime())); } return result; @@ -1033,9 +1033,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS } @Override - public void trackWithSwissTiming(SwissTimingRaceRecordDAO rr, String hostname, int port, boolean trackWind, - final boolean correctWindByDeclination) throws Exception { - final RaceHandle raceHandle = getService().addSwissTimingRace(rr.ID, hostname, port, + public void trackWithSwissTiming(SwissTimingRaceRecordDAO rr, String hostname, int port, boolean canSendRequests, + boolean trackWind, final boolean correctWindByDeclination) throws Exception { + final RaceHandle raceHandle = getService().addSwissTimingRace(rr.ID, hostname, port, canSendRequests, MongoWindStoreFactory.INSTANCE.getMongoWindStore(mongoObjectFactory, domainObjectFactory), TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); if (trackWind) { diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventService.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventService.java index 1ad12492ecb..2bd02317a3a 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventService.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventService.java @@ -138,7 +138,7 @@ public interface RacingEventService extends TrackedEventRegistry { Pair> getTracTracRaceRecords(URL jsonURL) throws IOException, ParseException, org.json.simple.parser.ParseException, URISyntaxException; - List getSwissTimingRaceRecords(String hostname, int port) + List getSwissTimingRaceRecords(String hostname, int port, boolean canSendRequests) throws InterruptedException, UnknownHostException, IOException, ParseException; boolean isRaceBeingTracked(RaceDefinition r); @@ -180,8 +180,8 @@ public interface RacingEventService extends TrackedEventRegistry { */ void updateStoredLeaderboard(Leaderboard leaderboard); - RaceHandle addSwissTimingRace(String raceID, String hostname, int port, WindStore windStore, - long timeoutInMilliseconds) throws InterruptedException, UnknownHostException, IOException, ParseException; + RaceHandle addSwissTimingRace(String raceID, String hostname, int port, boolean canSendRequests, + WindStore windStore, long timeoutInMilliseconds) throws InterruptedException, UnknownHostException, IOException, ParseException; SwissTimingFactory getSwissTimingFactory(); diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventServiceImpl.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventServiceImpl.java index b036b9cf104..a881fd36eef 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventServiceImpl.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventServiceImpl.java @@ -235,24 +235,26 @@ public class RacingEventServiceImpl implements RacingEventService { @Override public List getSwissTimingRaceRecords(String hostname, - int port) throws InterruptedException, UnknownHostException, IOException, ParseException { + int port, boolean canSendRequests) throws InterruptedException, UnknownHostException, IOException, ParseException { List result = new ArrayList(); - SailMasterConnector swissTimingConnector = swissTimingFactory.getOrCreateSailMasterConnector(hostname, port, swissTimingAdapterPersistence); + SailMasterConnector swissTimingConnector = swissTimingFactory.getOrCreateSailMasterConnector(hostname, port, swissTimingAdapterPersistence, + canSendRequests); for (Race race : swissTimingConnector.getRaces()) { TimePoint startTime = swissTimingConnector.getStartTime(race.getRaceID()); - result.add(new com.sap.sailing.domain.swisstimingadapter.RaceRecord(race.getRaceID(), race.getDescription(), startTime.asDate())); + result.add(new com.sap.sailing.domain.swisstimingadapter.RaceRecord(race.getRaceID(), race.getDescription(), + startTime==null?null:startTime.asDate())); } return result; } @Override - public synchronized RaceHandle addSwissTimingRace(String raceID, String hostname, int port, WindStore windStore, - long timeoutInMilliseconds) throws InterruptedException, UnknownHostException, IOException, ParseException { + public synchronized RaceHandle addSwissTimingRace(String raceID, String hostname, int port, boolean canSendRequests, + WindStore windStore, long timeoutInMilliseconds) throws InterruptedException, UnknownHostException, IOException, ParseException { Triple key = new Triple(raceID, hostname, port); RaceTracker tracker = raceTrackersByID.get(key); if (tracker == null) { - tracker = getSwissTimingFactory().createRaceTracker(raceID, hostname, port, windStore, - swissTimingAdapterPersistence, swissTimingDomainFactory, this); + tracker = getSwissTimingFactory().createRaceTracker(raceID, hostname, port, canSendRequests, + windStore, swissTimingAdapterPersistence, swissTimingDomainFactory, this); raceTrackersByID.put(tracker.getID(), tracker); Set trackers = raceTrackersByEvent.get(tracker.getEvent()); if (trackers == null) {