From ff23e68c9f3e52629184802cac9b1bc66ebe5e92 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 28 Mar 2012 15:42:33 +0200 Subject: [PATCH] added a second OT test which folds a leaderboard column addition with a leaderboard removal --- .../test/OperationalTransformationTest.java | 2 +- .../Transformer.java | 4 +- .../UnmergedOperationsQueue.java | 6 +-- .../test/OperationalTransformationTest.java | 17 ++++++++ .../AbstractLeaderboardColumnOperation.java | 36 ++++++++++++---- .../AbstractLeaderboardOperation.java | 40 ++++++++++++++++++ .../AbstractRacingEventServiceOperation.java | 42 +++++++++++++++++++ .../AddLeaderboard.java | 14 +++---- .../MoveLeaderboardColumnDown.java | 23 ---------- .../MoveLeaderboardColumnUp.java | 23 ---------- .../RacingEventServiceOperation.java | 8 ++++ .../RemoveColumnFromLeaderboard.java | 23 ---------- .../RemoveLeaderboard.java | 26 ++++++++++++ .../RenameLeaderboardColumn.java | 21 ---------- 14 files changed, 171 insertions(+), 114 deletions(-) create mode 100755 java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractLeaderboardOperation.java create mode 100755 java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/RemoveLeaderboard.java diff --git a/java/com.sap.sailing.operationaltransformation.test/src/com/sap/sailing/operationaltransformation/test/OperationalTransformationTest.java b/java/com.sap.sailing.operationaltransformation.test/src/com/sap/sailing/operationaltransformation/test/OperationalTransformationTest.java index 60598896fbf..98cd5801eff 100755 --- a/java/com.sap.sailing.operationaltransformation.test/src/com/sap/sailing/operationaltransformation/test/OperationalTransformationTest.java +++ b/java/com.sap.sailing.operationaltransformation.test/src/com/sap/sailing/operationaltransformation/test/OperationalTransformationTest.java @@ -45,7 +45,7 @@ public class OperationalTransformationTest { } public static class StringInsertTransformer implements Transformer { - @Override + @Override public ClientServerOperationPair transform(StringInsertOperation clientOp, StringInsertOperation serverOp) { StringInsertOperation resultClientOp; StringInsertOperation resultServerOp; diff --git a/java/com.sap.sailing.operationaltransformation/src/com/sap/sailing/operationaltransformation/Transformer.java b/java/com.sap.sailing.operationaltransformation/src/com/sap/sailing/operationaltransformation/Transformer.java index bd476488f5f..1dc7ea48479 100755 --- a/java/com.sap.sailing.operationaltransformation/src/com/sap/sailing/operationaltransformation/Transformer.java +++ b/java/com.sap.sailing.operationaltransformation/src/com/sap/sailing/operationaltransformation/Transformer.java @@ -9,8 +9,8 @@ public interface Transformer> { * again.

* * If a resulting operation is supposed to not have any effects, return the - * {@link ClientServerOperationPair#getNoOp()} operation, but never null + * {@link AbstractRacingEventServiceOperation#getNoOp()} operation, but never null * as any of the operations in the resulting pair. */ - ClientServerOperationPair transform(O clientOp, O serverOp); + ClientServerOperationPair transform(O transformedOp, O unconfirmedOperation); } diff --git a/java/com.sap.sailing.operationaltransformation/src/com/sap/sailing/operationaltransformation/UnmergedOperationsQueue.java b/java/com.sap.sailing.operationaltransformation/src/com/sap/sailing/operationaltransformation/UnmergedOperationsQueue.java index e499c02b99d..c39529ef803 100755 --- a/java/com.sap.sailing.operationaltransformation/src/com/sap/sailing/operationaltransformation/UnmergedOperationsQueue.java +++ b/java/com.sap.sailing.operationaltransformation/src/com/sap/sailing/operationaltransformation/UnmergedOperationsQueue.java @@ -48,8 +48,8 @@ public class UnmergedOperationsQueue, S> { * * @param localOperationNumber starts with 0 */ - public synchronized void updateWithTransformed(int localOperationNumber, O transformedOperation) { - unmergedOperations.set(localOperationNumber-numberOfFirstInList, transformedOperation); + public synchronized void updateWithTransformed(int localOperationNumber, O operation) { + unmergedOperations.set(localOperationNumber-numberOfFirstInList, operation); } /** @@ -76,7 +76,7 @@ public class UnmergedOperationsQueue, S> { StringBuilder result = new StringBuilder(); result.append('['); boolean first = true; - for (O op : unmergedOperations) { + for (Operation op : unmergedOperations) { if (!first) { result.append(", "); } else { diff --git a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/OperationalTransformationTest.java b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/OperationalTransformationTest.java index 0f34d9dc1dd..1bd53516a22 100755 --- a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/OperationalTransformationTest.java +++ b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/OperationalTransformationTest.java @@ -17,9 +17,11 @@ import com.sap.sailing.operationaltransformation.Peer.Role; import com.sap.sailing.operationaltransformation.PeerImpl; import com.sap.sailing.server.RacingEventService; import com.sap.sailing.server.impl.RacingEventServiceImpl; +import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard; import com.sap.sailing.server.operationaltransformation.AddLeaderboard; import com.sap.sailing.server.operationaltransformation.OperationalTransformer; import com.sap.sailing.server.operationaltransformation.RacingEventServiceOperation; +import com.sap.sailing.server.operationaltransformation.RemoveLeaderboard; public class OperationalTransformationTest { private static final String LEADERBOARDNAME = "TESTBOARD"; @@ -48,9 +50,24 @@ public class OperationalTransformationTest { RacingEventServiceOperation addLeaderboardOp = new AddLeaderboard(LEADERBOARDNAME, new int[] { 5 }); server.apply(addLeaderboardOp); server.waitForNotRunning(); + replica.waitForNotRunning(); Map replicaLeaderboards = racingEventServiceReplica.getLeaderboards(); assertEquals(2, replicaLeaderboards.size()); // expected to include the default leaderboard assertEquals(new HashSet(Arrays.asList(new String[] { DefaultLeaderboardName.DEFAULT_LEADERBOARD_NAME, LEADERBOARDNAME })), replicaLeaderboards.keySet()); + assertEquals(racingEventServiceServer.getLeaderboards().keySet(), replicaLeaderboards.keySet()); + } + + @Test + public void testAddColumnToLeaderboardOnClientAndRemoveLeaderboardOnServer() { + RacingEventServiceOperation addLeaderboardColumn = new AddColumnToLeaderboard( + "newColumn", DefaultLeaderboardName.DEFAULT_LEADERBOARD_NAME, /* medalRace */ true); + server.apply(addLeaderboardColumn); + RacingEventServiceOperation removeDefaultLeaderboard = new RemoveLeaderboard(DefaultLeaderboardName.DEFAULT_LEADERBOARD_NAME); + replica.apply(removeDefaultLeaderboard); + server.waitForNotRunning(); + replica.waitForNotRunning(); + assertEquals(0, racingEventServiceReplica.getLeaderboards().size()); + assertEquals(0, racingEventServiceServer.getLeaderboards().size()); } } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractLeaderboardColumnOperation.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractLeaderboardColumnOperation.java index 9658b199380..d92b65d71e7 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractLeaderboardColumnOperation.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractLeaderboardColumnOperation.java @@ -1,25 +1,43 @@ package com.sap.sailing.server.operationaltransformation; -public abstract class AbstractLeaderboardColumnOperation extends AbstractRacingEventServiceOperation { - private final String leaderboardName; + +public abstract class AbstractLeaderboardColumnOperation extends AbstractLeaderboardOperation { private final String columnName; public AbstractLeaderboardColumnOperation(String leaderboardName, String columnName) { - super(); - this.leaderboardName = leaderboardName; + super(leaderboardName); this.columnName = columnName; } - public String getLeaderboardName() { - return leaderboardName; - } - public String getColumnName() { return columnName; } protected boolean affectsSameColumn(AbstractLeaderboardColumnOperation other) { - return getLeaderboardName().equals(other.getLeaderboardName()) && getColumnName().equals(other.getColumnName()); + return affectsSameLeaderboard(other) && getColumnName().equals(other.getColumnName()); + } + + + @Override + public RacingEventServiceOperation transformServerRemoveColumnFromLeaderboard( + RemoveColumnFromLeaderboard removeColumnFromLeaderboardServerOp) { + if (affectsSameColumn(removeColumnFromLeaderboardServerOp)) { + // skip server's remove and hence only apply the client's remove operation + return AbstractRacingEventServiceOperation.getNoOp(); + } else { + return this; + } + } + + @Override + public RacingEventServiceOperation transformClientRemoveColumnFromLeaderboard( + RemoveColumnFromLeaderboard removeColumnFromLeaderboardClientOp) { + if (affectsSameColumn(removeColumnFromLeaderboardClientOp)) { + // skip client's remove and hence only apply the server's remove operation + return AbstractRacingEventServiceOperation.getNoOp(); + } else { + return this; + } } } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractLeaderboardOperation.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractLeaderboardOperation.java new file mode 100755 index 00000000000..d247a4ce86e --- /dev/null +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractLeaderboardOperation.java @@ -0,0 +1,40 @@ +package com.sap.sailing.server.operationaltransformation; + + + +public abstract class AbstractLeaderboardOperation extends AbstractRacingEventServiceOperation { + private final String leaderboardName; + + public AbstractLeaderboardOperation(String leaderboardName) { + super(); + this.leaderboardName = leaderboardName; + } + + protected String getLeaderboardName() { + return leaderboardName; + } + + protected boolean affectsSameLeaderboard(AbstractLeaderboardOperation other) { + return getLeaderboardName().equals(other.getLeaderboardName()); + } + + @Override + public RacingEventServiceOperation transformRemoveLeaderboardClientOp(RemoveLeaderboard removeLeaderboard) { + if (affectsSameLeaderboard(removeLeaderboard)) { + return AbstractRacingEventServiceOperation.getNoOp(); + } else { + return this; + } + } + + + @Override + public RacingEventServiceOperation transformRemoveLeaderboardServerOp(RemoveLeaderboard removeLeaderboard) { + if (affectsSameLeaderboard(removeLeaderboard)) { + return AbstractRacingEventServiceOperation.getNoOp(); + } else { + return this; + } + } + +} diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractRacingEventServiceOperation.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractRacingEventServiceOperation.java index abafe88a79e..a90686cf509 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractRacingEventServiceOperation.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AbstractRacingEventServiceOperation.java @@ -1,5 +1,8 @@ package com.sap.sailing.server.operationaltransformation; +import com.sap.sailing.server.RacingEventService; + + /** * Performs identical transformations for all operation types by simply returning the operation passed. Subclasses need @@ -9,6 +12,26 @@ package com.sap.sailing.server.operationaltransformation; * */ public abstract class AbstractRacingEventServiceOperation implements RacingEventServiceOperation { + @Override + public RacingEventServiceOperation transformRemoveLeaderboardClientOp(RemoveLeaderboard removeLeaderboard) { + return removeLeaderboard; + } + + @Override + public RacingEventServiceOperation transformRemoveLeaderboardServerOp(RemoveLeaderboard removeLeaderboard) { + return removeLeaderboard; + } + + @Override + public RacingEventServiceOperation transformAddLeaderboardClientOp(AddLeaderboard addLeaderboard) { + return addLeaderboard; + } + + @Override + public RacingEventServiceOperation transformAddLeaderboardServerOp(AddLeaderboard addLeaderboard) { + return addLeaderboard; + } + @Override public RacingEventServiceOperation transformClientRenameLeaderboardColumnOp( RenameLeaderboardColumn renameLeaderboardColumnClientOp) { @@ -30,4 +53,23 @@ public abstract class AbstractRacingEventServiceOperation implements RacingEvent public RacingEventServiceOperation transformClientRemoveColumnFromLeaderboard(RemoveColumnFromLeaderboard removeColumnFromLeaderboardClientOp) { return removeColumnFromLeaderboardClientOp; } + + public static RacingEventServiceOperation getNoOp() { + return new AbstractRacingEventServiceOperation() { + @Override + public RacingEventService applyTo(RacingEventService toState) { + return toState; + } + + @Override + public RacingEventServiceOperation transformClientOp(RacingEventServiceOperation serverOp) { + return serverOp; + } + + @Override + public RacingEventServiceOperation transformServerOp(RacingEventServiceOperation clientOp) { + return clientOp; + } + }; + } } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AddLeaderboard.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AddLeaderboard.java index ab81a226efa..008169725ea 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AddLeaderboard.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AddLeaderboard.java @@ -2,32 +2,28 @@ package com.sap.sailing.server.operationaltransformation; import com.sap.sailing.server.RacingEventService; -public class AddLeaderboard extends AbstractRacingEventServiceOperation { - private final String leaderboardName; +public class AddLeaderboard extends AbstractLeaderboardOperation { private final int[] discardThresholds; public AddLeaderboard(String leaderboardName, int[] discardThresholds) { - super(); - this.leaderboardName = leaderboardName; + super(leaderboardName); this.discardThresholds = discardThresholds; } @Override public RacingEventService applyTo(RacingEventService toState) { - toState.addLeaderboard(leaderboardName, discardThresholds); + toState.addLeaderboard(getLeaderboardName(), discardThresholds); return toState; } @Override public RacingEventServiceOperation transformClientOp(RacingEventServiceOperation serverOp) { - // TODO Auto-generated method stub - return null; + return serverOp.transformAddLeaderboardClientOp(this); } @Override public RacingEventServiceOperation transformServerOp(RacingEventServiceOperation clientOp) { - // TODO Auto-generated method stub - return null; + return clientOp.transformAddLeaderboardServerOp(this); } } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/MoveLeaderboardColumnDown.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/MoveLeaderboardColumnDown.java index 00d5f2a1bc3..4ce9e3792f1 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/MoveLeaderboardColumnDown.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/MoveLeaderboardColumnDown.java @@ -1,6 +1,5 @@ package com.sap.sailing.server.operationaltransformation; -import com.sap.sailing.operationaltransformation.ClientServerOperationPair; import com.sap.sailing.server.RacingEventService; public class MoveLeaderboardColumnDown extends AbstractLeaderboardColumnOperation { @@ -30,26 +29,4 @@ public class MoveLeaderboardColumnDown extends AbstractLeaderboardColumnOperatio return null; } - - @Override - public RacingEventServiceOperation transformServerRemoveColumnFromLeaderboard( - RemoveColumnFromLeaderboard removeColumnFromLeaderboardServerOp) { - if (affectsSameColumn(removeColumnFromLeaderboardServerOp)) { - return ClientServerOperationPair.getNoOp(); - } else { - return removeColumnFromLeaderboardServerOp; - } - } - - - @Override - public RacingEventServiceOperation transformClientRemoveColumnFromLeaderboard( - RemoveColumnFromLeaderboard removeColumnFromLeaderboardClientOp) { - if (affectsSameColumn(removeColumnFromLeaderboardClientOp)) { - return ClientServerOperationPair.getNoOp(); - } else { - return removeColumnFromLeaderboardClientOp; - } - } - } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/MoveLeaderboardColumnUp.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/MoveLeaderboardColumnUp.java index 10c320785dd..554e3687268 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/MoveLeaderboardColumnUp.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/MoveLeaderboardColumnUp.java @@ -1,6 +1,5 @@ package com.sap.sailing.server.operationaltransformation; -import com.sap.sailing.operationaltransformation.ClientServerOperationPair; import com.sap.sailing.server.RacingEventService; public class MoveLeaderboardColumnUp extends AbstractLeaderboardColumnOperation { @@ -30,26 +29,4 @@ public class MoveLeaderboardColumnUp extends AbstractLeaderboardColumnOperation return null; } - - @Override - public RacingEventServiceOperation transformServerRemoveColumnFromLeaderboard( - RemoveColumnFromLeaderboard removeColumnFromLeaderboardServerOp) { - if (affectsSameColumn(removeColumnFromLeaderboardServerOp)) { - return ClientServerOperationPair.getNoOp(); - } else { - return removeColumnFromLeaderboardServerOp; - } - } - - - @Override - public RacingEventServiceOperation transformClientRemoveColumnFromLeaderboard( - RemoveColumnFromLeaderboard removeColumnFromLeaderboardClientOp) { - if (affectsSameColumn(removeColumnFromLeaderboardClientOp)) { - return ClientServerOperationPair.getNoOp(); - } else { - return removeColumnFromLeaderboardClientOp; - } - } - } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/RacingEventServiceOperation.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/RacingEventServiceOperation.java index 5fdf9718407..2594b2a877a 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/RacingEventServiceOperation.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/RacingEventServiceOperation.java @@ -36,4 +36,12 @@ public interface RacingEventServiceOperation extends Operation