From 933399ccca42ce1e7ac1c9627e1b22168c85355a Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 4 Jul 2023 16:28:38 +0200 Subject: [PATCH] Split out NetconfClientConfigurationBuilderFactory The task of creating a client configuration is independent of the actual topology implementation. Rather that requiring a full-blown AbstractNetconfTopology to accomplish this, split it out into a self-contained component. This component is then injected into topologies instead of its constituent services -- which paves the way to expose NetconfNodeHandler at a later point in time. This also allows us to move a few tests from netconf-topology-impl to netconf-topology-spi. JIRA: NETCONF-1039 Change-Id: I9b92b662d6daf3106c26cbc6e470325bc5153348 Signed-off-by: Robert Varga --- .../mount/CallHomeMountDispatcher.java | 32 ++--- .../callhome/mount/CallHomeTopology.java | 13 +- .../mount/CallHomeMountDispatcherTest.java | 14 +-- .../topology/impl/NetconfTopologyImpl.java | 26 ++-- .../impl/NetconfTopologyImplTest.java | 113 ++--------------- apps/netconf-topology-singleton/pom.xml | 10 ++ .../impl/NetconfTopologyContext.java | 15 +-- .../impl/NetconfTopologyManager.java | 24 ++-- .../impl/NetconfTopologySingletonImpl.java | 15 +-- .../impl/utils/NetconfTopologySetup.java | 53 -------- .../blueprint/netconf-topology-singleton.xml | 9 +- .../impl/MountPointEndToEndTest.java | 11 +- .../singleton/impl/NetconfNodeActorTest.java | 16 --- .../impl/NetconfNodeManagerTest.java | 10 -- .../impl/NetconfTopologyManagerTest.java | 10 +- apps/netconf-topology/pom.xml | 9 ++ .../topology/spi/AbstractNetconfTopology.java | 91 ++------------ ...confClientConfigurationBuilderFactory.java | 105 ++++++++++++++++ ...confClientConfigurationBuilderFactory.java | 28 +++++ .../spi/AbstractNetconfTopologyTest.java | 55 ++++++++ ...ClientConfigurationBuilderFactoryTest.java | 118 ++++++++++++++++++ 21 files changed, 412 insertions(+), 365 deletions(-) create mode 100644 apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/DefaultNetconfClientConfigurationBuilderFactory.java create mode 100644 apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfClientConfigurationBuilderFactory.java create mode 100644 apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopologyTest.java create mode 100644 apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/DefaultNetconfClientConfigurationBuilderFactoryTest.java diff --git a/apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcher.java b/apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcher.java index 0164038af9..e7e8345b58 100644 --- a/apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcher.java +++ b/apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcher.java @@ -14,7 +14,6 @@ import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.FailedFuture; import io.netty.util.concurrent.Future; import java.net.InetSocketAddress; -import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; import org.opendaylight.controller.config.threadpool.ThreadPool; import org.opendaylight.mdsal.binding.api.DataBroker; @@ -26,10 +25,9 @@ import org.opendaylight.netconf.client.NetconfClientDispatcher; import org.opendaylight.netconf.client.NetconfClientSession; import org.opendaylight.netconf.client.conf.NetconfClientConfiguration; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; import org.opendaylight.netconf.topology.spi.NetconfNodeUtils; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.osgi.service.component.annotations.Activate; @@ -51,9 +49,7 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom private final SchemaResourceManager schemaRepositoryProvider; private final DataBroker dataBroker; private final DOMMountPointService mountService; - private final AAAEncryptionService encryptionService; - private final CredentialProvider credentialProvider; - private final SslHandlerFactoryProvider sslHandlerFactoryProvider; + private final NetconfClientConfigurationBuilderFactory builderFactory; protected CallHomeTopology topology; @@ -65,10 +61,9 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker, final DOMMountPointService mountService, - final AAAEncryptionService encryptionService, final CredentialProvider credentialProvider, - final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + final NetconfClientConfigurationBuilderFactory builderFactory) { this(topologyId, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider, baseSchemas, - dataBroker, mountService, encryptionService, credentialProvider, sslHandlerFactoryProvider, null); + dataBroker, mountService, builderFactory, null); } @Activate @@ -79,21 +74,19 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom @Reference(target = "(type=global-netconf-processing-executor)") final ThreadPool processingExecutor, @Reference final SchemaResourceManager schemaRepositoryProvider, @Reference final BaseNetconfSchemas baseSchemas, @Reference final DataBroker dataBroker, - @Reference final DOMMountPointService mountService, @Reference final AAAEncryptionService encryptionService, - @Reference final CredentialProvider credentialProvider, - @Reference final SslHandlerFactoryProvider sslHandlerFactoryProvider, + @Reference final DOMMountPointService mountService, + @Reference final NetconfClientConfigurationBuilderFactory builderFactory, @Reference final DeviceActionFactory deviceActionFactory) { this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, eventExecutor, keepaliveExecutor, processingExecutor, - schemaRepositoryProvider, baseSchemas, dataBroker, mountService, encryptionService, credentialProvider, - sslHandlerFactoryProvider, deviceActionFactory); + schemaRepositoryProvider, baseSchemas, dataBroker, mountService, builderFactory, deviceActionFactory); } public CallHomeMountDispatcher(final String topologyId, final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker, final DOMMountPointService mountService, - final AAAEncryptionService encryptionService, final CredentialProvider credentialProvider, - final SslHandlerFactoryProvider sslHandlerFactoryProvider, final DeviceActionFactory deviceActionFactory) { + final NetconfClientConfigurationBuilderFactory builderFactory, + final DeviceActionFactory deviceActionFactory) { this.topologyId = topologyId; this.eventExecutor = eventExecutor; this.keepaliveExecutor = keepaliveExecutor; @@ -103,9 +96,7 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom this.baseSchemas = requireNonNull(baseSchemas); this.dataBroker = dataBroker; this.mountService = mountService; - this.encryptionService = encryptionService; - this.credentialProvider = requireNonNull(credentialProvider); - this.sslHandlerFactoryProvider = requireNonNull(sslHandlerFactoryProvider); + this.builderFactory = requireNonNull(builderFactory); } @Override @@ -139,8 +130,7 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom @VisibleForTesting void createTopology() { topology = new CallHomeTopology(topologyId, this, eventExecutor, keepaliveExecutor, processingExecutor, - schemaRepositoryProvider, dataBroker, mountService, encryptionService, baseSchemas, - deviceActionFactory, credentialProvider, sslHandlerFactoryProvider); + schemaRepositoryProvider, dataBroker, mountService, builderFactory, baseSchemas, deviceActionFactory); } @VisibleForTesting diff --git a/apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java b/apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java index d8efc31872..a308e9789d 100644 --- a/apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java +++ b/apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java @@ -9,18 +9,16 @@ package org.opendaylight.netconf.callhome.mount; import com.google.common.annotations.VisibleForTesting; import io.netty.util.concurrent.EventExecutor; -import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; import org.opendaylight.controller.config.threadpool.ThreadPool; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.netconf.client.NetconfClientDispatcher; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; 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.Node; @@ -30,12 +28,11 @@ public class CallHomeTopology extends AbstractNetconfTopology { final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker, final DOMMountPointService mountPointService, - final AAAEncryptionService encryptionService, final BaseNetconfSchemas baseSchemas, - final DeviceActionFactory deviceActionFactory, final CredentialProvider credentialProvider, - final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + final NetconfClientConfigurationBuilderFactory builderFactory, final BaseNetconfSchemas baseSchemas, + final DeviceActionFactory deviceActionFactory) { super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor, - schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, deviceActionFactory, - baseSchemas, credentialProvider, sslHandlerFactoryProvider); + schemaRepositoryProvider, dataBroker, mountPointService, builderFactory, deviceActionFactory, + baseSchemas); } void disconnectNode(final NodeId nodeId) { diff --git a/apps/callhome-provider/src/test/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcherTest.java b/apps/callhome-provider/src/test/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcherTest.java index 6fe9cda6f2..d3c3c4d375 100644 --- a/apps/callhome-provider/src/test/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcherTest.java +++ b/apps/callhome-provider/src/test/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcherTest.java @@ -21,7 +21,6 @@ import java.net.InetSocketAddress; import java.net.UnknownHostException; import org.junit.Before; import org.junit.Test; -import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; import org.opendaylight.controller.config.threadpool.ThreadPool; import org.opendaylight.mdsal.binding.api.DataBroker; @@ -34,10 +33,9 @@ import org.opendaylight.netconf.client.NetconfClientSessionListener; import org.opendaylight.netconf.client.conf.NetconfClientConfiguration; import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; 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.Node; @@ -55,10 +53,8 @@ public class CallHomeMountDispatcherTest { private CallHomeMountSessionManager mockSessMgr; private CallHomeTopology mockTopology; private CallHomeProtocolSessionContext mockProtoSess; - private AAAEncryptionService mockEncryptionService; + private NetconfClientConfigurationBuilderFactory mockBuilderFactory; private BaseNetconfSchemas mockBaseSchemas; - private CredentialProvider mockCredentialProvider; - private SslHandlerFactoryProvider mockSslHandlerFactoryProvider; @Before public void setup() { @@ -72,14 +68,12 @@ public class CallHomeMountDispatcherTest { mockSessMgr = mock(CallHomeMountSessionManager.class); mockTopology = mock(CallHomeTopology.class); mockProtoSess = mock(CallHomeProtocolSessionContext.class); - mockEncryptionService = mock(AAAEncryptionService.class); + mockBuilderFactory = mock(NetconfClientConfigurationBuilderFactory .class); mockBaseSchemas = mock(BaseNetconfSchemas.class); - mockCredentialProvider = mock(CredentialProvider.class); - mockSslHandlerFactoryProvider = mock(SslHandlerFactoryProvider.class); instance = new CallHomeMountDispatcher(topologyId, mockExecutor, mockKeepAlive, mockProcessingExecutor, mockSchemaRepoProvider, mockBaseSchemas, mockDataBroker, mockMount, - mockEncryptionService, mockCredentialProvider, mockSslHandlerFactoryProvider) { + mockBuilderFactory) { @Override CallHomeMountSessionManager sessionManager() { return mockSessMgr; diff --git a/apps/netconf-topology-impl/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java b/apps/netconf-topology-impl/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java index 3a61b1fd47..c6311f92cc 100644 --- a/apps/netconf-topology-impl/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java +++ b/apps/netconf-topology-impl/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java @@ -27,11 +27,10 @@ import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.netconf.client.NetconfClientDispatcher; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; import org.opendaylight.netconf.topology.spi.NetconfNodeUtils; import org.opendaylight.netconf.topology.spi.NetconfTopologyRPCProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeTopologyService; @@ -75,25 +74,23 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology @Reference final SchemaResourceManager schemaRepositoryProvider, @Reference final DataBroker dataBroker, @Reference final DOMMountPointService mountPointService, @Reference final AAAEncryptionService encryptionService, + @Reference final NetconfClientConfigurationBuilderFactory builderFactory, @Reference final RpcProviderService rpcProviderService, @Reference final BaseNetconfSchemas baseSchemas, - @Reference final CredentialProvider credentialProvider, - @Reference final SslHandlerFactoryProvider sslHandlerFactoryProvider, @Reference final DeviceActionFactory deviceActionFactory) { this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, - rpcProviderService, baseSchemas, credentialProvider, sslHandlerFactoryProvider, deviceActionFactory); + builderFactory, rpcProviderService, baseSchemas, deviceActionFactory); } public NetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher, final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker, final DOMMountPointService mountPointService, - final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService, - final BaseNetconfSchemas baseSchemas, final CredentialProvider credentialProvider, - final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + final AAAEncryptionService encryptionService, final NetconfClientConfigurationBuilderFactory builderFactory, + final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) { this(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor, - schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, rpcProviderService, - baseSchemas, credentialProvider, sslHandlerFactoryProvider, null); + schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory, + rpcProviderService, baseSchemas, null); } @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR", @@ -102,12 +99,11 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker, final DOMMountPointService mountPointService, - final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService, - final BaseNetconfSchemas baseSchemas, final CredentialProvider credentialProvider, - final SslHandlerFactoryProvider sslHandlerFactoryProvider, final DeviceActionFactory deviceActionFactory) { + final AAAEncryptionService encryptionService, final NetconfClientConfigurationBuilderFactory builderFactory, + final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas, + final DeviceActionFactory deviceActionFactory) { super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor, - schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, deviceActionFactory, - baseSchemas, credentialProvider, sslHandlerFactoryProvider); + schemaRepositoryProvider, dataBroker, mountPointService, builderFactory, deviceActionFactory, baseSchemas); LOG.debug("Registering datastore listener"); dtclReg = dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create( diff --git a/apps/netconf-topology-impl/src/test/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImplTest.java b/apps/netconf-topology-impl/src/test/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImplTest.java index 5c9b3b01dd..fef2476461 100644 --- a/apps/netconf-topology-impl/src/test/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImplTest.java +++ b/apps/netconf-topology-impl/src/test/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImplTest.java @@ -7,12 +7,6 @@ */ package org.opendaylight.netconf.topology.impl; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -40,21 +34,14 @@ import org.opendaylight.mdsal.common.api.CommitInfo; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.netconf.client.NetconfClientDispatcher; -import org.opendaylight.netconf.client.NetconfClientSessionListener; -import org.opendaylight.netconf.client.SslHandlerFactory; -import org.opendaylight.netconf.client.conf.NetconfClientConfiguration.NetconfClientProtocol; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas; -import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; 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; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.Protocol.Name; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.ProtocolBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPasswordBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; @@ -69,7 +56,6 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.common.Decimal64; import org.opendaylight.yangtools.yang.common.Uint16; import org.opendaylight.yangtools.yang.common.Uint32; import org.opendaylight.yangtools.yang.parser.api.YangParserException; @@ -99,9 +85,7 @@ public class NetconfTopologyImplTest { @Mock private RpcProviderService rpcProviderService; @Mock - private CredentialProvider credentialProvider; - @Mock - private SslHandlerFactoryProvider sslHandlerFactoryProvider; + private NetconfClientConfigurationBuilderFactory builderFactory; @Mock private WriteTransaction wtx; @@ -116,7 +100,7 @@ public class NetconfTopologyImplTest { topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher, mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker, mountPointService, - encryptionService, rpcProviderService, credentialProvider, sslHandlerFactoryProvider); + encryptionService, builderFactory, rpcProviderService); //verify initialization of topology verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(NetworkTopology.class) .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))).build(), @@ -169,51 +153,6 @@ public class NetconfTopologyImplTest { verify(spyTopology, times(2)).ensureNode(nn.build()); } - @Test - public void testGetClientConfig() { - final NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class); - final NetconfNodeBuilder nodeBuilder = new NetconfNodeBuilder() - .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1")))) - .setPort(new PortNumber(Uint16.valueOf(9999))) - .setReconnectOnChangedSchema(true) - .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000)) - .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100)) - .setKeepaliveDelay(Uint32.valueOf(1000)) - .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build()) - .setMaxConnectionAttempts(Uint32.ZERO) - .setSleepFactor(Decimal64.valueOf("1.5")) - .setConnectionTimeoutMillis(Uint32.valueOf(20000)); - - final var configuration = spyTopology.getClientConfig(nodeBuilder.setTcpOnly(true).build(), NODE_ID) - .withSessionListener(sessionListener).build(); - assertEquals(NetconfClientProtocol.TCP, configuration.getProtocol()); - assertNotNull(configuration.getAuthHandler()); - assertNull(configuration.getSslHandlerFactory()); - - final var configuration2 = spyTopology.getClientConfig(nodeBuilder.setTcpOnly(false).build(), NODE_ID) - .withSessionListener(sessionListener).build(); - assertEquals(NetconfClientProtocol.SSH, configuration2.getProtocol()); - assertNotNull(configuration2.getAuthHandler()); - assertNull(configuration2.getSslHandlerFactory()); - - final var configuration3 = spyTopology.getClientConfig( - nodeBuilder.setProtocol(new ProtocolBuilder().setName(Name.SSH).build()).build(), NODE_ID) - .withSessionListener(sessionListener).build(); - assertEquals(NetconfClientProtocol.SSH, configuration3.getProtocol()); - assertNotNull(configuration3.getAuthHandler()); - assertNull(configuration3.getSslHandlerFactory()); - - final var sslHandlerFactory = mock(SslHandlerFactory.class); - doReturn(sslHandlerFactory).when(sslHandlerFactoryProvider).getSslHandlerFactory(null); - - final var configuration4 = spyTopology.getClientConfig( - nodeBuilder.setProtocol(new ProtocolBuilder().setName(Name.TLS).build()).build(), NODE_ID) - .withSessionListener(sessionListener).build(); - assertEquals(NetconfClientProtocol.TLS, configuration4.getProtocol()); - assertNull(configuration4.getAuthHandler()); - assertSame(sslHandlerFactory, configuration4.getSslHandlerFactory()); - } - public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl { private static final BaseNetconfSchemas BASE_SCHEMAS; @@ -226,18 +165,15 @@ public class NetconfTopologyImplTest { } public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher, - final EventExecutor eventExecutor, - final ScheduledThreadPool keepaliveExecutor, - final ThreadPool processingExecutor, - final SchemaResourceManager schemaRepositoryProvider, - final DataBroker dataBroker, final DOMMountPointService mountPointService, - final AAAEncryptionService encryptionService, - final RpcProviderService rpcProviderService, - final CredentialProvider credentialProvider, - final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, + final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider, + final DataBroker dataBroker, final DOMMountPointService mountPointService, + final AAAEncryptionService encryptionService, + final NetconfClientConfigurationBuilderFactory builderFactory, + final RpcProviderService rpcProviderService) { super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor, - schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, rpcProviderService, - BASE_SCHEMAS, credentialProvider, sslHandlerFactoryProvider, null); + schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory, + rpcProviderService, BASE_SCHEMAS); } @Override @@ -250,31 +186,4 @@ public class NetconfTopologyImplTest { // No-op } } - - @Test - public void hideCredentialsTest() { - final String userName = "admin"; - final String password = "pa$$word"; - final Node node = new NodeBuilder() - .addAugmentation(new NetconfNodeBuilder() - .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1")))) - .setPort(new PortNumber(Uint16.valueOf(9999))) - .setReconnectOnChangedSchema(true) - .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000)) - .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100)) - .setKeepaliveDelay(Uint32.valueOf(1000)) - .setTcpOnly(false) - .setProtocol(new ProtocolBuilder().setName(Name.TLS).build()) - .setCredentials(new LoginPasswordBuilder() - .setUsername(userName) - .setPassword(password) - .build()) - .build()) - .setNodeId(NodeId.getDefaultInstance("junos")) - .build(); - final String transformedNetconfNode = AbstractNetconfTopology.hideCredentials(node); - assertTrue(transformedNetconfNode.contains("credentials=***")); - assertFalse(transformedNetconfNode.contains(userName)); - assertFalse(transformedNetconfNode.contains(password)); - } } diff --git a/apps/netconf-topology-singleton/pom.xml b/apps/netconf-topology-singleton/pom.xml index c29bac88f5..b4200b62e5 100644 --- a/apps/netconf-topology-singleton/pom.xml +++ b/apps/netconf-topology-singleton/pom.xml @@ -84,5 +84,15 @@ com.typesafe.akka akka-testkit_2.13 + + com.guicedee.services + javax.inject + test + + + org.osgi + org.osgi.service.component.annotations + test + diff --git a/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java b/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java index 7c54c21e40..dbef0a2ed7 100644 --- a/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java +++ b/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java @@ -14,7 +14,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.util.concurrent.ListenableFuture; import io.netty.util.concurrent.EventExecutor; import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; import org.opendaylight.controller.config.threadpool.ThreadPool; import org.opendaylight.mdsal.binding.api.DataBroker; @@ -23,12 +22,11 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; import org.opendaylight.netconf.client.NetconfClientDispatcher; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; import org.opendaylight.netconf.topology.spi.NetconfNodeUtils; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNode; import org.opendaylight.yangtools.util.concurrent.FluentFutures; @@ -50,18 +48,17 @@ class NetconfTopologyContext implements ClusterSingletonService, AutoCloseable { final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor, final SchemaResourceManager schemaManager, final DataBroker dataBroker, final DOMMountPointService mountPointService, - final AAAEncryptionService encryptionService, final DeviceActionFactory deviceActionFactory, - final BaseNetconfSchemas baseSchemas, final Timeout actorResponseWaitTime, - final ServiceGroupIdentifier serviceGroupIdent, final NetconfTopologySetup setup, - final CredentialProvider credentialProvider, final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + final NetconfClientConfigurationBuilderFactory builderFactory, + final DeviceActionFactory deviceActionFactory, final BaseNetconfSchemas baseSchemas, + final Timeout actorResponseWaitTime, final ServiceGroupIdentifier serviceGroupIdent, + final NetconfTopologySetup setup) { this.serviceGroupIdent = requireNonNull(serviceGroupIdent); remoteDeviceId = NetconfNodeUtils.toRemoteDeviceId(setup.getNode().getNodeId(), setup.getNode().augmentation(NetconfNode.class)); topologySingleton = new NetconfTopologySingletonImpl(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor, schemaManager, dataBroker, mountPointService, - encryptionService, deviceActionFactory, baseSchemas, remoteDeviceId, setup, actorResponseWaitTime, - credentialProvider, sslHandlerFactoryProvider); + builderFactory, deviceActionFactory, baseSchemas, remoteDeviceId, setup, actorResponseWaitTime); } @VisibleForTesting diff --git a/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java b/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java index 21a1b489c7..6f22d004e1 100644 --- a/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java +++ b/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java @@ -42,15 +42,14 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegist import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; import org.opendaylight.netconf.client.NetconfClientDispatcher; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup.NetconfTopologySetupBuilder; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; import org.opendaylight.netconf.topology.spi.NetconfNodeUtils; import org.opendaylight.netconf.topology.spi.NetconfTopologyRPCProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNode; @@ -96,13 +95,13 @@ public class NetconfTopologyManager private final AAAEncryptionService encryptionService; private final RpcProviderService rpcProviderService; private final DeviceActionFactory deviceActionFactory; - private final CredentialProvider credentialProvider; - private final SslHandlerFactoryProvider sslHandlerFactoryProvider; + private final NetconfClientConfigurationBuilderFactory builderFactory; private final SchemaResourceManager resourceManager; private ListenerRegistration dataChangeListenerRegistration; private Registration rpcReg; + public NetconfTopologyManager(final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker, final DOMRpcProviderService rpcProviderRegistry, final DOMActionProviderService actionProviderService, @@ -116,17 +115,16 @@ public class NetconfTopologyManager final RpcProviderService rpcProviderService, final DeviceActionFactory deviceActionFactory, final SchemaResourceManager resourceManager, - final CredentialProvider credentialProvider, - final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + final NetconfClientConfigurationBuilderFactory builderFactory) { this.baseSchemas = requireNonNull(baseSchemas); this.dataBroker = requireNonNull(dataBroker); this.rpcProviderRegistry = requireNonNull(rpcProviderRegistry); actionProviderRegistry = requireNonNull(actionProviderService); this.clusterSingletonServiceProvider = requireNonNull(clusterSingletonServiceProvider); this.keepaliveExecutor = keepaliveExecutor; - this.keepaliveExecutorService = keepaliveExecutor.getExecutor(); + keepaliveExecutorService = keepaliveExecutor.getExecutor(); this.processingExecutor = processingExecutor; - this.processingExecutorService = MoreExecutors.listeningDecorator(processingExecutor.getExecutor()); + processingExecutorService = MoreExecutors.listeningDecorator(processingExecutor.getExecutor()); actorSystem = requireNonNull(actorSystemProvider).getActorSystem(); this.eventExecutor = requireNonNull(eventExecutor); this.clientDispatcher = requireNonNull(clientDispatcher); @@ -137,8 +135,7 @@ public class NetconfTopologyManager this.rpcProviderService = requireNonNull(rpcProviderService); this.deviceActionFactory = requireNonNull(deviceActionFactory); this.resourceManager = requireNonNull(resourceManager); - this.credentialProvider = requireNonNull(credentialProvider); - this.sslHandlerFactoryProvider = requireNonNull(sslHandlerFactoryProvider); + this.builderFactory = requireNonNull(builderFactory); } // Blueprint init method @@ -237,9 +234,9 @@ public class NetconfTopologyManager setup.getEventExecutor(), keepaliveExecutor, processingExecutor, resourceManager, dataBroker, mountPointService, - encryptionService, deviceActionFactory, + builderFactory, deviceActionFactory, baseSchemas, actorResponseWaitTime, - serviceGroupIdent, setup, credentialProvider, sslHandlerFactoryProvider); + serviceGroupIdent, setup); } @Override @@ -315,9 +312,6 @@ public class NetconfTopologyManager .setSchemaResourceDTO(resourceManager.getSchemaResources(netconfNode.getSchemaCacheDirectory(), deviceId)) .setIdleTimeout(writeTxIdleTimeout) - .setEncryptionService(encryptionService) - .setCredentialProvider(credentialProvider) - .setSslHandlerFactoryProvider(sslHandlerFactoryProvider) .build(); } } diff --git a/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologySingletonImpl.java b/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologySingletonImpl.java index 199cfa931e..32354b7b66 100644 --- a/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologySingletonImpl.java +++ b/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologySingletonImpl.java @@ -13,24 +13,22 @@ import akka.dispatch.OnComplete; import akka.pattern.Patterns; import akka.util.Timeout; import io.netty.util.concurrent.EventExecutor; -import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; import org.opendaylight.controller.config.threadpool.ThreadPool; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.netconf.client.NetconfClientDispatcher; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils; import org.opendaylight.netconf.topology.singleton.messages.RefreshSetupMasterActorData; import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,13 +48,12 @@ final class NetconfTopologySingletonImpl extends AbstractNetconfTopology impleme final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor, final SchemaResourceManager schemaManager, final DataBroker dataBroker, final DOMMountPointService mountPointService, - final AAAEncryptionService encryptionService, final DeviceActionFactory deviceActionFactory, - final BaseNetconfSchemas baseSchemas, final RemoteDeviceId remoteDeviceId, - final NetconfTopologySetup setup, final Timeout actorResponseWaitTime, - final CredentialProvider credentialProvider, final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + final NetconfClientConfigurationBuilderFactory builderFactory, + final DeviceActionFactory deviceActionFactory, final BaseNetconfSchemas baseSchemas, + final RemoteDeviceId remoteDeviceId, final NetconfTopologySetup setup, + final Timeout actorResponseWaitTime) { super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor, schemaManager, - dataBroker, mountPointService, encryptionService, deviceActionFactory, baseSchemas, credentialProvider, - sslHandlerFactoryProvider); + dataBroker, mountPointService, builderFactory, deviceActionFactory, baseSchemas); this.remoteDeviceId = remoteDeviceId; this.setup = setup; this.actorResponseWaitTime = actorResponseWaitTime; diff --git a/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologySetup.java b/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologySetup.java index 8a8f8770f3..7a0f3c0d99 100644 --- a/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologySetup.java +++ b/apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologySetup.java @@ -14,8 +14,6 @@ import com.google.common.util.concurrent.ListeningExecutorService; import io.netty.util.concurrent.EventExecutor; import java.time.Duration; import java.util.concurrent.ScheduledExecutorService; -import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.dom.api.DOMActionProviderService; import org.opendaylight.mdsal.dom.api.DOMRpcProviderService; @@ -23,8 +21,6 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvid import org.opendaylight.netconf.client.NetconfClientDispatcher; import org.opendaylight.netconf.client.mdsal.NetconfDevice; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -43,10 +39,7 @@ public class NetconfTopologySetup { private final String topologyId; private final NetconfDevice.SchemaResourcesDTO schemaResourceDTO; private final Duration idleTimeout; - private final AAAEncryptionService encryptionService; private final BaseNetconfSchemas baseSchemas; - private final @NonNull CredentialProvider credentialProvider; - private final @NonNull SslHandlerFactoryProvider sslHandlerFactoryProvider; NetconfTopologySetup(final NetconfTopologySetupBuilder builder) { clusterSingletonServiceProvider = builder.getClusterSingletonServiceProvider(); @@ -63,10 +56,7 @@ public class NetconfTopologySetup { topologyId = builder.getTopologyId(); schemaResourceDTO = builder.getSchemaResourceDTO(); idleTimeout = builder.getIdleTimeout(); - encryptionService = builder.getEncryptionService(); baseSchemas = builder.getBaseSchemas(); - credentialProvider = builder.getCredentialProvider(); - sslHandlerFactoryProvider = builder.getSslHandlerFactoryProvider(); } public ClusterSingletonServiceProvider getClusterSingletonServiceProvider() { @@ -125,18 +115,6 @@ public class NetconfTopologySetup { return idleTimeout; } - public AAAEncryptionService getEncryptionService() { - return encryptionService; - } - - public @NonNull CredentialProvider getCredentialProvider() { - return credentialProvider; - } - - public @NonNull SslHandlerFactoryProvider getSslHandlerFactoryProvider() { - return sslHandlerFactoryProvider; - } - public BaseNetconfSchemas getBaseSchemas() { return baseSchemas; } @@ -156,10 +134,7 @@ public class NetconfTopologySetup { private NetconfClientDispatcher netconfClientDispatcher; private NetconfDevice.SchemaResourcesDTO schemaResourceDTO; private Duration idleTimeout; - private AAAEncryptionService encryptionService; private BaseNetconfSchemas baseSchemas; - private CredentialProvider credentialProvider; - private SslHandlerFactoryProvider sslHandlerFactoryProvider; public NetconfTopologySetupBuilder() { @@ -307,34 +282,6 @@ public class NetconfTopologySetup { return idleTimeout; } - AAAEncryptionService getEncryptionService() { - return encryptionService; - } - - public NetconfTopologySetupBuilder setEncryptionService(final AAAEncryptionService encryptionService) { - this.encryptionService = encryptionService; - return this; - } - - @NonNull CredentialProvider getCredentialProvider() { - return requireNonNull(credentialProvider); - } - - public NetconfTopologySetupBuilder setCredentialProvider(final CredentialProvider credentialProvider) { - this.credentialProvider = credentialProvider; - return this; - } - - @NonNull SslHandlerFactoryProvider getSslHandlerFactoryProvider() { - return requireNonNull(sslHandlerFactoryProvider); - } - - public NetconfTopologySetupBuilder setSslHandlerFactoryProvider( - final SslHandlerFactoryProvider sslHandlerFactoryProvider) { - this.sslHandlerFactoryProvider = sslHandlerFactoryProvider; - return this; - } - public static NetconfTopologySetupBuilder create() { return new NetconfTopologySetupBuilder(); } diff --git a/apps/netconf-topology-singleton/src/main/resources/OSGI-INF/blueprint/netconf-topology-singleton.xml b/apps/netconf-topology-singleton/src/main/resources/OSGI-INF/blueprint/netconf-topology-singleton.xml index 4fc08cbb98..5fd6eeb440 100644 --- a/apps/netconf-topology-singleton/src/main/resources/OSGI-INF/blueprint/netconf-topology-singleton.xml +++ b/apps/netconf-topology-singleton/src/main/resources/OSGI-INF/blueprint/netconf-topology-singleton.xml @@ -43,10 +43,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html interface="org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager"/> - - + @@ -73,8 +71,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html - - + diff --git a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java index 4897482aab..3ec5445cc6 100644 --- a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java +++ b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java @@ -112,6 +112,8 @@ import org.opendaylight.netconf.client.mdsal.impl.DefaultSchemaResourceManager; 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; +import org.opendaylight.netconf.topology.spi.DefaultNetconfClientConfigurationBuilderFactory; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; 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; @@ -223,6 +225,7 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest { private final SettableFuture slaveNetconfTopologyContextFuture = SettableFuture.create(); private TransactionChain slaveTxChain; + private NetconfClientConfigurationBuilderFactory builderFactory; private final EventExecutor eventExecutor = GlobalEventExecutor.INSTANCE; private final Config config = new ConfigBuilder().setWriteTransactionIdleTimeout(Uint16.ZERO).build(); private EffectiveModelContext deviceSchemaContext; @@ -269,6 +272,9 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest { } }; + builderFactory = new DefaultNetconfClientConfigurationBuilderFactory(mockEncryptionService, credentialProvider, + sslHandlerFactoryProvider); + setupMaster(); setupSlave(); @@ -317,8 +323,7 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest { mockRpcProviderRegistry, mockActionProviderRegistry, masterClusterSingletonServiceProvider, mockKeepaliveExecutor, mockThreadPool, mockMasterActorSystemProvider, eventExecutor, mockClientDispatcher, TOPOLOGY_ID, config, masterMountPointService, mockEncryptionService, - mockRpcProviderService, deviceActionFactory, resourceManager, credentialProvider, - sslHandlerFactoryProvider) { + mockRpcProviderService, deviceActionFactory, resourceManager, builderFactory) { @Override protected NetconfTopologyContext newNetconfTopologyContext(final NetconfTopologySetup setup, final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime, @@ -359,7 +364,7 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest { mockActionProviderRegistry, mockSlaveClusterSingletonServiceProvider, mockKeepaliveExecutor, mockThreadPool, mockSlaveActorSystemProvider, eventExecutor, mockClientDispatcher, TOPOLOGY_ID, config, slaveMountPointService, mockEncryptionService, mockRpcProviderService, deviceActionFactory, - resourceManager, credentialProvider, sslHandlerFactoryProvider) { + resourceManager, builderFactory) { @Override protected NetconfTopologyContext newNetconfTopologyContext(final NetconfTopologySetup setup, final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime, diff --git a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java index 47a55305f0..52dac16d32 100644 --- a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java +++ b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java @@ -83,12 +83,10 @@ import org.opendaylight.mdsal.dom.api.DOMSchemaService; import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult; import org.opendaylight.mdsal.dom.spi.SimpleDOMActionResult; import org.opendaylight.netconf.client.mdsal.NetconfDevice.SchemaResourcesDTO; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices.Actions; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices.Rpcs; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.dom.api.NetconfDataTreeService; import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor; import org.opendaylight.netconf.topology.singleton.impl.utils.ClusteringActionException; @@ -172,10 +170,6 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest { private EffectiveModelContext mockSchemaContext; @Mock private SchemaResourcesDTO schemaResourceDTO; - @Mock - private CredentialProvider credentialProvider; - @Mock - private SslHandlerFactoryProvider sslHandlerFactoryProvider; @Before public void setup() { @@ -192,8 +186,6 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest { .setIdleTimeout(Duration.ofSeconds(1)) .setSchemaResourceDTO(schemaResourceDTO) .setBaseSchemas(BASE_SCHEMAS) - .setCredentialProvider(credentialProvider) - .setSslHandlerFactoryProvider(sslHandlerFactoryProvider) .build(); final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService); @@ -233,8 +225,6 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest { .setBaseSchemas(BASE_SCHEMAS) .setSchemaResourceDTO(schemaResourceDTO) .setActorSystem(system) - .setCredentialProvider(credentialProvider) - .setSslHandlerFactoryProvider(sslHandlerFactoryProvider) .build(); masterRef.tell(new RefreshSetupMasterActorData(newSetup, newRemoteDeviceId), testKit.getRef()); @@ -345,8 +335,6 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest { .setSchemaResourceDTO(schemaResourceDTO2) .setBaseSchemas(BASE_SCHEMAS) .setActorSystem(system) - .setCredentialProvider(credentialProvider) - .setSslHandlerFactoryProvider(sslHandlerFactoryProvider) .build(); final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, @@ -431,8 +419,6 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest { .setSchemaResourceDTO(schemaResourceDTO2) .setIdleTimeout(Duration.ofSeconds(1)) .setBaseSchemas(BASE_SCHEMAS) - .setCredentialProvider(credentialProvider) - .setSslHandlerFactoryProvider(sslHandlerFactoryProvider) .build(); final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService); ActorRef actor = TestActorRef.create(system, props, "master_messages_2"); @@ -682,8 +668,6 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest { .setSchemaResourceDTO(schemaResourceDTO2) .setActorSystem(system) .setBaseSchemas(BASE_SCHEMAS) - .setCredentialProvider(credentialProvider) - .setSslHandlerFactoryProvider(sslHandlerFactoryProvider) .build(), remoteDeviceId, TIMEOUT, mockMountPointService)); doReturn(Futures.immediateFuture(mockSchemaContext)) diff --git a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java index 6d586514cd..348b12fd45 100644 --- a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java +++ b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java @@ -57,13 +57,11 @@ import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.mdsal.dom.api.DOMNotificationService; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.netconf.client.mdsal.NetconfDevice; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.NetconfDeviceSchemasResolver; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices.Actions; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices.Rpcs; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.dom.api.NetconfDataTreeService; import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup; @@ -127,10 +125,6 @@ public class NetconfNodeManagerTest extends AbstractBaseSchemasTest { private NetconfDeviceSchemasResolver mockSchemasResolver; @Mock private EffectiveModelContextFactory mockSchemaContextFactory; - @Mock - private CredentialProvider credentialProvider; - @Mock - private SslHandlerFactoryProvider sslHandlerFactoryProvider; private ActorSystem slaveSystem; private ActorSystem masterSystem; @@ -170,8 +164,6 @@ public class NetconfNodeManagerTest extends AbstractBaseSchemasTest { .setSchemaResourceDTO(new NetconfDevice.SchemaResourcesDTO( masterSchemaRepository, masterSchemaRepository, mockSchemaContextFactory, mockSchemasResolver)) .setBaseSchemas(BASE_SCHEMAS) - .setCredentialProvider(credentialProvider) - .setSslHandlerFactoryProvider(sslHandlerFactoryProvider) .build(); testMasterActorRef = TestActorRef.create(masterSystem, Props.create(TestMasterActor.class, masterSetup, @@ -188,8 +180,6 @@ public class NetconfNodeManagerTest extends AbstractBaseSchemasTest { .setSchemaResourceDTO(new NetconfDevice.SchemaResourcesDTO( slaveSchemaRepository, slaveSchemaRepository, mockSchemaContextFactory, mockSchemasResolver)) .setBaseSchemas(BASE_SCHEMAS) - .setCredentialProvider(credentialProvider) - .setSslHandlerFactoryProvider(sslHandlerFactoryProvider) .build(); netconfNodeManager = new NetconfNodeManager(slaveSetup, DEVICE_ID, responseTimeout, diff --git a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java index 1ae20961f3..96680841f5 100644 --- a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java +++ b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java @@ -59,12 +59,11 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvid import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; import org.opendaylight.netconf.client.NetconfClientDispatcher; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; import org.opendaylight.netconf.client.mdsal.impl.DefaultSchemaResourceManager; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils; +import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory; 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; @@ -127,16 +126,15 @@ public class NetconfTopologyManagerTest extends AbstractBaseSchemasTest { final AAAEncryptionService encryptionService = mock(AAAEncryptionService.class); final DeviceActionFactory deviceActionFactory = mock(DeviceActionFactory.class); final RpcProviderService rpcProviderService = mock(RpcProviderService.class); - final CredentialProvider credentialProvider = mock(CredentialProvider.class); - final SslHandlerFactoryProvider sslHandlerFactoryProvider = mock(SslHandlerFactoryProvider.class); + final NetconfClientConfigurationBuilderFactory builderFactory = + mock(NetconfClientConfigurationBuilderFactory.class); final Config config = new ConfigBuilder().setWriteTransactionIdleTimeout(Uint16.ZERO).build(); netconfTopologyManager = new NetconfTopologyManager(BASE_SCHEMAS, dataBroker, rpcProviderRegistry, actionProviderRegistry, clusterSingletonServiceProvider, keepaliveExecutor, processingThreadPool, actorSystemProvider, eventExecutor, clientDispatcher, TOPOLOGY_ID, config, mountPointService, encryptionService, rpcProviderService, deviceActionFactory, - new DefaultSchemaResourceManager(new DefaultYangParserFactory()), credentialProvider, - sslHandlerFactoryProvider) { + new DefaultSchemaResourceManager(new DefaultYangParserFactory()), builderFactory) { @Override protected NetconfTopologyContext newNetconfTopologyContext(final NetconfTopologySetup setup, final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime, diff --git a/apps/netconf-topology/pom.xml b/apps/netconf-topology/pom.xml index df81f3bebc..44cf27de36 100644 --- a/apps/netconf-topology/pom.xml +++ b/apps/netconf-topology/pom.xml @@ -15,6 +15,11 @@ bundle + + com.guicedee.services + javax.inject + true + org.opendaylight.aaa aaa-encrypt-service @@ -35,6 +40,10 @@ org.opendaylight.netconf netconf-client-mdsal + + org.osgi + org.osgi.service.component.annotations + org.awaitility diff --git a/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopology.java b/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopology.java index 883ad18de0..6309225425 100644 --- a/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopology.java +++ b/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopology.java @@ -14,33 +14,19 @@ import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import io.netty.util.concurrent.EventExecutor; import java.util.HashMap; -import java.util.List; import java.util.concurrent.ExecutionException; import org.checkerframework.checker.lock.qual.Holding; -import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; import org.opendaylight.controller.config.threadpool.ThreadPool; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.netconf.client.NetconfClientDispatcher; -import org.opendaylight.netconf.client.conf.NetconfClientConfiguration; -import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder; -import org.opendaylight.netconf.client.mdsal.DatastoreBackedPublicKeyAuth; import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas; -import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler; import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId; import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager; -import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; -import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler; -import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.Protocol.Name; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.Credentials; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.KeyAuth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPw; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPwUnencrypted; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev221225.NetconfNodeAugmentedOptional; 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.NetworkTopology; @@ -61,27 +47,21 @@ public abstract class AbstractNetconfTopology { private final NetconfClientDispatcher clientDispatcher; private final EventExecutor eventExecutor; private final DeviceActionFactory deviceActionFactory; - private final CredentialProvider credentialProvider; - private final SslHandlerFactoryProvider sslHandlerFactoryProvider; private final SchemaResourceManager schemaManager; private final BaseNetconfSchemas baseSchemas; + private final NetconfClientConfigurationBuilderFactory builderFactory; protected final ScheduledThreadPool keepaliveExecutor; protected final ListeningExecutorService processingExecutor; protected final DataBroker dataBroker; protected final DOMMountPointService mountPointService; protected final String topologyId; - protected final AAAEncryptionService encryptionService; protected AbstractNetconfTopology(final String topologyId, final NetconfClientDispatcher clientDispatcher, - final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, - final ThreadPool processingExecutor, final SchemaResourceManager schemaManager, - final DataBroker dataBroker, final DOMMountPointService mountPointService, - final AAAEncryptionService encryptionService, - final DeviceActionFactory deviceActionFactory, - final BaseNetconfSchemas baseSchemas, - final CredentialProvider credentialProvider, - final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor, + final ThreadPool processingExecutor, final SchemaResourceManager schemaManager, final DataBroker dataBroker, + final DOMMountPointService mountPointService, final NetconfClientConfigurationBuilderFactory builderFactory, + final DeviceActionFactory deviceActionFactory, final BaseNetconfSchemas baseSchemas) { this.topologyId = requireNonNull(topologyId); this.clientDispatcher = clientDispatcher; this.eventExecutor = eventExecutor; @@ -91,10 +71,8 @@ public abstract class AbstractNetconfTopology { this.deviceActionFactory = deviceActionFactory; this.dataBroker = requireNonNull(dataBroker); this.mountPointService = mountPointService; - this.encryptionService = encryptionService; + this.builderFactory = requireNonNull(builderFactory); this.baseSchemas = requireNonNull(baseSchemas); - this.credentialProvider = requireNonNull(credentialProvider); - this.sslHandlerFactoryProvider = requireNonNull(sslHandlerFactoryProvider); // FIXME: this should be a put(), as we are initializing and will be re-populating the datastore with all the // devices. Whatever has been there before should be nuked to properly re-align lifecycle. @@ -163,7 +141,8 @@ public abstract class AbstractNetconfTopology { final var deviceSalFacade = createSalFacade(deviceId, netconfNode.requireLockDatastore()); final var nodeHandler = new NetconfNodeHandler(clientDispatcher, eventExecutor, keepaliveExecutor.getExecutor(), baseSchemas, schemaManager, processingExecutor, deviceActionFactory, - deviceSalFacade, deviceId, nodeId, netconfNode, nodeOptional, getClientConfig(netconfNode, nodeId)); + deviceSalFacade, deviceId, nodeId, netconfNode, nodeOptional, + builderFactory.createClientConfigurationBuilder(nodeId, netconfNode)); // ... record it ... activeConnectors.put(nodeId, nodeHandler); @@ -176,58 +155,6 @@ public abstract class AbstractNetconfTopology { return new NetconfTopologyDeviceSalFacade(deviceId, mountPointService, lockDatastore, dataBroker); } - @VisibleForTesting - public NetconfClientConfigurationBuilder getClientConfig(final NetconfNode node, final NodeId nodeId) { - final var builder = NetconfClientConfigurationBuilder.create(); - - final var protocol = node.getProtocol(); - if (node.requireTcpOnly()) { - builder.withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TCP) - .withAuthHandler(getHandlerFromCredentials(node.getCredentials())); - } else if (protocol == null || protocol.getName() == Name.SSH) { - builder.withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH) - .withAuthHandler(getHandlerFromCredentials(node.getCredentials())); - } else if (protocol.getName() == Name.TLS) { - builder.withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TLS) - .withSslHandlerFactory(sslHandlerFactoryProvider.getSslHandlerFactory(protocol.getSpecification())); - } else { - throw new IllegalStateException("Unsupported protocol type: " + protocol.getName()); - } - - final var helloCapabilities = node.getOdlHelloMessageCapabilities(); - if (helloCapabilities != null) { - builder.withOdlHelloCapabilities(List.copyOf(helloCapabilities.requireCapability())); - } - - return builder - .withName(nodeId.getValue()) - .withAddress(NetconfNodeUtils.toInetSocketAddress(node)) - .withConnectionTimeoutMillis(node.requireConnectionTimeoutMillis().toJava()); - } - - private AuthenticationHandler getHandlerFromCredentials(final Credentials credentials) { - if (credentials - instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430 - .credentials.credentials.LoginPassword loginPassword) { - return new LoginPasswordHandler(loginPassword.getUsername(), loginPassword.getPassword()); - } - if (credentials instanceof LoginPwUnencrypted unencrypted) { - final var loginPassword = unencrypted.getLoginPasswordUnencrypted(); - return new LoginPasswordHandler(loginPassword.getUsername(), loginPassword.getPassword()); - } - if (credentials instanceof LoginPw loginPw) { - final var loginPassword = loginPw.getLoginPassword(); - return new LoginPasswordHandler(loginPassword.getUsername(), - encryptionService.decrypt(loginPassword.getPassword())); - } - if (credentials instanceof KeyAuth keyAuth) { - final var keyPair = keyAuth.getKeyBased(); - return new DatastoreBackedPublicKeyAuth(keyPair.getUsername(), keyPair.getKeyId(), credentialProvider, - encryptionService); - } - throw new IllegalStateException("Unsupported credential type: " + credentials.getClass()); - } - /** * Hiding of private credentials from node configuration (credentials data is replaced by asterisks). * @@ -235,7 +162,7 @@ public abstract class AbstractNetconfTopology { * @return String representation of node configuration with credentials replaced by asterisks. */ @VisibleForTesting - public static final String hideCredentials(final Node nodeConfiguration) { + static final String hideCredentials(final Node nodeConfiguration) { final var netconfNodeAugmentation = nodeConfiguration.augmentation(NetconfNode.class); final var nodeCredentials = netconfNodeAugmentation.getCredentials().toString(); final var nodeConfigurationString = nodeConfiguration.toString(); diff --git a/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/DefaultNetconfClientConfigurationBuilderFactory.java b/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/DefaultNetconfClientConfigurationBuilderFactory.java new file mode 100644 index 0000000000..55ccf74f42 --- /dev/null +++ b/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/DefaultNetconfClientConfigurationBuilderFactory.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.topology.spi; + +import static java.util.Objects.requireNonNull; + +import java.util.List; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.aaa.encrypt.AAAEncryptionService; +import org.opendaylight.netconf.client.conf.NetconfClientConfiguration.NetconfClientProtocol; +import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder; +import org.opendaylight.netconf.client.mdsal.DatastoreBackedPublicKeyAuth; +import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; +import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; +import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler; +import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.Protocol.Name; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.Credentials; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.KeyAuth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPassword; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPw; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPwUnencrypted; +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.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * Default implementation of NetconfClientConfigurationBuildFactory. + */ +@Component +@Singleton +public final class DefaultNetconfClientConfigurationBuilderFactory implements NetconfClientConfigurationBuilderFactory { + private final SslHandlerFactoryProvider sslHandlerFactoryProvider; + private final AAAEncryptionService encryptionService; + private final CredentialProvider credentialProvider; + + @Inject + @Activate + public DefaultNetconfClientConfigurationBuilderFactory( + @Reference final AAAEncryptionService encryptionService, + @Reference final CredentialProvider credentialProvider, + @Reference final SslHandlerFactoryProvider sslHandlerFactoryProvider) { + this.encryptionService = requireNonNull(encryptionService); + this.credentialProvider = requireNonNull(credentialProvider); + this.sslHandlerFactoryProvider = requireNonNull(sslHandlerFactoryProvider); + } + + @Override + public NetconfClientConfigurationBuilder createClientConfigurationBuilder(final NodeId nodeId, + final NetconfNode node) { + final var builder = NetconfClientConfigurationBuilder.create(); + + final var protocol = node.getProtocol(); + if (node.requireTcpOnly()) { + builder.withProtocol(NetconfClientProtocol.TCP) + .withAuthHandler(getHandlerFromCredentials(node.getCredentials())); + } else if (protocol == null || protocol.getName() == Name.SSH) { + builder.withProtocol(NetconfClientProtocol.SSH) + .withAuthHandler(getHandlerFromCredentials(node.getCredentials())); + } else if (protocol.getName() == Name.TLS) { + builder.withProtocol(NetconfClientProtocol.TLS) + .withSslHandlerFactory(sslHandlerFactoryProvider.getSslHandlerFactory(protocol.getSpecification())); + } else { + throw new IllegalArgumentException("Unsupported protocol type: " + protocol.getName()); + } + + final var helloCapabilities = node.getOdlHelloMessageCapabilities(); + if (helloCapabilities != null) { + builder.withOdlHelloCapabilities(List.copyOf(helloCapabilities.requireCapability())); + } + + return builder + .withName(nodeId.getValue()) + .withAddress(NetconfNodeUtils.toInetSocketAddress(node)) + .withConnectionTimeoutMillis(node.requireConnectionTimeoutMillis().toJava()); + } + + private @NonNull AuthenticationHandler getHandlerFromCredentials(final Credentials credentials) { + if (credentials instanceof LoginPassword loginPassword) { + return new LoginPasswordHandler(loginPassword.getUsername(), loginPassword.getPassword()); + } else if (credentials instanceof LoginPwUnencrypted unencrypted) { + final var loginPassword = unencrypted.getLoginPasswordUnencrypted(); + return new LoginPasswordHandler(loginPassword.getUsername(), loginPassword.getPassword()); + } else if (credentials instanceof LoginPw loginPw) { + final var loginPassword = loginPw.getLoginPassword(); + return new LoginPasswordHandler(loginPassword.getUsername(), + encryptionService.decrypt(loginPassword.getPassword())); + } else if (credentials instanceof KeyAuth keyAuth) { + final var keyPair = keyAuth.getKeyBased(); + return new DatastoreBackedPublicKeyAuth(keyPair.getUsername(), keyPair.getKeyId(), credentialProvider, + encryptionService); + } else { + throw new IllegalArgumentException("Unsupported credential type: " + credentials.getClass()); + } + } +} diff --git a/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfClientConfigurationBuilderFactory.java b/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfClientConfigurationBuilderFactory.java new file mode 100644 index 0000000000..08d3fa770a --- /dev/null +++ b/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfClientConfigurationBuilderFactory.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.topology.spi; + +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder; +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; + +/** + * Factory for creating {@link NetconfClientConfigurationBuilder}s. + */ +public interface NetconfClientConfigurationBuilderFactory { + /** + * Create a new {@link NetconfClientConfigurationBuilder} initialized based on configuration {@link NetconfNode}. + * + * @param nodeId A topology node identifier + * @param node A {@link NetconfNode} + * @return An initialized {@link NetconfClientConfigurationBuilder} + */ + @NonNull NetconfClientConfigurationBuilder createClientConfigurationBuilder(@NonNull NodeId nodeId, + @NonNull NetconfNode node); +} diff --git a/apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopologyTest.java b/apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopologyTest.java new file mode 100644 index 0000000000..ac84df901c --- /dev/null +++ b/apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopologyTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.topology.spi; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +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; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.Protocol.Name; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.ProtocolBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPasswordBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeBuilder; +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.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; + +public class AbstractNetconfTopologyTest { + @Test + public void hideCredentialsTest() { + final String userName = "admin"; + final String password = "pa$$word"; + final Node node = new NodeBuilder() + .addAugmentation(new NetconfNodeBuilder() + .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1")))) + .setPort(new PortNumber(Uint16.valueOf(9999))) + .setReconnectOnChangedSchema(true) + .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000)) + .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100)) + .setKeepaliveDelay(Uint32.valueOf(1000)) + .setTcpOnly(false) + .setProtocol(new ProtocolBuilder().setName(Name.TLS).build()) + .setCredentials(new LoginPasswordBuilder() + .setUsername(userName) + .setPassword(password) + .build()) + .build()) + .setNodeId(NodeId.getDefaultInstance("junos")) + .build(); + final String transformedNetconfNode = AbstractNetconfTopology.hideCredentials(node); + assertTrue(transformedNetconfNode.contains("credentials=***")); + assertFalse(transformedNetconfNode.contains(userName)); + assertFalse(transformedNetconfNode.contains(password)); + } +} diff --git a/apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/DefaultNetconfClientConfigurationBuilderFactoryTest.java b/apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/DefaultNetconfClientConfigurationBuilderFactoryTest.java new file mode 100644 index 0000000000..6e63e1fb19 --- /dev/null +++ b/apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/DefaultNetconfClientConfigurationBuilderFactoryTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.topology.spi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.doReturn; + +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.netconf.client.NetconfClientSessionListener; +import org.opendaylight.netconf.client.SslHandlerFactory; +import org.opendaylight.netconf.client.conf.NetconfClientConfiguration; +import org.opendaylight.netconf.client.conf.NetconfClientConfiguration.NetconfClientProtocol; +import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; +import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider; +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; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.Protocol.Name; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.ProtocolBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPasswordBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.Decimal64; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class DefaultNetconfClientConfigurationBuilderFactoryTest { + private static final NodeId NODE_ID = new NodeId("testing-node"); + + @Mock + private NetconfClientSessionListener sessionListener; + @Mock + private AAAEncryptionService encryptionService; + @Mock + private CredentialProvider credentialProvider; + @Mock + private SslHandlerFactoryProvider sslHandlerFactoryProvider; + @Mock + private SslHandlerFactory sslHandlerFactory; + + private final NetconfNodeBuilder nodeBuilder = new NetconfNodeBuilder() + .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1")))) + .setPort(new PortNumber(Uint16.valueOf(9999))) + .setReconnectOnChangedSchema(true) + .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000)) + .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100)) + .setKeepaliveDelay(Uint32.valueOf(1000)) + .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build()) + .setMaxConnectionAttempts(Uint32.ZERO) + .setSleepFactor(Decimal64.valueOf("1.5")) + .setConnectionTimeoutMillis(Uint32.valueOf(20000)); + + private DefaultNetconfClientConfigurationBuilderFactory factory; + + @Before + public void before() { + doReturn(sslHandlerFactory).when(sslHandlerFactoryProvider).getSslHandlerFactory(null); + + factory = new DefaultNetconfClientConfigurationBuilderFactory(encryptionService, credentialProvider, + sslHandlerFactoryProvider); + } + + @Test + public void testDefault() { + final var config = createConfig(nodeBuilder.setTcpOnly(false).build()); + assertEquals(NetconfClientProtocol.SSH, config.getProtocol()); + assertNotNull(config.getAuthHandler()); + assertNull(config.getSslHandlerFactory()); + } + + @Test + public void testSsh() { + final var config = createConfig( + nodeBuilder.setTcpOnly(false).setProtocol(new ProtocolBuilder().setName(Name.SSH).build()).build()); + assertEquals(NetconfClientProtocol.SSH, config.getProtocol()); + assertNotNull(config.getAuthHandler()); + assertNull(config.getSslHandlerFactory()); + } + + @Test + public void testTcp() { + final var config = createConfig(nodeBuilder.setTcpOnly(true).build()); + assertEquals(NetconfClientProtocol.TCP, config.getProtocol()); + assertNotNull(config.getAuthHandler()); + assertNull(config.getSslHandlerFactory()); + } + + @Test + public void testTls() { + final var config = createConfig( + nodeBuilder.setTcpOnly(false).setProtocol(new ProtocolBuilder().setName(Name.TLS).build()).build()); + assertEquals(NetconfClientProtocol.TLS, config.getProtocol()); + assertNull(config.getAuthHandler()); + assertSame(sslHandlerFactory, config.getSslHandlerFactory()); + } + + private NetconfClientConfiguration createConfig(final NetconfNode netconfNode) { + return factory.createClientConfigurationBuilder(NODE_ID, netconfNode) + .withSessionListener(sessionListener) + .build(); + } +} -- 2.36.6