From 7506ce46c6c1045d98fa3bef735e60649dabc009 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 | 4 +- .../impl/actors/NetconfNodeActor.java | 16 +++--- .../singleton/messages/RefreshSlaveActor.java | 5 +- .../singleton/impl/NetconfNodeActorTest.java | 52 +++++++++++++++---- .../impl/NetconfNodeManagerTest.java | 3 +- 6 files changed, 56 insertions(+), 37 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 61eb8e9e21..d6ee3c53bb 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 @Holding("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 f6c21d979e..673e8a8298 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 @@ -8,7 +8,6 @@ package org.opendaylight.netconf.topology.singleton.impl; import static java.util.Objects.requireNonNull; -import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY; import akka.actor.ActorRef; import akka.cluster.Cluster; @@ -82,8 +81,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()); 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 7f8ff7d836..a3f73e1446 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 @@ -83,23 +83,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 145140011e..b1b887299c 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 @@ -26,6 +26,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; @@ -70,6 +71,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; @@ -159,6 +161,9 @@ public class NetconfNodeActorTest { @Mock private EffectiveModelContext mockSchemaContext; + @Mock + private SchemaResourcesDTO schemaResourceDTO; + @Before public void setup() { initMocks(this); @@ -169,11 +174,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"); @@ -206,7 +212,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()); @@ -311,10 +318,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)).createEffectiveModelContextFactory(); } + @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).createEffectiveModelContext(anyCollection()); 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