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
Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: com.sap.sailing.domain.persistence,
com.sap.sailing.expeditionconnector,
com.sap.sailing.domain.shared.android,
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();
}
@@ -0,0 +1,13 @@
package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration;
public interface ExpeditionDeviceIdentifier extends DeviceIdentifier {
/**
* Derived from an {@link ExpeditionDeviceConfiguration#getDeviceUuid()}.
*/
UUID getId();
}
@@ -0,0 +1,12 @@
package com.sap.sailing.expeditionconnector.persistence;
/**
* A device identifier used to identify an installation of the regatta tool "Expedition"
* regarding its basic GPS information.
*
* @author Axel Uhl (d043530)
*
*/
public interface ExpeditionGpsDeviceIdentifier extends ExpeditionDeviceIdentifier {
public static final String TYPE = "EXPEDITION_GPS";
}
@@ -0,0 +1,18 @@
package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID;
import com.sap.sailing.expeditionconnector.persistence.impl.AbstractExpeditionDeviceIdentifierImpl;
public class ExpeditionGpsDeviceIdentifierImpl extends AbstractExpeditionDeviceIdentifierImpl implements ExpeditionGpsDeviceIdentifier {
private static final long serialVersionUID = -4049961972156611640L;
public ExpeditionGpsDeviceIdentifierImpl(UUID id) {
super(id);
}
@Override
public String getIdentifierType() {
return ExpeditionGpsDeviceIdentifier.TYPE;
}
}
@@ -0,0 +1,16 @@
package com.sap.sailing.expeditionconnector.persistence;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
public class ExpeditionGpsDeviceIdentifierJsonHandler extends ExpeditionGpsDeviceIdentifierSerializationHandler
implements DeviceIdentifierJsonHandler {
@Override
public DeviceIdentifier deserialize(Object serialized, String type, String stringRepresentation)
throws TransformationException {
return deserialize((String) serialized, type, stringRepresentation);
}
}
@@ -0,0 +1,27 @@
package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sse.common.Util;
public class ExpeditionGpsDeviceIdentifierSerializationHandler {
private ExpeditionGpsDeviceIdentifier castIdentifier(DeviceIdentifier identifier) throws TransformationException {
if (!(identifier instanceof ExpeditionGpsDeviceIdentifier))
throw new TransformationException("Expected a ExpeditionGpsDeviceIdentifier, got instead: " + identifier);
return (ExpeditionGpsDeviceIdentifier) identifier;
}
public Util.Pair<String, String> serialize(DeviceIdentifier deviceIdentifier) throws TransformationException {
return new Util.Pair<String, String>(ExpeditionGpsDeviceIdentifier.TYPE, castIdentifier(deviceIdentifier).getId().toString());
}
public DeviceIdentifier deserialize(String input, String type, String stringRep) throws TransformationException {
try {
return new ExpeditionGpsDeviceIdentifierImpl(UUID.fromString(input));
} catch (IllegalArgumentException e) {
throw new TransformationException("Invalid string representation of smartphone UUID", e);
}
}
}
@@ -0,0 +1,12 @@
package com.sap.sailing.expeditionconnector.persistence;
/**
* A device identifier used to identify an installation of the regatta tool "Expedition"
* regarding its sensor data beyond the basic GPS and wind information.
*
* @author Axel Uhl (d043530)
*
*/
public interface ExpeditionSensorDeviceIdentifier extends ExpeditionDeviceIdentifier {
public static final String TYPE = "EXPEDITION_SENSOR";
}
@@ -0,0 +1,18 @@
package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID;
import com.sap.sailing.expeditionconnector.persistence.impl.AbstractExpeditionDeviceIdentifierImpl;
public class ExpeditionSensorDeviceIdentifierImpl extends AbstractExpeditionDeviceIdentifierImpl implements ExpeditionSensorDeviceIdentifier {
private static final long serialVersionUID = -4049961972156611640L;
public ExpeditionSensorDeviceIdentifierImpl(UUID id) {
super(id);
}
@Override
public String getIdentifierType() {
return ExpeditionSensorDeviceIdentifier.TYPE;
}
}
@@ -0,0 +1,27 @@
package com.sap.sailing.expeditionconnector.persistence;
import java.util.UUID;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sse.common.Util;
public class ExpeditionSensorDeviceIdentifierSerializationHandler {
private ExpeditionSensorDeviceIdentifier castIdentifier(DeviceIdentifier identifier) throws TransformationException {
if (!(identifier instanceof ExpeditionSensorDeviceIdentifier))
throw new TransformationException("Expected a ExpeditionSensorDeviceIdentifier, got instead: " + identifier);
return (ExpeditionSensorDeviceIdentifier) identifier;
}
public Util.Pair<String, String> serialize(DeviceIdentifier deviceIdentifier) throws TransformationException {
return new Util.Pair<String, String>(ExpeditionSensorDeviceIdentifier.TYPE, castIdentifier(deviceIdentifier).getId().toString());
}
public DeviceIdentifier deserialize(String input, String type, String stringRep) throws TransformationException {
try {
return new ExpeditionSensorDeviceIdentifierImpl(UUID.fromString(input));
} catch (IllegalArgumentException e) {
throw new TransformationException("Invalid string representation of smartphone UUID", e);
}
}
}
@@ -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);
}
@@ -0,0 +1,37 @@
package com.sap.sailing.expeditionconnector.persistence.impl;
import java.util.UUID;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionDeviceIdentifier;
public abstract class AbstractExpeditionDeviceIdentifierImpl implements ExpeditionDeviceIdentifier {
private static final long serialVersionUID = -6605059302775505785L;
private final UUID id;
public AbstractExpeditionDeviceIdentifierImpl(UUID id) {
super();
this.id = id;
}
@Override
public String getStringRepresentation() {
return id.toString();
}
@Override
public UUID getId() {
return id;
}
@Override
public boolean equals(Object obj) {
return (obj instanceof ExpeditionDeviceIdentifier) &&
((ExpeditionDeviceIdentifier) obj).getIdentifierType().equals(getIdentifierType()) &&
((ExpeditionDeviceIdentifier) obj).getId().equals(getId());
}
@Override
public int hashCode() {
return 9478 ^ getIdentifierType().hashCode() ^ getId().hashCode();
}
}
@@ -10,9 +10,10 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.expeditionconnector.ExpeditionGpsDeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionSensorDeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdentifier;
import com.sap.sailing.expeditionconnector.persistence.ExpeditionSensorDeviceIdentifier;
import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.mongodb.MongoDBService;
public class Activator implements BundleActivator {
@@ -36,6 +37,9 @@ public class Activator implements BundleActivator {
Activator.context = bundleContext;
registrations.add(context.registerService(DeviceIdentifierMongoHandler.class, new ExpeditionGpsDeviceIdentifierMongoHandler(), getDict(ExpeditionGpsDeviceIdentifier.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.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
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
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.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
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
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());
}
}