mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-26 23:46:36 +00:00
added a second OT test which folds a leaderboard column addition with a leaderboard removal
This commit is contained in:
+2
-2
@@ -9,8 +9,8 @@ public interface Transformer<O extends Operation<?>> {
|
||||
* again.<p>
|
||||
*
|
||||
* If a resulting operation is supposed to not have any effects, return the
|
||||
* {@link ClientServerOperationPair#getNoOp()} operation, but never <code>null</code>
|
||||
* {@link AbstractRacingEventServiceOperation#getNoOp()} operation, but never <code>null</code>
|
||||
* as any of the operations in the resulting pair.
|
||||
*/
|
||||
ClientServerOperationPair<O> transform(O clientOp, O serverOp);
|
||||
ClientServerOperationPair<O> transform(O transformedOp, O unconfirmedOperation);
|
||||
}
|
||||
|
||||
+3
-3
@@ -48,8 +48,8 @@ public class UnmergedOperationsQueue<O extends Operation<S>, 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<O extends Operation<S>, S> {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append('[');
|
||||
boolean first = true;
|
||||
for (O op : unmergedOperations) {
|
||||
for (Operation<S> op : unmergedOperations) {
|
||||
if (!first) {
|
||||
result.append(", ");
|
||||
} else {
|
||||
|
||||
+17
@@ -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<String, Leaderboard> replicaLeaderboards = racingEventServiceReplica.getLeaderboards();
|
||||
assertEquals(2, replicaLeaderboards.size()); // expected to include the default leaderboard
|
||||
assertEquals(new HashSet<String>(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());
|
||||
}
|
||||
}
|
||||
|
||||
+27
-9
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+5
-9
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-23
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-23
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
@@ -36,4 +36,12 @@ public interface RacingEventServiceOperation extends Operation<RacingEventServic
|
||||
RacingEventServiceOperation transformClientRenameLeaderboardColumnOp(RenameLeaderboardColumn renameLeaderboardColumnClientOp);
|
||||
|
||||
RacingEventServiceOperation transformServerRenameLeaderboardColumnOp(RenameLeaderboardColumn renameLeaderboardColumnServerOp);
|
||||
|
||||
RacingEventServiceOperation transformAddLeaderboardClientOp(AddLeaderboard addLeaderboard);
|
||||
|
||||
RacingEventServiceOperation transformAddLeaderboardServerOp(AddLeaderboard addLeaderboard);
|
||||
|
||||
RacingEventServiceOperation transformRemoveLeaderboardClientOp(RemoveLeaderboard removeLeaderboard);
|
||||
|
||||
RacingEventServiceOperation transformRemoveLeaderboardServerOp(RemoveLeaderboard removeLeaderboard);
|
||||
}
|
||||
|
||||
-23
@@ -1,6 +1,5 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.operationaltransformation.ClientServerOperationPair;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class RemoveColumnFromLeaderboard extends AbstractLeaderboardColumnOperation {
|
||||
@@ -26,26 +25,4 @@ public class RemoveColumnFromLeaderboard extends AbstractLeaderboardColumnOperat
|
||||
return clientOp.transformServerRemoveColumnFromLeaderboard(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation transformServerRemoveColumnFromLeaderboard(
|
||||
RemoveColumnFromLeaderboard removeColumnFromLeaderboardServerOp) {
|
||||
if (affectsSameColumn(removeColumnFromLeaderboardServerOp)) {
|
||||
// skip server's remove and hence only apply the client's remove operation
|
||||
return ClientServerOperationPair.getNoOp();
|
||||
} else {
|
||||
return removeColumnFromLeaderboardServerOp;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation transformClientRemoveColumnFromLeaderboard(
|
||||
RemoveColumnFromLeaderboard removeColumnFromLeaderboardClientOp) {
|
||||
if (affectsSameColumn(removeColumnFromLeaderboardClientOp)) {
|
||||
// skip client's remove and hence only apply the server's remove operation
|
||||
return ClientServerOperationPair.getNoOp();
|
||||
} else {
|
||||
return removeColumnFromLeaderboardClientOp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class RemoveLeaderboard extends AbstractLeaderboardOperation {
|
||||
public RemoveLeaderboard(String leaderboardName) {
|
||||
super(leaderboardName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation transformClientOp(RacingEventServiceOperation serverOp) {
|
||||
return serverOp.transformRemoveLeaderboardClientOp(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation transformServerOp(RacingEventServiceOperation clientOp) {
|
||||
return clientOp.transformRemoveLeaderboardServerOp(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventService applyTo(RacingEventService toState) {
|
||||
toState.removeLeaderboard(getLeaderboardName());
|
||||
return toState;
|
||||
}
|
||||
|
||||
}
|
||||
-21
@@ -1,6 +1,5 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.operationaltransformation.ClientServerOperationPair;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class RenameLeaderboardColumn extends AbstractLeaderboardColumnOperation {
|
||||
@@ -29,24 +28,4 @@ public class RenameLeaderboardColumn extends AbstractLeaderboardColumnOperation
|
||||
return clientOp.transformServerRenameLeaderboardColumnOp(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation transformServerRemoveColumnFromLeaderboard(
|
||||
RemoveColumnFromLeaderboard removeColumnFromLeaderboardServerOp) {
|
||||
if (affectsSameColumn(removeColumnFromLeaderboardServerOp)) {
|
||||
return ClientServerOperationPair.getNoOp(); // don't need the rename anymore when column is removed
|
||||
} else {
|
||||
return removeColumnFromLeaderboardServerOp;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation transformClientRemoveColumnFromLeaderboard(
|
||||
RemoveColumnFromLeaderboard removeColumnFromLeaderboardClientOp) {
|
||||
if (affectsSameColumn(removeColumnFromLeaderboardClientOp)) {
|
||||
return ClientServerOperationPair.getNoOp(); // don't need the rename anymore when column is removed
|
||||
} else {
|
||||
return removeColumnFromLeaderboardClientOp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user