From: Moiz Raja Date: Fri, 20 Jun 2014 23:42:19 +0000 (-0700) Subject: Ensure that modifications are tracked by ShardTransaction X-Git-Tag: release/helium~579^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=5ff14f6824d1a831b9c1def6b820a2516fed435f;p=controller.git Ensure that modifications are tracked by ShardTransaction 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 --- diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransaction.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransaction.java index b316b9df04..f43dd7b52a 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransaction.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransaction.java @@ -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 - * + *

* The ShardTransaction Actor delegates all actions to DOMDataReadWriteTransaction - * + *

+ *

* 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} + *

+ *

+ * 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} + *

    */ 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; + } + } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModification.java index 9319f79e73..3a8eff1aa5 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModification.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModification.java @@ -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. *

    */ -public class CompositeModification implements Modification { - private final List 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 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 index 0000000000..5a15d76d27 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/ImmutableCompositeModification.java @@ -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 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 index 0000000000..983ac860e1 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModification.java @@ -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 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 getModifications(){ + return Collections.unmodifiableList(modifications); + } + +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java index 36633c55d5..075001b0d8 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java @@ -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 modificationType){ + new JavaTestKit(getSystem()) {{ + new Within(duration("1 seconds")) { + protected void run() { + subject.tell(new ShardTransaction.GetCompositedModification(), getRef()); + + final CompositeModification compositeModification = new ExpectMsg("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(); } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModificationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModificationTest.java similarity index 85% rename from opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModificationTest.java rename to opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModificationTest.java index 21f96c71c3..e30936b327 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModificationTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModificationTest.java @@ -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();