Merge branch 'foiling' of ssh://sapsailing.com/home/trac/git into foiling

This commit is contained in:
Papick Garcia Taboada
2016-05-04 12:52:55 +02:00
13 changed files with 217 additions and 37 deletions
@@ -35,6 +35,7 @@ import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonH
import com.sap.sailing.server.gateway.serialization.racelog.tracking.impl.GPSFixJsonHandlerImpl;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.impl.SmartphoneUUIDJsonHandler;
import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.replication.Replicable;
import com.sap.sse.util.ServiceTrackerFactory;
public class Activator implements BundleActivator {
@@ -87,14 +88,14 @@ public class Activator implements BundleActivator {
registrations.add(context.registerService(SensorFixMapper.class, new BravoDataFixMapper(), null));
sensorFixMapperTracker = (ServiceTracker) ServiceTrackerFactory.createAndOpen(context, SensorFixMapper.class);
racingEventServiceTracker = ServiceTrackerFactory.createAndOpen(
context,
RacingEventService.class);
racingEventServiceTracker = ServiceTrackerFactory.createAndOpen(context, RacingEventService.class);
RegattaLogSensorDataTrackerTrackedRegattaListener regattaLogSensorDataTrackerTrackedRegattaListener = new RegattaLogSensorDataTrackerTrackedRegattaListener(
racingEventServiceTracker, new SensorFixMapperFactoryImpl(sensorFixMapperTracker));
registrations.add(context.registerService(TrackedRegattaListener.class,
new RegattaLogSensorDataTrackerTrackedRegattaListener(racingEventServiceTracker,
new SensorFixMapperFactoryImpl(sensorFixMapperTracker)), null));
regattaLogSensorDataTrackerTrackedRegattaListener, null));
registrations.add(context.registerService(Replicable.class,
regattaLogSensorDataTrackerTrackedRegattaListener, null));
logger.log(Level.INFO, "Started "+context.getBundle().getSymbolicName());
}
@@ -59,9 +59,7 @@ public class RegattaLogSensorDataTracker {
public synchronized void stop() {
trackedRegatta.removeRaceListener(raceListener);
knownTrackedRaces.keySet().forEach(raceIdentifier -> {
removeRaceLogSensorDataTracker(raceIdentifier);
});
knownTrackedRaces.keySet().forEach(this::removeRaceLogSensorDataTracker);
knownTrackedRaces.clear();
dataTrackers.clear();
}
@@ -73,4 +71,10 @@ public class RegattaLogSensorDataTracker {
dataTrackers.remove(currentActiveDataTracker);
}
}
@Override
public String toString() {
return "RegattaLogSensorDataTracker [regattaId=" + trackedRegatta.getRegatta().getId() + "]";
}
}
@@ -1,8 +1,17 @@
package com.sap.sailing.domain.racelogtracking.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.osgi.util.tracker.ServiceTracker;
@@ -12,12 +21,18 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackedRegattaListener;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.replication.OperationExecutionListener;
import com.sap.sse.replication.OperationWithResult;
import com.sap.sse.replication.ReplicationMasterDescriptor;
import com.sap.sse.replication.impl.OperationWithResultWithIdWrapper;
import com.sap.sse.replication.impl.ReplicableWithObjectInputStream;
public class RegattaLogSensorDataTrackerTrackedRegattaListener implements TrackedRegattaListener {
private static final Logger log = Logger.getLogger(RegattaLogSensorDataTrackerTrackedRegattaListener.class
.getName());
private final Map<Serializable, TrackedRegatta> knownRegattas = new ConcurrentHashMap<Serializable, TrackedRegatta>();
private final Map<Serializable, RegattaLogSensorDataTracker> registeredTrackers = new ConcurrentHashMap<Serializable, RegattaLogSensorDataTracker>();
public class RegattaLogSensorDataTrackerTrackedRegattaListener implements TrackedRegattaListener,
ReplicableWithObjectInputStream<RegattaLogSensorDataTrackerTrackedRegattaListener, OperationWithResult<RegattaLogSensorDataTrackerTrackedRegattaListener, ?>> {
private static final Logger log = Logger.getLogger(RegattaLogSensorDataTrackerTrackedRegattaListener.class.getName());
private final Map<Serializable, RegattaLogSensorDataTracker> registeredTrackers = new HashMap<>();
private final ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker;
private final SensorFixMapperFactory sensorFixMapperFactory;
@@ -29,34 +44,124 @@ public class RegattaLogSensorDataTrackerTrackedRegattaListener implements Tracke
}
@Override
public void regattaAdded(TrackedRegatta trackedRegatta) {
Serializable regattaId = trackedRegatta.getRegatta().getId();
if (knownRegattas.putIfAbsent(regattaId, trackedRegatta) == null) {
synchronized (knownRegattas) {
RegattaLogSensorDataTracker tracker = null;
tracker = new RegattaLogSensorDataTracker((DynamicTrackedRegatta) trackedRegatta,
racingEventServiceTracker.getService().getSensorFixStore(), sensorFixMapperFactory);
registeredTrackers.put(regattaId, tracker);
log.fine("Added sensor data tracker to tracked regatta: " + trackedRegatta.getRegatta().getName());
}
public synchronized void regattaAdded(TrackedRegatta trackedRegatta) {
final Serializable regattaId = trackedRegatta.getRegatta().getId();
if (!isReplica) {
RegattaLogSensorDataTracker tracker = new RegattaLogSensorDataTracker((DynamicTrackedRegatta)
trackedRegatta, racingEventServiceTracker.getService().getSensorFixStore(), sensorFixMapperFactory);
this.stopIfNotNull(registeredTrackers.put(regattaId, tracker));
log.fine("Added sensor data tracker to tracked regatta: " + trackedRegatta.getRegatta().getName());
} else {
log.warning("Regatta already known, not adding sensor twice");
}
}
@Override
public void regattaRemoved(TrackedRegatta trackedRegatta) {
synchronized (knownRegattas) {
Serializable regattaId = trackedRegatta.getRegatta().getId();
public synchronized void regattaRemoved(TrackedRegatta trackedRegatta) {
final Serializable regattaId = trackedRegatta.getRegatta().getId();
try {
this.stopIfNotNull(registeredTrackers.get(regattaId));
} finally {
registeredTrackers.remove(regattaId);
}
}
private void stopIfNotNull(RegattaLogSensorDataTracker tracker) {
if (tracker != null) {
try {
RegattaLogSensorDataTracker tracker = registeredTrackers.get(trackedRegatta.getRegatta().getId());
if (tracker != null) {
tracker.stop();
}
} finally {
knownRegattas.remove(regattaId);
registeredTrackers.remove(regattaId);
tracker.stop();
} catch (Exception exc) {
log.log(Level.SEVERE, "Stopping of tracker failed: " + tracker, exc);
}
}
}
// Replication related methods and fields
private final ConcurrentHashMap<OperationExecutionListener<RegattaLogSensorDataTrackerTrackedRegattaListener>, OperationExecutionListener<RegattaLogSensorDataTrackerTrackedRegattaListener>> operationExecutionListeners = new ConcurrentHashMap<>();
private final ThreadLocal<Boolean> currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster = ThreadLocal.withInitial(() -> false);
private final Set<OperationWithResultWithIdWrapper<RegattaLogSensorDataTrackerTrackedRegattaListener, ?>> operationsSentToMasterForReplication = new HashSet<>();
private ReplicationMasterDescriptor master;
private boolean isReplica = false;
@Override
public Serializable getId() {
return getClass().getName();
}
@Override
public ReplicationMasterDescriptor getMasterDescriptor() {
return master;
}
@Override
public void startedReplicatingFrom(ReplicationMasterDescriptor master) {
this.master = master;
}
@Override
public void stoppedReplicatingFrom(ReplicationMasterDescriptor master) {
this.master = null;
}
@Override
public Iterable<OperationExecutionListener<RegattaLogSensorDataTrackerTrackedRegattaListener>> getOperationExecutionListeners() {
return operationExecutionListeners.keySet();
}
@Override
public void addOperationExecutionListener(
OperationExecutionListener<RegattaLogSensorDataTrackerTrackedRegattaListener> listener) {
this.operationExecutionListeners.put(listener, listener);
}
@Override
public void removeOperationExecutionListener(
OperationExecutionListener<RegattaLogSensorDataTrackerTrackedRegattaListener> listener) {
this.operationExecutionListeners.remove(listener);
}
@Override
public boolean isCurrentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster() {
return currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster.get();
}
@Override
public void setCurrentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster(boolean b) {
this.currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster.set(b);
}
@Override
public void addOperationSentToMasterForReplication(
OperationWithResultWithIdWrapper<RegattaLogSensorDataTrackerTrackedRegattaListener, ?> operationWithResultWithIdWrapper) {
this.operationsSentToMasterForReplication.add(operationWithResultWithIdWrapper);
}
@Override
public boolean hasSentOperationToMaster(
OperationWithResult<RegattaLogSensorDataTrackerTrackedRegattaListener, ?> operation) {
return operationsSentToMasterForReplication.remove(operation);
}
@Override
public ObjectInputStream createObjectInputStreamResolvingAgainstCache(InputStream is) throws IOException {
return new ObjectInputStream(is);
}
@Override
public synchronized void initiallyFillFromInternal(ObjectInputStream is)
throws IOException, ClassNotFoundException, InterruptedException {
this.isReplica = true;
this.registeredTrackers.values().forEach(this::stopIfNotNull);
this.registeredTrackers.clear();
}
@Override
public void serializeForInitialReplicationInternal(ObjectOutputStream objectOutputStream) throws IOException {
}
@Override
public synchronized void clearReplicaState() throws MalformedURLException, IOException, InterruptedException {
this.isReplica = false;
}
}
@@ -74,6 +74,7 @@ import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
import com.sap.sailing.domain.tracking.WindPositionMode;
import com.sap.sailing.domain.tracking.WindStore;
@@ -809,6 +810,10 @@ public class MockedTrackedRace implements DynamicTrackedRace {
@Override
public void setStatus(TrackedRaceStatus newStatus) {
}
@Override
public void setStatus(TrackingDataLoader loader, TrackedRaceStatus status) {
}
@Override
public void waitUntilNotLoading() {
@@ -161,6 +161,8 @@ public interface DynamicTrackedRace extends TrackedRace {
void setRaceIsKnownToStartUpwind(boolean raceIsKnownToStartUpwind);
void setStatus(TrackedRaceStatus newStatus);
void setStatus(TrackingDataLoader loader, TrackedRaceStatus status);
/**
* whenever a new course design is published by the race committee and the appropriate event occurs in the race log,
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.tracking;
public interface TrackingDataLoader {
TrackedRaceStatus getStatus();
}
@@ -0,0 +1,26 @@
package com.sap.sailing.domain.tracking.impl;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
public abstract class AbstractTrackingDataLoaderImpl implements TrackingDataLoader {
private final DynamicTrackedRace trackedRace;
private TrackedRaceStatus status;
protected AbstractTrackingDataLoaderImpl(DynamicTrackedRace trackedRace) {
this.trackedRace = trackedRace;
}
protected void updateStatus(TrackedRaceStatus status) {
this.status = status;
this.trackedRace.setStatus(this, status);
}
@Override
public TrackedRaceStatus getStatus() {
return status;
}
}
@@ -58,6 +58,7 @@ import com.sap.sailing.domain.tracking.TrackFactory;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sse.common.TimePoint;
@@ -184,6 +185,11 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
super.setStatus(newStatus);
notifyListeners(newStatus, oldStatus);
}
@Override
public void setStatus(TrackingDataLoader loader, TrackedRaceStatus status) {
// FIXME implement loader status aggregation
}
@Override
public void recordFix(Mark mark, GPSFix fix, boolean onlyWhenInTrackingTimeInterval) {
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.tracking.impl;
import java.io.Serializable;
import java.util.function.Consumer;
import com.sap.sailing.domain.common.tracking.SensorFix;
import com.sap.sailing.domain.tracking.DynamicSensorFixTrack;
@@ -25,6 +26,24 @@ public class SensorFixTrackImpl<ItemType extends WithID & Serializable, FixT ext
this.valueNames = valueNames;
this.listeners = new TrackListenerCollection<>();
}
@Override
public boolean add(FixT fix, boolean replace) {
final boolean result;
lockForWrite();
try {
final boolean firstFixInTrack = getRawFixes().isEmpty();
result = addWithoutLocking(fix, replace);
this.notifyListeners((listener) -> listener.fixReceived(fix, trackedItem, trackName, firstFixInTrack));
} finally {
unlockAfterWrite();
}
return result;
}
protected void notifyListeners(Consumer<SensorFixTrackListener<ItemType, FixT>> notification) {
listeners.getListeners().forEach(notification);
}
@Override
public Iterable<String> getValueNames() {
@@ -62,6 +62,7 @@ import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
import com.sap.sailing.domain.tracking.WindPositionMode;
import com.sap.sailing.domain.tracking.WindStore;
@@ -566,6 +567,10 @@ public class MockedTrackedRace implements DynamicTrackedRace {
@Override
public void setStatus(TrackedRaceStatus newStatus) {
}
@Override
public void setStatus(TrackingDataLoader loader, TrackedRaceStatus status) {
}
@Override
public void waitUntilNotLoading() {
@@ -19,7 +19,7 @@
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console -clean"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djetty.port=8889 -Dreplication.exchangeName=sapsailinganalytics-replica -Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dexpedition.udp.port=2011 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -XX:+UseMembar -Dmongo.dbName=replica -Dreplicate.on.start=com.sap.sailing.server.impl.RacingEventServiceImpl,com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sse.filestorage.impl.FileStorageManagementServiceImpl,com.sap.sse.mail.impl.MailServiceImpl,com.sap.sailing.polars.impl.PolarDataServiceImpl -Dreplicate.master.queue.host=52.16.112.6 -Dreplicate.master.queue.port=5672 -Dreplicate.master.servlet.port=8888 -Dreplicate.master.servlet.host=54.154.72.33 -Dreplicate.master.exchange.name=sapsailinganalytics-dev"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djetty.port=8889 -Dreplication.exchangeName=sapsailinganalytics-replica -Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dexpedition.udp.port=2011 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -XX:+UseMembar -Dmongo.dbName=replica -Dreplicate.on.start=com.sap.sailing.server.impl.RacingEventServiceImpl,com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sse.filestorage.impl.FileStorageManagementServiceImpl,com.sap.sse.mail.impl.MailServiceImpl,com.sap.sailing.polars.impl.PolarDataServiceImpl,com.sap.sailing.domain.racelogtracking.impl.RegattaLogSensorDataTrackerTrackedRegattaListener -Dreplicate.master.queue.host=52.16.112.6 -Dreplicate.master.queue.port=5672 -Dreplicate.master.servlet.port=8888 -Dreplicate.master.servlet.host=54.154.72.33 -Dreplicate.master.exchange.name=sapsailinganalytics-dev"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
@@ -21,7 +21,7 @@
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console -clean"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djetty.port=8889 -Dreplication.exchangeName=sapsailinganalytics-replica -Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dexpedition.udp.port=2011 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -XX:+UseMembar -Dmongo.dbName=replica -Dreplicate.on.start=com.sap.sailing.server.impl.RacingEventServiceImpl,com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sse.filestorage.impl.FileStorageManagementServiceImpl,com.sap.sse.mail.impl.MailServiceImpl,com.sap.sailing.polars.impl.PolarDataServiceImpl -Dreplicate.master.queue.host=127.0.0.1 -Dreplicate.master.queue.port=5672 -Dreplicate.master.servlet.port=8888 -Dreplicate.master.servlet.host=127.0.0.1 -Dreplicate.master.exchange.name=sapsailinganalytics"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djetty.port=8889 -Dreplication.exchangeName=sapsailinganalytics-replica -Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dexpedition.udp.port=2011 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -XX:+UseMembar -Dmongo.dbName=replica -Dreplicate.on.start=com.sap.sailing.server.impl.RacingEventServiceImpl,com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sse.filestorage.impl.FileStorageManagementServiceImpl,com.sap.sse.mail.impl.MailServiceImpl,com.sap.sailing.polars.impl.PolarDataServiceImpl,com.sap.sailing.domain.racelogtracking.impl.RegattaLogSensorDataTrackerTrackedRegattaListener -Dreplicate.master.queue.host=127.0.0.1 -Dreplicate.master.queue.port=5672 -Dreplicate.master.servlet.port=8888 -Dreplicate.master.servlet.host=127.0.0.1 -Dreplicate.master.exchange.name=sapsailinganalytics"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
+1 -1
View File
@@ -41,7 +41,7 @@ EXPEDITION_PORT=2010
# set the REPLICATE_MASTER_EXCHANGE_NAME variable to the
# same channel the master is using in its REPLICATION_CHANNEL variable
# REPLICATE_ON_START=com.sap.sailing.server.impl.RacingEventServiceImpl,com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sse.filestorage.impl.FileStorageManagementServiceImpl,com.sap.sse.mail.impl.MailServiceImpl,com.sap.sailing.polars.impl.PolarDataServiceImpl
# REPLICATE_ON_START=com.sap.sailing.server.impl.RacingEventServiceImpl,com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sse.filestorage.impl.FileStorageManagementServiceImpl,com.sap.sse.mail.impl.MailServiceImpl,com.sap.sailing.polars.impl.PolarDataServiceImpl,com.sap.sailing.domain.racelogtracking.impl.RegattaLogSensorDataTrackerTrackedRegattaListener
# Host where the master Java instance is running
# Make sure firewall configurations allow access