From 3c0667dedcd089624c4de1fdf39f9c971bdce209 Mon Sep 17 00:00:00 2001
From: Moiz Raja
Date: Fri, 20 Jun 2014 11:46:53 -0700
Subject: [PATCH] Introducing the Modification classses
The purpose of these classes is to capture all modifications are done on a transaction.
The reason for capturing these modifications is so that we can persist them to the transaction journal
When a member is restarted or a shard is restarted the "Modifications" will be read from the log and replayed
on the Shard at which point the Shard can create a new transaction and apply it to the current state
Change-Id: I4a9b1c3f28eac5c4d360d743efc44286d8a1acca
Signed-off-by: Moiz Raja
---
.../modification/AbstractModification.java | 22 ++++++++++
.../modification/CompositeModification.java | 36 +++++++++++++++
.../modification/DeleteModification.java | 26 +++++++++++
.../modification/MergeModification.java | 31 +++++++++++++
.../datastore/modification/Modification.java | 33 ++++++++++++++
.../modification/WriteModification.java | 31 +++++++++++++
.../AbstractModificationTest.java | 44 +++++++++++++++++++
.../CompositeModificationTest.java | 28 ++++++++++++
.../modification/DeleteModificationTest.java | 35 +++++++++++++++
.../modification/MergeModificationTest.java | 28 ++++++++++++
.../modification/WriteModificationTest.java | 26 +++++++++++
11 files changed, 340 insertions(+)
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModification.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModification.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModification.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MergeModification.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/Modification.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/WriteModification.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModificationTest.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModificationTest.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModificationTest.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MergeModificationTest.java
create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/WriteModificationTest.java
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModification.java
new file mode 100644
index 0000000000..ffb263519a
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModification.java
@@ -0,0 +1,22 @@
+/*
+ * 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.yangtools.yang.data.api.InstanceIdentifier;
+
+/**
+ * Base class to be used for all simple modifications that can be applied to a DOMStoreTransaction
+ */
+public abstract class AbstractModification implements Modification {
+ protected final InstanceIdentifier path;
+
+ protected AbstractModification(InstanceIdentifier path) {
+ this.path = path;
+ }
+}
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
new file mode 100644
index 0000000000..9319f79e73
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModification.java
@@ -0,0 +1,36 @@
+/*
+ * 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.List;
+
+/**
+ * CompositeModification contains a list of modifications that need to be applied to the DOMStore
+ *
+ * A CompositeModification gets stored in the transaction log for a Shard. During recovery when the transaction log
+ * 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);
+ }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModification.java
new file mode 100644
index 0000000000..063ec3e1fc
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModification.java
@@ -0,0 +1,26 @@
+/*
+ * 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 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+/**
+ * DeleteModification store all the parameters required to delete a path from the data tree
+ */
+public class DeleteModification extends AbstractModification {
+ public DeleteModification(InstanceIdentifier path) {
+ super(path);
+ }
+
+ @Override
+ public void apply(DOMStoreWriteTransaction transaction) {
+ transaction.delete(path);
+ }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MergeModification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MergeModification.java
new file mode 100644
index 0000000000..0457a78280
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MergeModification.java
@@ -0,0 +1,31 @@
+/*
+ * 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 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * MergeModification stores all the parameters required to merge data into the specified path
+ */
+public class MergeModification extends AbstractModification{
+ private final NormalizedNode data;
+
+
+ public MergeModification(InstanceIdentifier path, NormalizedNode data) {
+ super(path);
+ this.data = data;
+ }
+
+ @Override
+ public void apply(DOMStoreWriteTransaction transaction) {
+ transaction.merge(path, data);
+ }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/Modification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/Modification.java
new file mode 100644
index 0000000000..60dbf0f4b1
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/Modification.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+/**
+ * Represents a modification to the data store.
+ *
+ * Simple modifications can be of type,
+ *
{@link org.opendaylight.controller.cluster.datastore.modification.WriteModification}
+ * {@link org.opendaylight.controller.cluster.datastore.modification.MergeModification}
+ * {@link org.opendaylight.controller.cluster.datastore.modification.DeleteModification}
+ *
+ *
+ *
+ * Modifications can in turn be lumped into a single {@link org.opendaylight.controller.cluster.datastore.modification.CompositeModification}
+ * which can then be applied to a write transaction
+ *
+ */
+public interface Modification {
+ /**
+ * Apply the modification to the specified transaction
+ * @param transaction
+ */
+ void apply(DOMStoreWriteTransaction transaction);
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/WriteModification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/WriteModification.java
new file mode 100644
index 0000000000..c5b12d071a
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/WriteModification.java
@@ -0,0 +1,31 @@
+/*
+ * 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 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * WriteModification stores all the parameters required to write data to the specified path
+ */
+public class WriteModification extends AbstractModification {
+ private final NormalizedNode data;
+
+
+ public WriteModification(InstanceIdentifier path, NormalizedNode data) {
+ super(path);
+ this.data = data;
+ }
+
+ @Override
+ public void apply(DOMStoreWriteTransaction transaction) {
+ transaction.write(path, data);
+ }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModificationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModificationTest.java
new file mode 100644
index 0000000000..efaca5d4f6
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModificationTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.Before;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public abstract class AbstractModificationTest {
+
+ protected InMemoryDOMDataStore store;
+
+ @Before
+ public void setUp(){
+ store = new InMemoryDOMDataStore("test", MoreExecutors.sameThreadExecutor());
+ store.onGlobalContextUpdated(TestModel.createTestContext());
+ }
+
+ protected void commitTransaction(DOMStoreWriteTransaction transaction){
+ DOMStoreThreePhaseCommitCohort cohort = transaction.ready();
+ cohort.preCommit();
+ cohort.commit();
+ }
+
+ protected Optional> readData(InstanceIdentifier path) throws Exception{
+ DOMStoreReadTransaction transaction = store.newReadOnlyTransaction();
+ ListenableFuture>> future = transaction.read(path);
+ return future.get();
+ }
+}
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/CompositeModificationTest.java
new file mode 100644
index 0000000000..21f96c71c3
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/CompositeModificationTest.java
@@ -0,0 +1,28 @@
+package org.opendaylight.controller.cluster.datastore.modification;
+
+import com.google.common.base.Optional;
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+public class CompositeModificationTest extends AbstractModificationTest {
+
+ @Test
+ public void testApply() throws Exception {
+
+ CompositeModification compositeModification = new CompositeModification();
+ compositeModification.addModification(new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)));
+
+ DOMStoreReadWriteTransaction transaction = store.newReadWriteTransaction();
+ compositeModification.apply(transaction);
+ commitTransaction(transaction);
+
+ Optional> data = readData(TestModel.TEST_PATH);
+
+ Assert.assertNotNull(data.get());
+ Assert.assertEquals(TestModel.TEST_QNAME, data.get().getNodeType());
+ }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModificationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModificationTest.java
new file mode 100644
index 0000000000..c1f9f3a631
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModificationTest.java
@@ -0,0 +1,35 @@
+package org.opendaylight.controller.cluster.datastore.modification;
+
+import com.google.common.base.Optional;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+public class DeleteModificationTest extends AbstractModificationTest{
+
+ @Test
+ public void testApply() throws Exception {
+ //Write something into the datastore
+ DOMStoreReadWriteTransaction writeTransaction = store.newReadWriteTransaction();
+ WriteModification writeModification = new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+ writeModification.apply(writeTransaction);
+ commitTransaction(writeTransaction);
+
+ //Check if it's in the datastore
+ Optional> data = readData(TestModel.TEST_PATH);
+ Assert.assertTrue(data.isPresent());
+
+ //Delete stuff from the datastore
+ DOMStoreWriteTransaction deleteTransaction = store.newWriteOnlyTransaction();
+ DeleteModification deleteModification = new DeleteModification(TestModel.TEST_PATH);
+ deleteModification.apply(deleteTransaction);
+ commitTransaction(deleteTransaction);
+
+ data = readData(TestModel.TEST_PATH);
+ Assert.assertFalse(data.isPresent());
+ }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MergeModificationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MergeModificationTest.java
new file mode 100644
index 0000000000..fd125fb79d
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MergeModificationTest.java
@@ -0,0 +1,28 @@
+package org.opendaylight.controller.cluster.datastore.modification;
+
+import com.google.common.base.Optional;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+public class MergeModificationTest extends AbstractModificationTest{
+
+ @Test
+ public void testApply() throws Exception {
+ //TODO : Need to write a better test for this
+
+ //Write something into the datastore
+ DOMStoreReadWriteTransaction writeTransaction = store.newReadWriteTransaction();
+ MergeModification writeModification = new MergeModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+ writeModification.apply(writeTransaction);
+ commitTransaction(writeTransaction);
+
+ //Check if it's in the datastore
+ Optional> data = readData(TestModel.TEST_PATH);
+ Assert.assertTrue(data.isPresent());
+
+ }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/WriteModificationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/WriteModificationTest.java
new file mode 100644
index 0000000000..e206bf8196
--- /dev/null
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/WriteModificationTest.java
@@ -0,0 +1,26 @@
+package org.opendaylight.controller.cluster.datastore.modification;
+
+import com.google.common.base.Optional;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+public class WriteModificationTest extends AbstractModificationTest{
+
+ @Test
+ public void testApply() throws Exception {
+ //Write something into the datastore
+ DOMStoreReadWriteTransaction writeTransaction = store.newReadWriteTransaction();
+ WriteModification writeModification = new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+ writeModification.apply(writeTransaction);
+ commitTransaction(writeTransaction);
+
+ //Check if it's in the datastore
+ Optional> data = readData(TestModel.TEST_PATH);
+ Assert.assertTrue(data.isPresent());
+
+ }
+}
\ No newline at end of file
--
2.36.6