From 8e59d67f1b7580c2135cbcc229d4c377c8cc1b09 Mon Sep 17 00:00:00 2001 From: Jakub Toth Date: Thu, 8 Aug 2019 08:15:17 -0400 Subject: [PATCH] Custom scheme-cache-directory yang models are not replicated among cluster members The problem was talking about the MissingSchemaSources, where in the master wasn't setup schema repo & schema registry correctly based on the data from NetconfNode (from NetconfTopologySetup). Espacially if the node was using the specific schema cache directory. According to, slaves were trying to ask the master for sources (YangTextSchemaSource). In this way, master was trying to resolve sources from the empty schema repo and it was failing there. JIRA: NETCONF-610 Change-Id: I84290c085b8a54a9758a85b68113c18aee284a1c Signed-off-by: Jakub Toth --- .../singleton/impl/NetconfNodeManager.java | 13 ++--- .../impl/NetconfTopologyContext.java | 8 +-- .../impl/actors/NetconfNodeActor.java | 16 +++--- .../singleton/messages/RefreshSlaveActor.java | 5 +- .../singleton/impl/NetconfNodeActorTest.java | 52 +++++++++++++++---- .../impl/NetconfNodeManagerTest.java | 3 +- 6 files changed, 57 insertions(+), 40 deletions(-) diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManager.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManager.java index 81cc43e3e6..95c86efcbd 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManager.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManager.java @@ -38,8 +38,6 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository; -import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scala.concurrent.Future; @@ -55,8 +53,6 @@ class NetconfNodeManager private final Timeout actorResponseWaitTime; private final DOMMountPointService mountPointService; - private final SchemaSourceRegistry schemaRegistry; - private final SchemaRepository schemaRepository; private volatile NetconfTopologySetup setup; private volatile ListenerRegistration dataChangeListenerRegistration; @@ -76,8 +72,6 @@ class NetconfNodeManager final DOMMountPointService mountPointService) { this.setup = setup; this.id = id; - this.schemaRegistry = setup.getSchemaResourcesDTO().getSchemaRegistry(); - this.schemaRepository = setup.getSchemaResourcesDTO().getSchemaRepository(); this.actorResponseWaitTime = actorResponseWaitTime; this.mountPointService = mountPointService; } @@ -212,13 +206,12 @@ class NetconfNodeManager @GuardedBy("this") private void createOrUpdateActorRef() { if (slaveActorRef == null) { - slaveActorRef = setup.getActorSystem().actorOf(NetconfNodeActor.props(setup, id, schemaRegistry, - schemaRepository, actorResponseWaitTime, mountPointService)); + slaveActorRef = setup.getActorSystem().actorOf(NetconfNodeActor.props(setup, id, actorResponseWaitTime, + mountPointService)); LOG.debug("{}: Slave actor created with name {}", id, slaveActorRef); } else { slaveActorRef - .tell(new RefreshSlaveActor(setup, id, schemaRegistry, schemaRepository, actorResponseWaitTime), - ActorRef.noSender()); + .tell(new RefreshSlaveActor(setup, id, actorResponseWaitTime), ActorRef.noSender()); } } diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java index 09e0fefc68..4d101833ef 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java @@ -7,8 +7,6 @@ */ package org.opendaylight.netconf.topology.singleton.impl; -import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY; - import akka.actor.ActorRef; import akka.cluster.Cluster; import akka.dispatch.OnComplete; @@ -18,7 +16,6 @@ import com.google.common.base.Preconditions; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.util.concurrent.atomic.AtomicBoolean; -import javax.annotation.Nonnull; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; @@ -82,8 +79,7 @@ class NetconfTopologyContext implements ClusterSingletonService, AutoCloseable { final String masterAddress = Cluster.get(netconfTopologyDeviceSetup.getActorSystem()).selfAddress().toString(); masterActorRef = netconfTopologyDeviceSetup.getActorSystem().actorOf(NetconfNodeActor.props( - netconfTopologyDeviceSetup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY, DEFAULT_SCHEMA_REPOSITORY, - actorResponseWaitTime, mountService), + netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime, mountService), NetconfTopologyUtils.createMasterActorName(remoteDeviceId.getName(), masterAddress)); remoteDeviceConnector.startRemoteDeviceConnection(newMasterSalFacade()); @@ -135,7 +131,7 @@ class NetconfTopologyContext implements ClusterSingletonService, AutoCloseable { * Refresh, if configuration data was changed. * @param setup new setup */ - void refresh(@Nonnull final NetconfTopologySetup setup) { + void refresh(final NetconfTopologySetup setup) { netconfTopologyDeviceSetup = Preconditions.checkNotNull(setup); remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(), netconfTopologyDeviceSetup.getNode().augmentation(NetconfNode.class)); diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/actors/NetconfNodeActor.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/actors/NetconfNodeActor.java index 3893b22821..1cf7b9904e 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/actors/NetconfNodeActor.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/actors/NetconfNodeActor.java @@ -87,23 +87,19 @@ public class NetconfNodeActor extends AbstractUntypedActor { private ActorRef readTxActor; private List> registeredSchemas; - public static Props props(final NetconfTopologySetup setup, - final RemoteDeviceId id, final SchemaSourceRegistry schemaRegistry, - final SchemaRepository schemaRepository, final Timeout actorResponseWaitTime, - final DOMMountPointService mountPointService) { + public static Props props(final NetconfTopologySetup setup, final RemoteDeviceId id, + final Timeout actorResponseWaitTime, final DOMMountPointService mountPointService) { return Props.create(NetconfNodeActor.class, () -> - new NetconfNodeActor(setup, id, schemaRegistry, schemaRepository, actorResponseWaitTime, - mountPointService)); + new NetconfNodeActor(setup, id, actorResponseWaitTime, mountPointService)); } protected NetconfNodeActor(final NetconfTopologySetup setup, - final RemoteDeviceId id, final SchemaSourceRegistry schemaRegistry, - final SchemaRepository schemaRepository, final Timeout actorResponseWaitTime, + final RemoteDeviceId id, final Timeout actorResponseWaitTime, final DOMMountPointService mountPointService) { this.setup = setup; this.id = id; - this.schemaRegistry = schemaRegistry; - this.schemaRepository = schemaRepository; + this.schemaRegistry = setup.getSchemaResourcesDTO().getSchemaRegistry(); + this.schemaRepository = setup.getSchemaResourcesDTO().getSchemaRepository(); this.actorResponseWaitTime = actorResponseWaitTime; this.writeTxIdleTimeout = setup.getIdleTimeout(); this.mountPointService = mountPointService; diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RefreshSlaveActor.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RefreshSlaveActor.java index 95798f66ac..10bc07ff41 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RefreshSlaveActor.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RefreshSlaveActor.java @@ -23,12 +23,11 @@ public class RefreshSlaveActor { private final Timeout actorResponseWaitTime; public RefreshSlaveActor(final NetconfTopologySetup setup, final RemoteDeviceId id, - final SchemaSourceRegistry schemaRegistry, final SchemaRepository schemaRepository, final Timeout actorResponseWaitTime) { this.setup = setup; this.id = id; - this.schemaRegistry = schemaRegistry; - this.schemaRepository = schemaRepository; + this.schemaRegistry = setup.getSchemaResourcesDTO().getSchemaRegistry(); + this.schemaRepository = setup.getSchemaResourcesDTO().getSchemaRepository(); this.actorResponseWaitTime = actorResponseWaitTime; } diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java index 4f79e46c1a..8065c32f17 100644 --- a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java +++ b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.MockitoAnnotations.initMocks; +import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY; import akka.actor.ActorRef; import akka.actor.ActorSystem; @@ -69,6 +70,7 @@ import org.opendaylight.mdsal.dom.api.DOMRpcException; import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice.SchemaResourcesDTO; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor; import org.opendaylight.netconf.topology.singleton.impl.utils.ClusteringRpcException; @@ -158,6 +160,9 @@ public class NetconfNodeActorTest { @Mock private SchemaContext mockSchemaContext; + @Mock + private SchemaResourcesDTO schemaResourceDTO; + @Before public void setup() { initMocks(this); @@ -168,11 +173,12 @@ public class NetconfNodeActorTest { masterSchemaRepository.registerSchemaSourceListener( TextToASTTransformer.create(masterSchemaRepository, masterSchemaRepository)); + doReturn(masterSchemaRepository).when(schemaResourceDTO).getSchemaRepository(); + doReturn(mockRegistry).when(schemaResourceDTO).getSchemaRegistry(); final NetconfTopologySetup setup = NetconfTopologySetupBuilder.create().setActorSystem(system) - .setIdleTimeout(Duration.apply(1, TimeUnit.SECONDS)).build(); + .setIdleTimeout(Duration.apply(1, TimeUnit.SECONDS)).setSchemaResourceDTO(schemaResourceDTO).build(); - final Props props = NetconfNodeActor.props(setup, remoteDeviceId, masterSchemaRepository, - masterSchemaRepository, TIMEOUT, mockMountPointService); + final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService); masterRef = TestActorRef.create(system, props, "master_messages"); @@ -205,7 +211,8 @@ public class NetconfNodeActorTest { final RemoteDeviceId newRemoteDeviceId = new RemoteDeviceId("netconf-topology2", new InetSocketAddress(InetAddresses.forString("127.0.0.2"), 9999)); - final NetconfTopologySetup newSetup = NetconfTopologySetupBuilder.create().setActorSystem(system).build(); + final NetconfTopologySetup newSetup = NetconfTopologySetupBuilder.create() + .setSchemaResourceDTO(schemaResourceDTO).setActorSystem(system).build(); masterRef.tell(new RefreshSetupMasterActorData(newSetup, newRemoteDeviceId), testKit.getRef()); @@ -310,10 +317,14 @@ public class NetconfNodeActorTest { @SuppressWarnings("unchecked") @Test public void testRegisterMountPointWithSchemaFailures() throws Exception { - final NetconfTopologySetup setup = NetconfTopologySetupBuilder.create().setActorSystem(system).build(); + SchemaResourcesDTO schemaResourceDTO2 = mock(SchemaResourcesDTO.class); + doReturn(mockRegistry).when(schemaResourceDTO2).getSchemaRegistry(); + doReturn(mockSchemaRepository).when(schemaResourceDTO2).getSchemaRepository(); + final NetconfTopologySetup setup = NetconfTopologySetupBuilder.create().setSchemaResourceDTO(schemaResourceDTO2) + .setActorSystem(system).build(); - final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props(setup, remoteDeviceId, mockRegistry, - mockSchemaRepository, TIMEOUT, mockMountPointService)); + final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, + mockMountPointService)); // Test unrecoverable failure. @@ -383,6 +394,26 @@ public class NetconfNodeActorTest { verify(mockSchemaRepository, times(2)).createSchemaContextFactory(any(SchemaSourceFilter.class)); } + @Test(expected = MissingSchemaSourceException.class) + public void testMissingSchemaSourceOnMissingProvider() throws Exception { + SchemaResourcesDTO schemaResourceDTO2 = mock(SchemaResourcesDTO.class); + doReturn(DEFAULT_SCHEMA_REPOSITORY).when(schemaResourceDTO2).getSchemaRegistry(); + doReturn(DEFAULT_SCHEMA_REPOSITORY).when(schemaResourceDTO2).getSchemaRepository(); + final NetconfTopologySetup setup = NetconfTopologySetupBuilder.create().setActorSystem(system) + .setSchemaResourceDTO(schemaResourceDTO2).setIdleTimeout(Duration.apply(1, TimeUnit.SECONDS)).build(); + final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService); + ActorRef actor = TestActorRef.create(system, props, "master_messages_2"); + + final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("testID"); + + final ProxyYangTextSourceProvider proxyYangProvider = + new ProxyYangTextSourceProvider(actor, system.dispatcher(), TIMEOUT); + + final Future resolvedSchemaFuture = + proxyYangProvider.getYangTextSchemaSource(sourceIdentifier); + Await.result(resolvedSchemaFuture, TIMEOUT.duration()); + } + @Test public void testYangTextSchemaSourceRequest() throws Exception { final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("testID"); @@ -522,9 +553,12 @@ public class NetconfNodeActorTest { } private ActorRef registerSlaveMountPoint() { + SchemaResourcesDTO schemaResourceDTO2 = mock(SchemaResourcesDTO.class); + doReturn(mockRegistry).when(schemaResourceDTO2).getSchemaRegistry(); + doReturn(mockSchemaRepository).when(schemaResourceDTO2).getSchemaRepository(); final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props( - NetconfTopologySetupBuilder.create().setActorSystem(system).build(), remoteDeviceId, mockRegistry, - mockSchemaRepository, TIMEOUT, mockMountPointService)); + NetconfTopologySetupBuilder.create().setSchemaResourceDTO(schemaResourceDTO2).setActorSystem(system) + .build(), remoteDeviceId, TIMEOUT, mockMountPointService)); doReturn(Futures.immediateFuture(mockSchemaContext)) .when(mockSchemaContextFactory).createSchemaContext(any()); diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java index d7bd0de49e..d0219758db 100644 --- a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java +++ b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java @@ -392,8 +392,7 @@ public class NetconfNodeManagerTest { TestMasterActor(final NetconfTopologySetup setup, final RemoteDeviceId deviceId, final Timeout actorResponseWaitTime, final DOMMountPointService mountPointService) { - super(setup, deviceId, setup.getSchemaResourcesDTO().getSchemaRegistry(), - setup.getSchemaResourcesDTO().getSchemaRepository(), actorResponseWaitTime, mountPointService); + super(setup, deviceId, actorResponseWaitTime, mountPointService); } @SuppressWarnings({ "rawtypes", "unchecked" }) -- 2.36.6