X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fnetconf-topology-singleton%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Ftopology%2Fsingleton%2Fimpl%2FMountPointEndToEndTest.java;h=44fcf748e1db5fe84ed5516e21b2bf663407491d;hb=29c57bb8a9d5f6cecd2c890c614709b83a7f516e;hp=b19a2cca2079ba04b035217c198ff925a06d1253;hpb=6ab1941217e38336ae5970a29505f9bb21d4ef21;p=netconf.git diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java index b19a2cca20..44fcf748e1 100644 --- a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java +++ b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java @@ -14,22 +14,23 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static org.mockito.MockitoAnnotations.initMocks; import akka.actor.ActorSystem; import akka.testkit.javadsl.TestKit; import akka.util.Timeout; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.FluentFuture; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; @@ -37,13 +38,14 @@ import com.google.common.util.concurrent.SettableFuture; import com.typesafe.config.ConfigFactory; import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.GlobalEventExecutor; -import io.netty.util.concurrent.SucceededFuture; import java.io.File; import java.util.AbstractMap.SimpleEntry; -import java.util.Arrays; -import java.util.Collections; +import java.util.ArrayList; import java.util.Iterator; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -51,49 +53,58 @@ import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.controller.cluster.ActorSystemProvider; import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; import org.opendaylight.controller.config.threadpool.ThreadPool; -import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; -import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; -import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; -import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec; -import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest; -import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.TransactionChain; -import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; -import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; -import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction; -import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction; -import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; -import org.opendaylight.controller.md.sal.dom.api.DOMService; -import org.opendaylight.controller.md.sal.dom.broker.impl.DOMRpcRouter; -import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl; -import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult; -import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener; -import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext; -import org.opendaylight.mdsal.eos.dom.simple.SimpleDOMEntityOwnershipService; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; +import org.opendaylight.mdsal.binding.api.DataTreeModification; +import org.opendaylight.mdsal.binding.api.ReadTransaction; +import org.opendaylight.mdsal.binding.api.RpcProviderService; +import org.opendaylight.mdsal.binding.api.Transaction; +import org.opendaylight.mdsal.binding.api.TransactionChain; +import org.opendaylight.mdsal.binding.api.TransactionChainListener; +import org.opendaylight.mdsal.binding.api.WriteTransaction; +import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractConcurrentDataBrokerTest; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers; +import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.mdsal.dom.api.DOMActionProviderService; +import org.opendaylight.mdsal.dom.api.DOMActionService; +import org.opendaylight.mdsal.dom.api.DOMDataBroker; +import org.opendaylight.mdsal.dom.api.DOMDataTreeReadOperations; +import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; +import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; +import org.opendaylight.mdsal.dom.api.DOMMountPoint; +import org.opendaylight.mdsal.dom.api.DOMMountPointListener; +import org.opendaylight.mdsal.dom.api.DOMMountPointService; +import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier; +import org.opendaylight.mdsal.dom.api.DOMRpcImplementation; +import org.opendaylight.mdsal.dom.api.DOMRpcProviderService; +import org.opendaylight.mdsal.dom.api.DOMRpcResult; +import org.opendaylight.mdsal.dom.api.DOMRpcService; +import org.opendaylight.mdsal.dom.api.DOMService; +import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl; +import org.opendaylight.mdsal.dom.broker.DOMRpcRouter; +import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; import org.opendaylight.mdsal.singleton.dom.impl.DOMClusterSingletonServiceProviderImpl; import org.opendaylight.netconf.client.NetconfClientDispatcher; +import org.opendaylight.netconf.nettyutil.ReconnectFuture; +import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory; +import org.opendaylight.netconf.sal.connect.api.SchemaResourceManager; +import org.opendaylight.netconf.sal.connect.impl.DefaultSchemaResourceManager; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice.SchemaResourcesDTO; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; +import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.topology.singleton.impl.utils.ClusteringRpcException; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils; @@ -110,24 +121,32 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.Config; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.ConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.GetTopInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.GetTopOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.PutTopInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.rfc8528.data.util.EmptyMountPointContext; +import org.opendaylight.yangtools.util.concurrent.FluentFutures; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; -import org.opendaylight.yangtools.yang.binding.util.BindingReflections; +import org.opendaylight.yangtools.yang.common.ErrorTag; +import org.opendaylight.yangtools.yang.common.ErrorType; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; @@ -135,13 +154,13 @@ import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier; +import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource; +import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -150,24 +169,30 @@ import org.slf4j.LoggerFactory; * * @author Thomas Pantelis */ -public class MountPointEndToEndTest { - private static Logger LOG = LoggerFactory.getLogger(MountPointEndToEndTest.class); +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class MountPointEndToEndTest extends AbstractBaseSchemasTest { + private static final Logger LOG = LoggerFactory.getLogger(MountPointEndToEndTest.class); private static final String TOP_MODULE_NAME = "opendaylight-mdsal-list-test"; private static final String ACTOR_SYSTEM_NAME = "test"; private static final String TOPOLOGY_ID = TopologyNetconf.QNAME.getLocalName(); - private static final NodeId NODE_ID = new NodeId("node-id"); - private static final InstanceIdentifier NODE_INSTANCE_ID = NetconfTopologyUtils.createTopologyNodeListPath( - new NodeKey(NODE_ID), TOPOLOGY_ID); + private static final KeyedInstanceIdentifier NODE_INSTANCE_ID = + NetconfTopologyUtils.createTopologyNodeListPath(new NodeKey(new NodeId("node-id")), TOPOLOGY_ID); - @Mock private RpcProviderRegistry mockRpcProviderRegistry; + private static final String TEST_ROOT_DIRECTORY = "test-cache-root"; + private static final String TEST_DEFAULT_SUBDIR = "test-schema"; + + @Mock private DOMRpcProviderService mockRpcProviderRegistry; + @Mock private RpcProviderService mockRpcProviderService; + @Mock private DOMActionProviderService mockActionProviderRegistry; @Mock private NetconfClientDispatcher mockClientDispatcher; @Mock private AAAEncryptionService mockEncryptionService; @Mock private ThreadPool mockThreadPool; @Mock private ScheduledThreadPool mockKeepaliveExecutor; + @Mock private DeviceActionFactory deviceActionFactory; @Mock private ActorSystemProvider mockMasterActorSystemProvider; - @Mock private MountProvisionListener masterMountPointListener; + @Mock private DOMMountPointListener masterMountPointListener; private final DOMMountPointService masterMountPointService = new DOMMountPointServiceImpl(); private final DOMRpcRouter deviceRpcService = new DOMRpcRouter(); private DOMClusterSingletonServiceProviderImpl masterClusterSingletonServiceProvider; @@ -180,43 +205,44 @@ public class MountPointEndToEndTest { @Mock private ActorSystemProvider mockSlaveActorSystemProvider; @Mock private ClusterSingletonServiceProvider mockSlaveClusterSingletonServiceProvider; @Mock private ClusterSingletonServiceRegistration mockSlaveClusterSingletonServiceReg; - @Mock private MountProvisionListener slaveMountPointListener; + @Mock private DOMMountPointListener slaveMountPointListener; private final DOMMountPointService slaveMountPointService = new DOMMountPointServiceImpl(); private DataBroker slaveDataBroker; private ActorSystem slaveSystem; private NetconfTopologyManager slaveNetconfTopologyManager; private final SettableFuture slaveNetconfTopologyContextFuture = SettableFuture.create(); - private BindingTransactionChain slaveTxChain; + private TransactionChain slaveTxChain; private final EventExecutor eventExecutor = GlobalEventExecutor.INSTANCE; - private final Config config = new ConfigBuilder().setWriteTransactionIdleTimeout(0).build(); - private SchemaContext deviceSchemaContext; + private final Config config = new ConfigBuilder().setWriteTransactionIdleTimeout(Uint16.ZERO).build(); + private EffectiveModelContext deviceSchemaContext; private YangModuleInfo topModuleInfo; - private SchemaPath putTopRpcSchemaPath; - private SchemaPath getTopRpcSchemaPath; - private BindingToNormalizedNodeCodec bindingToNormalized; + private QName putTopRpcSchemaPath; + private QName getTopRpcSchemaPath; + private BindingNormalizedNodeSerializer bindingToNormalized; private YangInstanceIdentifier yangNodeInstanceId; private final TopDOMRpcImplementation topRpcImplementation = new TopDOMRpcImplementation(); + private final ContainerNode getTopInput = ImmutableNodes.containerNode(GetTopInput.QNAME); + + private SchemaResourceManager resourceManager; - @SuppressWarnings({ "unchecked", "rawtypes" }) @Before public void setUp() throws Exception { - initMocks(this); - deleteCacheDir(); + resourceManager = new DefaultSchemaResourceManager(new DefaultYangParserFactory(), TEST_ROOT_DIRECTORY, + TEST_DEFAULT_SUBDIR); + topModuleInfo = BindingReflections.getModuleInfo(Top.class); - final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create(); - moduleContext.addModuleInfos(Arrays.asList(topModuleInfo)); - deviceSchemaContext = moduleContext.tryToCreateSchemaContext().get(); + deviceSchemaContext = BindingRuntimeHelpers.createEffectiveModel(Top.class); - deviceRpcService.onGlobalContextUpdated(deviceSchemaContext); + deviceRpcService.onModelContextUpdated(deviceSchemaContext); - putTopRpcSchemaPath = findRpcDefinition("put-top").getPath(); - getTopRpcSchemaPath = findRpcDefinition("get-top").getPath(); + putTopRpcSchemaPath = findRpcDefinition("put-top").getQName(); + getTopRpcSchemaPath = findRpcDefinition("get-top").getQName(); - deviceRpcService.registerRpcImplementation(topRpcImplementation, + deviceRpcService.getRpcProviderService().registerRpcImplementation(topRpcImplementation, DOMRpcIdentifier.create(putTopRpcSchemaPath), DOMRpcIdentifier.create(getTopRpcSchemaPath)); setupMaster(); @@ -225,54 +251,58 @@ public class MountPointEndToEndTest { yangNodeInstanceId = bindingToNormalized.toYangInstanceIdentifier(NODE_INSTANCE_ID); - doReturn(new SucceededFuture(GlobalEventExecutor.INSTANCE, null)).when(mockClientDispatcher) - .createReconnectingClient(any()); + doReturn(mock(ReconnectFuture.class)).when(mockClientDispatcher).createReconnectingClient(any()); LOG.info("****** Setup complete"); } - private void deleteCacheDir() { - FileUtils.deleteQuietly(new File(NetconfTopologyUtils.CACHE_DIRECTORY)); + private static void deleteCacheDir() { + FileUtils.deleteQuietly(new File(TEST_ROOT_DIRECTORY)); } @After public void tearDown() throws Exception { deleteCacheDir(); - TestKit.shutdownActorSystem(slaveSystem, Boolean.TRUE); - TestKit.shutdownActorSystem(masterSystem, Boolean.TRUE); + TestKit.shutdownActorSystem(slaveSystem, true); + TestKit.shutdownActorSystem(masterSystem, true); } private void setupMaster() throws Exception { AbstractConcurrentDataBrokerTest dataBrokerTest = newDataBrokerTest(); masterDataBroker = dataBrokerTest.getDataBroker(); deviceDOMDataBroker = dataBrokerTest.getDomBroker(); - bindingToNormalized = dataBrokerTest.getDataBrokerTestCustomizer().getBindingToNormalized(); + bindingToNormalized = dataBrokerTest.getDataBrokerTestCustomizer().getAdapterContext().currentSerializer(); masterSystem = ActorSystem.create(ACTOR_SYSTEM_NAME, ConfigFactory.load().getConfig("Master")); - masterClusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl( - new SimpleDOMEntityOwnershipService()); + masterClusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(); masterClusterSingletonServiceProvider.initializeProvider(); doReturn(masterSystem).when(mockMasterActorSystemProvider).getActorSystem(); doReturn(MoreExecutors.newDirectExecutorService()).when(mockThreadPool).getExecutor(); - NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY.registerSchemaSource( + final SchemaResourcesDTO resources = resourceManager.getSchemaResources( + new NetconfNodeBuilder().setSchemaCacheDirectory(TEST_DEFAULT_SUBDIR).build(), "test"); + resources.getSchemaRegistry().registerSchemaSource( id -> Futures.immediateFuture(YangTextSchemaSource.delegateForByteSource(id, topModuleInfo.getYangTextByteSource())), - PotentialSchemaSource.create(RevisionSourceIdentifier.create(TOP_MODULE_NAME, - topModuleInfo.getName().getRevision()), YangTextSchemaSource.class, 1)); - - masterNetconfTopologyManager = new NetconfTopologyManager(masterDataBroker, mockRpcProviderRegistry, - masterClusterSingletonServiceProvider, mockKeepaliveExecutor, mockThreadPool, - mockMasterActorSystemProvider, eventExecutor, mockClientDispatcher, TOPOLOGY_ID, config, - masterMountPointService, mockEncryptionService) { + PotentialSchemaSource.create(new SourceIdentifier(TOP_MODULE_NAME, + topModuleInfo.getName().getRevision().map(Revision::toString).orElse(null)), + YangTextSchemaSource.class, 1)); + + masterNetconfTopologyManager = new NetconfTopologyManager(BASE_SCHEMAS, masterDataBroker, + mockRpcProviderRegistry, mockActionProviderRegistry, masterClusterSingletonServiceProvider, + mockKeepaliveExecutor, mockThreadPool, mockMasterActorSystemProvider, eventExecutor, + mockClientDispatcher, TOPOLOGY_ID, config, masterMountPointService, mockEncryptionService, + mockRpcProviderService, deviceActionFactory, resourceManager) { @Override - protected NetconfTopologyContext newNetconfTopologyContext(NetconfTopologySetup setup, - ServiceGroupIdentifier serviceGroupIdent, Timeout actorResponseWaitTime) { + protected NetconfTopologyContext newNetconfTopologyContext(final NetconfTopologySetup setup, + final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime, + final DeviceActionFactory deviceActionFact) { NetconfTopologyContext context = - super.newNetconfTopologyContext(setup, serviceGroupIdent, actorResponseWaitTime); + super.newNetconfTopologyContext(setup, serviceGroupIdent, actorResponseWaitTime, deviceActionFact); + NetconfTopologyContext spiedContext = spy(context); doAnswer(invocation -> { final MasterSalFacade spiedFacade = (MasterSalFacade) spy(invocation.callRealMethod()); @@ -301,15 +331,18 @@ public class MountPointEndToEndTest { doReturn(mockSlaveClusterSingletonServiceReg).when(mockSlaveClusterSingletonServiceProvider) .registerClusterSingletonService(any()); - slaveNetconfTopologyManager = new NetconfTopologyManager(slaveDataBroker, mockRpcProviderRegistry, - mockSlaveClusterSingletonServiceProvider, mockKeepaliveExecutor, mockThreadPool, + slaveNetconfTopologyManager = new NetconfTopologyManager(BASE_SCHEMAS, slaveDataBroker, mockRpcProviderRegistry, + mockActionProviderRegistry, mockSlaveClusterSingletonServiceProvider, mockKeepaliveExecutor, mockThreadPool, mockSlaveActorSystemProvider, eventExecutor, mockClientDispatcher, TOPOLOGY_ID, config, - slaveMountPointService, mockEncryptionService) { + slaveMountPointService, mockEncryptionService, mockRpcProviderService, deviceActionFactory, + resourceManager) { @Override - protected NetconfTopologyContext newNetconfTopologyContext(NetconfTopologySetup setup, - ServiceGroupIdentifier serviceGroupIdent, Timeout actorResponseWaitTime) { - NetconfTopologyContext spiedContext = - spy(super.newNetconfTopologyContext(setup, serviceGroupIdent, actorResponseWaitTime)); + protected NetconfTopologyContext newNetconfTopologyContext(final NetconfTopologySetup setup, + final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime, + final DeviceActionFactory actionFactory) { + NetconfTopologyContext spiedContext = spy(super.newNetconfTopologyContext(setup, serviceGroupIdent, + actorResponseWaitTime, actionFactory)); + slaveNetconfTopologyContextFuture.set(spiedContext); return spiedContext; } @@ -321,12 +354,12 @@ public class MountPointEndToEndTest { slaveTxChain = slaveDataBroker.createTransactionChain(new TransactionChainListener() { @Override - public void onTransactionChainSuccessful(TransactionChain chain) { + public void onTransactionChainSuccessful(final TransactionChain chain) { } @Override - public void onTransactionChainFailed(TransactionChain chain, AsyncTransaction transaction, - Throwable cause) { + public void onTransactionChainFailed(final TransactionChain chain, final Transaction transaction, + final Throwable cause) { LOG.error("Slave transaction chain failed", cause); } }); @@ -348,12 +381,14 @@ public class MountPointEndToEndTest { private MasterSalFacade testMaster() throws InterruptedException, ExecutionException, TimeoutException { LOG.info("****** Testing master"); - writeNetconfNode(NetconfTopologyUtils.DEFAULT_CACHE_DIRECTORY, masterDataBroker); + writeNetconfNode(TEST_DEFAULT_SUBDIR, masterDataBroker); final MasterSalFacade masterSalFacade = masterSalFacadeFuture.get(5, TimeUnit.SECONDS); + final ArrayList capabilities = Lists.newArrayList( + NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString()); - masterSalFacade.onDeviceConnected(deviceSchemaContext, - NetconfSessionPreferences.fromStrings(Collections.emptyList()), deviceRpcService); + masterSalFacade.onDeviceConnected(new EmptyMountPointContext(deviceSchemaContext), + NetconfSessionPreferences.fromStrings(capabilities), deviceRpcService.getRpcService()); DOMMountPoint masterMountPoint = awaitMountPoint(masterMountPointService); @@ -378,7 +413,7 @@ public class MountPointEndToEndTest { // This is essentially what happens in a clustered environment but we'll use a DTCL here. masterDataBroker.registerDataTreeChangeListener( - new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, NODE_INSTANCE_ID), changes -> { + DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, NODE_INSTANCE_ID), changes -> { final WriteTransaction slaveTx = slaveTxChain.newWriteOnlyTransaction(); for (DataTreeModification dataTreeModification : changes) { DataObjectModification rootNode = dataTreeModification.getRootNode(); @@ -421,14 +456,16 @@ public class MountPointEndToEndTest { slaveMountPointService.registerProvisionListener(slaveMountPointListener); masterSalFacadeFuture = SettableFuture.create(); - writeNetconfNode(NetconfTopologyUtils.DEFAULT_CACHE_DIRECTORY, masterDataBroker); + writeNetconfNode(TEST_DEFAULT_SUBDIR, masterDataBroker); verify(masterMountPointListener, timeout(5000)).onMountPointRemoved(yangNodeInstanceId); MasterSalFacade masterSalFacade = masterSalFacadeFuture.get(5, TimeUnit.SECONDS); + final ArrayList capabilities = Lists.newArrayList( + NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString()); - masterSalFacade.onDeviceConnected(deviceSchemaContext, - NetconfSessionPreferences.fromStrings(Collections.emptyList()), deviceRpcService); + masterSalFacade.onDeviceConnected(new EmptyMountPointContext(deviceSchemaContext), + NetconfSessionPreferences.fromStrings(capabilities), deviceRpcService.getRpcService()); verify(masterMountPointListener, timeout(5000)).onMountPointCreated(yangNodeInstanceId); @@ -447,11 +484,11 @@ public class MountPointEndToEndTest { awaitMountPointNotPresent(masterMountPointService); await().atMost(5, TimeUnit.SECONDS).until(() -> { - try (ReadOnlyTransaction readTx = masterDataBroker.newReadOnlyTransaction()) { + try (ReadTransaction readTx = masterDataBroker.newReadOnlyTransaction()) { Optional node = readTx.read(LogicalDatastoreType.OPERATIONAL, NODE_INSTANCE_ID).get(5, TimeUnit.SECONDS); assertTrue(node.isPresent()); - final NetconfNode netconfNode = node.get().getAugmentation(NetconfNode.class); + final NetconfNode netconfNode = node.get().augmentation(NetconfNode.class); return netconfNode.getConnectionStatus() != NetconfNodeConnectionStatus.ConnectionStatus.Connected; } }); @@ -466,37 +503,42 @@ public class MountPointEndToEndTest { verify(mockSlaveClusterSingletonServiceReg).close(); } - private void testDOMRpcService(DOMRpcService domRpcService) + private void testDOMRpcService(final DOMRpcService domRpcService) throws InterruptedException, ExecutionException, TimeoutException { - testPutTopRpc(domRpcService, new DefaultDOMRpcResult((NormalizedNode)null)); + testPutTopRpc(domRpcService, new DefaultDOMRpcResult((NormalizedNode)null)); testPutTopRpc(domRpcService, null); testPutTopRpc(domRpcService, new DefaultDOMRpcResult(ImmutableList.of( - RpcResultBuilder.newError(ErrorType.APPLICATION, "tag1", "error1"), - RpcResultBuilder.newError(ErrorType.APPLICATION, "tag2", "error2")))); + RpcResultBuilder.newError(ErrorType.APPLICATION, new ErrorTag("tag1"), "error1"), + RpcResultBuilder.newError(ErrorType.APPLICATION, new ErrorTag("tag2"), "error2")))); testGetTopRpc(domRpcService, new DefaultDOMRpcResult(bindingToNormalized.toNormalizedNodeRpcData( - new GetTopOutputBuilder().setTopLevelList(Arrays.asList(new TopLevelListBuilder().setName("one") - .build())).build()))); + new GetTopOutputBuilder().setTopLevelList(oneTopLevelList()).build()))); - testFailedRpc(domRpcService, getTopRpcSchemaPath, null); + testFailedRpc(domRpcService, getTopRpcSchemaPath, getTopInput); } - private void testPutTopRpc(DOMRpcService domRpcService, DOMRpcResult result) + private void testPutTopRpc(final DOMRpcService domRpcService, final DOMRpcResult result) throws InterruptedException, ExecutionException, TimeoutException { ContainerNode putTopInput = bindingToNormalized.toNormalizedNodeRpcData( - new PutTopInputBuilder().setTopLevelList(Arrays.asList(new TopLevelListBuilder().setName("one") - .build())).build()); + new PutTopInputBuilder().setTopLevelList(oneTopLevelList()).build()); testRpc(domRpcService, putTopRpcSchemaPath, putTopInput, result); } - private void testGetTopRpc(DOMRpcService domRpcService, DOMRpcResult result) + private static Map oneTopLevelList() { + final TopLevelListKey key = new TopLevelListKey("one"); + return ImmutableMap.of(key, new TopLevelListBuilder().withKey(key).build()); + } + + private void testGetTopRpc(final DOMRpcService domRpcService, final DOMRpcResult result) throws InterruptedException, ExecutionException, TimeoutException { - testRpc(domRpcService, getTopRpcSchemaPath, null, result); + testRpc(domRpcService, getTopRpcSchemaPath, getTopInput, result); } - private void testRpc(DOMRpcService domRpcService, SchemaPath schemaPath, NormalizedNode input, - DOMRpcResult result) throws InterruptedException, ExecutionException, TimeoutException { - final DOMRpcResult actual = invokeRpc(domRpcService, schemaPath, input, Futures.immediateCheckedFuture(result)); + private void testRpc(final DOMRpcService domRpcService, final QName qname, final NormalizedNode input, + final DOMRpcResult result) throws InterruptedException, ExecutionException, TimeoutException { + final FluentFuture future = result == null ? FluentFutures.immediateNullFluentFuture() + : FluentFutures.immediateFluentFuture(result); + final DOMRpcResult actual = invokeRpc(domRpcService, qname, input, future); if (result == null) { assertNull(actual); return; @@ -506,8 +548,8 @@ public class MountPointEndToEndTest { assertEquals(result.getResult(), actual.getResult()); assertEquals(result.getErrors().size(), actual.getErrors().size()); - Iterator iter1 = result.getErrors().iterator(); - Iterator iter2 = actual.getErrors().iterator(); + Iterator iter1 = result.getErrors().iterator(); + Iterator iter2 = actual.getErrors().iterator(); while (iter1.hasNext() && iter2.hasNext()) { RpcError err1 = iter1.next(); RpcError err2 = iter2.next(); @@ -520,10 +562,10 @@ public class MountPointEndToEndTest { } } - private void testFailedRpc(DOMRpcService domRpcService, SchemaPath schemaPath, NormalizedNode input) - throws InterruptedException, TimeoutException { + private void testFailedRpc(final DOMRpcService domRpcService, final QName qname, final NormalizedNode input) + throws InterruptedException, TimeoutException { try { - invokeRpc(domRpcService, schemaPath, input, Futures.immediateFailedCheckedFuture( + invokeRpc(domRpcService, qname, input, FluentFutures.immediateFailedFluentFuture( new ClusteringRpcException("mock"))); fail("Expected exception"); } catch (ExecutionException e) { @@ -532,21 +574,21 @@ public class MountPointEndToEndTest { } } - private DOMRpcResult invokeRpc(DOMRpcService domRpcService, SchemaPath schemaPath, NormalizedNode input, - CheckedFuture returnFuture) - throws InterruptedException, ExecutionException, TimeoutException { + private DOMRpcResult invokeRpc(final DOMRpcService domRpcService, final QName qname, final NormalizedNode input, + final FluentFuture returnFuture) + throws InterruptedException, ExecutionException, TimeoutException { topRpcImplementation.init(returnFuture); - final ListenableFuture resultFuture = domRpcService.invokeRpc(schemaPath, input); + final ListenableFuture resultFuture = domRpcService.invokeRpc(qname, input); - topRpcImplementation.verify(DOMRpcIdentifier.create(schemaPath), input); + topRpcImplementation.verify(DOMRpcIdentifier.create(qname), input); return resultFuture.get(5, TimeUnit.SECONDS); } - private static void testDOMDataBrokerOperations(DOMDataBroker dataBroker) + private static void testDOMDataBrokerOperations(final DOMDataBroker dataBroker) throws InterruptedException, ExecutionException, TimeoutException { - DOMDataWriteTransaction writeTx = dataBroker.newWriteOnlyTransaction(); + DOMDataTreeWriteTransaction writeTx = dataBroker.newWriteOnlyTransaction(); final ContainerNode topNode = Builders.containerBuilder() .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(Top.QNAME)).build(); @@ -568,37 +610,43 @@ public class MountPointEndToEndTest { writeTx.delete(LogicalDatastoreType.CONFIGURATION, topPath); writeTx.commit().get(5, TimeUnit.SECONDS); - DOMDataReadWriteTransaction readTx = dataBroker.newReadWriteTransaction(); + DOMDataTreeReadWriteTransaction readTx = dataBroker.newReadWriteTransaction(); assertFalse(readTx.exists(LogicalDatastoreType.CONFIGURATION, topPath).get(5, TimeUnit.SECONDS)); assertTrue(readTx.cancel()); } - private static void writeNetconfNode(String cacheDir, DataBroker databroker) + private static void writeNetconfNode(final String cacheDir, final DataBroker databroker) throws InterruptedException, ExecutionException, TimeoutException { - final NetconfNode netconfNode = new NetconfNodeBuilder() - .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1")))) - .setPort(new PortNumber(1234)) - .setActorResponseWaitTime(10) - .setTcpOnly(Boolean.TRUE) - .setSchemaless(Boolean.FALSE) - .setKeepaliveDelay(0L) - .setConnectionTimeoutMillis(5000L) - .setDefaultRequestTimeoutMillis(5000L) - .setMaxConnectionAttempts(1L) - .setCredentials(new LoginPwUnencryptedBuilder().setLoginPasswordUnencrypted( - new LoginPasswordUnencryptedBuilder().setUsername("user").setPassword("pass").build()).build()) - .setSchemaCacheDirectory(cacheDir) + final Node node = new NodeBuilder() + .withKey(NODE_INSTANCE_ID.getKey()) + .addAugmentation(new NetconfNodeBuilder() + .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1")))) + .setPort(new PortNumber(Uint16.valueOf(1234))) + .setActorResponseWaitTime(Uint16.valueOf(10)) + .setTcpOnly(Boolean.TRUE) + .setSchemaless(Boolean.FALSE) + .setKeepaliveDelay(Uint32.ZERO) + .setConnectionTimeoutMillis(Uint32.valueOf(5000)) + .setDefaultRequestTimeoutMillis(Uint32.valueOf(5000)) + .setMaxConnectionAttempts(Uint32.ONE) + .setCredentials(new LoginPwUnencryptedBuilder() + .setLoginPasswordUnencrypted(new LoginPasswordUnencryptedBuilder() + .setUsername("user") + .setPassword("pass") + .build()) + .build()) + .setSchemaCacheDirectory(cacheDir) + .build()) .build(); - final Node node = new NodeBuilder().setNodeId(NODE_ID).addAugmentation(NetconfNode.class, netconfNode).build(); final WriteTransaction writeTx = databroker.newWriteOnlyTransaction(); writeTx.put(LogicalDatastoreType.CONFIGURATION, NODE_INSTANCE_ID, node); writeTx.commit().get(5, TimeUnit.SECONDS); } - private static void verifyDataInStore(DOMDataReadTransaction readTx, YangInstanceIdentifier path, - NormalizedNode expNode) throws InterruptedException, ExecutionException, TimeoutException { - final Optional> read = readTx.read(LogicalDatastoreType.CONFIGURATION, path) + private static void verifyDataInStore(final DOMDataTreeReadOperations readTx, final YangInstanceIdentifier path, + final NormalizedNode expNode) throws InterruptedException, ExecutionException, TimeoutException { + final Optional read = readTx.read(LogicalDatastoreType.CONFIGURATION, path) .get(5, TimeUnit.SECONDS); assertTrue(read.isPresent()); assertEquals(expNode, read.get()); @@ -607,9 +655,9 @@ public class MountPointEndToEndTest { assertTrue(exists); } - private static void verifyTopologyNodesCreated(DataBroker dataBroker) { + private static void verifyTopologyNodesCreated(final DataBroker dataBroker) { await().atMost(5, TimeUnit.SECONDS).until(() -> { - try (ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction()) { + try (ReadTransaction readTx = dataBroker.newReadOnlyTransaction()) { Optional configTopology = readTx.read(LogicalDatastoreType.CONFIGURATION, NetconfTopologyUtils.createTopologyListPath(TOPOLOGY_ID)).get(3, TimeUnit.SECONDS); Optional operTopology = readTx.read(LogicalDatastoreType.OPERATIONAL, @@ -622,7 +670,7 @@ public class MountPointEndToEndTest { private AbstractConcurrentDataBrokerTest newDataBrokerTest() throws Exception { AbstractConcurrentDataBrokerTest dataBrokerTest = new AbstractConcurrentDataBrokerTest(true) { @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(NetconfNode.class), BindingReflections.getModuleInfo(NetworkTopology.class), BindingReflections.getModuleInfo(Topology.class), @@ -635,34 +683,38 @@ public class MountPointEndToEndTest { return dataBrokerTest; } - private void awaitMountPointNotPresent(DOMMountPointService mountPointService) { + private void awaitMountPointNotPresent(final DOMMountPointService mountPointService) { await().atMost(5, TimeUnit.SECONDS).until( - () -> !mountPointService.getMountPoint(yangNodeInstanceId).isPresent()); + () -> mountPointService.getMountPoint(yangNodeInstanceId).isEmpty()); } - private static DOMDataBroker getDOMDataBroker(DOMMountPoint mountPoint) { + private static DOMDataBroker getDOMDataBroker(final DOMMountPoint mountPoint) { return getMountPointService(mountPoint, DOMDataBroker.class); } - private static DOMRpcService getDOMRpcService(DOMMountPoint mountPoint) { + private static DOMRpcService getDOMRpcService(final DOMMountPoint mountPoint) { return getMountPointService(mountPoint, DOMRpcService.class); } - private static T getMountPointService(DOMMountPoint mountPoint, Class serviceClass) { + private static DOMActionService getDomActionService(final DOMMountPoint mountPoint) { + return getMountPointService(mountPoint, DOMActionService.class); + } + + private static T getMountPointService(final DOMMountPoint mountPoint, + final Class serviceClass) { final Optional maybeService = mountPoint.getService(serviceClass); assertTrue(maybeService.isPresent()); return maybeService.get(); } - private DOMMountPoint awaitMountPoint(DOMMountPointService mountPointService) { - await().atMost(5, TimeUnit.SECONDS).until(() -> { - return mountPointService.getMountPoint(yangNodeInstanceId).isPresent(); - }); + private DOMMountPoint awaitMountPoint(final DOMMountPointService mountPointService) { + await().atMost(5, TimeUnit.SECONDS).until(() -> + mountPointService.getMountPoint(yangNodeInstanceId).isPresent()); return mountPointService.getMountPoint(yangNodeInstanceId).get(); } - private RpcDefinition findRpcDefinition(String rpc) { + private RpcDefinition findRpcDefinition(final String rpc) { Module topModule = deviceSchemaContext.findModule(TOP_MODULE_NAME, topModuleInfo.getName().getRevision()).get(); RpcDefinition rpcDefinition = null; for (RpcDefinition def: topModule.getRpcs()) { @@ -677,24 +729,23 @@ public class MountPointEndToEndTest { } private static class TopDOMRpcImplementation implements DOMRpcImplementation { - private volatile SettableFuture>> rpcInvokedFuture; - private volatile CheckedFuture returnFuture; + private volatile SettableFuture> rpcInvokedFuture; + private volatile FluentFuture returnFuture; @Override - public CheckedFuture invokeRpc(DOMRpcIdentifier rpc, - NormalizedNode input) { + public FluentFuture invokeRpc(final DOMRpcIdentifier rpc, final NormalizedNode input) { rpcInvokedFuture.set(new SimpleEntry<>(rpc, input)); return returnFuture; } - void init(CheckedFuture retFuture) { - this.returnFuture = retFuture; + void init(final FluentFuture retFuture) { + returnFuture = retFuture; rpcInvokedFuture = SettableFuture.create(); } - void verify(DOMRpcIdentifier expRpc, NormalizedNode expInput) + void verify(final DOMRpcIdentifier expRpc, final NormalizedNode expInput) throws InterruptedException, ExecutionException, TimeoutException { - final Entry> actual = rpcInvokedFuture.get(5, TimeUnit.SECONDS); + final Entry actual = rpcInvokedFuture.get(5, TimeUnit.SECONDS); assertEquals(expRpc, actual.getKey()); assertEquals(expInput, actual.getValue()); }