Split up NetconfKeystoreAdapter 29/105829/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 4 May 2023 16:42:46 +0000 (18:42 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 4 May 2023 18:50:29 +0000 (20:50 +0200)
We have conflated interfaces for constructing KeyStores and looking up
KeyCredential objects. Split these two up, so they can be evolved
separately. This turns CredentialProvider into a very simple class.

JIRA: NETCONF-1006
Change-Id: I600ce21ccceb46ec3e2d5e3b1ccf7fd5022fd2f9
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
24 files changed:
apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcher.java
apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java
apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/tls/NetconfCallHomeTlsService.java
apps/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/tls/SslHandlerFactoryAdapter.java
apps/callhome-provider/src/test/java/org/opendaylight/netconf/callhome/mount/CallHomeMountDispatcherTest.java
apps/netconf-topology-impl/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java
apps/netconf-topology-impl/src/test/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImplTest.java
apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java
apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java
apps/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologySetup.java
apps/netconf-topology-singleton/src/main/resources/OSGI-INF/blueprint/netconf-topology-singleton.xml
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/NetconfNodeActorTest.java
apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManagerTest.java
apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java
apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImplTest.java
apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopology.java
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/DatastoreBackedPublicKeyAuth.java
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/CredentialProvider.java [new file with mode: 0644]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/KeyStoreProvider.java [moved from plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/NetconfKeystoreAdapter.java with 88% similarity]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultCredentialProvider.java [new file with mode: 0644]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultKeyStoreProvider.java [moved from plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultNetconfKeystoreAdapter.java with 79% similarity]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/sal/connect/util/SslHandlerFactoryImpl.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/DefaultKeyStoreProviderTest.java [moved from plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/DefaultNetconfKeystoreAdapterTest.java with 96% similarity]

index 16e1671a9cb5951131a568bf242d15a1e66b5eb2..fd53d4028a8f77d2da96c84e581ce03595612609 100644 (file)
@@ -27,8 +27,9 @@ import org.opendaylight.netconf.client.NetconfClientSession;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.nettyutil.ReconnectFuture;
 import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
@@ -54,7 +55,8 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom
     private final DataBroker dataBroker;
     private final DOMMountPointService mountService;
     private final AAAEncryptionService encryptionService;
-    private final NetconfKeystoreAdapter keystoreAdapter;
+    private final CredentialProvider credentialProvider;
+    private final KeyStoreProvider keyStoreProvider;
 
     protected CallHomeTopology topology;
 
@@ -66,9 +68,10 @@ 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 NetconfKeystoreAdapter keystoreAdapter) {
+            final AAAEncryptionService encryptionService, final CredentialProvider credentialProvider,
+            final KeyStoreProvider keyStoreProvider) {
         this(topologyId, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider, baseSchemas,
-            dataBroker, mountService, encryptionService, keystoreAdapter, null);
+            dataBroker, mountService, encryptionService, credentialProvider, keyStoreProvider, null);
     }
 
     @Activate
@@ -80,19 +83,20 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom
             @Reference final SchemaResourceManager schemaRepositoryProvider,
             @Reference final BaseNetconfSchemas baseSchemas, @Reference final DataBroker dataBroker,
             @Reference final DOMMountPointService mountService, @Reference final AAAEncryptionService encryptionService,
-            @Reference final NetconfKeystoreAdapter keystoreAdapter,
+            @Reference final CredentialProvider credentialProvider,
+            @Reference final KeyStoreProvider keyStoreProvider,
             @Reference final DeviceActionFactory deviceActionFactory) {
         this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, eventExecutor, keepaliveExecutor, processingExecutor,
-            schemaRepositoryProvider, baseSchemas, dataBroker, mountService, encryptionService, keystoreAdapter,
-            deviceActionFactory);
+            schemaRepositoryProvider, baseSchemas, dataBroker, mountService, encryptionService, credentialProvider,
+            keyStoreProvider, 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 NetconfKeystoreAdapter keystoreAdapter, final DeviceActionFactory deviceActionFactory) {
+            final AAAEncryptionService encryptionService, final CredentialProvider credentialProvider,
+            final KeyStoreProvider keyStoreProvider, final DeviceActionFactory deviceActionFactory) {
         this.topologyId = topologyId;
         this.eventExecutor = eventExecutor;
         this.keepaliveExecutor = keepaliveExecutor;
@@ -103,7 +107,8 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom
         this.dataBroker = dataBroker;
         this.mountService = mountService;
         this.encryptionService = encryptionService;
-        this.keystoreAdapter = requireNonNull(keystoreAdapter);
+        this.credentialProvider = requireNonNull(credentialProvider);
+        this.keyStoreProvider = requireNonNull(keyStoreProvider);
     }
 
     @Override
@@ -144,7 +149,7 @@ public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHom
     void createTopology() {
         topology = new CallHomeTopology(topologyId, this, eventExecutor, keepaliveExecutor, processingExecutor,
                 schemaRepositoryProvider, dataBroker, mountService, encryptionService, baseSchemas,
-                deviceActionFactory, keystoreAdapter);
+                deviceActionFactory, credentialProvider, keyStoreProvider);
     }
 
     @VisibleForTesting
index d002d522171bf81aee277fbf83be4c380dee6bb6..e01f4e8f05427b9130d927ab7c37133f2369ac52 100644 (file)
@@ -15,22 +15,23 @@ 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
 
 // Non-final for mocking
 public class CallHomeTopology extends AbstractNetconfTopology {
-
     public CallHomeTopology(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 BaseNetconfSchemas baseSchemas,
-            final DeviceActionFactory deviceActionFactory, final NetconfKeystoreAdapter keystoreAdapter) {
+            final DeviceActionFactory deviceActionFactory, final CredentialProvider credentialProvider,
+            final KeyStoreProvider keyStoreProvider) {
         super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
             schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, deviceActionFactory,
-            baseSchemas, keystoreAdapter);
+            baseSchemas, credentialProvider, keyStoreProvider);
     }
 }
index 063153ccde3c835a0920cc8328c8f0dc5c98bb70..5b9eb77c4bdaa17b282d7021c05058aa31ba6f48 100644 (file)
@@ -14,7 +14,7 @@ import org.opendaylight.netconf.callhome.protocol.CallHomeNetconfSubsystemListen
 import org.opendaylight.netconf.callhome.protocol.tls.NetconfCallHomeTlsServer;
 import org.opendaylight.netconf.callhome.protocol.tls.NetconfCallHomeTlsServerBuilder;
 import org.opendaylight.netconf.callhome.protocol.tls.TlsAllowedDevicesMonitor;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
@@ -29,17 +29,17 @@ public class NetconfCallHomeTlsService implements AutoCloseable {
     private final NetconfCallHomeTlsServer server;
 
     @Activate
-    public NetconfCallHomeTlsService(@Reference final NetconfKeystoreAdapter keystoreAdapter,
+    public NetconfCallHomeTlsService(@Reference final KeyStoreProvider keyStoreProvider,
             @Reference final TlsAllowedDevicesMonitor allowedDevicesMonitor,
             @Reference final CallHomeNetconfSubsystemListener subsystemListener,
             @Reference(target = "(type=global-boss-group)") final EventLoopGroup bossGroup,
             @Reference(target = "(type=global-worker-group)") final EventLoopGroup workerGroup) {
-        this(keystoreAdapter, allowedDevicesMonitor, subsystemListener, bossGroup, workerGroup,
+        this(keyStoreProvider, allowedDevicesMonitor, subsystemListener, bossGroup, workerGroup,
             // FIXME: tie together with OSGi Config Admin
             defaultTlsConfiguration());
     }
 
-    public NetconfCallHomeTlsService(final NetconfKeystoreAdapter keystoreAdapter,
+    public NetconfCallHomeTlsService(final KeyStoreProvider keyStoreProvider,
                                      final TlsAllowedDevicesMonitor allowedDevicesMonitor,
                                      final CallHomeNetconfSubsystemListener subsystemListener,
                                      final EventLoopGroup bossGroup,
@@ -51,7 +51,7 @@ public class NetconfCallHomeTlsService implements AutoCloseable {
             .setTimeout(config.getTimeout())
             .setMaxConnections(config.getMaxConnections())
             .setAllowedDevicesMonitor(requireNonNull(allowedDevicesMonitor))
-            .setSslHandlerFactory(new SslHandlerFactoryAdapter(keystoreAdapter, allowedDevicesMonitor))
+            .setSslHandlerFactory(new SslHandlerFactoryAdapter(keyStoreProvider, allowedDevicesMonitor))
             .setSubsystemListener(requireNonNull(subsystemListener))
             .setBossGroup(requireNonNull(bossGroup))
             .setWorkerGroup(requireNonNull(workerGroup))
index 8b53db1b9b08378f1d7aa9ad04564bdbcbc07644..ced99a0e249915e40417d250a40ad6406a7a29b0 100644 (file)
@@ -14,7 +14,7 @@ import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.netconf.callhome.protocol.tls.TlsAllowedDevicesMonitor;
 import org.opendaylight.netconf.client.SslHandlerFactory;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.sal.connect.util.SslHandlerFactoryImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -25,10 +25,10 @@ public class SslHandlerFactoryAdapter implements SslHandlerFactory {
     private final TlsAllowedDevicesMonitor allowedDevicesMonitor;
     private final SslHandlerFactory sslHandlerFactory;
 
-    public SslHandlerFactoryAdapter(final NetconfKeystoreAdapter keystoreAdapter,
+    public SslHandlerFactoryAdapter(final KeyStoreProvider keyStoreProvider,
             final @NonNull TlsAllowedDevicesMonitor allowedDevicesMonitor) {
         this.allowedDevicesMonitor = requireNonNull(allowedDevicesMonitor);
-        sslHandlerFactory = new SslHandlerFactoryImpl(keystoreAdapter);
+        sslHandlerFactory = new SslHandlerFactoryImpl(keyStoreProvider);
     }
 
     @Override
index 475c0ff070e1b68bee7618a95027e9ab2d984f57..0ab7af5bd62c4b25e63384738c7d5a9de5a941c4 100644 (file)
@@ -34,7 +34,8 @@ 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
@@ -57,7 +58,8 @@ public class CallHomeMountDispatcherTest {
     private CallHomeProtocolSessionContext mockProtoSess;
     private AAAEncryptionService mockEncryptionService;
     private BaseNetconfSchemas mockBaseSchemas;
-    private NetconfKeystoreAdapter mockKeystoreAdapter;
+    private CredentialProvider mockCredentialProvider;
+    private KeyStoreProvider mockKeyStoreProvider;
 
     @Before
     public void setup() {
@@ -73,11 +75,12 @@ public class CallHomeMountDispatcherTest {
         mockProtoSess = mock(CallHomeProtocolSessionContext.class);
         mockEncryptionService = mock(AAAEncryptionService.class);
         mockBaseSchemas = mock(BaseNetconfSchemas.class);
-        mockKeystoreAdapter = mock(NetconfKeystoreAdapter.class);
+        mockCredentialProvider = mock(CredentialProvider.class);
+        mockKeyStoreProvider = mock(KeyStoreProvider.class);
 
         instance = new CallHomeMountDispatcher(topologyId, mockExecutor, mockKeepAlive,
                 mockProcessingExecutor, mockSchemaRepoProvider, mockBaseSchemas, mockDataBroker, mockMount,
-                mockEncryptionService, mockKeystoreAdapter) {
+                mockEncryptionService, mockCredentialProvider, mockKeyStoreProvider) {
             @Override
             CallHomeMountSessionManager sessionManager() {
                 return mockSessMgr;
index 5b8263af61c529288fba32cdd2a81f3e171f1096..e8c8e744354b9ed526fb60a3482b5d706c78925a 100644 (file)
@@ -27,8 +27,9 @@ 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
 import org.opendaylight.netconf.topology.spi.NetconfConnectorDTO;
@@ -75,11 +76,12 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology
             @Reference final DOMMountPointService mountPointService,
             @Reference final AAAEncryptionService encryptionService,
             @Reference final RpcProviderService rpcProviderService, @Reference final BaseNetconfSchemas baseSchemas,
-            @Reference final NetconfKeystoreAdapter keystoreAdapter,
+            @Reference final CredentialProvider credentialProvider,
+            @Reference final KeyStoreProvider keyStoreProvider,
             @Reference final DeviceActionFactory deviceActionFactory) {
         this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, clientDispatcher, eventExecutor, keepaliveExecutor,
             processingExecutor, schemaRepositoryProvider, dataBroker, mountPointService, encryptionService,
-            rpcProviderService, baseSchemas, keystoreAdapter, deviceActionFactory);
+            rpcProviderService, baseSchemas, credentialProvider, keyStoreProvider, deviceActionFactory);
     }
 
     public NetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
@@ -87,10 +89,11 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology
             final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
             final DataBroker dataBroker, final DOMMountPointService mountPointService,
             final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService,
-            final BaseNetconfSchemas baseSchemas, final NetconfKeystoreAdapter keystoreAdapter) {
+            final BaseNetconfSchemas baseSchemas, final CredentialProvider credentialProvider,
+            final KeyStoreProvider keyStoreProvider) {
         this(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
                 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, rpcProviderService,
-                baseSchemas, keystoreAdapter, null);
+                baseSchemas, credentialProvider, keyStoreProvider, null);
     }
 
     @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR",
@@ -100,11 +103,11 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology
             final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
             final DataBroker dataBroker, final DOMMountPointService mountPointService,
             final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService,
-            final BaseNetconfSchemas baseSchemas, final NetconfKeystoreAdapter keystoreAdapter,
-            final DeviceActionFactory deviceActionFactory) {
+            final BaseNetconfSchemas baseSchemas, final CredentialProvider credentialProvider,
+            final KeyStoreProvider keyStoreProvider, final DeviceActionFactory deviceActionFactory) {
         super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
                 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, deviceActionFactory,
-                baseSchemas, keystoreAdapter);
+                baseSchemas, credentialProvider, keyStoreProvider);
 
         LOG.debug("Registering datastore listener");
         dtclReg = dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
index 7da19aa0f48e9708b5dfe58c58d71f92e6487cba..9c693889318b10726a2b408391dc57cbc36f93cd 100644 (file)
@@ -46,7 +46,8 @@ import org.opendaylight.netconf.client.NetconfClientSessionListener;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
 import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
@@ -101,7 +102,9 @@ public class NetconfTopologyImplTest {
     @Mock
     private RpcProviderService rpcProviderService;
     @Mock
-    private NetconfKeystoreAdapter keystoreAdapter;
+    private CredentialProvider credentialProvider;
+    @Mock
+    private KeyStoreProvider keyStoreProvider;
     @Mock
     private WriteTransaction wtx;
 
@@ -116,7 +119,7 @@ public class NetconfTopologyImplTest {
 
         topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher, mockedEventExecutor,
             mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker, mountPointService,
-            encryptionService, rpcProviderService, keystoreAdapter);
+            encryptionService, rpcProviderService, credentialProvider, keyStoreProvider);
         //verify initialization of topology
         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))).build(),
@@ -232,10 +235,11 @@ public class NetconfTopologyImplTest {
                                           final DataBroker dataBroker, final DOMMountPointService mountPointService,
                                           final AAAEncryptionService encryptionService,
                                           final RpcProviderService rpcProviderService,
-                                          final NetconfKeystoreAdapter keystoreAdapter) {
+                                          final CredentialProvider credentialProvider,
+                                          final KeyStoreProvider keyStoreProvider) {
             super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
                 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, rpcProviderService,
-                BASE_SCHEMAS, keystoreAdapter, null);
+                BASE_SCHEMAS, credentialProvider, keyStoreProvider, null);
         }
 
         @Override
index 7b77f6b80de25e7e8eaf6ada42f15d37329d75ff..1be18f640bf2eeecae1b669cd7a217b87b63e1ed 100644 (file)
@@ -42,8 +42,9 @@ 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService;
@@ -93,7 +94,8 @@ public class NetconfTopologyManager
     private final AAAEncryptionService encryptionService;
     private final RpcProviderService rpcProviderService;
     private final DeviceActionFactory deviceActionFactory;
-    private final NetconfKeystoreAdapter keystoreAdapter;
+    private final CredentialProvider credentialProvider;
+    private final KeyStoreProvider keyStoreProvider;
     private final SchemaResourceManager resourceManager;
 
     private ListenerRegistration<NetconfTopologyManager> dataChangeListenerRegistration;
@@ -112,7 +114,8 @@ public class NetconfTopologyManager
                                   final RpcProviderService rpcProviderService,
                                   final DeviceActionFactory deviceActionFactory,
                                   final SchemaResourceManager resourceManager,
-                                  final NetconfKeystoreAdapter keystoreAdapter) {
+                                  final CredentialProvider credentialProvider,
+                                  final KeyStoreProvider keyStoreProvider) {
         this.baseSchemas = requireNonNull(baseSchemas);
         this.dataBroker = requireNonNull(dataBroker);
         this.rpcProviderRegistry = requireNonNull(rpcProviderRegistry);
@@ -130,7 +133,8 @@ public class NetconfTopologyManager
         this.rpcProviderService = requireNonNull(rpcProviderService);
         this.deviceActionFactory = requireNonNull(deviceActionFactory);
         this.resourceManager = requireNonNull(resourceManager);
-        this.keystoreAdapter = requireNonNull(keystoreAdapter);
+        this.credentialProvider = requireNonNull(credentialProvider);
+        this.keyStoreProvider = requireNonNull(keyStoreProvider);
     }
 
     // Blueprint init method
@@ -303,7 +307,8 @@ public class NetconfTopologyManager
                     deviceId))
                 .setIdleTimeout(writeTxIdleTimeout)
                 .setEncryptionService(encryptionService)
-                .setKeystoreAdapter(keystoreAdapter)
+                .setCredentialProvider(credentialProvider)
+                .setKeyStoreProvider(keyStoreProvider)
                 .build();
     }
 }
index a393f5ee7bde59fba02775c9b8c8b2a742974b95..d0ce53bce202058efe6dcb5835d533b97820f504 100644 (file)
@@ -16,10 +16,8 @@ import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
 import java.math.BigDecimal;
 import java.net.InetSocketAddress;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
 import org.opendaylight.netconf.client.NetconfClientSessionListener;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
@@ -31,8 +29,9 @@ import org.opendaylight.netconf.client.mdsal.LibrarySchemaSourceProvider;
 import org.opendaylight.netconf.client.mdsal.NetconfDevice;
 import org.opendaylight.netconf.client.mdsal.NetconfDeviceBuilder;
 import org.opendaylight.netconf.client.mdsal.SchemalessNetconfDevice;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDevice;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
@@ -59,7 +58,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev22
 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.Empty;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
@@ -75,7 +73,8 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector {
     private final NetconfTopologySetup netconfTopologyDeviceSetup;
     private final RemoteDeviceId remoteDeviceId;
     private final AAAEncryptionService encryptionService;
-    private final NetconfKeystoreAdapter keystoreAdapter;
+    private final CredentialProvider credentialProvider;
+    private final KeyStoreProvider keyStoreProvider;
     private final DeviceActionFactory deviceActionFactory;
 
     // FIXME: this seems to be a builder-like transition between {start,stop}RemoteDeviceConnection. More documentation
@@ -88,7 +87,8 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector {
         this.remoteDeviceId = remoteDeviceId;
         this.deviceActionFactory = requireNonNull(deviceActionFactory);
         encryptionService = netconfTopologyDeviceSetup.getEncryptionService();
-        keystoreAdapter = netconfTopologyDeviceSetup.getKeystoreAdapter();
+        credentialProvider = netconfTopologyDeviceSetup.getCredentialProvider();
+        keyStoreProvider = netconfTopologyDeviceSetup.getKeyStoreProvider();
     }
 
     @Override
@@ -168,15 +168,11 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector {
                     libraryModulesSchemas = LibraryModulesSchemas.create(yangLibURL);
                 }
 
-                for (final Map.Entry<SourceIdentifier, URL> sourceIdentifierURLEntry :
-                        libraryModulesSchemas.getAvailableModels().entrySet()) {
-                    registeredYangLibSources
-                            .add(schemaResourcesDTO.getSchemaRegistry().registerSchemaSource(
-                                    new LibrarySchemaSourceProvider(remoteDeviceId,
-                                            libraryModulesSchemas.getAvailableModels()),
-                                    PotentialSchemaSource
-                                            .create(sourceIdentifierURLEntry.getKey(), YangTextSchemaSource.class,
-                                                    PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
+                for (var sourceIdentifierURLEntry : libraryModulesSchemas.getAvailableModels().entrySet()) {
+                    registeredYangLibSources.add(schemaResourcesDTO.getSchemaRegistry().registerSchemaSource(
+                        new LibrarySchemaSourceProvider(remoteDeviceId, libraryModulesSchemas.getAvailableModels()),
+                        PotentialSchemaSource.create(sourceIdentifierURLEntry.getKey(), YangTextSchemaSource.class,
+                            PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
                 }
             }
         }
@@ -249,7 +245,7 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector {
                     .withAuthHandler(getHandlerFromCredentials(node.getCredentials()));
         } else if (protocol.getName() == Name.TLS) {
             reconnectingClientConfigurationBuilder = NetconfReconnectingClientConfigurationBuilder.create()
-                    .withSslHandlerFactory(new SslHandlerFactoryImpl(keystoreAdapter, protocol.getSpecification()))
+                    .withSslHandlerFactory(new SslHandlerFactoryImpl(keyStoreProvider, protocol.getSpecification()))
                     .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TLS);
         } else {
             throw new IllegalStateException("Unsupported protocol type: " + protocol.getName());
@@ -292,7 +288,7 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector {
         if (credentials instanceof KeyAuth keyAuth) {
             final var keyPair = keyAuth.getKeyBased();
             return new DatastoreBackedPublicKeyAuth(keyPair.getUsername(), keyPair.getKeyId(),
-                    keystoreAdapter, encryptionService);
+                    credentialProvider, encryptionService);
         }
         throw new IllegalStateException("Unsupported credential type: " + credentials.getClass());
     }
index 2f8e885f1c350a252fdc0c0edc99840e8780e4b0..17a9274f32024f88a44185123c3be3a9bd3df429 100644 (file)
@@ -22,7 +22,8 @@ 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 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,7 +44,8 @@ public class NetconfTopologySetup {
     private final Duration idleTimeout;
     private final AAAEncryptionService encryptionService;
     private final BaseNetconfSchemas baseSchemas;
-    private final NetconfKeystoreAdapter keystoreAdapter;
+    private final CredentialProvider credentialProvider;
+    private final KeyStoreProvider keyStoreProvider;
 
     NetconfTopologySetup(final NetconfTopologySetupBuilder builder) {
         clusterSingletonServiceProvider = builder.getClusterSingletonServiceProvider();
@@ -62,7 +64,8 @@ public class NetconfTopologySetup {
         idleTimeout = builder.getIdleTimeout();
         encryptionService = builder.getEncryptionService();
         baseSchemas = builder.getBaseSchemas();
-        keystoreAdapter = builder.getKeystoreAdapter();
+        credentialProvider = builder.getCredentialProvider();
+        keyStoreProvider = builder.getKeyStoreProvider();
     }
 
     public ClusterSingletonServiceProvider getClusterSingletonServiceProvider() {
@@ -125,8 +128,12 @@ public class NetconfTopologySetup {
         return encryptionService;
     }
 
-    public NetconfKeystoreAdapter getKeystoreAdapter() {
-        return keystoreAdapter;
+    public CredentialProvider getCredentialProvider() {
+        return requireNonNull(credentialProvider);
+    }
+
+    public KeyStoreProvider getKeyStoreProvider() {
+        return requireNonNull(keyStoreProvider);
     }
 
     public BaseNetconfSchemas getBaseSchemas() {
@@ -150,7 +157,8 @@ public class NetconfTopologySetup {
         private Duration idleTimeout;
         private AAAEncryptionService encryptionService;
         private BaseNetconfSchemas baseSchemas;
-        private NetconfKeystoreAdapter keystoreAdapter;
+        private CredentialProvider credentialProvider;
+        private KeyStoreProvider keyStoreProvider;
 
         public NetconfTopologySetupBuilder() {
 
@@ -307,12 +315,21 @@ public class NetconfTopologySetup {
             return this;
         }
 
-        NetconfKeystoreAdapter getKeystoreAdapter() {
-            return requireNonNull(keystoreAdapter);
+        CredentialProvider getCredentialProvider() {
+            return requireNonNull(credentialProvider);
+        }
+
+        public NetconfTopologySetupBuilder setCredentialProvider(final CredentialProvider credentialProvider) {
+            this.credentialProvider = credentialProvider;
+            return this;
+        }
+
+        KeyStoreProvider getKeyStoreProvider() {
+            return requireNonNull(keyStoreProvider);
         }
 
-        public NetconfTopologySetupBuilder setKeystoreAdapter(final NetconfKeystoreAdapter keystoreAdapter) {
-            this.keystoreAdapter = keystoreAdapter;
+        public NetconfTopologySetupBuilder setKeyStoreProvider(final KeyStoreProvider keyStoreProvider) {
+            this.keyStoreProvider = keyStoreProvider;
             return this;
         }
 
index de7cf49e4a06e3712b8f4d18bc43ce7ae4ada287..f24f559eceb9c42d23a80f7db81414cafa278a8e 100644 (file)
@@ -43,16 +43,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
                interface="org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager"/>
     <reference id="baseSchemas"
                interface="org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas"/>
-    <reference id="keystoreAdapter"
-               interface="org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter"/>
-    <odl:clustered-app-config
-            id="singletonConfig"
-            binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.Config"
-    />
-
+    <reference id="credentialProvider"
+               interface="org.opendaylight.netconf.client.mdsal.api.CredentialProvider"/>
+    <reference id="keyStoreProvider"
+               interface="org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider"/>
     <reference id="encryptionService"
                interface="org.opendaylight.aaa.encrypt.AAAEncryptionService" />
 
+    <odl:clustered-app-config id="singletonConfig"
+        binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.Config"/>
+
     <bean id="netconfTopologyManager"
           class="org.opendaylight.netconf.topology.singleton.impl.NetconfTopologyManager"
           init-method="init" destroy-method="close">
@@ -73,7 +73,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <argument ref="rpcProvider" />
         <argument ref="deviceActionFactory"/>
         <argument ref="schemaManager"/>
-        <argument ref="keystoreAdapter"/>
+        <argument ref="credentialProvider"/>
+        <argument ref="keyStoreProvider"/>
     </bean>
     <service ref="netconfTopologyManager"
              interface="org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService"/>
index 41b049591bd35ea45b791fc60acc57d0602af2f5..b16a67554a82fcceb9a54ca35eb753948ab15cc8 100644 (file)
@@ -100,8 +100,9 @@ import org.opendaylight.mdsal.singleton.dom.impl.DOMClusterSingletonServiceProvi
 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.netconf.client.mdsal.NetconfDeviceSchema;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices.Rpcs;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
@@ -197,7 +198,8 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest {
     @Mock private ThreadPool mockThreadPool;
     @Mock private ScheduledThreadPool mockKeepaliveExecutor;
     @Mock private DeviceActionFactory deviceActionFactory;
-    @Mock private NetconfKeystoreAdapter keystoreAdapter;
+    @Mock private CredentialProvider credentialProvider;
+    @Mock private KeyStoreProvider keyStoreProvider;
 
     @Mock private ActorSystemProvider mockMasterActorSystemProvider;
     @Mock private DOMMountPointListener masterMountPointListener;
@@ -318,7 +320,7 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest {
                 mockRpcProviderRegistry, mockActionProviderRegistry, masterClusterSingletonServiceProvider,
                 mockKeepaliveExecutor, mockThreadPool, mockMasterActorSystemProvider, eventExecutor,
                 mockClientDispatcher, TOPOLOGY_ID, config, masterMountPointService, mockEncryptionService,
-                mockRpcProviderService, deviceActionFactory, resourceManager, keystoreAdapter) {
+                mockRpcProviderService, deviceActionFactory, resourceManager, credentialProvider, keyStoreProvider) {
             @Override
             protected NetconfTopologyContext newNetconfTopologyContext(final NetconfTopologySetup setup,
                     final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime,
@@ -359,7 +361,7 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest {
             mockActionProviderRegistry, mockSlaveClusterSingletonServiceProvider, mockKeepaliveExecutor, mockThreadPool,
                 mockSlaveActorSystemProvider, eventExecutor, mockClientDispatcher, TOPOLOGY_ID, config,
                 slaveMountPointService, mockEncryptionService, mockRpcProviderService, deviceActionFactory,
-                resourceManager, keystoreAdapter) {
+                resourceManager, credentialProvider, keyStoreProvider) {
             @Override
             protected NetconfTopologyContext newNetconfTopologyContext(final NetconfTopologySetup setup,
                 final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime,
index e66e55f075c9191574d9319943c63a4ad861f1d0..96bd51bba9c0fb4a679ff193639edc734c92f8eb 100644 (file)
@@ -86,7 +86,8 @@ 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 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;
@@ -175,7 +176,9 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
     @Mock
     private SchemaResourcesDTO schemaResourceDTO;
     @Mock
-    private NetconfKeystoreAdapter keystoreAdapter;
+    private CredentialProvider credentialProvider;
+    @Mock
+    private KeyStoreProvider keyStoreProvider;
 
     @Before
     public void setup() {
@@ -192,7 +195,8 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
             .setIdleTimeout(Duration.ofSeconds(1))
             .setSchemaResourceDTO(schemaResourceDTO)
             .setBaseSchemas(BASE_SCHEMAS)
-            .setKeystoreAdapter(keystoreAdapter)
+            .setCredentialProvider(credentialProvider)
+            .setKeyStoreProvider(keyStoreProvider)
             .build();
 
         final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService);
@@ -232,7 +236,8 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
             .setBaseSchemas(BASE_SCHEMAS)
             .setSchemaResourceDTO(schemaResourceDTO)
             .setActorSystem(system)
-            .setKeystoreAdapter(keystoreAdapter)
+            .setCredentialProvider(credentialProvider)
+            .setKeyStoreProvider(keyStoreProvider)
             .build();
 
         masterRef.tell(new RefreshSetupMasterActorData(newSetup, newRemoteDeviceId), testKit.getRef());
@@ -343,7 +348,8 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
                 .setSchemaResourceDTO(schemaResourceDTO2)
                 .setBaseSchemas(BASE_SCHEMAS)
                 .setActorSystem(system)
-                .setKeystoreAdapter(keystoreAdapter)
+                .setCredentialProvider(credentialProvider)
+                .setKeyStoreProvider(keyStoreProvider)
                 .build();
 
         final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT,
@@ -428,7 +434,8 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
             .setSchemaResourceDTO(schemaResourceDTO2)
             .setIdleTimeout(Duration.ofSeconds(1))
             .setBaseSchemas(BASE_SCHEMAS)
-            .setKeystoreAdapter(keystoreAdapter)
+            .setCredentialProvider(credentialProvider)
+            .setKeyStoreProvider(keyStoreProvider)
             .build();
         final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService);
         ActorRef actor = TestActorRef.create(system, props, "master_messages_2");
@@ -678,7 +685,8 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
                 .setSchemaResourceDTO(schemaResourceDTO2)
                 .setActorSystem(system)
                 .setBaseSchemas(BASE_SCHEMAS)
-                .setKeystoreAdapter(keystoreAdapter)
+                .setCredentialProvider(credentialProvider)
+                .setKeyStoreProvider(keyStoreProvider)
                 .build(), remoteDeviceId, TIMEOUT, mockMountPointService));
 
         doReturn(Futures.immediateFuture(mockSchemaContext))
index 329a6cc8135afd0dc541f3281feb9788362832c3..4e39a20a9d18f17a49b285dcad535107ff9b3554 100644 (file)
@@ -58,8 +58,9 @@ 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.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.NetconfDeviceSchemasResolver;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
 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;
@@ -128,7 +129,9 @@ public class NetconfNodeManagerTest extends AbstractBaseSchemasTest {
     @Mock
     private EffectiveModelContextFactory mockSchemaContextFactory;
     @Mock
-    private NetconfKeystoreAdapter keystoreAdapter;
+    private CredentialProvider credentialProvider;
+    @Mock
+    private KeyStoreProvider keyStoreProvider;
 
     private ActorSystem slaveSystem;
     private ActorSystem masterSystem;
@@ -168,7 +171,8 @@ public class NetconfNodeManagerTest extends AbstractBaseSchemasTest {
                 .setSchemaResourceDTO(new NetconfDevice.SchemaResourcesDTO(
                     masterSchemaRepository, masterSchemaRepository, mockSchemaContextFactory, mockSchemasResolver))
                 .setBaseSchemas(BASE_SCHEMAS)
-                .setKeystoreAdapter(keystoreAdapter)
+                .setCredentialProvider(credentialProvider)
+                .setKeyStoreProvider(keyStoreProvider)
                 .build();
 
         testMasterActorRef = TestActorRef.create(masterSystem, Props.create(TestMasterActor.class, masterSetup,
@@ -185,7 +189,8 @@ public class NetconfNodeManagerTest extends AbstractBaseSchemasTest {
                 .setSchemaResourceDTO(new NetconfDevice.SchemaResourcesDTO(
                     slaveSchemaRepository, slaveSchemaRepository, mockSchemaContextFactory, mockSchemasResolver))
                 .setBaseSchemas(BASE_SCHEMAS)
-                .setKeystoreAdapter(keystoreAdapter)
+                .setCredentialProvider(credentialProvider)
+                .setKeyStoreProvider(keyStoreProvider)
                 .build();
 
         netconfNodeManager = new NetconfNodeManager(slaveSetup, DEVICE_ID, responseTimeout,
index ac0880773877077d698cffaa4846b7d31aec8b83..51cfec7c24560815fa9f4309e65ae185d7a573dc 100644 (file)
@@ -59,8 +59,9 @@ 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 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;
@@ -126,14 +127,16 @@ public class NetconfTopologyManagerTest extends AbstractBaseSchemasTest {
         final AAAEncryptionService encryptionService = mock(AAAEncryptionService.class);
         final DeviceActionFactory deviceActionFactory = mock(DeviceActionFactory.class);
         final RpcProviderService rpcProviderService = mock(RpcProviderService.class);
-        final NetconfKeystoreAdapter keystoreAdapter = mock(NetconfKeystoreAdapter.class);
+        final CredentialProvider credentialProvider = mock(CredentialProvider.class);
+        final KeyStoreProvider keyStoreProvider = mock(KeyStoreProvider.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()), keystoreAdapter) {
+                new DefaultSchemaResourceManager(new DefaultYangParserFactory()), credentialProvider,
+                keyStoreProvider) {
             @Override
             protected NetconfTopologyContext newNetconfTopologyContext(final NetconfTopologySetup setup,
                 final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime,
index 856f56cfe5ed334868a7e7d1f9ffd5beda82358b..b66fd57f5b69a931de672b2bb47f51d366b7b665 100644 (file)
@@ -35,8 +35,9 @@ import org.opendaylight.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.netconf.client.NetconfClientSessionListener;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
 import org.opendaylight.netconf.client.mdsal.impl.DefaultSchemaResourceManager;
@@ -89,7 +90,9 @@ public class RemoteDeviceConnectorImplTest extends AbstractBaseSchemasTest {
     @Mock
     private DeviceActionFactory deviceActionFactory;
     @Mock
-    private NetconfKeystoreAdapter keystoreAdapter;
+    private CredentialProvider credentialProvider;
+    @Mock
+    private KeyStoreProvider keyStoreProvider;
 
     private NetconfTopologySetup.NetconfTopologySetupBuilder builder;
     private RemoteDeviceId remoteDeviceId;
@@ -110,7 +113,8 @@ public class RemoteDeviceConnectorImplTest extends AbstractBaseSchemasTest {
                 .setEventExecutor(eventExecutor)
                 .setNetconfClientDispatcher(clientDispatcher)
                 .setTopologyId(TOPOLOGY_ID)
-                .setKeystoreAdapter(keystoreAdapter);
+                .setCredentialProvider(credentialProvider)
+                .setKeyStoreProvider(keyStoreProvider);
     }
 
     @Test
index 8f2d175d49a02a673e35e24c91cca989f9b51ae0..ba53f48d88a71a882a9984e8341066b07efdb14a 100644 (file)
@@ -41,8 +41,9 @@ import org.opendaylight.netconf.client.mdsal.NetconfDevice.SchemaResourcesDTO;
 import org.opendaylight.netconf.client.mdsal.NetconfDeviceBuilder;
 import org.opendaylight.netconf.client.mdsal.SchemalessNetconfDevice;
 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.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDevice;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
@@ -86,7 +87,8 @@ public abstract class AbstractNetconfTopology implements NetconfTopology {
     private final NetconfClientDispatcher clientDispatcher;
     private final EventExecutor eventExecutor;
     private final DeviceActionFactory deviceActionFactory;
-    private final NetconfKeystoreAdapter keystoreAdapter;
+    private final CredentialProvider credentialProvider;
+    private final KeyStoreProvider keystoreProvider;
     private final SchemaResourceManager schemaManager;
     private final BaseNetconfSchemas baseSchemas;
 
@@ -105,7 +107,8 @@ public abstract class AbstractNetconfTopology implements NetconfTopology {
                                       final AAAEncryptionService encryptionService,
                                       final DeviceActionFactory deviceActionFactory,
                                       final BaseNetconfSchemas baseSchemas,
-                                      final NetconfKeystoreAdapter keystoreAdapter) {
+                                      final CredentialProvider credentialProvider,
+                                      final KeyStoreProvider keystoreProvider) {
         this.topologyId = requireNonNull(topologyId);
         this.clientDispatcher = clientDispatcher;
         this.eventExecutor = eventExecutor;
@@ -117,7 +120,8 @@ public abstract class AbstractNetconfTopology implements NetconfTopology {
         this.mountPointService = mountPointService;
         this.encryptionService = encryptionService;
         this.baseSchemas = requireNonNull(baseSchemas);
-        this.keystoreAdapter = requireNonNull(keystoreAdapter);
+        this.credentialProvider = requireNonNull(credentialProvider);
+        this.keystoreProvider = requireNonNull(keystoreProvider);
 
         // 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.
@@ -313,7 +317,7 @@ public abstract class AbstractNetconfTopology implements NetconfTopology {
                     .withAuthHandler(getHandlerFromCredentials(node.getCredentials()));
         } else if (protocol.getName() == Name.TLS) {
             reconnectingClientConfigurationBuilder = NetconfReconnectingClientConfigurationBuilder.create()
-                .withSslHandlerFactory(new SslHandlerFactoryImpl(keystoreAdapter, protocol.getSpecification()))
+                .withSslHandlerFactory(new SslHandlerFactoryImpl(keystoreProvider, protocol.getSpecification()))
                 .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TLS);
         } else {
             throw new IllegalStateException("Unsupported protocol type: " + protocol.getName());
@@ -351,8 +355,8 @@ public abstract class AbstractNetconfTopology implements NetconfTopology {
         }
         if (credentials instanceof KeyAuth keyAuth) {
             final var keyPair = keyAuth.getKeyBased();
-            return new DatastoreBackedPublicKeyAuth(keyPair.getUsername(), keyPair.getKeyId(),
-                    keystoreAdapter, encryptionService);
+            return new DatastoreBackedPublicKeyAuth(keyPair.getUsername(), keyPair.getKeyId(), credentialProvider,
+                encryptionService);
         }
         throw new IllegalStateException("Unsupported credential type: " + credentials.getClass());
     }
index fff6a8bf38bceab7245aa9302d60729b401a3c02..a58b376b29b143b7101c6573aeec07113e50b3f8 100644 (file)
@@ -14,11 +14,10 @@ import java.security.KeyPair;
 import java.util.Optional;
 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
 import org.opendaylight.aaa.encrypt.PKIUtil;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
 import org.opendaylight.netconf.shaded.sshd.client.future.AuthFuture;
 import org.opendaylight.netconf.shaded.sshd.client.session.ClientSession;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,18 +26,18 @@ public final class DatastoreBackedPublicKeyAuth extends AuthenticationHandler {
 
     private final String username;
     private final String pairId;
-    private final NetconfKeystoreAdapter keystoreAdapter;
+    private final CredentialProvider credentialProvider;
     private final AAAEncryptionService encryptionService;
 
     // FIXME: do not use Optional here and deal with atomic set
     private Optional<KeyPair> keyPair = Optional.empty();
 
     public DatastoreBackedPublicKeyAuth(final String username, final String pairId,
-                                        final NetconfKeystoreAdapter keystoreAdapter,
+                                        final CredentialProvider credentialProvider,
                                         final AAAEncryptionService encryptionService) {
         this.username = username;
         this.pairId = pairId;
-        this.keystoreAdapter = keystoreAdapter;
+        this.credentialProvider = credentialProvider;
         this.encryptionService = encryptionService;
 
         // try to immediately retrieve the pair from the adapter
@@ -62,23 +61,21 @@ public final class DatastoreBackedPublicKeyAuth extends AuthenticationHandler {
 
     private boolean tryToSetKeyPair() {
         LOG.debug("Trying to retrieve keypair for: {}", pairId);
-        final Optional<KeyCredential> keypairOptional = keystoreAdapter.getKeypairFromId(pairId);
-
-        if (keypairOptional.isPresent()) {
-            final KeyCredential dsKeypair = keypairOptional.orElseThrow();
-            final String passPhrase = Strings.isNullOrEmpty(dsKeypair.getPassphrase()) ? "" : dsKeypair.getPassphrase();
+        final var dsKeypair = credentialProvider.credentialForId(pairId);
+        if (dsKeypair == null) {
+            LOG.debug("Unable to retrieve keypair for: {}", pairId);
+            return false;
+        }
 
-            try {
-                keyPair = Optional.of(new PKIUtil().decodePrivateKey(
-                    new StringReader(encryptionService.decrypt(dsKeypair.getPrivateKey()).replace("\\n", "\n")),
-                    encryptionService.decrypt(passPhrase)));
-            } catch (IOException exception) {
-                LOG.warn("Unable to decode private key, id={}", pairId, exception);
-                return false;
-            }
-            return true;
+        final String passPhrase = Strings.isNullOrEmpty(dsKeypair.getPassphrase()) ? "" : dsKeypair.getPassphrase();
+        try {
+            keyPair = Optional.of(new PKIUtil().decodePrivateKey(
+                new StringReader(encryptionService.decrypt(dsKeypair.getPrivateKey()).replace("\\n", "\n")),
+                encryptionService.decrypt(passPhrase)));
+        } catch (IOException exception) {
+            LOG.warn("Unable to decode private key, id={}", pairId, exception);
+            return false;
         }
-        LOG.debug("Unable to retrieve keypair for: {}", pairId);
-        return false;
+        return true;
     }
 }
diff --git a/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/CredentialProvider.java b/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/CredentialProvider.java
new file mode 100644 (file)
index 0000000..8a69af1
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * 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.client.mdsal.api;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
+
+public interface CredentialProvider {
+    /**
+     * Get the a {@link KeyCredential} for a particular id.
+     *
+     * @param id Credential id
+     * @return A {@link KeyCredential} object, {@code null} if not found
+     * @throws NullPointerException if {@code id} is {@code null}
+     */
+    @Nullable KeyCredential credentialForId(String id);
+}
similarity index 88%
rename from plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/NetconfKeystoreAdapter.java
rename to plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/KeyStoreProvider.java
index e090f907ed0d378ef69b094d393be16dc433c0ba..c061368d61de90a910c7de40b8929567400b9b29 100644 (file)
@@ -11,14 +11,9 @@ package org.opendaylight.netconf.client.mdsal.api;
 import java.io.IOException;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
-import java.util.Optional;
 import java.util.Set;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
-
-public interface NetconfKeystoreAdapter {
-
-    Optional<KeyCredential> getKeypairFromId(String keyId);
 
+public interface KeyStoreProvider {
     /**
      * Using private keys and trusted certificates to create a new JDK <code>KeyStore</code> which
      * will be used by TLS clients to create <code>SSLEngine</code>. The private keys are essential
diff --git a/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultCredentialProvider.java b/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultCredentialProvider.java
new file mode 100644 (file)
index 0000000..ff3d96e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. 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.client.mdsal.impl;
+
+import com.google.common.collect.Iterables;
+import java.util.Collection;
+import java.util.Map;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialKey;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+@Component(service = CredentialProvider.class)
+public final class DefaultCredentialProvider
+        implements CredentialProvider, ClusteredDataTreeChangeListener<Keystore>, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultCredentialProvider.class);
+
+    private final @NonNull Registration reg;
+
+    private volatile @NonNull Map<KeyCredentialKey, KeyCredential> credentials = Map.of();
+
+    @Inject
+    @Activate
+    public DefaultCredentialProvider(@Reference final DataBroker dataBroker) {
+        reg = dataBroker.registerDataTreeChangeListener(
+            DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Keystore.class)),
+            this);
+    }
+
+    @Deactivate
+    @PreDestroy
+    @Override
+    public void close() {
+        reg.close();
+    }
+
+    @Override
+    public KeyCredential credentialForId(final String id) {
+        return credentials.get(new KeyCredentialKey(id));
+    }
+
+    @Override
+    public void onDataTreeChanged(final Collection<DataTreeModification<Keystore>> changes) {
+        final var keystore = Iterables.getLast(changes).getRootNode().getDataAfter();
+        final var newCredentials = keystore != null ? keystore.nonnullKeyCredential()
+            : Map.<KeyCredentialKey, KeyCredential>of();
+        LOG.debug("Updating to {} credentials", newCredentials.size());
+        credentials = newCredentials;
+    }
+}
@@ -7,13 +7,10 @@
  */
 package org.opendaylight.netconf.client.mdsal.impl;
 
-import static com.google.common.base.Verify.verifyNotNull;
 import static java.util.Objects.requireNonNull;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.VarHandle;
 import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
 import java.security.KeyFactory;
@@ -29,7 +26,6 @@ import java.util.Base64;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
@@ -41,10 +37,9 @@ import org.opendaylight.mdsal.binding.api.DataObjectModification;
 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -56,26 +51,23 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-@Component(service = NetconfKeystoreAdapter.class)
-public final class DefaultNetconfKeystoreAdapter
-        implements NetconfKeystoreAdapter, ClusteredDataTreeChangeListener<Keystore>, AutoCloseable {
+@Component(service = KeyStoreProvider.class)
+public final class DefaultKeyStoreProvider
+        implements KeyStoreProvider, ClusteredDataTreeChangeListener<Keystore>, AutoCloseable {
     /**
      * Internal state, updated atomically.
      */
     private record State(
-        @NonNull Map<String, KeyCredential> pairs,
         @NonNull Map<String, PrivateKey> privateKeys,
         @NonNull Map<String, TrustedCertificate> trustedCertificates) {
 
         State {
-            requireNonNull(pairs);
             requireNonNull(privateKeys);
             requireNonNull(trustedCertificates);
         }
 
         @NonNull StateBuilder newBuilder() {
-            return new StateBuilder(new HashMap<>(pairs), new HashMap<>(privateKeys),
-                new HashMap<>(trustedCertificates));
+            return new StateBuilder(new HashMap<>(privateKeys), new HashMap<>(trustedCertificates));
         }
     }
 
@@ -83,18 +75,16 @@ public final class DefaultNetconfKeystoreAdapter
      * Intermediate builder for State.
      */
     private record StateBuilder(
-        @NonNull HashMap<String, KeyCredential> pairs,
         @NonNull HashMap<String, PrivateKey> privateKeys,
         @NonNull HashMap<String, TrustedCertificate> trustedCertificates) {
 
         StateBuilder {
-            requireNonNull(pairs);
             requireNonNull(privateKeys);
             requireNonNull(trustedCertificates);
         }
 
         @NonNull State build() {
-            return new State(Map.copyOf(pairs), Map.copyOf(privateKeys), Map.copyOf(trustedCertificates));
+            return new State(Map.copyOf(privateKeys), Map.copyOf(trustedCertificates));
         }
     }
 
@@ -132,26 +122,16 @@ public final class DefaultNetconfKeystoreAdapter
         }
     }
 
-    private static final Logger LOG = LoggerFactory.getLogger(DefaultNetconfKeystoreAdapter.class);
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultKeyStoreProvider.class);
     private static final char[] EMPTY_CHARS = { };
-    private static final VarHandle STATE_VH;
-
-    static {
-        try {
-            STATE_VH = MethodHandles.lookup().findVarHandle(DefaultNetconfKeystoreAdapter.class, "state", State.class);
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new ExceptionInInitializerError(e);
-        }
-    }
 
     private final @NonNull Registration reg;
 
-    @SuppressWarnings("unused")
-    private volatile @NonNull State state = new State(Map.of(), Map.of(), Map.of());
+    private volatile @NonNull State state = new State(Map.of(), Map.of());
 
     @Inject
     @Activate
-    public DefaultNetconfKeystoreAdapter(@Reference final DataBroker dataBroker) {
+    public DefaultKeyStoreProvider(@Reference final DataBroker dataBroker) {
         reg = dataBroker.registerDataTreeChangeListener(
             DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Keystore.class)),
             this);
@@ -164,15 +144,10 @@ public final class DefaultNetconfKeystoreAdapter
         reg.close();
     }
 
-    @Override
-    public Optional<KeyCredential> getKeypairFromId(final String keyId) {
-        return Optional.ofNullable(currentState().pairs.get(keyId));
-    }
-
     @Override
     public KeyStore getJavaKeyStore(final Set<String> allowedKeys) throws GeneralSecurityException, IOException {
         requireNonNull(allowedKeys);
-        final var current = currentState();
+        final var current = state;
         if (current.privateKeys.isEmpty()) {
             throw new KeyStoreException("No keystore private key found");
         }
@@ -212,10 +187,6 @@ public final class DefaultNetconfKeystoreAdapter
         return keyStore;
     }
 
-    private @NonNull State currentState() {
-        return verifyNotNull((@NonNull State) STATE_VH.getAcquire(this));
-    }
-
     private static byte[] base64Decode(final String base64) {
         return Base64.getMimeDecoder().decode(base64.getBytes(StandardCharsets.US_ASCII));
     }
@@ -223,9 +194,9 @@ public final class DefaultNetconfKeystoreAdapter
     @Override
     public void onDataTreeChanged(final Collection<DataTreeModification<Keystore>> changes) {
         LOG.debug("Starting update with {} changes", changes.size());
-        final var builder = currentState().newBuilder();
+        final var builder = state.newBuilder();
         onDataTreeChanged(builder, changes);
-        STATE_VH.setRelease(this, builder.build());
+        state = builder.build();
         LOG.debug("Update finished");
     }
 
@@ -236,14 +207,7 @@ public final class DefaultNetconfKeystoreAdapter
             final var rootNode = change.getRootNode();
 
             for (var changedChild : rootNode.getModifiedChildren()) {
-                if (changedChild.getDataType().equals(KeyCredential.class)) {
-                    final var dataAfter = rootNode.getDataAfter();
-                    builder.pairs.clear();
-                    if (dataAfter != null) {
-                        dataAfter.nonnullKeyCredential().values()
-                            .forEach(pair -> builder.pairs.put(pair.key().getKeyId(), pair));
-                    }
-                } else if (changedChild.getDataType().equals(PrivateKey.class)) {
+                if (changedChild.getDataType().equals(PrivateKey.class)) {
                     onPrivateKeyChanged(builder.privateKeys, (DataObjectModification<PrivateKey>)changedChild);
                 } else if (changedChild.getDataType().equals(TrustedCertificate.class)) {
                     onTrustedCertificateChanged(builder.trustedCertificates,
index 4c88f38803c9d4c095bc674fe7ec58750c7b8c9c..64ea3d87d3382d1ef94335a377069cdeeec52261 100644 (file)
@@ -21,27 +21,27 @@ import javax.net.ssl.SSLEngine;
 import javax.net.ssl.TrustManagerFactory;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.netconf.client.SslHandlerFactory;
-import org.opendaylight.netconf.client.mdsal.api.NetconfKeystoreAdapter;
+import org.opendaylight.netconf.client.mdsal.api.KeyStoreProvider;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.protocol.Specification;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.connection.parameters.protocol.specification.TlsCase;
 
 public final class SslHandlerFactoryImpl implements SslHandlerFactory {
-    private final NetconfKeystoreAdapter keystoreAdapter;
+    private final KeyStoreProvider keyStoreProvider;
     private final @Nullable Specification specification;
 
-    public SslHandlerFactoryImpl(final NetconfKeystoreAdapter keystoreAdapter) {
-        this(keystoreAdapter, null);
+    public SslHandlerFactoryImpl(final KeyStoreProvider keyStoreProvider) {
+        this(keyStoreProvider, null);
     }
 
-    public SslHandlerFactoryImpl(final NetconfKeystoreAdapter keystoreAdapter, final Specification specification) {
-        this.keystoreAdapter = requireNonNull(keystoreAdapter);
+    public SslHandlerFactoryImpl(final KeyStoreProvider keyStoreProvider, final Specification specification) {
+        this.keyStoreProvider = requireNonNull(keyStoreProvider);
         this.specification = specification;
     }
 
     @Override
     public SslHandler createSslHandler(final Set<String> allowedKeys) {
         try {
-            final KeyStore keyStore = keystoreAdapter.getJavaKeyStore(allowedKeys);
+            final KeyStore keyStore = keyStoreProvider.getJavaKeyStore(allowedKeys);
 
             final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
             kmf.init(keyStore, "".toCharArray());
@@ -42,7 +42,7 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
 @RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class DefaultNetconfKeystoreAdapterTest {
+public class DefaultKeyStoreProviderTest {
     private static final String XML_ELEMENT_PRIVATE_KEY = "private-key";
     private static final String XML_ELEMENT_NAME = "name";
     private static final String XML_ELEMENT_DATA = "data";
@@ -58,12 +58,12 @@ public class DefaultNetconfKeystoreAdapterTest {
     @Before
     public void setUp() {
         doReturn(listenerRegistration).when(dataBroker)
-            .registerDataTreeChangeListener(any(DataTreeIdentifier.class), any(DefaultNetconfKeystoreAdapter.class));
+            .registerDataTreeChangeListener(any(DataTreeIdentifier.class), any(DefaultKeyStoreProvider.class));
     }
 
     @Test
     public void testKeystoreAdapterInit() throws Exception {
-        final DefaultNetconfKeystoreAdapter keystoreAdapter = new DefaultNetconfKeystoreAdapter(dataBroker);
+        final DefaultKeyStoreProvider keystoreAdapter = new DefaultKeyStoreProvider(dataBroker);
         final var ex = assertThrows(KeyStoreException.class, keystoreAdapter::getJavaKeyStore);
         assertThat(ex.getMessage(), startsWith("No keystore private key found"));
     }
@@ -84,7 +84,7 @@ public class DefaultNetconfKeystoreAdapterTest {
         final var privateKey = getPrivateKey();
         doReturn(privateKey).when(childObjectModification).getDataAfter();
 
-        final var keystoreAdapter = new DefaultNetconfKeystoreAdapter(dataBroker);
+        final var keystoreAdapter = new DefaultKeyStoreProvider(dataBroker);
         keystoreAdapter.onDataTreeChanged(List.of(dataTreeModification));
 
         final var keyStore = keystoreAdapter.getJavaKeyStore();
@@ -124,7 +124,7 @@ public class DefaultNetconfKeystoreAdapterTest {
         doReturn(trustedCertificate).when(childObjectModification2).getDataAfter();
 
         // Apply configurations
-        final var keystoreAdapter = new DefaultNetconfKeystoreAdapter(dataBroker);
+        final var keystoreAdapter = new DefaultKeyStoreProvider(dataBroker);
         keystoreAdapter.onDataTreeChanged(List.of(dataTreeModification1, dataTreeModification2));
 
         // Check result