fixed swiss timing tests

This commit is contained in:
Axel Uhl
2011-11-11 18:14:09 +01:00
parent b33335251a
commit 4d6b68fcd9
14 changed files with 154 additions and 33 deletions
@@ -22,7 +22,7 @@ public interface SwissTimingAdapterPersistence extends RaceSpecificMessageLoader
*
* @return messages in ascending sequence number order; always a valid but perhaps empty list
*/
List<SailMasterMessage> loadMessages(int firstSequenceNumber);
List<SailMasterMessage> loadCommandMessages(int firstSequenceNumber);
/**
* Loads all command messages (not race specific) received and stored to the DB.
@@ -91,13 +91,13 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers
}
@Override
public List<SailMasterMessage> loadMessages(int firstSequenceNumber) {
DBCollection rawMessages = database.getCollection(CollectionNames.RAW_MESSAGES.name());
public List<SailMasterMessage> loadCommandMessages(int firstSequenceNumber) {
DBCollection commandMessages = database.getCollection(CollectionNames.COMMAND_MESSAGES.name());
BasicDBObject query = new BasicDBObject();
if (firstSequenceNumber != -1) {
query.append(FieldNames.MESSAGE_SEQUENCE_NUMBER.name(), new BasicDBObject("$gte", firstSequenceNumber));
}
DBCursor results = rawMessages.find(query);
DBCursor results = commandMessages.find(query);
List<SailMasterMessage> result = new ArrayList<SailMasterMessage>();
for (DBObject o : results) {
result.add(swissTimingFactory.createMessage((String) o.get(FieldNames.MESSAGE_CONTENT.name()),
@@ -141,6 +141,7 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers
}
@Override
public Race getRace(String raceID) {
DBCollection races = database.getCollection(CollectionNames.RACES_MASTERDATA.name());
@@ -158,6 +159,7 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers
return null;
}
@Override
public Iterable<Race> getRaces() {
DBCollection races = database.getCollection(CollectionNames.RACES_MASTERDATA.name());
@@ -69,7 +69,7 @@ public class OverlappingStoredAndReceivedMessagesTest implements RaceSpecificMes
}.start();
swissTimingFactory = SwissTimingFactory.INSTANCE;
transceiver = swissTimingFactory.createSailMasterTransceiver();
connector = swissTimingFactory.createSailMasterConnector("localhost", PORT, this);
connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", PORT, this);
synchronized (this) {
while (sendingStream == null) {
wait();
@@ -202,5 +202,10 @@ public class OverlappingStoredAndReceivedMessagesTest implements RaceSpecificMes
return null;
}
@Override
public Race getRace(String raceID) {
// TODO Auto-generated method stub
return null;
}
}
@@ -47,7 +47,7 @@ public class SailMasterConnectivityTest {
@Before
public void setUp() throws InterruptedException, ParseException {
startSailMasterDummy();
connector = SwissTimingFactory.INSTANCE.createSailMasterConnector("localhost", port, SwissTimingAdapterPersistence.INSTANCE);
connector = SwissTimingFactory.INSTANCE.getOrCreateSailMasterConnector("localhost", port, SwissTimingAdapterPersistence.INSTANCE);
connector.trackRace("W4702");
connector.trackRace("4711");
connector.trackRace("4712");
@@ -53,7 +53,7 @@ public class StoreAndForwardTest {
sendingStream = sendingSocket.getOutputStream();
swissTimingFactory = SwissTimingFactory.INSTANCE;
transceiver = swissTimingFactory.createSailMasterTransceiver();
connector = swissTimingFactory.createSailMasterConnector("localhost", CLIENT_PORT, null);
connector = swissTimingFactory.getOrCreateSailMasterConnector("localhost", CLIENT_PORT, null);
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);
@@ -97,7 +97,7 @@ public class StoreAndForwardTest {
DBCollection lastMessageCountCollection = db.getCollection(CollectionNames.LAST_MESSAGE_COUNT.name());
Long lastMessageCount = (Long) lastMessageCountCollection.findOne().get(FieldNames.LAST_MESSAGE_COUNT.name());
assertEquals((Long) 1l, lastMessageCount);
List<SailMasterMessage> rawMessages = swissTimingAdapterPersistence.loadMessages(0);
List<SailMasterMessage> rawMessages = swissTimingAdapterPersistence.loadCommandMessages(0);
assertEquals(1, rawMessages.size());
assertEquals(rawMessage, rawMessages.get(0).getMessage());
assertEquals(0l, (long) rawMessages.get(0).getSequenceNumber());
@@ -43,7 +43,7 @@ public class SwissTimingSailMasterLiveTest implements SailMasterListener {
@Before
public void connect() throws InterruptedException {
connector = SwissTimingFactory.INSTANCE.createSailMasterConnector("gps.sportresult.com", 40300, SwissTimingAdapterPersistence.INSTANCE);
connector = SwissTimingFactory.INSTANCE.getOrCreateSailMasterConnector("gps.sportresult.com", 40300, SwissTimingAdapterPersistence.INSTANCE);
}
@After
@@ -6,6 +6,7 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: com.sap.sailing.domain,
com.sap.sailing.udpconnector
com.sap.sailing.udpconnector,
org.eclipse.osgi;bundle-version="3.7.1"
Export-Package: com.sap.sailing.domain.swisstimingadapter,
com.sap.sailing.domain.swisstimingadapter.impl;x-friends:="com.sap.sailing.domain.swisstimingadapter.test"
@@ -19,4 +19,6 @@ public interface RaceSpecificMessageLoader {
List<SailMasterMessage> loadRaceMessages(String raceID);
Iterable<Race> getRaces();
Race getRace(String raceID);
}
@@ -48,6 +48,12 @@ public interface SailMasterConnector {
*/
void addSailMasterListener(SailMasterListener listener) throws UnknownHostException, IOException;
/**
* Like {@link #addSailMasterListener(SailMasterListener)}, but only forwards race-specific events for the
* race identified by <code>raceID</code> to the <code>listener</code>
*/
void addSailMasterListener(String raceID, SailMasterListener listener) throws UnknownHostException, IOException;
void removeSailMasterListener(SailMasterListener listener);
SailMasterMessage receiveMessage(MessageType type) throws InterruptedException;
@@ -80,4 +86,8 @@ public interface SailMasterConnector {
void trackRace(String raceID) throws ParseException;
void stopTrackingRace(String raceID);
void removeSailMasterListener(String raceID, SailMasterListener listener);
boolean isStopped();
}
@@ -1,5 +1,8 @@
package com.sap.sailing.domain.swisstimingadapter;
import java.io.IOException;
import java.net.UnknownHostException;
import com.sap.sailing.domain.base.TimePoint;
import com.sap.sailing.domain.swisstimingadapter.impl.SwissTimingFactoryImpl;
import com.sap.sailing.domain.tracking.WindStore;
@@ -9,13 +12,13 @@ public interface SwissTimingFactory {
SwissTimingMessageParser createMessageParser();
SailMasterConnector createSailMasterConnector(String hostname, int port, RaceSpecificMessageLoader messageLoader) throws InterruptedException;
SailMasterConnector getOrCreateSailMasterConnector(String hostname, int port, RaceSpecificMessageLoader messageLoader) throws InterruptedException;
SailMasterTransceiver createSailMasterTransceiver();
SwissTimingConfiguration createSwissTimingConfiguration(String name, String hostname, int port);
SwissTimingRaceTracker createRaceTracker(String raceID, String hostname, int port, WindStore windStore, RaceSpecificMessageLoader messageLoader) throws InterruptedException;
SwissTimingRaceTracker createRaceTracker(String raceID, String hostname, int port, WindStore windStore, RaceSpecificMessageLoader messageLoader) throws InterruptedException, UnknownHostException, IOException;
Race createRace(String raceId, String description, TimePoint startTime);
@@ -79,6 +79,7 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
private Socket socket;
private final DateFormat dateFormat;
private final Set<SailMasterListener> listeners;
private final Map<String, Set<SailMasterListener>> raceSpecificListeners;
private final Thread receiverThread;
private boolean stopped;
private boolean connected;
@@ -110,7 +111,7 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
private final Map<String, Long> sequenceNumberOfLastMessageForRaceID;
private final RaceSpecificMessageLoader messageLoader;
public SailMasterConnectorImpl(String host, int port, RaceSpecificMessageLoader messageLoader) throws InterruptedException {
super();
this.messageLoader = messageLoader;
@@ -119,6 +120,7 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
this.host = host;
this.port = port;
this.listeners = new HashSet<SailMasterListener>();
this.raceSpecificListeners = new HashMap<String, Set<SailMasterListener>>();
this.unprocessedMessagesByType = new HashMap<MessageType, BlockingQueue<SailMasterMessage>>();
raceSpecificMessageBuffers = new HashMap<String, List<SailMasterMessage>>();
sequenceNumberOfLastMessageForRaceID = new HashMap<String, Long>();
@@ -417,16 +419,43 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
socket = null;
}
@Override
public boolean isStopped() {
return stopped;
}
@Override
public void addSailMasterListener(SailMasterListener listener) throws UnknownHostException, IOException {
ensureSocketIsOpen();
listeners.add(listener);
}
@Override
public synchronized void addSailMasterListener(String raceID, SailMasterListener listener) throws UnknownHostException, IOException {
ensureSocketIsOpen();
Set<SailMasterListener> set = raceSpecificListeners.get(raceID);
if (set == null) {
set = new HashSet<SailMasterListener>();
raceSpecificListeners.put(raceID, set);
}
set.add(listener);
}
@Override
public void removeSailMasterListener(SailMasterListener listener) {
listeners.remove(listener);
}
@Override
public synchronized void removeSailMasterListener(String raceID, SailMasterListener listener) {
Set<SailMasterListener> set = raceSpecificListeners.get(raceID);
if (set != null) {
set.remove(listener);
if (set.isEmpty()) {
raceSpecificListeners.remove(raceID);
}
}
}
public SailMasterMessage sendRequestAndGetResponse(MessageType messageType, String... args) throws UnknownHostException, IOException, InterruptedException {
ensureSocketIsOpen();
@@ -1,5 +1,11 @@
package com.sap.sailing.domain.swisstimingadapter.impl;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import com.sap.sailing.domain.base.TimePoint;
import com.sap.sailing.domain.swisstimingadapter.Race;
import com.sap.sailing.domain.swisstimingadapter.RaceSpecificMessageLoader;
@@ -11,8 +17,14 @@ import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessageParser;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingRaceTracker;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.util.Util.Triple;
public class SwissTimingFactoryImpl implements SwissTimingFactory {
private final Map<Triple<String, Integer, RaceSpecificMessageLoader>, SailMasterConnector> connectors;
public SwissTimingFactoryImpl() {
connectors = new HashMap<Triple<String, Integer, RaceSpecificMessageLoader>, SailMasterConnector>();
}
@Override
public SwissTimingMessageParser createMessageParser() {
@@ -20,8 +32,18 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory {
}
@Override
public SailMasterConnector createSailMasterConnector(String host, int port, RaceSpecificMessageLoader messageLoader) throws InterruptedException {
return new SailMasterConnectorImpl(host, port, messageLoader);
public SailMasterConnector getOrCreateSailMasterConnector(String host, int port, RaceSpecificMessageLoader messageLoader) throws InterruptedException {
Triple<String, Integer, RaceSpecificMessageLoader> key = new Triple<String, Integer, RaceSpecificMessageLoader>(host, port, messageLoader);
SailMasterConnector result = connectors.get(key);
if (result == null) {
result = new SailMasterConnectorImpl(host, port, messageLoader);
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);
connectors.put(key, result);
}
return result;
}
@Override
@@ -31,7 +53,7 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory {
@Override
public SwissTimingRaceTracker createRaceTracker(String raceID, String hostname, int port, WindStore windStore,
RaceSpecificMessageLoader messageLoader) throws InterruptedException {
RaceSpecificMessageLoader messageLoader) throws InterruptedException, UnknownHostException, IOException {
return new SwissTimingRaceTrackerImpl(raceID, hostname, port, this, messageLoader);
}
@@ -2,13 +2,25 @@ package com.sap.sailing.domain.swisstimingadapter.impl;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.sap.sailing.domain.base.Distance;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.TimePoint;
import com.sap.sailing.domain.base.impl.EventImpl;
import com.sap.sailing.domain.swisstimingadapter.Course;
import com.sap.sailing.domain.swisstimingadapter.Fix;
import com.sap.sailing.domain.swisstimingadapter.Race;
import com.sap.sailing.domain.swisstimingadapter.RaceSpecificMessageLoader;
import com.sap.sailing.domain.swisstimingadapter.RaceStatus;
import com.sap.sailing.domain.swisstimingadapter.SailMasterConnector;
import com.sap.sailing.domain.swisstimingadapter.SailMasterListener;
import com.sap.sailing.domain.swisstimingadapter.StartList;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingRaceTracker;
import com.sap.sailing.domain.tracking.DynamicTrackedEvent;
@@ -16,29 +28,23 @@ import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.util.Util.Triple;
public class SwissTimingRaceTrackerImpl implements SwissTimingRaceTracker {
public class SwissTimingRaceTrackerImpl implements SwissTimingRaceTracker, SailMasterListener {
private final SailMasterConnector connector;
private final RaceDefinition race;
private RaceDefinition race;
private final String raceID;
private final RaceSpecificMessageLoader messageLoader;
protected SwissTimingRaceTrackerImpl(String raceID, String hostname, int port, SwissTimingFactory factory,
RaceSpecificMessageLoader messageLoader) throws InterruptedException {
connector = factory.createSailMasterConnector(hostname, port, messageLoader);
/*
connector.addSailMasterListener(new SailMasterAdapter() {
@Override
public void receivedAvailableRaces(Iterable<Race> races) {
}
});
*/
// TODO fix race after having created it
race = null;
RaceSpecificMessageLoader messageLoader) throws InterruptedException, UnknownHostException, IOException {
this.connector = factory.getOrCreateSailMasterConnector(hostname, port, messageLoader);
this.raceID = raceID;
this.messageLoader = messageLoader;
connector.addSailMasterListener(this);
}
@Override
public void stop() throws MalformedURLException, IOException, InterruptedException {
connector.stop();
connector.removeSailMasterListener(raceID, this);
}
@Override
@@ -76,4 +82,45 @@ public class SwissTimingRaceTrackerImpl implements SwissTimingRaceTracker {
return null;
}
@Override
public void receivedRacePositionData(String raceID, RaceStatus status, TimePoint timePoint, TimePoint startTime,
Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader, Distance distanceToNextMarkForLeader,
Collection<Fix> fixes) {
// TODO Auto-generated method stub
}
@Override
public void receivedTimingData(String raceID, String boatID,
List<Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds) {
// TODO Auto-generated method stub
}
@Override
public void receivedClockAtMark(String raceID,
List<Triple<Integer, TimePoint, String>> markIndicesTimePointsAndBoatIDs) {
// TODO Auto-generated method stub
}
@Override
public void receivedStartList(String raceID, StartList startList) {
// now we can create the RaceDefinition and most other things
Race race = messageLoader.getRace(raceID);
// Event event = new EventImpl(name, boatClass)
}
@Override
public void receivedCourseConfiguration(String raceID, Course course) {
// TODO Auto-generated method stub
}
@Override
public void receivedAvailableRaces(Iterable<Race> races) {
// TODO Auto-generated method stub
}
}
@@ -1025,7 +1025,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
throws UnknownHostException, IOException, InterruptedException, ParseException {
List<SwissTimingRaceRecordDAO> result = new ArrayList<SwissTimingRaceRecordDAO>();
// FIXME can't rely on the connector being able to send a request; perhaps need to extract from SwissTiming persistence
SailMasterConnector swissTimingConnector = swissTimingFactory.createSailMasterConnector(hostname, port, swissTimingAdapterPersistence);
SailMasterConnector swissTimingConnector = swissTimingFactory.getOrCreateSailMasterConnector(hostname, port, swissTimingAdapterPersistence);
for (Race race : swissTimingConnector.getRaces()) {
TimePoint startTime = swissTimingConnector.getStartTime(race.getRaceID());
result.add(new SwissTimingRaceRecordDAO(race.getRaceID(), race.getDescription(), startTime.asDate()));