bug 4354: added persistence for ExpeditionDeviceConfiguration objects

Change-Id: I48ec066e22259f0701eff6daee522599d90741a1
This commit is contained in:
Axel Uhl
2017-10-26 11:17:53 +02:00
parent 4a376979fd
commit cf4a8975be
30 changed files with 270 additions and 44 deletions
@@ -8,7 +8,11 @@ Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0" Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: com.sap.sailing.domain.persistence, Require-Bundle: com.sap.sailing.domain.persistence,
com.sap.sailing.expeditionconnector,
com.sap.sailing.domain.shared.android, com.sap.sailing.domain.shared.android,
com.sap.sailing.domain.common, com.sap.sailing.domain.common,
com.sap.sse.common com.sap.sse.common,
com.sap.sse.mongodb,
org.mongodb.mongo-java-driver;bundle-version="2.13.0",
com.sap.sailing.expeditionconnector.common,
com.sap.sailing.server.gateway.serialization.shared.android
Export-Package: com.sap.sailing.expeditionconnector.persistence
@@ -0,0 +1,7 @@
package com.sap.sailing.expeditionconnector.persistence;
import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration;
public interface DomainObjectFactory {
Iterable<ExpeditionDeviceConfiguration> getExpeditionDeviceConfigurations();
}
@@ -1,8 +1,9 @@
package com.sap.sailing.expeditionconnector; package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID; import java.util.UUID;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration;
public interface ExpeditionDeviceIdentifier extends DeviceIdentifier { public interface ExpeditionDeviceIdentifier extends DeviceIdentifier {
/** /**
@@ -1,10 +1,10 @@
package com.sap.sailing.expeditionconnector; package com.sap.sailing.expeditionconnector.persistence;
/** /**
* A device identifier used to identify an installation of the regatta tool "Expedition" * A device identifier used to identify an installation of the regatta tool "Expedition"
* regarding its basic GPS information. * regarding its basic GPS information.
* *
* @author Fredrik Teschke * @author Axel Uhl (d043530)
* *
*/ */
public interface ExpeditionGpsDeviceIdentifier extends ExpeditionDeviceIdentifier { public interface ExpeditionGpsDeviceIdentifier extends ExpeditionDeviceIdentifier {
@@ -1,8 +1,8 @@
package com.sap.sailing.expeditionconnector.impl; package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID; import java.util.UUID;
import com.sap.sailing.expeditionconnector.ExpeditionGpsDeviceIdentifier; import com.sap.sailing.expeditionconnector.persistence.impl.AbstractExpeditionDeviceIdentifierImpl;
public class ExpeditionGpsDeviceIdentifierImpl extends AbstractExpeditionDeviceIdentifierImpl implements ExpeditionGpsDeviceIdentifier { public class ExpeditionGpsDeviceIdentifierImpl extends AbstractExpeditionDeviceIdentifierImpl implements ExpeditionGpsDeviceIdentifier {
private static final long serialVersionUID = -4049961972156611640L; private static final long serialVersionUID = -4049961972156611640L;
@@ -1,4 +1,4 @@
package com.sap.sailing.expeditionconnector.impl; package com.sap.sailing.expeditionconnector.persistence;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException; import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
@@ -1,10 +1,9 @@
package com.sap.sailing.expeditionconnector.impl; package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID; import java.util.UUID;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException; import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionGpsDeviceIdentifier;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
public class ExpeditionGpsDeviceIdentifierSerializationHandler { public class ExpeditionGpsDeviceIdentifierSerializationHandler {
@@ -1,10 +1,10 @@
package com.sap.sailing.expeditionconnector; package com.sap.sailing.expeditionconnector.persistence;
/** /**
* A device identifier used to identify an installation of the regatta tool "Expedition" * A device identifier used to identify an installation of the regatta tool "Expedition"
* regarding its sensor data beyond the basic GPS and wind information. * regarding its sensor data beyond the basic GPS and wind information.
* *
* @author Axel Uhl * @author Axel Uhl (d043530)
* *
*/ */
public interface ExpeditionSensorDeviceIdentifier extends ExpeditionDeviceIdentifier { public interface ExpeditionSensorDeviceIdentifier extends ExpeditionDeviceIdentifier {
@@ -1,8 +1,8 @@
package com.sap.sailing.expeditionconnector.impl; package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID; import java.util.UUID;
import com.sap.sailing.expeditionconnector.ExpeditionSensorDeviceIdentifier; import com.sap.sailing.expeditionconnector.persistence.impl.AbstractExpeditionDeviceIdentifierImpl;
public class ExpeditionSensorDeviceIdentifierImpl extends AbstractExpeditionDeviceIdentifierImpl implements ExpeditionSensorDeviceIdentifier { public class ExpeditionSensorDeviceIdentifierImpl extends AbstractExpeditionDeviceIdentifierImpl implements ExpeditionSensorDeviceIdentifier {
private static final long serialVersionUID = -4049961972156611640L; private static final long serialVersionUID = -4049961972156611640L;
@@ -1,10 +1,9 @@
package com.sap.sailing.expeditionconnector.impl; package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID; import java.util.UUID;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException; import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionSensorDeviceIdentifier;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
public class ExpeditionSensorDeviceIdentifierSerializationHandler { public class ExpeditionSensorDeviceIdentifierSerializationHandler {
@@ -0,0 +1,9 @@
package com.sap.sailing.expeditionconnector.persistence;
import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration;
public interface MongoObjectFactory {
void storeExpeditionDeviceConfiguration(ExpeditionDeviceConfiguration expeditionDeviceConfiguration);
void removeExpeditionDeviceConfiguration(ExpeditionDeviceConfiguration expeditionDeviceConfiguration);
}
@@ -0,0 +1,23 @@
package com.sap.sailing.expeditionconnector.persistence;
import com.sap.sailing.expeditionconnector.persistence.impl.PersistenceFactoryImpl;
import com.sap.sse.mongodb.MongoDBConfiguration;
import com.sap.sse.mongodb.MongoDBService;
public interface PersistenceFactory {
PersistenceFactory INSTANCE = new PersistenceFactoryImpl();
/**
* Obtains the domain object factory using the default persistence settings from {@link MongoDBConfiguration#getDefaultConfiguration()}.
*/
DomainObjectFactory getDefaultDomainObjectFactory();
DomainObjectFactory getDomainObjectFactory(MongoDBService mongoDbService);
/**
* Obtains the Mongo object factory using the default persistence settings from {@link MongoDBConfiguration#getDefaultConfiguration()}.
*/
MongoObjectFactory getDefaultMongoObjectFactory();
MongoObjectFactory getMongoObjectFactory(MongoDBService mongoDbService);
}
@@ -1,8 +1,8 @@
package com.sap.sailing.expeditionconnector.impl; package com.sap.sailing.expeditionconnector.persistence.impl;
import java.util.UUID; import java.util.UUID;
import com.sap.sailing.expeditionconnector.ExpeditionDeviceIdentifier; import com.sap.sailing.expeditionconnector.persistence.ExpeditionDeviceIdentifier;
public abstract class AbstractExpeditionDeviceIdentifierImpl implements ExpeditionDeviceIdentifier { public abstract class AbstractExpeditionDeviceIdentifierImpl implements ExpeditionDeviceIdentifier {
private static final long serialVersionUID = -6605059302775505785L; private static final long serialVersionUID = -6605059302775505785L;
@@ -10,9 +10,10 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration; import org.osgi.framework.ServiceRegistration;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler; import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.expeditionconnector.ExpeditionGpsDeviceIdentifier; import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionSensorDeviceIdentifier; import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifier;
import com.sap.sse.common.TypeBasedServiceFinder; import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.mongodb.MongoDBService;
public class Activator implements BundleActivator { public class Activator implements BundleActivator {
@@ -36,6 +37,9 @@ public class Activator implements BundleActivator {
Activator.context = bundleContext; Activator.context = bundleContext;
registrations.add(context.registerService(DeviceIdentifierMongoHandler.class, new ExpeditionGpsDeviceIdentifierMongoHandler(), getDict(ExpeditionGpsDeviceIdentifier.TYPE))); registrations.add(context.registerService(DeviceIdentifierMongoHandler.class, new ExpeditionGpsDeviceIdentifierMongoHandler(), getDict(ExpeditionGpsDeviceIdentifier.TYPE)));
registrations.add(context.registerService(DeviceIdentifierMongoHandler.class, new ExpeditionSensorDeviceIdentifierMongoHandler(), getDict(ExpeditionSensorDeviceIdentifier.TYPE))); registrations.add(context.registerService(DeviceIdentifierMongoHandler.class, new ExpeditionSensorDeviceIdentifierMongoHandler(), getDict(ExpeditionSensorDeviceIdentifier.TYPE)));
for (CollectionNames name : CollectionNames.values()) {
MongoDBService.INSTANCE.registerExclusively(CollectionNames.class, name.name());
}
} }
/* /*
@@ -0,0 +1,5 @@
package com.sap.sailing.expeditionconnector.persistence.impl;
public enum CollectionNames {
EXPEDITION_DEVICE_CONFIGURATIONS;
}
@@ -0,0 +1,35 @@
package com.sap.sailing.expeditionconnector.persistence.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration;
import com.sap.sailing.expeditionconnector.persistence.DomainObjectFactory;
public class DomainObjectFactoryImpl implements DomainObjectFactory {
private final DB db;
public DomainObjectFactoryImpl(DB db) {
this.db = db;
}
@Override
public Iterable<ExpeditionDeviceConfiguration> getExpeditionDeviceConfigurations() {
final List<ExpeditionDeviceConfiguration> result = new ArrayList<>();
final DBCollection expeditionDeviceConfigurationsCollection = db.getCollection(CollectionNames.EXPEDITION_DEVICE_CONFIGURATIONS.name());
for (final Object o : expeditionDeviceConfigurationsCollection.find()) {
final DBObject dbo = (DBObject) o;
final UUID uuid = (UUID) dbo.get(FieldNames.EXPEDITION_DEVICE_CONFIGURATION_UUID.name());
final String name = (String) dbo.get(FieldNames.EXPEDITION_DEVICE_CONFIGURATION_NAME.name());
final Number boatIdAsNumber = (Number) dbo.get(FieldNames.EXPEDITION_DEVICE_CONFIGURATION_BOAT_ID.name());
final Integer boatId = boatIdAsNumber == null ? null : boatIdAsNumber.intValue();
result.add(new ExpeditionDeviceConfiguration(name, uuid, boatId));
}
return result;
}
}
@@ -3,7 +3,7 @@ package com.sap.sailing.expeditionconnector.persistence.impl;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException; import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler; import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.expeditionconnector.impl.ExpeditionGpsDeviceIdentifierSerializationHandler; import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifierSerializationHandler;
public class ExpeditionGpsDeviceIdentifierMongoHandler extends ExpeditionGpsDeviceIdentifierSerializationHandler public class ExpeditionGpsDeviceIdentifierMongoHandler extends ExpeditionGpsDeviceIdentifierSerializationHandler
implements DeviceIdentifierMongoHandler { implements DeviceIdentifierMongoHandler {
@@ -3,7 +3,7 @@ package com.sap.sailing.expeditionconnector.persistence.impl;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException; import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler; import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.expeditionconnector.impl.ExpeditionSensorDeviceIdentifierSerializationHandler; import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifierSerializationHandler;
public class ExpeditionSensorDeviceIdentifierMongoHandler extends ExpeditionSensorDeviceIdentifierSerializationHandler public class ExpeditionSensorDeviceIdentifierMongoHandler extends ExpeditionSensorDeviceIdentifierSerializationHandler
implements DeviceIdentifierMongoHandler { implements DeviceIdentifierMongoHandler {
@@ -0,0 +1,5 @@
package com.sap.sailing.expeditionconnector.persistence.impl;
public enum FieldNames {
EXPEDITION_DEVICE_CONFIGURATION_NAME, EXPEDITION_DEVICE_CONFIGURATION_UUID, EXPEDITION_DEVICE_CONFIGURATION_BOAT_ID;
}
@@ -0,0 +1,59 @@
package com.sap.sailing.expeditionconnector.persistence.impl;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.WriteConcern;
import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration;
import com.sap.sailing.expeditionconnector.persistence.MongoObjectFactory;
public class MongoObjectFactoryImpl implements MongoObjectFactory {
private static final Logger logger = Logger.getLogger(MongoObjectFactoryImpl.class.getName());
private final DBCollection expeditionDeviceConfigurationsCollection;
public MongoObjectFactoryImpl(DB db) {
this.expeditionDeviceConfigurationsCollection = db.getCollection(CollectionNames.EXPEDITION_DEVICE_CONFIGURATIONS.name());
DBObject index = new BasicDBObject();
index.put(FieldNames.EXPEDITION_DEVICE_CONFIGURATION_UUID.name(), 1);
expeditionDeviceConfigurationsCollection.createIndex(index, new BasicDBObject("unique", true));
}
private BasicDBObject getExpeditionDeviceConfigurationDBKey(ExpeditionDeviceConfiguration expeditionDeviceConfiguration) {
final BasicDBObject basicDBObject = new BasicDBObject(FieldNames.EXPEDITION_DEVICE_CONFIGURATION_UUID.name(), expeditionDeviceConfiguration.getDeviceUuid());
return basicDBObject;
}
@Override
public void storeExpeditionDeviceConfiguration(ExpeditionDeviceConfiguration expeditionDeviceConfiguration) {
final BasicDBObject key = getExpeditionDeviceConfigurationDBKey(expeditionDeviceConfiguration);
final DBObject expeditionDeviceConfigurationDBObject = new BasicDBObject();
expeditionDeviceConfigurationDBObject.put(FieldNames.EXPEDITION_DEVICE_CONFIGURATION_UUID.name(), expeditionDeviceConfiguration.getDeviceUuid());
expeditionDeviceConfigurationDBObject.put(FieldNames.EXPEDITION_DEVICE_CONFIGURATION_NAME.name(), expeditionDeviceConfiguration.getName());
expeditionDeviceConfigurationDBObject.put(FieldNames.EXPEDITION_DEVICE_CONFIGURATION_BOAT_ID.name(), expeditionDeviceConfiguration.getExpeditionBoatId());
boolean success = false;
int attempt = 0;
Exception lastException = null;
while (attempt < 5 && !success) {
try {
expeditionDeviceConfigurationsCollection.update(key, expeditionDeviceConfigurationDBObject, /* upsert */ true, /* multi */ false, WriteConcern.SAFE);
success = true;
attempt++;
} catch (Exception e) {
lastException = e;
logger.log(Level.WARNING, "Exception trying to write Expedition device configuration. Trying again", e);
}
}
if (!success) {
throw new RuntimeException("Couldn't store Expedition device configuration "+expeditionDeviceConfiguration, lastException);
}
}
@Override
public void removeExpeditionDeviceConfiguration(ExpeditionDeviceConfiguration expeditionDeviceConfiguration) {
expeditionDeviceConfigurationsCollection.remove(getExpeditionDeviceConfigurationDBKey(expeditionDeviceConfiguration), WriteConcern.SAFE);
}
}
@@ -0,0 +1,31 @@
package com.sap.sailing.expeditionconnector.persistence.impl;
import com.sap.sailing.expeditionconnector.persistence.DomainObjectFactory;
import com.sap.sailing.expeditionconnector.persistence.MongoObjectFactory;
import com.sap.sailing.expeditionconnector.persistence.PersistenceFactory;
import com.sap.sse.mongodb.MongoDBConfiguration;
import com.sap.sse.mongodb.MongoDBService;
public class PersistenceFactoryImpl implements PersistenceFactory {
@Override
public DomainObjectFactory getDomainObjectFactory(MongoDBService mongoDbService) {
return new DomainObjectFactoryImpl(mongoDbService.getDB());
}
@Override
public MongoObjectFactory getMongoObjectFactory(MongoDBService mongoDbService) {
return new MongoObjectFactoryImpl(mongoDbService.getDB());
}
@Override
public DomainObjectFactory getDefaultDomainObjectFactory() {
return getDomainObjectFactory(MongoDBConfiguration.getDefaultConfiguration().getService());
}
@Override
public MongoObjectFactory getDefaultMongoObjectFactory() {
return getMongoObjectFactory(MongoDBConfiguration.getDefaultConfiguration().getService());
}
}
@@ -15,7 +15,8 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sse, com.sap.sse,
com.sap.sailing.domain.shared.android, com.sap.sailing.domain.shared.android,
com.sap.sailing.server.gateway.serialization.shared.android, com.sap.sailing.server.gateway.serialization.shared.android,
com.sap.sailing.expeditionconnector.common com.sap.sailing.expeditionconnector.common,
com.sap.sailing.expeditionconnector.persistence
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Import-Package: org.osgi.framework, Import-Package: org.osgi.framework,
org.osgi.util.tracker;version="1.5.1" org.osgi.util.tracker;version="1.5.1"
@@ -1,6 +1,8 @@
package com.sap.sailing.expeditionconnector; package com.sap.sailing.expeditionconnector;
import com.sap.sailing.domain.racelog.tracking.SensorFixStore; import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifier;
/** /**
* Makes accessible a mapping from "Expedition" boat IDs to device UUIDs. * Makes accessible a mapping from "Expedition" boat IDs to device UUIDs.
@@ -24,8 +24,13 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.WindTracker; import com.sap.sailing.domain.tracking.WindTracker;
import com.sap.sailing.domain.tracking.WindTrackerFactory; import com.sap.sailing.domain.tracking.WindTrackerFactory;
import com.sap.sailing.expeditionconnector.impl.Activator; import com.sap.sailing.expeditionconnector.impl.Activator;
import com.sap.sailing.expeditionconnector.impl.ExpeditionGpsDeviceIdentifierImpl; import com.sap.sailing.expeditionconnector.persistence.DomainObjectFactory;
import com.sap.sailing.expeditionconnector.impl.ExpeditionSensorDeviceIdentifierImpl; import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifierImpl;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifierImpl;
import com.sap.sailing.expeditionconnector.persistence.MongoObjectFactory;
import com.sap.sailing.expeditionconnector.persistence.PersistenceFactory;
public class ExpeditionTrackerFactory implements WindTrackerFactory, DeviceRegistry { public class ExpeditionTrackerFactory implements WindTrackerFactory, DeviceRegistry {
private static Logger logger = Logger.getLogger(ExpeditionTrackerFactory.class.getName()); private static Logger logger = Logger.getLogger(ExpeditionTrackerFactory.class.getName());
@@ -66,23 +71,31 @@ public class ExpeditionTrackerFactory implements WindTrackerFactory, DeviceRegis
private ServiceTracker<SensorFixStoreSupplier, SensorFixStoreSupplier> sensorFixServiceTracker; private ServiceTracker<SensorFixStoreSupplier, SensorFixStoreSupplier> sensorFixServiceTracker;
public ExpeditionTrackerFactory(SensorFixStore sensorFixStore) { private final MongoObjectFactory mongoObjectFactory;
public ExpeditionTrackerFactory(SensorFixStore sensorFixStore, DomainObjectFactory domainObjectFactory, MongoObjectFactory mongoObjectFactory) {
this.windTrackers = new HashMap<RaceDefinition, WindTracker>(); this.windTrackers = new HashMap<RaceDefinition, WindTracker>();
this.sensorFixStore = sensorFixStore; this.sensorFixStore = sensorFixStore;
windReceivers = new HashMap<Integer, UDPExpeditionReceiver>(); windReceivers = new HashMap<Integer, UDPExpeditionReceiver>();
final Activator activator = Activator.getInstance(); final Activator activator = Activator.getInstance();
defaultPort = activator.getExpeditionUDPPort(); defaultPort = activator.getExpeditionUDPPort();
deviceConfigurations = new ConcurrentHashMap<>(); // TODO add persistence; these need to be loaded from the DB deviceConfigurations = new ConcurrentHashMap<>();
devicesPerBoatId = new ConcurrentHashMap<>(); devicesPerBoatId = new ConcurrentHashMap<>();
final BundleContext context = activator.getContext(); final BundleContext context = activator.getContext();
this.mongoObjectFactory = mongoObjectFactory;
for (final ExpeditionDeviceConfiguration expeditionDeviceConfigurationLoadedFromDB : domainObjectFactory.getExpeditionDeviceConfigurations()) {
addOrReplaceDeviceConfigurationNoPersistence(expeditionDeviceConfigurationLoadedFromDB);
}
if (context != null) { if (context != null) {
startListeningForSensorFixStoreSuppliers(context); sensorFixServiceTracker = startListeningForSensorFixStoreSuppliers(context);
} else {
sensorFixServiceTracker = null;
} }
logger.info("Created "+getClass().getName()+" with default UDP port "+defaultPort); logger.info("Created "+getClass().getName()+" with default UDP port "+defaultPort);
} }
private void startListeningForSensorFixStoreSuppliers(BundleContext context) { private ServiceTracker<SensorFixStoreSupplier, SensorFixStoreSupplier> startListeningForSensorFixStoreSuppliers(BundleContext context) {
sensorFixServiceTracker = new ServiceTracker<>(context, SensorFixStoreSupplier.class, final ServiceTracker<SensorFixStoreSupplier, SensorFixStoreSupplier> result = new ServiceTracker<>(context, SensorFixStoreSupplier.class,
new ServiceTrackerCustomizer<SensorFixStoreSupplier, SensorFixStoreSupplier>() { new ServiceTrackerCustomizer<SensorFixStoreSupplier, SensorFixStoreSupplier>() {
@Override @Override
public SensorFixStoreSupplier addingService(ServiceReference<SensorFixStoreSupplier> reference) { public SensorFixStoreSupplier addingService(ServiceReference<SensorFixStoreSupplier> reference) {
@@ -106,20 +119,22 @@ public class ExpeditionTrackerFactory implements WindTrackerFactory, DeviceRegis
} }
} }
}); });
sensorFixServiceTracker.open(); result.open();
return result;
} }
public synchronized static ExpeditionTrackerFactory getInstance() { public synchronized static ExpeditionTrackerFactory getInstance() {
return getInstance(/* sensorFixStore */ null); return getInstance(/* sensorFixStore */ null, PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(),
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory());
} }
/** /**
* Use this constructor in non-OSGi scenarios such as plain JUnit test environments where the * Use this constructor in non-OSGi scenarios such as plain JUnit test environments where the
* {@link SensorFixStoreSupplier} cannot be discovered through the registry. * {@link SensorFixStoreSupplier} cannot be discovered through the registry.
*/ */
public static ExpeditionTrackerFactory getInstance(SensorFixStore sensorFixStore) { public static ExpeditionTrackerFactory getInstance(SensorFixStore sensorFixStore, DomainObjectFactory domainObjectFactory, MongoObjectFactory mongoObjectFactory) {
if (defaultInstance == null) { if (defaultInstance == null) {
defaultInstance = new ExpeditionTrackerFactory(sensorFixStore); defaultInstance = new ExpeditionTrackerFactory(sensorFixStore, domainObjectFactory, mongoObjectFactory);
} }
return defaultInstance; return defaultInstance;
} }
@@ -189,6 +204,11 @@ public class ExpeditionTrackerFactory implements WindTrackerFactory, DeviceRegis
} }
public void addOrReplaceDeviceConfiguration(ExpeditionDeviceConfiguration deviceConfiguration) { public void addOrReplaceDeviceConfiguration(ExpeditionDeviceConfiguration deviceConfiguration) {
addOrReplaceDeviceConfigurationNoPersistence(deviceConfiguration);
mongoObjectFactory.storeExpeditionDeviceConfiguration(deviceConfiguration);
}
private void addOrReplaceDeviceConfigurationNoPersistence(ExpeditionDeviceConfiguration deviceConfiguration) {
if (deviceConfiguration.getExpeditionBoatId() != null && if (deviceConfiguration.getExpeditionBoatId() != null &&
devicesPerBoatId.containsKey(deviceConfiguration.getExpeditionBoatId()) && devicesPerBoatId.containsKey(deviceConfiguration.getExpeditionBoatId()) &&
!devicesPerBoatId.get(deviceConfiguration.getExpeditionBoatId()).equals(deviceConfiguration)) { !devicesPerBoatId.get(deviceConfiguration.getExpeditionBoatId()).equals(deviceConfiguration)) {
@@ -211,6 +231,7 @@ public class ExpeditionTrackerFactory implements WindTrackerFactory, DeviceRegis
if (deviceConfiguration.getExpeditionBoatId() != null) { if (deviceConfiguration.getExpeditionBoatId() != null) {
devicesPerBoatId.remove(deviceConfiguration.getExpeditionBoatId()); devicesPerBoatId.remove(deviceConfiguration.getExpeditionBoatId());
} }
mongoObjectFactory.removeExpeditionDeviceConfiguration(deviceConfiguration);
} }
@Override @Override
@@ -9,6 +9,8 @@ import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.racelog.tracking.SensorFixStore; import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
import com.sap.sailing.expeditionconnector.impl.ExpeditionMessageParser; import com.sap.sailing.expeditionconnector.impl.ExpeditionMessageParser;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifier;
import com.sap.sailing.udpconnector.UDPReceiver; import com.sap.sailing.udpconnector.UDPReceiver;
/** /**
@@ -4,6 +4,8 @@ import java.util.Dictionary;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -13,11 +15,16 @@ import org.osgi.framework.ServiceRegistration;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler; import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
import com.sap.sailing.domain.tracking.WindTrackerFactory; import com.sap.sailing.domain.tracking.WindTrackerFactory;
import com.sap.sailing.expeditionconnector.ExpeditionGpsDeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionSensorDeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionTrackerFactory; import com.sap.sailing.expeditionconnector.ExpeditionTrackerFactory;
import com.sap.sailing.expeditionconnector.persistence.DomainObjectFactory;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifierJsonHandler;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.MongoObjectFactory;
import com.sap.sailing.expeditionconnector.persistence.PersistenceFactory;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler; import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
import com.sap.sse.common.TypeBasedServiceFinder; import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.util.impl.ThreadFactoryWithPriority;
public class Activator implements BundleActivator { public class Activator implements BundleActivator {
private static Logger logger = Logger.getLogger(Activator.class.getName()); private static Logger logger = Logger.getLogger(Activator.class.getName());
@@ -37,6 +44,8 @@ public class Activator implements BundleActivator {
private BundleContext context; private BundleContext context;
private final ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactoryWithPriority(Thread.NORM_PRIORITY, /* daemon */ true));
public Activator() { public Activator() {
port = Integer.valueOf(System.getProperty(EXPEDITION_UDP_PORT_PROPERTY_NAME, ""+DEFAULT_PORT)); port = Integer.valueOf(System.getProperty(EXPEDITION_UDP_PORT_PROPERTY_NAME, ""+DEFAULT_PORT));
logger.log(Level.INFO, "setting default for "+EXPEDITION_UDP_PORT_PROPERTY_NAME+" to "+port); logger.log(Level.INFO, "setting default for "+EXPEDITION_UDP_PORT_PROPERTY_NAME+" to "+port);
@@ -59,13 +68,20 @@ public class Activator implements BundleActivator {
logger.log(Level.INFO, "found "+EXPEDITION_UDP_PORT_PROPERTY_NAME+"="+port+" in OSGi context"); logger.log(Level.INFO, "found "+EXPEDITION_UDP_PORT_PROPERTY_NAME+"="+port+" in OSGi context");
} }
// register the Expedition wind tracker factory as an OSGi service // register the Expedition wind tracker factory as an OSGi service
registrations.add(context.registerService(ExpeditionTrackerFactory.class, ExpeditionTrackerFactory.getInstance(), /* properties */null)); final DomainObjectFactory domainObjectFactory = PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory();
registrations.add(context.registerService(WindTrackerFactory.class, ExpeditionTrackerFactory.getInstance(), /* properties */null)); final MongoObjectFactory mongoObjectFactory = PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory();
executor.execute(()->{
registrations.add(context.registerService(DeviceIdentifierJsonHandler.class, new ExpeditionGpsDeviceIdentifierJsonHandler(), getDict(ExpeditionGpsDeviceIdentifier.TYPE))); logger.info("Creating ExpeditionTrackerFactory");
registrations.add(context.registerService(DeviceIdentifierStringSerializationHandler.class, new ExpeditionGpsStringSerializationHandler(), getDict(ExpeditionGpsDeviceIdentifier.TYPE))); final ExpeditionTrackerFactory expeditionTrackerFactory = new ExpeditionTrackerFactory(
registrations.add(context.registerService(DeviceIdentifierJsonHandler.class, new ExpeditionSensorDeviceIdentifierJsonHandler(), getDict(ExpeditionSensorDeviceIdentifier.TYPE))); /* sensorFixStore will be discovered by tracker factory through OSGi */ null, domainObjectFactory, mongoObjectFactory);
registrations.add(context.registerService(DeviceIdentifierStringSerializationHandler.class, new ExpeditionSensorStringSerializationHandler(), getDict(ExpeditionSensorDeviceIdentifier.TYPE))); registrations.add(context.registerService(ExpeditionTrackerFactory.class, expeditionTrackerFactory, /* properties */null));
registrations.add(context.registerService(WindTrackerFactory.class, expeditionTrackerFactory, /* properties */null));
registrations.add(context.registerService(DeviceIdentifierJsonHandler.class, new ExpeditionGpsDeviceIdentifierJsonHandler(), getDict(ExpeditionGpsDeviceIdentifier.TYPE)));
registrations.add(context.registerService(DeviceIdentifierStringSerializationHandler.class, new ExpeditionGpsStringSerializationHandler(), getDict(ExpeditionGpsDeviceIdentifier.TYPE)));
registrations.add(context.registerService(DeviceIdentifierJsonHandler.class, new ExpeditionSensorDeviceIdentifierJsonHandler(), getDict(ExpeditionSensorDeviceIdentifier.TYPE)));
registrations.add(context.registerService(DeviceIdentifierStringSerializationHandler.class, new ExpeditionSensorStringSerializationHandler(), getDict(ExpeditionSensorDeviceIdentifier.TYPE)));
});
} }
public static Activator getInstance() { public static Activator getInstance() {
@@ -1,6 +1,7 @@
package com.sap.sailing.expeditionconnector.impl; package com.sap.sailing.expeditionconnector.impl;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler; import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifierSerializationHandler;
public class ExpeditionGpsStringSerializationHandler extends ExpeditionGpsDeviceIdentifierSerializationHandler public class ExpeditionGpsStringSerializationHandler extends ExpeditionGpsDeviceIdentifierSerializationHandler
implements DeviceIdentifierStringSerializationHandler { implements DeviceIdentifierStringSerializationHandler {
@@ -2,6 +2,7 @@ package com.sap.sailing.expeditionconnector.impl;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException; import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifierSerializationHandler;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler; import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
public class ExpeditionSensorDeviceIdentifierJsonHandler extends ExpeditionSensorDeviceIdentifierSerializationHandler public class ExpeditionSensorDeviceIdentifierJsonHandler extends ExpeditionSensorDeviceIdentifierSerializationHandler
@@ -1,6 +1,7 @@
package com.sap.sailing.expeditionconnector.impl; package com.sap.sailing.expeditionconnector.impl;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler; import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifierSerializationHandler;
public class ExpeditionSensorStringSerializationHandler extends ExpeditionSensorDeviceIdentifierSerializationHandler public class ExpeditionSensorStringSerializationHandler extends ExpeditionSensorDeviceIdentifierSerializationHandler
implements DeviceIdentifierStringSerializationHandler { implements DeviceIdentifierStringSerializationHandler {
@@ -3512,7 +3512,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
private Iterable<WindTrackerFactory> getWindTrackerFactories() { private Iterable<WindTrackerFactory> getWindTrackerFactories() {
final Set<WindTrackerFactory> result; final Set<WindTrackerFactory> result;
if (bundleContext == null) { // the non-OSGi case if (bundleContext == null) { // the non-OSGi case
result = Collections.singleton((WindTrackerFactory) ExpeditionTrackerFactory.getInstance(getSensorFixStore())); result = Collections.singleton((WindTrackerFactory) ExpeditionTrackerFactory.getInstance());
} else { } else {
ServiceTracker<WindTrackerFactory, WindTrackerFactory> tracker = new ServiceTracker<WindTrackerFactory, WindTrackerFactory>( ServiceTracker<WindTrackerFactory, WindTrackerFactory> tracker = new ServiceTracker<WindTrackerFactory, WindTrackerFactory>(
bundleContext, WindTrackerFactory.class, null); bundleContext, WindTrackerFactory.class, null);