added an operation execution listener pattern for RacingEventService

This commit is contained in:
Axel Uhl
2012-04-20 17:53:33 +02:00
parent 34124bdd4c
commit 10ef972c75
36 changed files with 85 additions and 7 deletions
@@ -16,12 +16,12 @@ import com.sap.sailing.operationaltransformation.Peer;
import com.sap.sailing.operationaltransformation.Peer.Role;
import com.sap.sailing.operationaltransformation.PeerImpl;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sailing.server.impl.RacingEventServiceImpl;
import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard;
import com.sap.sailing.server.operationaltransformation.CreateLeaderboard;
import com.sap.sailing.server.operationaltransformation.MoveLeaderboardColumnUp;
import com.sap.sailing.server.operationaltransformation.OperationalTransformer;
import com.sap.sailing.server.operationaltransformation.RacingEventServiceOperation;
import com.sap.sailing.server.operationaltransformation.RemoveLeaderboard;
public class OperationalTransformationTest {
@@ -0,0 +1,5 @@
package com.sap.sailing.server;
public interface OperationExecutionListener {
<T> void executed(RacingEventServiceOperation<T> operation);
}
@@ -40,7 +40,6 @@ import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.RaceRecord;
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.sap.sailing.expeditionconnector.ExpeditionListener;
import com.sap.sailing.server.operationaltransformation.RacingEventServiceOperation;
/**
* An OSGi service that can be used to track boat races using a TracTrac connector that pushes
@@ -339,8 +338,13 @@ public interface RacingEventService extends TrackedEventRegistry, EventFetcher,
void updateLeaderboardGroup(String oldName, String newName, String description, List<String> leaderboardNames);
/**
* Executes an operation whose effects need to be replicated to any replica of this service known.
* Executes an operation whose effects need to be replicated to any replica of this service known and
* {@link OperationExecutionListener#executed(RacingEventServiceOperation) notifies} all registered
* operation execution listeners about the execution of the operation.
*/
<T> T apply(RacingEventServiceOperation<T> operation);
void addOperationExecutionListener(OperationExecutionListener listener);
void removeOperationExecutionListener(OperationExecutionListener listener);
}
@@ -1,10 +1,16 @@
package com.sap.sailing.server.operationaltransformation;
package com.sap.sailing.server;
import java.io.Serializable;
import com.sap.sailing.operationaltransformation.Operation;
import com.sap.sailing.operationaltransformation.Transformer;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard;
import com.sap.sailing.server.operationaltransformation.CreateLeaderboard;
import com.sap.sailing.server.operationaltransformation.MoveLeaderboardColumnDown;
import com.sap.sailing.server.operationaltransformation.MoveLeaderboardColumnUp;
import com.sap.sailing.server.operationaltransformation.RemoveLeaderboard;
import com.sap.sailing.server.operationaltransformation.RemoveLeaderboardColumn;
import com.sap.sailing.server.operationaltransformation.RenameLeaderboardColumn;
public interface RacingEventServiceOperation<ResultType> extends Operation<RacingEventService>, Serializable {
/**
@@ -13,6 +19,11 @@ public interface RacingEventServiceOperation<ResultType> extends Operation<Racin
*/
ResultType internalApplyTo(RacingEventService toState) throws Exception;
/**
* Tells if this operation needs to be executed in order with other operations requesting synchronous execution.
*/
boolean requiresSynchronousExecution();
/**
* Implements the specific transformation rule for the implementing subclass for the set of possible peer operations
* along which to transform this operation, assuming this is the client operation. See
@@ -68,8 +68,9 @@ import com.sap.sailing.expeditionconnector.ExpeditionListener;
import com.sap.sailing.expeditionconnector.ExpeditionWindTrackerFactory;
import com.sap.sailing.expeditionconnector.UDPExpeditionReceiver;
import com.sap.sailing.operationaltransformation.Operation;
import com.sap.sailing.server.OperationExecutionListener;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.operationaltransformation.RacingEventServiceOperation;
import com.sap.sailing.server.RacingEventServiceOperation;
public class RacingEventServiceImpl implements RacingEventService {
private static final Logger logger = Logger.getLogger(RacingEventServiceImpl.class.getName());
@@ -119,6 +120,8 @@ public class RacingEventServiceImpl implements RacingEventService {
private final SwissTimingAdapterPersistence swissTimingAdapterPersistence;
private final Map<Event, DynamicTrackedEvent> eventTrackingCache;
private final Set<OperationExecutionListener> operationExecutionListeners;
public RacingEventServiceImpl() {
tractracDomainFactory = DomainFactory.INSTANCE;
@@ -135,6 +138,7 @@ public class RacingEventServiceImpl implements RacingEventService {
raceTrackersByID = new HashMap<Object, RaceTracker>();
leaderboardGroupsByName = new HashMap<String, LeaderboardGroup>();
leaderboardsByName = new HashMap<String, Leaderboard>();
operationExecutionListeners = new HashSet<OperationExecutionListener>();
// Add one default leaderboard that aggregates all races currently tracked by this service.
// This is more for debugging purposes than for anything else.
addLeaderboard(DefaultLeaderboardName.DEFAULT_LEADERBOARD_NAME, new int[] { 5, 8 });
@@ -918,9 +922,24 @@ public class RacingEventServiceImpl implements RacingEventService {
@Override
public <T> T apply(RacingEventServiceOperation<T> operation) {
try {
return operation.internalApplyTo(this);
T result = operation.internalApplyTo(this);
for (OperationExecutionListener listener : operationExecutionListeners) {
listener.executed(operation);
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void addOperationExecutionListener(OperationExecutionListener listener) {
operationExecutionListeners.add(listener);
}
@Override
public void removeOperationExecutionListener(OperationExecutionListener listener) {
operationExecutionListeners.remove(listener);
}
}
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
@@ -14,6 +15,14 @@ import com.sap.sailing.server.RacingEventService;
public abstract class AbstractRacingEventServiceOperation<ResultType> implements RacingEventServiceOperation<ResultType> {
private static final long serialVersionUID = 3888231857034991271L;
/**
* This default implementation requests synchronous execution.
*/
@Override
public boolean requiresSynchronousExecution() {
return true;
}
/**
* Ignores the actual result of {@link #internalApplyTo(RacingEventService)} and returns <code>toState</code> which
* for the operational transformation algorithm is the "next state reached."
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
/**
* Doesn't transform for the {@link RemoveLeaderboardColumn} because only existing leaderboards can be removed,
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class AddEvent extends AbstractRacingEventServiceOperation<Void> {
private static final long serialVersionUID = -3550383541066673065L;
@@ -3,6 +3,7 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.common.EventIdentifier;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class AddRaceDefinition extends AbstractRacingEventServiceOperation<Void> {
private static final long serialVersionUID = -2282997511967012426L;
@@ -5,6 +5,7 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class ConnectTrackedRaceToLeaderboardColumn extends AbstractLeaderboardColumnOperation<Boolean> {
private static final long serialVersionUID = -1336511401516212508L;
@@ -2,6 +2,7 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class CreateLeaderboard extends AbstractLeaderboardOperation<Leaderboard> {
private static final long serialVersionUID = 891352705068098580L;
@@ -4,6 +4,7 @@ import java.util.List;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class CreateLeaderboardGroup extends AbstractLeaderboardGroupOperation<LeaderboardGroup> {
private static final long serialVersionUID = -5028997286564650805L;
@@ -8,6 +8,7 @@ import com.sap.sailing.domain.tracking.TrackedEvent;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
/**
* Creates a tracked race for a race identifier by a {@link RaceIdentifier}. The operation assumes that the
@@ -3,6 +3,7 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class DisconnectLeaderboardColumnFromTrackedRace extends AbstractLeaderboardColumnOperation<Void> {
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class MoveLeaderboardColumnDown extends AbstractLeaderboardColumnOperation<Void> {
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class MoveLeaderboardColumnUp extends AbstractLeaderboardColumnOperation<Void> {
@@ -2,6 +2,7 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.operationaltransformation.ClientServerOperationPair;
import com.sap.sailing.operationaltransformation.Transformer;
import com.sap.sailing.server.RacingEventServiceOperation;
public class OperationalTransformer implements Transformer<RacingEventServiceOperation<?>> {
@@ -6,6 +6,7 @@ import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class RemoveAndUntrackRace extends AbstractRaceOperation<Void> {
private static final long serialVersionUID = 4260421466093529004L;
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class RemoveLeaderboard extends AbstractLeaderboardOperation<Void> {
private static final long serialVersionUID = -6491003416450255268L;
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class RemoveLeaderboardColumn extends AbstractLeaderboardColumnOperation<Void> {
private static final long serialVersionUID = 5425526859417359535L;
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class RemoveLeaderboardGroup extends AbstractLeaderboardGroupOperation<Void> {
private static final long serialVersionUID = 3177217793859319236L;
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class RenameLeaderboard extends AbstractLeaderboardOperation<Void> {
private static final long serialVersionUID = 8874599127010526971L;
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class RenameLeaderboardColumn extends AbstractLeaderboardColumnOperation<Void> {
private static final long serialVersionUID = -1238503068559477351L;
@@ -1,6 +1,7 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class RenameLeaderboardGroup extends AbstractLeaderboardGroupOperation<Void> {
private static final long serialVersionUID = -5007784579411727148L;
@@ -3,6 +3,7 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class SetRaceIsKnownToStartUpwind extends AbstractRaceOperation<Void> {
private static final long serialVersionUID = 272403191741207144L;
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.common.EventAndRaceIdentifier;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class SetWindSourcesToExclude extends AbstractRaceOperation<Void> {
private static final long serialVersionUID = 7639288885720509529L;
@@ -6,6 +6,7 @@ import java.net.MalformedURLException;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.common.EventIdentifier;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class StopTrackingEvent extends AbstractRacingEventServiceOperation<Void> {
private static final long serialVersionUID = -651066062098923320L;
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class StopTrackingRace extends AbstractRaceOperation<Void> {
private static final long serialVersionUID = -6074168525544219596L;
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.common.EventIdentifier;
import com.sap.sailing.domain.tracking.DynamicTrackedEvent;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class TrackEvent extends AbstractRacingEventServiceOperation<DynamicTrackedEvent> {
private static final long serialVersionUID = 7891960455598410633L;
@@ -3,6 +3,7 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateCompetitorDisplayNameInLeaderboard extends AbstractLeaderboardOperation<Void> {
private static final long serialVersionUID = 366335484317671148L;
@@ -2,6 +2,7 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateIsMedalRace extends AbstractLeaderboardColumnOperation<Void> {
private static final long serialVersionUID = 5925081961634860757L;
@@ -5,6 +5,7 @@ import java.util.Arrays;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateLeaderboard extends AbstractLeaderboardOperation<Void> {
private static final long serialVersionUID = -8040361040050151768L;
@@ -3,6 +3,7 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateLeaderboardCarryValue extends AbstractLeaderboardOperation<Void> {
private static final long serialVersionUID = 5467731814788887426L;
@@ -3,6 +3,7 @@ package com.sap.sailing.server.operationaltransformation;
import java.util.List;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateLeaderboardGroup extends AbstractLeaderboardGroupOperation<Void> {
private static final long serialVersionUID = -1822477339916802467L;
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.Leaderboard.Entry;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateLeaderboardMaxPointsReason extends AbstractLeaderboardColumnOperation<Pair<Integer, Integer>> {
private static final long serialVersionUID = -492130952256848047L;
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateLeaderboardScoreCorrection extends AbstractLeaderboardColumnOperation<Pair<Integer, Integer>> {
private static final long serialVersionUID = -977025759476022993L;