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;
/**
* 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) {
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());
}
}
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());
}
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;
+ }
+ }
}
package org.opendaylight.controller.cluster.datastore.modification;
-import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
-
-import java.util.ArrayList;
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();
}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+
+}
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());
}};
}
+ 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()) {{
assertEquals("match", out);
+ assertModification(subject, WriteModification.class);
expectNoMsg();
}
assertEquals("match", out);
+ assertModification(subject, MergeModification.class);
+
expectNoMsg();
}
assertEquals("match", out);
+ assertModification(subject, DeleteModification.class);
expectNoMsg();
}
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();