Ensure that modifications are tracked by ShardTransaction 69/8269/4
authorMoiz Raja <moraja@cisco.com>
Fri, 20 Jun 2014 23:42:19 +0000 (16:42 -0700)
committerMoiz Raja <moraja@cisco.com>
Wed, 25 Jun 2014 21:17:22 +0000 (14:17 -0700)
As modifications are made on a ShardTransaction they are applied to the transaction object that ShardTransaction wraps
However the modifications also need to be tracked. This tracking would be used ultimately by the Shard when persisting data.

Change-Id: I4bb76699d251dbdc786416313479f0e6b31962e1
Signed-off-by: Moiz Raja <moraja@cisco.com>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModification.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/ImmutableCompositeModification.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModification.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModificationTest.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModificationTest.java with 85% similarity]

index b316b9d..f43dd7b 100644 (file)
@@ -28,6 +28,12 @@ import org.opendaylight.controller.cluster.datastore.messages.ReadyTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.WriteData;
 import org.opendaylight.controller.cluster.datastore.messages.WriteDataReply;
+import org.opendaylight.controller.cluster.datastore.modification.CompositeModification;
+import org.opendaylight.controller.cluster.datastore.modification.DeleteModification;
+import org.opendaylight.controller.cluster.datastore.modification.ImmutableCompositeModification;
+import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
+import org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification;
+import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
@@ -37,27 +43,32 @@ import java.util.concurrent.ExecutionException;
 
 /**
  * The ShardTransaction Actor represents a remote transaction
- *
+ *<p>
  * The ShardTransaction Actor delegates all actions to DOMDataReadWriteTransaction
- *
+ *</p>
+ *<p>
  * Even though the DOMStore and the DOMStoreTransactionChain implement multiple types of transactions
  * the ShardTransaction Actor only works with read-write transactions. This is just to keep the logic simple. At this
  * time there are no known advantages for creating a read-only or write-only transaction which may change over time
  * at which point we can optimize things in the distributed store as well.
- *
- * Handles Messages
- * ----------------
- * {@link org.opendaylight.controller.cluster.datastore.messages.ReadData}
- * {@link org.opendaylight.controller.cluster.datastore.messages.WriteData}
- * {@link org.opendaylight.controller.cluster.datastore.messages.MergeData}
- * {@link org.opendaylight.controller.cluster.datastore.messages.DeleteData}
- * {@link org.opendaylight.controller.cluster.datastore.messages.ReadyTransaction}
- * {@link org.opendaylight.controller.cluster.datastore.messages.CloseTransaction}
+ *</p>
+ *<p>
+ * Handles Messages <br/>
+ * ---------------- <br/>
+ * <li> {@link org.opendaylight.controller.cluster.datastore.messages.ReadData}
+ * <li> {@link org.opendaylight.controller.cluster.datastore.messages.WriteData}
+ * <li> {@link org.opendaylight.controller.cluster.datastore.messages.MergeData}
+ * <li> {@link org.opendaylight.controller.cluster.datastore.messages.DeleteData}
+ * <li> {@link org.opendaylight.controller.cluster.datastore.messages.ReadyTransaction}
+ * <li> {@link org.opendaylight.controller.cluster.datastore.messages.CloseTransaction}
+ * </p>
  */
 public class ShardTransaction extends UntypedActor {
 
   private final DOMStoreReadWriteTransaction transaction;
 
+  private final MutableCompositeModification modification = new MutableCompositeModification();
+
   private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
 
   public ShardTransaction(DOMStoreReadWriteTransaction transaction) {
@@ -89,6 +100,9 @@ public class ShardTransaction extends UntypedActor {
       readyTransaction((ReadyTransaction) message);
     } else if(message instanceof CloseTransaction){
       closeTransaction((CloseTransaction) message);
+    } else if(message instanceof GetCompositedModification){
+      // This is here for testing only
+      getSender().tell(new GetCompositeModificationReply(new ImmutableCompositeModification(modification)), getSelf());
     }
   }
 
@@ -118,16 +132,19 @@ public class ShardTransaction extends UntypedActor {
 
 
   private void writeData(WriteData message){
+    modification.addModification(new WriteModification(message.getPath(), message.getData()));
     transaction.write(message.getPath(), message.getData());
     getSender().tell(new WriteDataReply(), getSelf());
   }
 
   private void mergeData(MergeData message){
+    modification.addModification(new MergeModification(message.getPath(), message.getData()));
     transaction.merge(message.getPath(), message.getData());
     getSender().tell(new MergeDataReply(), getSelf());
   }
 
   private void deleteData(DeleteData message){
+    modification.addModification(new DeleteModification(message.getPath()));
     transaction.delete(message.getPath());
     getSender().tell(new DeleteDataReply(), getSelf());
   }
@@ -143,4 +160,25 @@ public class ShardTransaction extends UntypedActor {
     transaction.close();
     getSender().tell(new CloseTransactionReply(), getSelf());
   }
+
+
+  // These classes are in here for test purposes only
+
+  static class GetCompositedModification {
+
+  }
+
+  static class GetCompositeModificationReply {
+    private final CompositeModification modification;
+
+
+    GetCompositeModificationReply(CompositeModification modification) {
+      this.modification = modification;
+    }
+
+
+    public CompositeModification getModification() {
+      return modification;
+    }
+  }
 }
index 9319f79..3a8eff1 100644 (file)
@@ -8,9 +8,6 @@
 
 package org.opendaylight.controller.cluster.datastore.modification;
 
-import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
-
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -20,17 +17,6 @@ import java.util.List;
  * is being replayed a DOMStoreWriteTransaction could be created and a CompositeModification could be applied to it.
  * </p>
  */
-public class CompositeModification implements Modification {
-  private final List<Modification> modifications = new ArrayList<>();
-
-  @Override
-  public void apply(DOMStoreWriteTransaction transaction) {
-    for(Modification modification : modifications){
-      modification.apply(transaction);
-    }
-  }
-
-  public void addModification(Modification modification){
-    modifications.add(modification);
-  }
+public interface CompositeModification extends Modification {
+  List<Modification> getModifications();
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/ImmutableCompositeModification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/ImmutableCompositeModification.java
new file mode 100644 (file)
index 0000000..5a15d76
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.modification;
+
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+
+import java.util.List;
+
+public class ImmutableCompositeModification implements CompositeModification{
+
+  private final CompositeModification modification;
+
+  public ImmutableCompositeModification(CompositeModification modification){
+    this.modification = modification;
+  }
+
+  @Override
+  public List<Modification> getModifications() {
+    return modification.getModifications();
+  }
+
+  @Override
+  public void apply(DOMStoreWriteTransaction transaction) {
+    modification.apply(transaction);
+  }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModification.java
new file mode 100644 (file)
index 0000000..983ac86
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.modification;
+
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class MutableCompositeModification implements CompositeModification {
+  private final List<Modification> modifications = new ArrayList<>();
+
+  @Override
+  public void apply(DOMStoreWriteTransaction transaction) {
+    for(Modification modification : modifications){
+      modification.apply(transaction);
+    }
+  }
+
+  public void addModification(Modification modification){
+    modifications.add(modification);
+  }
+
+  public List<Modification> getModifications(){
+    return Collections.unmodifiableList(modifications);
+  }
+
+}
index 36633c5..075001b 100644 (file)
@@ -18,12 +18,18 @@ import org.opendaylight.controller.cluster.datastore.messages.ReadyTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.WriteData;
 import org.opendaylight.controller.cluster.datastore.messages.WriteDataReply;
+import org.opendaylight.controller.cluster.datastore.modification.CompositeModification;
+import org.opendaylight.controller.cluster.datastore.modification.DeleteModification;
+import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
+import org.opendaylight.controller.cluster.datastore.modification.Modification;
+import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 public class ShardTransactionTest extends AbstractActorTest {
   private static ListeningExecutorService storeExecutor = MoreExecutors.listeningDecorator(MoreExecutors.sameThreadExecutor());
@@ -69,6 +75,31 @@ public class ShardTransactionTest extends AbstractActorTest {
     }};
   }
 
+  private void assertModification(final ActorRef subject, final Class<? extends Modification> modificationType){
+    new JavaTestKit(getSystem()) {{
+      new Within(duration("1 seconds")) {
+        protected void run() {
+          subject.tell(new ShardTransaction.GetCompositedModification(), getRef());
+
+          final CompositeModification compositeModification = new ExpectMsg<CompositeModification>("match hint") {
+            // do not put code outside this method, will run afterwards
+            protected CompositeModification match(Object in) {
+              if (in instanceof ShardTransaction.GetCompositeModificationReply) {
+                return ((ShardTransaction.GetCompositeModificationReply) in).getModification();
+              } else {
+                throw noMatch();
+              }
+            }
+          }.get(); // this extracts the received message
+
+          assertTrue(compositeModification.getModifications().size() == 1);
+          assertEquals(modificationType, compositeModification.getModifications().get(0).getClass());
+
+        }
+      };
+    }};
+  }
+
   @Test
   public void testOnReceiveWriteData() throws Exception {
     new JavaTestKit(getSystem()) {{
@@ -93,6 +124,7 @@ public class ShardTransactionTest extends AbstractActorTest {
 
           assertEquals("match", out);
 
+          assertModification(subject, WriteModification.class);
           expectNoMsg();
         }
 
@@ -125,6 +157,8 @@ public class ShardTransactionTest extends AbstractActorTest {
 
           assertEquals("match", out);
 
+          assertModification(subject, MergeModification.class);
+
           expectNoMsg();
         }
 
@@ -157,6 +191,7 @@ public class ShardTransactionTest extends AbstractActorTest {
 
           assertEquals("match", out);
 
+          assertModification(subject, DeleteModification.class);
           expectNoMsg();
         }
 
@@ -8,12 +8,12 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransactio
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 
-public class CompositeModificationTest extends AbstractModificationTest {
+public class MutableCompositeModificationTest extends AbstractModificationTest {
 
   @Test
   public void testApply() throws Exception {
 
-    CompositeModification compositeModification = new CompositeModification();
+    MutableCompositeModification compositeModification = new MutableCompositeModification();
     compositeModification.addModification(new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)));
 
     DOMStoreReadWriteTransaction transaction = store.newReadWriteTransaction();

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.