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%2Fsharding%2FDistributedShardedDOMDataTreeTest.java;h=9a855a9a883aabc1ceb8fe858e76d7566d77e1f1;hp=33a8e59935fed6917a34b36bd7a3bfcdbc30e52c;hb=2fd1fa721510a30f58b3bc277deb05fce58badd6;hpb=149feb98f151186975fe42bab5853e05aafd4b51 diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/sharding/DistributedShardedDOMDataTreeTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/sharding/DistributedShardedDOMDataTreeTest.java index 33a8e59935..9a855a9a88 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/sharding/DistributedShardedDOMDataTreeTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/sharding/DistributedShardedDOMDataTreeTest.java @@ -10,8 +10,9 @@ package org.opendaylight.controller.cluster.sharding; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.mockito.Matchers.anyCollection; -import static org.mockito.Matchers.anyMap; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -25,19 +26,22 @@ import akka.actor.ActorRef; import akka.actor.ActorSystem; import akka.actor.Address; import akka.actor.AddressFromURIString; +import akka.actor.Props; import akka.cluster.Cluster; -import akka.testkit.JavaTestKit; -import com.google.common.base.Optional; +import akka.testkit.javadsl.TestKit; import com.google.common.collect.Lists; -import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FluentFuture; +import com.google.common.util.concurrent.ListenableFuture; import com.typesafe.config.ConfigFactory; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletionStage; +import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -49,19 +53,25 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.opendaylight.controller.cluster.ActorSystemProvider; import org.opendaylight.controller.cluster.access.concepts.MemberName; +import org.opendaylight.controller.cluster.databroker.actors.dds.ClientLocalHistory; +import org.opendaylight.controller.cluster.databroker.actors.dds.ClientTransaction; +import org.opendaylight.controller.cluster.databroker.actors.dds.DataStoreClient; +import org.opendaylight.controller.cluster.databroker.actors.dds.SimpleDataStoreClientActor; import org.opendaylight.controller.cluster.datastore.AbstractTest; import org.opendaylight.controller.cluster.datastore.DatastoreContext; import org.opendaylight.controller.cluster.datastore.DatastoreContext.Builder; import org.opendaylight.controller.cluster.datastore.DistributedDataStore; import org.opendaylight.controller.cluster.datastore.IntegrationTestKit; +import org.opendaylight.controller.cluster.datastore.utils.ActorContext; import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils; +import org.opendaylight.controller.cluster.dom.api.CDSDataTreeProducer; +import org.opendaylight.controller.cluster.dom.api.CDSShardAccess; import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal; import org.opendaylight.controller.cluster.raft.utils.InMemorySnapshotStore; import org.opendaylight.controller.cluster.sharding.DistributedShardFactory.DistributedShardRegistration; import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper; import org.opendaylight.controller.md.cluster.datastore.model.TestModel; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.mdsal.common.api.TransactionCommitFailedException; import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier; import org.opendaylight.mdsal.dom.api.DOMDataTreeListener; @@ -100,7 +110,7 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { .node(TestModel.INNER_LIST_QNAME)); private static final Set SINGLE_MEMBER = Collections.singleton(AbstractTest.MEMBER_NAME); - private static final String MODULE_SHARDS_CONFIG = "module-shards-cars-member-1.conf"; + private static final String MODULE_SHARDS_CONFIG = "module-shards-default-member-1.conf"; private ActorSystem leaderSystem; @@ -108,8 +118,7 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { DatastoreContext.newBuilder() .shardHeartbeatIntervalInMillis(100) .shardElectionTimeoutFactor(2) - .logicalStoreType( - org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION); + .logicalStoreType(LogicalDatastoreType.CONFIGURATION); private DistributedDataStore leaderDistributedDataStore; private DistributedDataStore operDistributedDatastore; @@ -139,7 +148,7 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { } @After - public void tearDown() throws Exception { + public void tearDown() { if (leaderDistributedDataStore != null) { leaderDistributedDataStore.close(); } @@ -148,20 +157,20 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { operDistributedDatastore.close(); } - JavaTestKit.shutdownActorSystem(leaderSystem); + TestKit.shutdownActorSystem(leaderSystem); InMemoryJournal.clear(); InMemorySnapshotStore.clear(); } - private void initEmptyDatastores() { + private void initEmptyDatastores() throws Exception { leaderTestKit = new IntegrationTestKit(leaderSystem, leaderDatastoreContextBuilder); - leaderDistributedDataStore = (DistributedDataStore) leaderTestKit.setupDistributedDataStore( + leaderDistributedDataStore = leaderTestKit.setupDistributedDataStore( "config", MODULE_SHARDS_CONFIG, "empty-modules.conf", true, SchemaContextHelper.distributedShardedDOMDataTreeSchemaContext()); - operDistributedDatastore = (DistributedDataStore) leaderTestKit.setupDistributedDataStore( + operDistributedDatastore = leaderTestKit.setupDistributedDataStore( "operational", MODULE_SHARDS_CONFIG, "empty-modules.conf",true, SchemaContextHelper.distributedShardedDOMDataTreeSchemaContext()); @@ -195,11 +204,11 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { cursor.write(test.getIdentifier(), test); cursor.close(); - tx.submit().checkedGet(); + tx.commit().get(); } @Test - public void testSingleNodeWrites() throws Exception { + public void testSingleNodeWritesAndRead() throws Exception { initEmptyDatastores(); final DistributedShardRegistration shardRegistration = waitOnAsyncTask( @@ -225,7 +234,7 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { cursor.close(); LOG.debug("Got to pre submit"); - tx.submit().checkedGet(); + tx.commit().get(); final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class); doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap()); @@ -237,7 +246,7 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { captorForSubtrees.capture()); final List> capturedValue = captorForChanges.getAllValues(); - final Optional> dataAfter = + final java.util.Optional> dataAfter = capturedValue.get(0).iterator().next().getRootNode().getDataAfter(); final NormalizedNode expected = ImmutableContainerNodeBuilder.create() @@ -246,6 +255,26 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { verifyNoMoreInteractions(mockedDataTreeListener); + final String shardName = ClusterUtils.getCleanShardName(TEST_ID.getRootIdentifier()); + LOG.debug("Creating distributed datastore client for shard {}", shardName); + + final ActorContext actorContext = leaderDistributedDataStore.getActorContext(); + final Props distributedDataStoreClientProps = + SimpleDataStoreClientActor.props(actorContext.getCurrentMemberName(), + "Shard-" + shardName, actorContext, shardName); + + final ActorRef clientActor = leaderSystem.actorOf(distributedDataStoreClientProps); + final DataStoreClient distributedDataStoreClient = SimpleDataStoreClientActor + .getDistributedDataStoreClient(clientActor, 30, TimeUnit.SECONDS); + + final ClientLocalHistory localHistory = distributedDataStoreClient.createLocalHistory(); + final ClientTransaction tx2 = localHistory.createTransaction(); + final FluentFuture>> read = tx2.read(YangInstanceIdentifier.EMPTY); + + final Optional> optional = read.get(); + tx2.abort(); + localHistory.close(); + shardRegistration.close().toCompletableFuture().get(); } @@ -292,9 +321,9 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { cursor.write(new NodeIdentifier(TestModel.INNER_LIST_QNAME), innerList); cursor.close(); - tx.submit().checkedGet(); + tx.commit().get(); - final ArrayList> futures = new ArrayList<>(); + final ArrayList> futures = new ArrayList<>(); for (int i = 0; i < 1000; i++) { final Collection innerListMapEntries = createInnerListMapEntries(1000, "run-" + i); for (final MapEntryNode innerListMapEntry : innerListMapEntries) { @@ -304,11 +333,11 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { oid1.node(new NodeIdentifier(TestModel.INNER_LIST_QNAME)))); cursor1.write(innerListMapEntry.getIdentifier(), innerListMapEntry); cursor1.close(); - futures.add(tx1.submit()); + futures.add(tx1.commit()); } } - futures.get(futures.size() - 1).checkedGet(); + futures.get(futures.size() - 1).get(); final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class); doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap()); @@ -335,8 +364,8 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { } // top level shard at TEST element, with subshards on each outer-list map entry - @Ignore("https://bugs.opendaylight.org/show_bug.cgi?id=8116") @Test + @Ignore public void testMultipleShardLevels() throws Exception { initEmptyDatastores(); @@ -377,7 +406,7 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { cursor.write(testNode.getIdentifier(), testNode); cursor.close(); - transaction.submit().checkedGet(); + transaction.commit().get(); final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class); doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap()); @@ -392,13 +421,12 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { cursor.write(wholeList.getIdentifier(), wholeList); cursor.close(); - transaction.submit().checkedGet(); + transaction.commit().get(); leaderShardFactory.registerListener(mockedDataTreeListener, Collections.singletonList(TEST_ID), true, Collections.emptyList()); - // need 6 invocations, first initial thats from the parent shard, and then each individual subshard - verify(mockedDataTreeListener, timeout(20000).times(6)).onDataTreeChanged(captorForChanges.capture(), + verify(mockedDataTreeListener, timeout(35000).atLeast(2)).onDataTreeChanged(captorForChanges.capture(), captorForSubtrees.capture()); verifyNoMoreInteractions(mockedDataTreeListener); final List>> allSubtrees = captorForSubtrees.getAllValues(); @@ -448,6 +476,40 @@ public class DistributedShardedDOMDataTreeTest extends AbstractTest { } } + @Test + public void testCDSDataTreeProducer() throws Exception { + initEmptyDatastores(); + + final DistributedShardRegistration reg1 = waitOnAsyncTask(leaderShardFactory.createDistributedShard( + TEST_ID, Lists.newArrayList(AbstractTest.MEMBER_NAME)), + DistributedShardedDOMDataTree.SHARD_FUTURE_TIMEOUT_DURATION); + + leaderTestKit.waitUntilLeader(leaderDistributedDataStore.getActorContext(), + ClusterUtils.getCleanShardName(TestModel.TEST_PATH)); + + assertNotNull(findLocalShard(leaderDistributedDataStore.getActorContext(), + ClusterUtils.getCleanShardName(TestModel.TEST_PATH))); + + + final DOMDataTreeIdentifier configRoot = + new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY); + final DOMDataTreeProducer producer = leaderShardFactory.createProducer(Collections.singleton(configRoot)); + + assertTrue(producer instanceof CDSDataTreeProducer); + + final CDSDataTreeProducer cdsProducer = (CDSDataTreeProducer) producer; + CDSShardAccess shardAccess = cdsProducer.getShardAccess(TEST_ID); + assertEquals(shardAccess.getShardIdentifier(), TEST_ID); + + shardAccess = cdsProducer.getShardAccess(INNER_LIST_ID); + assertEquals(TEST_ID, shardAccess.getShardIdentifier()); + + shardAccess = cdsProducer.getShardAccess(configRoot); + assertEquals(configRoot, shardAccess.getShardIdentifier()); + + waitOnAsyncTask(reg1.close(), DistributedShardedDOMDataTree.SHARD_FUTURE_TIMEOUT_DURATION); + } + private static Collection createOuterEntries(final int amount, final String valuePrefix) { final Collection ret = new ArrayList<>(); for (int i = 0; i < amount; i++) {