X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2FDistributedDataStoreIntegrationTest.java;h=7b78da29234706a56848031169be919a2f3458a7;hp=fa066ee32e5973347c6ff1fc9d22b31add12bd44;hb=20e100c1377799a60976c4153e4f664578896cb9;hpb=6e6659e77f3e07e157c81332b367dbbd05d21f2b diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java index fa066ee32e..7b78da2923 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java @@ -31,7 +31,9 @@ import com.typesafe.config.ConfigFactory; import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; @@ -43,12 +45,17 @@ import org.junit.Test; import org.mockito.Mockito; 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.utils.MockDataChangeListener; +import org.opendaylight.controller.cluster.datastore.utils.SerializationUtils; +import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry; +import org.opendaylight.controller.cluster.raft.Snapshot; import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal; 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; import org.opendaylight.controller.md.cluster.datastore.model.TestModel; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; @@ -71,6 +78,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; @@ -489,6 +497,8 @@ public class DistributedDataStoreIntegrationTest { CountDownLatch blockRecoveryLatch = new CountDownLatch(1); InMemoryJournal.addBlockReadMessagesLatch(persistentID, blockRecoveryLatch); + InMemoryJournal.addEntry(persistentID, 1, "Dummy data so akka will read from persistence"); + DistributedDataStore dataStore = setupDistributedDataStore(testName, false, shardName); // Create the write Tx @@ -559,6 +569,8 @@ public class DistributedDataStoreIntegrationTest { CountDownLatch blockRecoveryLatch = new CountDownLatch(1); InMemoryJournal.addBlockReadMessagesLatch(persistentID, blockRecoveryLatch); + InMemoryJournal.addEntry(persistentID, 1, "Dummy data so akka will read from persistence"); + DistributedDataStore dataStore = setupDistributedDataStore(testName, false, shardName); // Create the read-write Tx @@ -982,6 +994,51 @@ public class DistributedDataStoreIntegrationTest { }}; } + @Test + public void testChainWithReadOnlyTxAfterPreviousReady() throws Throwable { + new IntegrationTestKit(getSystem(), datastoreContextBuilder) {{ + DistributedDataStore dataStore = setupDistributedDataStore( + "testChainWithReadOnlyTxAfterPreviousReady", "test-1"); + + final DOMStoreTransactionChain txChain = dataStore.createTransactionChain(); + + // Create a write tx and submit. + + DOMStoreWriteTransaction writeTx = txChain.newWriteOnlyTransaction(); + writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); + DOMStoreThreePhaseCommitCohort cohort1 = writeTx.ready(); + + // Create read-only tx's and issue a read. + + CheckedFuture>, ReadFailedException> readFuture1 = + txChain.newReadOnlyTransaction().read(TestModel.TEST_PATH); + + CheckedFuture>, ReadFailedException> readFuture2 = + txChain.newReadOnlyTransaction().read(TestModel.TEST_PATH); + + // Create another write tx and issue the write. + + DOMStoreWriteTransaction writeTx2 = txChain.newWriteOnlyTransaction(); + writeTx2.write(TestModel.OUTER_LIST_PATH, + ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build()); + + // Ensure the reads succeed. + + assertEquals("isPresent", true, readFuture1.checkedGet(5, TimeUnit.SECONDS).isPresent()); + assertEquals("isPresent", true, readFuture2.checkedGet(5, TimeUnit.SECONDS).isPresent()); + + // Ensure the writes succeed. + + DOMStoreThreePhaseCommitCohort cohort2 = writeTx2.ready(); + + doCommit(cohort1); + doCommit(cohort2); + + assertEquals("isPresent", true, txChain.newReadOnlyTransaction().read(TestModel.OUTER_LIST_PATH). + checkedGet(5, TimeUnit.SECONDS).isPresent()); + }}; + } + @Test public void testChainedTransactionFailureWithSingleShard() throws Exception{ new IntegrationTestKit(getSystem(), datastoreContextBuilder) {{ @@ -1106,4 +1163,52 @@ public class DistributedDataStoreIntegrationTest { cleanup(dataStore); }}; } + + @Test + public void testRestoreFromDatastoreSnapshot() throws Exception{ + new IntegrationTestKit(getSystem(), datastoreContextBuilder) {{ + String name = "transactionIntegrationTest"; + + ContainerNode carsNode = CarsModel.newCarsNode(CarsModel.newCarsMapNode( + CarsModel.newCarEntry("optima", BigInteger.valueOf(20000L)), + CarsModel.newCarEntry("sportage", BigInteger.valueOf(30000L)))); + + ShardDataTree dataTree = new ShardDataTree(SchemaContextHelper.full(), TreeType.OPERATIONAL); + AbstractShardTest.writeToStore(dataTree, CarsModel.BASE_PATH, carsNode); + NormalizedNode root = AbstractShardTest.readStore(dataTree.getDataTree(), + YangInstanceIdentifier.builder().build()); + + Snapshot carsSnapshot = Snapshot.create(SerializationUtils.serializeNormalizedNode(root), + Collections.emptyList(), 2, 1, 2, 1, 1, "member-1"); + + NormalizedNode peopleNode = PeopleModel.create(); + dataTree = new ShardDataTree(SchemaContextHelper.full(), TreeType.OPERATIONAL); + AbstractShardTest.writeToStore(dataTree, PeopleModel.BASE_PATH, peopleNode); + root = AbstractShardTest.readStore(dataTree.getDataTree(), YangInstanceIdentifier.builder().build()); + + Snapshot peopleSnapshot = Snapshot.create(SerializationUtils.serializeNormalizedNode(root), + Collections.emptyList(), 2, 1, 2, 1, 1, "member-1"); + + 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)))); + + DistributedDataStore dataStore = setupDistributedDataStore(name, "module-shards-member1.conf", + true, "cars", "people"); + + DOMStoreReadTransaction readTx = dataStore.newReadOnlyTransaction(); + + Optional> optional = readTx.read(CarsModel.BASE_PATH).get(5, TimeUnit.SECONDS); + assertEquals("isPresent", true, optional.isPresent()); + assertEquals("Data node", carsNode, optional.get()); + + optional = readTx.read(PeopleModel.BASE_PATH).get(5, TimeUnit.SECONDS); + assertEquals("isPresent", true, optional.isPresent()); + assertEquals("Data node", peopleNode, optional.get()); + + cleanup(dataStore); + }}; + } }