Merge "Ensure that modifications are tracked by ShardTransaction"
authorEd Warnicke <eaw@cisco.com>
Mon, 30 Jun 2014 16:39:04 +0000 (16:39 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 30 Jun 2014 16:39:04 +0000 (16:39 +0000)
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 b316b9df04966d82faf19ffc0743994dc684ec4a..f43dd7b52a62b745a17929d545107a9b57fbc1ff 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 9319f79e733b9e105ab19030a9e81eab3e3dffa3..3a8eff1aa511e8194992a72d98598251cd61a9ed 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 36633c55d590c023651a39e82feef8ba48d780d5..075001b0d8327c17c03373126d0a1019da4d45fe 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();