Bug 7521: Convert byte[] to ShardManagerSnapshot in DatastoreSnapshot
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / DistributedDataStoreIntegrationTest.java
index 4d81442ba6ce3c574a443f0636080f2215654483..e5b14b021e64aa770691aaf06e647ecc4ae4b3f3 100644 (file)
@@ -30,7 +30,10 @@ import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
 import com.google.common.util.concurrent.Uninterruptibles;
 import com.typesafe.config.ConfigFactory;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
 import java.io.IOException;
+import java.io.ObjectOutputStream;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -48,14 +51,17 @@ import org.mockito.Mockito;
 import org.opendaylight.controller.cluster.databroker.ConcurrentDOMDataBroker;
 import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException;
 import org.opendaylight.controller.cluster.datastore.exceptions.NotInitializedException;
-import org.opendaylight.controller.cluster.datastore.messages.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.messages.FindLocalShard;
 import org.opendaylight.controller.cluster.datastore.messages.LocalShardFound;
+import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.MetadataShardDataTreeSnapshot;
+import org.opendaylight.controller.cluster.datastore.persisted.PayloadVersion;
+import org.opendaylight.controller.cluster.datastore.persisted.ShardSnapshotState;
 import org.opendaylight.controller.cluster.datastore.utils.MockDataChangeListener;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
-import org.opendaylight.controller.cluster.raft.Snapshot;
+import org.opendaylight.controller.cluster.raft.persisted.Snapshot;
 import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
+import org.opendaylight.controller.cluster.raft.utils.InMemorySnapshotStore;
 import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
 import org.opendaylight.controller.md.cluster.datastore.model.PeopleModel;
 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
@@ -97,7 +103,7 @@ public class DistributedDataStoreIntegrationTest {
     @BeforeClass
     public static void setUpClass() throws IOException {
         system = ActorSystem.create("cluster-test", ConfigFactory.load().getConfig("Member1"));
-        Address member1Address = AddressFromURIString.parse("akka.tcp://cluster-test@127.0.0.1:2558");
+        Address member1Address = AddressFromURIString.parse("akka://cluster-test@127.0.0.1:2558");
         Cluster.get(system).join(member1Address);
     }
 
@@ -115,7 +121,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testWriteTransactionWithSingleShard() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore("transactionIntegrationTest",
+                try (AbstractDataStore dataStore = setupDistributedDataStore("transactionIntegrationTest",
                         "test-1")) {
 
                     testWriteTransaction(dataStore, TestModel.TEST_PATH,
@@ -132,7 +138,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testWriteTransactionWithMultipleShards() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testWriteTransactionWithMultipleShards", "cars-1", "people-1")) {
 
                     DOMStoreWriteTransaction writeTx = dataStore.newWriteOnlyTransaction();
@@ -180,10 +186,9 @@ public class DistributedDataStoreIntegrationTest {
 
     @Test
     public void testReadWriteTransactionWithSingleShard() throws Exception {
-        System.setProperty("shard.persistent", "true");
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testReadWriteTransactionWithSingleShard", "test-1")) {
 
                     // 1. Create a read-write Tx
@@ -230,7 +235,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testReadWriteTransactionWithMultipleShards() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testReadWriteTransactionWithMultipleShards", "cars-1", "people-1")) {
 
                     DOMStoreReadWriteTransaction readWriteTx = dataStore.newReadWriteTransaction();
@@ -288,7 +293,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testSingleTransactionsWritesInQuickSuccession() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testSingleTransactionsWritesInQuickSuccession", "cars-1")) {
 
                     DOMStoreTransactionChain txChain = dataStore.createTransactionChain();
@@ -331,7 +336,7 @@ public class DistributedDataStoreIntegrationTest {
                 CountDownLatch blockRecoveryLatch = new CountDownLatch(1);
                 InMemoryJournal.addBlockReadMessagesLatch(persistentID, blockRecoveryLatch);
 
-                try (DistributedDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
+                try (AbstractDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
 
                     // Create the write Tx
 
@@ -437,7 +442,7 @@ public class DistributedDataStoreIntegrationTest {
                 CountDownLatch blockRecoveryLatch = new CountDownLatch(1);
                 InMemoryJournal.addBlockReadMessagesLatch(persistentID, blockRecoveryLatch);
 
-                try (DistributedDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
+                try (AbstractDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
 
                     // Create the read-write Tx
 
@@ -520,7 +525,7 @@ public class DistributedDataStoreIntegrationTest {
 
                 InMemoryJournal.addEntry(persistentID, 1, "Dummy data so akka will read from persistence");
 
-                try (DistributedDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
+                try (AbstractDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
 
                     // Create the write Tx
 
@@ -598,7 +603,7 @@ public class DistributedDataStoreIntegrationTest {
 
                 InMemoryJournal.addEntry(persistentID, 1, "Dummy data so akka will read from persistence");
 
-                try (DistributedDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
+                try (AbstractDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
 
                     // Create the read-write Tx
 
@@ -675,7 +680,7 @@ public class DistributedDataStoreIntegrationTest {
                 datastoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(1)
                         .shardInitializationTimeout(200, TimeUnit.MILLISECONDS);
 
-                try (DistributedDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
+                try (AbstractDataStore dataStore = setupDistributedDataStore(testName, false, shardName)) {
 
                     Object result = dataStore.getActorContext().executeOperation(
                             dataStore.getActorContext().getShardManager(), new FindLocalShard(shardName, true));
@@ -683,7 +688,7 @@ public class DistributedDataStoreIntegrationTest {
 
                     // Create the write Tx.
 
-                    try (final DOMStoreWriteTransaction writeTx = writeOnly ? dataStore.newWriteOnlyTransaction()
+                    try (DOMStoreWriteTransaction writeTx = writeOnly ? dataStore.newWriteOnlyTransaction()
                             : dataStore.newReadWriteTransaction()) {
                         assertNotNull("newReadWriteTransaction returned null", writeTx);
 
@@ -753,7 +758,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testTransactionAbort() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore("transactionAbortIntegrationTest",
+                try (AbstractDataStore dataStore = setupDistributedDataStore("transactionAbortIntegrationTest",
                         "test-1")) {
 
                     DOMStoreWriteTransaction writeTx = dataStore.newWriteOnlyTransaction();
@@ -779,7 +784,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testTransactionChainWithSingleShard() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore("testTransactionChainWithSingleShard",
+                try (AbstractDataStore dataStore = setupDistributedDataStore("testTransactionChainWithSingleShard",
                         "test-1")) {
 
                     // 1. Create a Tx chain and write-only Tx
@@ -875,7 +880,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testTransactionChainWithMultipleShards() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testTransactionChainWithMultipleShards", "cars-1", "people-1")) {
 
                     DOMStoreTransactionChain txChain = dataStore.createTransactionChain();
@@ -943,7 +948,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testCreateChainedTransactionsInQuickSuccession() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testCreateChainedTransactionsInQuickSuccession", "cars-1")) {
 
                     ConcurrentDOMDataBroker broker = new ConcurrentDOMDataBroker(
@@ -992,7 +997,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testCreateChainedTransactionAfterEmptyTxReadied() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testCreateChainedTransactionAfterEmptyTxReadied", "test-1")) {
 
                     DOMStoreTransactionChain txChain = dataStore.createTransactionChain();
@@ -1016,7 +1021,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testCreateChainedTransactionWhenPreviousNotReady() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testCreateChainedTransactionWhenPreviousNotReady", "test-1")) {
 
                     final DOMStoreTransactionChain txChain = dataStore.createTransactionChain();
@@ -1040,7 +1045,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testCreateChainedTransactionAfterClose() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testCreateChainedTransactionAfterClose", "test-1")) {
 
                     DOMStoreTransactionChain txChain = dataStore.createTransactionChain();
@@ -1060,7 +1065,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testChainWithReadOnlyTxAfterPreviousReady() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testChainWithReadOnlyTxAfterPreviousReady", "test-1")) {
 
                     final DOMStoreTransactionChain txChain = dataStore.createTransactionChain();
@@ -1108,7 +1113,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testChainedTransactionFailureWithSingleShard() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testChainedTransactionFailureWithSingleShard", "cars-1")) {
 
                     ConcurrentDOMDataBroker broker = new ConcurrentDOMDataBroker(
@@ -1148,7 +1153,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testChainedTransactionFailureWithMultipleShards() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore(
+                try (AbstractDataStore dataStore = setupDistributedDataStore(
                         "testChainedTransactionFailureWithMultipleShards", "cars-1", "people-1")) {
 
                     ConcurrentDOMDataBroker broker = new ConcurrentDOMDataBroker(
@@ -1194,7 +1199,7 @@ public class DistributedDataStoreIntegrationTest {
     public void testChangeListenerRegistration() throws Exception {
         new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
             {
-                try (DistributedDataStore dataStore = setupDistributedDataStore("testChangeListenerRegistration",
+                try (AbstractDataStore dataStore = setupDistributedDataStore("testChangeListenerRegistration",
                         "test-1")) {
 
                     testWriteTransaction(dataStore, TestModel.TEST_PATH,
@@ -1255,8 +1260,9 @@ public class DistributedDataStoreIntegrationTest {
                 AbstractShardTest.writeToStore(dataTree, CarsModel.BASE_PATH, carsNode);
                 NormalizedNode<?, ?> root = AbstractShardTest.readStore(dataTree, YangInstanceIdentifier.EMPTY);
 
-                final Snapshot carsSnapshot = Snapshot.create(new MetadataShardDataTreeSnapshot(root).serialize(),
-                        Collections.<ReplicatedLogEntry>emptyList(), 2, 1, 2, 1, 1, "member-1");
+                final Snapshot carsSnapshot = Snapshot.create(
+                        new ShardSnapshotState(new MetadataShardDataTreeSnapshot(root)),
+                        Collections.<ReplicatedLogEntry>emptyList(), 2, 1, 2, 1, 1, "member-1", null);
 
                 NormalizedNode<?, ?> peopleNode = PeopleModel.create();
                 dataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.OPERATIONAL);
@@ -1264,17 +1270,15 @@ public class DistributedDataStoreIntegrationTest {
                 AbstractShardTest.writeToStore(dataTree, PeopleModel.BASE_PATH, peopleNode);
                 root = AbstractShardTest.readStore(dataTree, YangInstanceIdentifier.EMPTY);
 
-                Snapshot peopleSnapshot = Snapshot.create(new MetadataShardDataTreeSnapshot(root).serialize(),
-                        Collections.<ReplicatedLogEntry>emptyList(), 2, 1, 2, 1, 1, "member-1");
+                Snapshot peopleSnapshot = Snapshot.create(
+                        new ShardSnapshotState(new MetadataShardDataTreeSnapshot(root)),
+                        Collections.<ReplicatedLogEntry>emptyList(), 2, 1, 2, 1, 1, "member-1", null);
 
-                restoreFromSnapshot = new DatastoreSnapshot(name, null,
-                        Arrays.asList(
-                                new DatastoreSnapshot.ShardSnapshot("cars",
-                                        org.apache.commons.lang3.SerializationUtils.serialize(carsSnapshot)),
-                                new DatastoreSnapshot.ShardSnapshot("people",
-                                        org.apache.commons.lang3.SerializationUtils.serialize(peopleSnapshot))));
+                restoreFromSnapshot = new DatastoreSnapshot(name, null, Arrays.asList(
+                        new DatastoreSnapshot.ShardSnapshot("cars", carsSnapshot),
+                        new DatastoreSnapshot.ShardSnapshot("people", peopleSnapshot)));
 
-                try (DistributedDataStore dataStore = setupDistributedDataStore(name, "module-shards-member1.conf",
+                try (AbstractDataStore dataStore = setupDistributedDataStore(name, "module-shards-member1.conf",
                         true, "cars", "people")) {
 
                     DOMStoreReadTransaction readTx = dataStore.newReadOnlyTransaction();
@@ -1290,4 +1294,48 @@ public class DistributedDataStoreIntegrationTest {
             }
         };
     }
+
+    @Test
+    @Deprecated
+    public void testRecoveryFromPreCarbonSnapshot() throws Exception {
+        new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
+            {
+                final String name = "testRecoveryFromPreCarbonSnapshot";
+
+                ContainerNode carsNode = CarsModel.newCarsNode(
+                        CarsModel.newCarsMapNode(CarsModel.newCarEntry("optima", BigInteger.valueOf(20000L)),
+                                CarsModel.newCarEntry("sportage", BigInteger.valueOf(30000L))));
+
+                DataTree dataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.OPERATIONAL);
+                dataTree.setSchemaContext(SchemaContextHelper.full());
+                AbstractShardTest.writeToStore(dataTree, CarsModel.BASE_PATH, carsNode);
+                NormalizedNode<?, ?> root = AbstractShardTest.readStore(dataTree, YangInstanceIdentifier.EMPTY);
+
+                MetadataShardDataTreeSnapshot shardSnapshot = new MetadataShardDataTreeSnapshot(root);
+                final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                try (final DataOutputStream dos = new DataOutputStream(bos)) {
+                    PayloadVersion.BORON.writeTo(dos);
+                    try (ObjectOutputStream oos = new ObjectOutputStream(dos)) {
+                        oos.writeObject(shardSnapshot);
+                    }
+                }
+
+                final org.opendaylight.controller.cluster.raft.Snapshot snapshot =
+                    org.opendaylight.controller.cluster.raft.Snapshot.create(bos.toByteArray(),
+                            Collections.<ReplicatedLogEntry>emptyList(), 2, 1, 2, 1, 1, "member-1", null);
+
+                InMemorySnapshotStore.addSnapshot("member-1-shard-cars-" + name, snapshot);
+
+                try (AbstractDataStore dataStore = setupDistributedDataStore(name, "module-shards-member1.conf",
+                        true, "cars")) {
+
+                    DOMStoreReadTransaction readTx = dataStore.newReadOnlyTransaction();
+
+                    Optional<NormalizedNode<?, ?>> optional = readTx.read(CarsModel.BASE_PATH).get(5, TimeUnit.SECONDS);
+                    assertEquals("isPresent", true, optional.isPresent());
+                    assertEquals("Data node", carsNode, optional.get());
+                }
+            }
+        };
+    }
 }