Turn NetconfTopologyRPCProvider into a resource 90/107990/3
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 26 Sep 2023 13:41:26 +0000 (15:41 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 26 Sep 2023 15:52:35 +0000 (17:52 +0200)
Rether than exposing ClassToInstanceMap and have users repeat the same
thing, turn the provider into a properly-managed resource which needs
to be cleaned up with close().

JIRA: NETCONF-1116
Change-Id: I77ab5020627ae3ed5632e919d2866b17c46878aa
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
apps/netconf-topology-impl/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java
apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java
apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java
apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java
apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfTopologyRPCProvider.java
apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/NetconfTopologyRPCProviderTest.java

index c7327ec1623e65793717a5830fbf9dc4281bdbd7..372daf415f54a016f210c67ea8f0fc8ae992f325 100644 (file)
@@ -60,7 +60,7 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology
     private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyImpl.class);
 
     private Registration dtclReg;
-    private Registration rpcReg;
+    private NetconfTopologyRPCProvider rpcProvider;
 
     @Inject
     @Activate
@@ -107,17 +107,16 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology
         LOG.debug("Registering datastore listener");
         dtclReg = dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
             LogicalDatastoreType.CONFIGURATION, createTopologyListPath(topologyId).child(Node.class)), this);
-        final var nodeTopologyRpcs = new NetconfTopologyRPCProvider(dataBroker, encryptionService, topologyId);
-        rpcReg = rpcProviderService.registerRpcImplementations(nodeTopologyRpcs.getRpcClassToInstanceMap());
+        rpcProvider = new NetconfTopologyRPCProvider(rpcProviderService, dataBroker, encryptionService, topologyId);
     }
 
     @PreDestroy
     @Deactivate
     @Override
     public void close() {
-        if (rpcReg != null) {
-            rpcReg.close();
-            rpcReg = null;
+        if (rpcProvider != null) {
+            rpcProvider.close();
+            rpcProvider = null;
         }
 
         // close all existing connectors, delete whole topology in datastore?
index 67ef8c19c793b13b0f8c88b9c78a67be57303feb..d80b6f7ec545655cd26023fd98c4e78973f54260 100644 (file)
@@ -62,7 +62,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.TopologyKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.osgi.service.component.annotations.Activate;
@@ -108,14 +107,12 @@ public class NetconfTopologyManager implements ClusteredDataTreeChangeListener<N
     private final String topologyId;
     private final Duration writeTxIdleTimeout;
     private final DOMMountPointService mountPointService;
-    private final AAAEncryptionService encryptionService;
-    private final RpcProviderService rpcProviderService;
     private final DeviceActionFactory deviceActionFactory;
     private final NetconfClientConfigurationBuilderFactory builderFactory;
     private final SchemaResourceManager resourceManager;
 
     private ListenerRegistration<NetconfTopologyManager> dataChangeListenerRegistration;
-    private Registration rpcReg;
+    private NetconfTopologyRPCProvider rpcProvider;
 
     @Activate
     public NetconfTopologyManager(@Reference final BaseNetconfSchemas baseSchemas,
@@ -178,15 +175,12 @@ public class NetconfTopologyManager implements ClusteredDataTreeChangeListener<N
         this.topologyId = requireNonNull(topologyId);
         writeTxIdleTimeout = Duration.ofSeconds(writeTransactionIdleTimeout.toJava());
         this.mountPointService = mountPointService;
-        this.encryptionService = requireNonNull(encryptionService);
-        this.rpcProviderService = requireNonNull(rpcProviderService);
         this.deviceActionFactory = requireNonNull(deviceActionFactory);
         this.resourceManager = requireNonNull(resourceManager);
         this.builderFactory = requireNonNull(builderFactory);
 
         dataChangeListenerRegistration = registerDataTreeChangeListener();
-        final var nodeTopologyRpcs = new NetconfTopologyRPCProvider(dataBroker, encryptionService, topologyId);
-        rpcReg = rpcProviderService.registerRpcImplementations(nodeTopologyRpcs.getRpcClassToInstanceMap());
+        rpcProvider = new NetconfTopologyRPCProvider(rpcProviderService, dataBroker, encryptionService, topologyId);
     }
 
     @Override
@@ -282,9 +276,9 @@ public class NetconfTopologyManager implements ClusteredDataTreeChangeListener<N
     @Deactivate
     @Override
     public void close() {
-        if (rpcReg != null) {
-            rpcReg.close();
-            rpcReg = null;
+        if (rpcProvider != null) {
+            rpcProvider.close();
+            rpcProvider = null;
         }
         if (dataChangeListenerRegistration != null) {
             dataChangeListenerRegistration.close();
index ac3186200e8fc12ae9db32e95cb185c0f7cf3997..b6fe8947b0515bc811a5a049cc7f57b9e124db34 100644 (file)
@@ -134,6 +134,7 @@ 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.NodeBuilder;
 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.concepts.Registration;
 import org.opendaylight.yangtools.util.concurrent.FluentFutures;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -184,6 +185,7 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest {
     private static final String TEST_DEFAULT_SUBDIR = "test-schema";
 
     @Mock private RpcProviderService mockRpcProviderService;
+    @Mock private Registration mockRpcReg;
     @Mock private NetconfClientDispatcher mockClientDispatcher;
     @Mock private AAAEncryptionService mockEncryptionService;
     @Mock private ScheduledExecutorService mockKeepaliveExecutor;
@@ -262,6 +264,8 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest {
         builderFactory = new DefaultNetconfClientConfigurationBuilderFactory(mockEncryptionService, credentialProvider,
             sslHandlerFactoryProvider);
 
+        doReturn(mockRpcReg).when(mockRpcProviderService).registerRpcImplementations(any());
+
         setupMaster();
 
         setupSlave();
index 62e26a52011ef795246694189f0733a6e63eb22d..3827787b3c1ceea4487ebd0e5a05a46f875c1ac2 100644 (file)
@@ -73,6 +73,7 @@ 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.NodeBuilder;
 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.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.common.Uint16;
@@ -87,9 +88,10 @@ public class NetconfTopologyManagerTest extends AbstractBaseSchemasTest {
 
     @Mock
     private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
-
     @Mock
     private ListenerRegistration<?> mockListenerReg;
+    @Mock
+    private Registration mockRpcReg;
 
     private DataBroker dataBroker;
 
@@ -122,6 +124,7 @@ public class NetconfTopologyManagerTest extends AbstractBaseSchemasTest {
 
         doNothing().when(mockListenerReg).close();
         doReturn(mockListenerReg).when(dataBroker).registerDataTreeChangeListener(any(), any());
+        doReturn(mockRpcReg).when(rpcProviderService).registerRpcImplementations(any());
 
         netconfTopologyManager = new NetconfTopologyManager(BASE_SCHEMAS, dataBroker, clusterSingletonServiceProvider,
                 keepaliveExecutor, processingService, actorSystem, eventExecutor, clientDispatcher,
index ff528c4bc820321386a22afba50f5068a1b3c9a9..c4ba32ce0f4674e10705819c69c866ead2f9a945 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.netconf.topology.spi;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ClassToInstanceMap;
 import com.google.common.collect.ImmutableClassToInstanceMap;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -19,6 +18,7 @@ import com.google.common.util.concurrent.SettableFuture;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
 import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
 import org.opendaylight.mdsal.binding.api.WriteTransaction;
 import org.opendaylight.mdsal.common.api.CommitInfo;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
@@ -43,6 +43,7 @@ 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.TopologyKey;
 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.NodeKey;
+import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.Rpc;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -51,26 +52,37 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Deprecated
-public class NetconfTopologyRPCProvider {
+public final class NetconfTopologyRPCProvider implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyRPCProvider.class);
 
     private final @NonNull InstanceIdentifier<Topology> topologyPath;
     private final @NonNull AAAEncryptionService encryptionService;
     private final @NonNull DataBroker dataBroker;
 
-    public NetconfTopologyRPCProvider(final DataBroker dataBroker, final AAAEncryptionService encryptionService,
-            final String topologyId) {
+    private final Registration reg;
+
+    public NetconfTopologyRPCProvider(final RpcProviderService rpcProviderService, final DataBroker dataBroker,
+            final AAAEncryptionService encryptionService, final String topologyId) {
         this.dataBroker = requireNonNull(dataBroker);
         this.encryptionService = requireNonNull(encryptionService);
         topologyPath = InstanceIdentifier.builder(NetworkTopology.class)
             .child(Topology.class, new TopologyKey(new TopologyId(topologyId)))
             .build();
+        reg = rpcProviderService.registerRpcImplementations(ImmutableClassToInstanceMap.<Rpc<?, ?>>builder()
+            .put(CreateDevice.class, this::createDevice)
+            .put(DeleteDevice.class, this::deleteDevice)
+            .build());
     }
 
-    protected final @NonNull InstanceIdentifier<Topology> topologyPath() {
+    protected @NonNull InstanceIdentifier<Topology> topologyPath() {
         return topologyPath;
     }
 
+    @Override
+    public void close() {
+        reg.close();
+    }
+
     private ListenableFuture<RpcResult<CreateDeviceOutput>> createDevice(final CreateDeviceInput input) {
         final NetconfNode node = encryptPassword(input);
         final SettableFuture<RpcResult<CreateDeviceOutput>> futureResult = SettableFuture.create();
@@ -154,11 +166,4 @@ public class NetconfTopologyRPCProvider {
             }
         }, MoreExecutors.directExecutor());
     }
-
-    public ClassToInstanceMap<Rpc<?, ?>> getRpcClassToInstanceMap() {
-        return ImmutableClassToInstanceMap.<Rpc<?, ?>>builder()
-            .put(CreateDevice.class, this::createDevice)
-            .put(DeleteDevice.class, this::deleteDevice)
-            .build();
-    }
 }
index 75b388de76b2be3fb516496d88e9a296dcf07f03..75ad5b0a26b3716308582417e91521608457c360 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.netconf.topology.spi;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 
 import org.junit.Before;
@@ -18,6 +19,7 @@ import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
 import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
@@ -33,6 +35,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev22
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.CreateDeviceInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNode;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.common.Uint16;
 
 @RunWith(MockitoJUnitRunner.StrictStubs.class)
@@ -42,9 +45,12 @@ public class NetconfTopologyRPCProviderTest {
     private static final String TEST_PWD =  "test";
     private static final String ENC_PWD = "4o9/Hn3Pi4150YrP12N/1g==";
 
+    @Mock
+    private RpcProviderService rpcProviderService;
+    @Mock
+    private Registration rpcReg;
     @Mock
     private DataBroker dataBroker;
-
     @Mock
     private AAAEncryptionService encryptionService;
 
@@ -53,7 +59,8 @@ public class NetconfTopologyRPCProviderTest {
     @Before
     public void setUp() {
         doReturn(ENC_PWD).when(encryptionService).encrypt(TEST_PWD);
-        rpcProvider = new NetconfTopologyRPCProvider(dataBroker, encryptionService, TOPOLOGY_ID);
+        doReturn(rpcReg).when(rpcProviderService).registerRpcImplementations(any());
+        rpcProvider = new NetconfTopologyRPCProvider(rpcProviderService, dataBroker, encryptionService, TOPOLOGY_ID);
     }
 
     @Test