Rework BaseScheams 59/110059/11
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 28 Jan 2024 10:29:00 +0000 (11:29 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 17 Feb 2024 10:43:19 +0000 (11:43 +0100)
The EffectiveModelContext we use for initial baseline access depends on
the set of advertized capabilities.

This patch refactors BaseNetconfSchemas and BaseSchema, so that we have
well-defined API-level contract backed by a cache.

JIRA: NETCONF-1256
Change-Id: I9a432f03be861eb082a7f2349801b921849e6e5d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
38 files changed:
apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeMountService.java
apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeTopology.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/NetconfNodeContext.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/utils/NetconfTopologySetup.java
apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/AbstractBaseSchemasTest.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/src/main/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopology.java
apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfNodeHandler.java
apps/netconf-topology/src/test/java/org/opendaylight/netconf/topology/spi/NetconfNodeHandlerTest.java
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/DeviceSourcesResolver.java
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/NetconfDevice.java
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/NetconfDeviceBuilder.java
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/SchemalessNetconfDevice.java
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchema.java [new file with mode: 0644]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchemaProvider.java [new file with mode: 0644]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchemas.java [deleted file]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/BaseRpcSchemalessTransformer.java
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultBaseNetconfSchema.java [moved from plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/BaseSchema.java with 61% similarity]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultBaseNetconfSchemaProvider.java [new file with mode: 0644]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultBaseNetconfSchemas.java [deleted file]
plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/NetconfMessageTransformer.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/AbstractBaseSchemasTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/NetconfNestedNotificationTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/NetconfStateSchemasTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/NetconfToNotificationTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/NetconfToRpcRequestTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/SchemalessNetconfDeviceTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/BaseRpcSchemalessTransformerTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/NetconfBaseOpsTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/NetconfMessageTransformerTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/spi/NetconfDataTreeServiceImplTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/spi/NetconfDeviceRpcTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/spi/NetconfDeviceWriteOnlyTxTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/spi/SchemalessNetconfDeviceRpcTest.java

index 0d88b9c2f6c76378da29bdcd642e6cd5ae101795..f20cd1a95eadd20e65edaf863bd0a05966995da8 100644 (file)
@@ -25,7 +25,7 @@ import org.opendaylight.netconf.client.NetconfClientSession;
 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.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.common.NetconfTimer;
@@ -114,24 +114,24 @@ public final class CallHomeMountService implements AutoCloseable {
             final @Reference NetconfTimer timer,
             final @Reference NetconfTopologySchemaAssembler schemaAssembler,
             final @Reference SchemaResourceManager schemaRepositoryProvider,
-            final @Reference BaseNetconfSchemas baseSchemas,
+            final @Reference BaseNetconfSchemaProvider baseSchemaProvider,
             final @Reference DataBroker dataBroker,
             final @Reference DOMMountPointService mountService,
             final @Reference DeviceActionFactory deviceActionFactory) {
-        this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, timer, schemaAssembler, schemaRepositoryProvider, baseSchemas,
-            dataBroker, mountService, deviceActionFactory);
+        this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, timer, schemaAssembler, schemaRepositoryProvider,
+            baseSchemaProvider, dataBroker, mountService, deviceActionFactory);
     }
 
     public CallHomeMountService(final String topologyId, final NetconfTimer timer,
             final NetconfTopologySchemaAssembler schemaAssembler, final SchemaResourceManager schemaRepositoryProvider,
-            final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker, final DOMMountPointService mountService,
-            final DeviceActionFactory deviceActionFactory) {
+            final BaseNetconfSchemaProvider baseSchemaProvider, final DataBroker dataBroker,
+            final DOMMountPointService mountService, final DeviceActionFactory deviceActionFactory) {
 
         final var clientConfBuilderFactory = createClientConfigurationBuilderFactory();
         final var clientFactory = createClientFactory();
         topology = new CallHomeTopology(topologyId, clientFactory, timer, schemaAssembler,
             schemaRepositoryProvider, dataBroker, mountService, clientConfBuilderFactory,
-            baseSchemas, deviceActionFactory);
+            baseSchemaProvider, deviceActionFactory);
     }
 
     @VisibleForTesting
index b9cf85a9a53bad1ff33161c6ff8590c149010ab1..ca8a307320bf75678833f84351247798524708ea 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.netconf.topology.callhome;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
 import org.opendaylight.netconf.client.NetconfClientFactory;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.common.NetconfTimer;
@@ -25,10 +25,10 @@ class CallHomeTopology extends AbstractNetconfTopology {
     CallHomeTopology(final String topologyId, final NetconfClientFactory clientFactory, final NetconfTimer timer,
             final NetconfTopologySchemaAssembler schemaAssembler, final SchemaResourceManager schemaRepositoryProvider,
             final DataBroker dataBroker, final DOMMountPointService mountPointService,
-            final NetconfClientConfigurationBuilderFactory builderFactory, final BaseNetconfSchemas baseSchemas,
-            final DeviceActionFactory deviceActionFactory) {
+            final NetconfClientConfigurationBuilderFactory builderFactory,
+            final BaseNetconfSchemaProvider baseSchemaProvider, final DeviceActionFactory deviceActionFactory) {
         super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
-            mountPointService, builderFactory, deviceActionFactory, baseSchemas);
+            mountPointService, builderFactory, deviceActionFactory, baseSchemaProvider);
     }
 
     void disableNode(final NodeId nodeId) {
index 4883042ba388a11e1c0a371f76c9d2f82426f3af..c1ef98e1aa27895b43e23d2e069e820c675d5b0d 100644 (file)
@@ -21,7 +21,7 @@ import org.opendaylight.mdsal.binding.api.RpcProviderService;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
 import org.opendaylight.netconf.client.NetconfClientFactory;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
 import org.opendaylight.netconf.common.NetconfTimer;
@@ -63,10 +63,11 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology
             @Reference final DOMMountPointService mountPointService,
             @Reference final AAAEncryptionService encryptionService,
             @Reference final NetconfClientConfigurationBuilderFactory builderFactory,
-            @Reference final RpcProviderService rpcProviderService, @Reference final BaseNetconfSchemas baseSchemas,
+            @Reference final RpcProviderService rpcProviderService,
+            @Reference final BaseNetconfSchemaProvider baseSchemaProvider,
             @Reference final DeviceActionFactory deviceActionFactory) {
         this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, clientFactory, timer, schemaAssembler, schemaRepositoryProvider,
-            dataBroker, mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemas,
+            dataBroker, mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemaProvider,
             deviceActionFactory);
     }
 
@@ -75,9 +76,9 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology
             final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker,
             final DOMMountPointService mountPointService, final AAAEncryptionService encryptionService,
             final NetconfClientConfigurationBuilderFactory builderFactory, final RpcProviderService rpcProviderService,
-            final BaseNetconfSchemas baseSchemas) {
+            final BaseNetconfSchemaProvider baseSchemaProvider) {
         this(topologyId, clientclientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
-            mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemas, null);
+            mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemaProvider, null);
     }
 
     @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR",
@@ -87,9 +88,9 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology
             final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker,
             final DOMMountPointService mountPointService, final AAAEncryptionService encryptionService,
             final NetconfClientConfigurationBuilderFactory builderFactory, final RpcProviderService rpcProviderService,
-            final BaseNetconfSchemas baseSchemas, final DeviceActionFactory deviceActionFactory) {
+            final BaseNetconfSchemaProvider baseSchemaProvider, final DeviceActionFactory deviceActionFactory) {
         super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
-            mountPointService, builderFactory, deviceActionFactory, baseSchemas);
+            mountPointService, builderFactory, deviceActionFactory, baseSchemaProvider);
 
         LOG.debug("Registering datastore listener");
         dtclReg = dataBroker.registerLegacyTreeChangeListener(DataTreeIdentifier.of(
index d9bff3595eea80306e4671ef2e8638a4dcfd5ef7..77c8f064538e31c9740b0e6a76bcde6b5cae7dac 100644 (file)
@@ -29,9 +29,9 @@ 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.NetconfClientFactory;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
-import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemaProvider;
 import org.opendaylight.netconf.common.NetconfTimer;
 import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
 import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
@@ -95,7 +95,7 @@ class NetconfTopologyImplTest {
             final var topology = new TestingNetconfTopologyImpl(TOPOLOGY_KEY.getTopologyId().getValue(),
                 mockedClientFactory, mockedTimer, schemaAssembler, mockedResourceManager, dataBroker, mountPointService,
                 encryptionService, builderFactory, rpcProviderService,
-                new DefaultBaseNetconfSchemas(new DefaultYangParserFactory()));
+                new DefaultBaseNetconfSchemaProvider(new DefaultYangParserFactory()));
             //verify initialization of topology
             verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, TOPOLOGY_PATH,
                 new TopologyBuilder().withKey(TOPOLOGY_KEY).build());
@@ -152,9 +152,9 @@ class NetconfTopologyImplTest {
                 final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker,
                 final DOMMountPointService mountPointService, final AAAEncryptionService encryptionService,
                 final NetconfClientConfigurationBuilderFactory builderFactory,
-                final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) {
-            super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider,
-                dataBroker, mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemas);
+                final RpcProviderService rpcProviderService, final BaseNetconfSchemaProvider baseSchemaProvider) {
+            super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
+                mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemaProvider);
         }
 
         @Override
index 212d3a61b9105ca25e9fe6d9f16b51174af23ff5..e0c4a62352ccceb3ce9a33b6999b3067b45a9e75 100644 (file)
@@ -141,9 +141,9 @@ final class NetconfNodeContext implements AutoCloseable {
         // Instantiate the handler ...
         masterSalFacade = createSalFacade(netconfNode.requireLockDatastore());
 
-        nodeHandler = new NetconfNodeHandler(setup.getNetconfClientFactory(), setup.getTimer(), setup.getBaseSchemas(),
-            schemaManager, setup.getSchemaAssembler(), builderFactory, deviceActionFactory, masterSalFacade,
-            remoteDeviceId, configNode.getNodeId(), netconfNode, nodeOptional);
+        nodeHandler = new NetconfNodeHandler(setup.getNetconfClientFactory(), setup.getTimer(),
+            setup.getBaseSchemaProvider(), schemaManager, setup.getSchemaAssembler(), builderFactory,
+            deviceActionFactory, masterSalFacade, remoteDeviceId, configNode.getNodeId(), netconfNode, nodeOptional);
         nodeHandler.connect();
     }
 
index 4b3a259839c8c61f31871238e5ce0df5aedb9579..bad929cca0d0d092a3900b4814eac74965afb832 100644 (file)
@@ -36,7 +36,7 @@ import org.opendaylight.mdsal.dom.api.DOMMountPointService;
 import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.api.ServiceGroupIdentifier;
 import org.opendaylight.netconf.client.NetconfClientFactory;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
@@ -89,7 +89,7 @@ public class NetconfTopologyManager implements DataTreeChangeListener<Node>, Aut
     private final Map<InstanceIdentifier<Node>, NetconfTopologyContext> contexts = new ConcurrentHashMap<>();
     private final Map<InstanceIdentifier<Node>, Registration> clusterRegistrations = new ConcurrentHashMap<>();
 
-    private final BaseNetconfSchemas baseSchemas;
+    private final BaseNetconfSchemaProvider baseSchemaProvider;
     private final DataBroker dataBroker;
     private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
     private final NetconfTimer timer;
@@ -107,7 +107,7 @@ public class NetconfTopologyManager implements DataTreeChangeListener<Node>, Aut
     private NetconfTopologyRPCProvider rpcProvider;
 
     @Activate
-    public NetconfTopologyManager(@Reference final BaseNetconfSchemas baseSchemas,
+    public NetconfTopologyManager(@Reference final BaseNetconfSchemaProvider baseSchemaProvider,
             @Reference final DataBroker dataBroker,
             @Reference final ClusterSingletonServiceProvider clusterSingletonServiceProvider,
             @Reference final NetconfTimer timer,
@@ -121,21 +121,21 @@ public class NetconfTopologyManager implements DataTreeChangeListener<Node>, Aut
             @Reference final SchemaResourceManager resourceManager,
             @Reference final NetconfClientConfigurationBuilderFactory builderFactory,
             final Configuration configuration) {
-        this(baseSchemas, dataBroker, clusterSingletonServiceProvider, timer, schemaAssembler,
+        this(baseSchemaProvider, dataBroker, clusterSingletonServiceProvider, timer, schemaAssembler,
             actorSystemProvider.getActorSystem(), clientFactory, mountPointService, encryptionService,
             rpcProviderService, deviceActionFactory, resourceManager, builderFactory, configuration.topology$_$id(),
             Uint16.valueOf(configuration.write$_$transaction$_$idle$_$timeout()));
     }
 
     @Inject
-    public NetconfTopologyManager(final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker,
+    public NetconfTopologyManager(final BaseNetconfSchemaProvider baseSchemaProvider, final DataBroker dataBroker,
             final ClusterSingletonServiceProvider clusterSingletonServiceProvider, final NetconfTimer timer,
             final NetconfTopologySchemaAssembler schemaAssembler, final ActorSystemProvider actorSystemProvider,
             final NetconfClientFactory clientFactory, final DOMMountPointService mountPointService,
             final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService,
             final DeviceActionFactory deviceActionFactory, final SchemaResourceManager resourceManager,
             final NetconfClientConfigurationBuilderFactory builderFactory) {
-        this(baseSchemas, dataBroker, clusterSingletonServiceProvider, timer, schemaAssembler,
+        this(baseSchemaProvider, dataBroker, clusterSingletonServiceProvider, timer, schemaAssembler,
             actorSystemProvider.getActorSystem(), clientFactory, mountPointService, encryptionService,
             rpcProviderService, deviceActionFactory, resourceManager, builderFactory,
             NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, Uint16.ZERO);
@@ -143,7 +143,7 @@ public class NetconfTopologyManager implements DataTreeChangeListener<Node>, Aut
 
     @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR",
         justification = "Non-final for mocking, but we register for DTCL and that leaks 'this'")
-    public NetconfTopologyManager(final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker,
+    public NetconfTopologyManager(final BaseNetconfSchemaProvider baseSchemaProvider, final DataBroker dataBroker,
             final ClusterSingletonServiceProvider clusterSingletonServiceProvider, final NetconfTimer timer,
             final NetconfTopologySchemaAssembler schemaAssembler, final ActorSystem actorSystem,
             final NetconfClientFactory clientFactory, final DOMMountPointService mountPointService,
@@ -151,7 +151,7 @@ public class NetconfTopologyManager implements DataTreeChangeListener<Node>, Aut
             final DeviceActionFactory deviceActionFactory, final SchemaResourceManager resourceManager,
             final NetconfClientConfigurationBuilderFactory builderFactory, final String topologyId,
             final Uint16 writeTransactionIdleTimeout) {
-        this.baseSchemas = requireNonNull(baseSchemas);
+        this.baseSchemaProvider = requireNonNull(baseSchemaProvider);
         this.dataBroker = requireNonNull(dataBroker);
         this.clusterSingletonServiceProvider = requireNonNull(clusterSingletonServiceProvider);
         this.timer = requireNonNull(timer);
@@ -317,7 +317,7 @@ public class NetconfTopologyManager implements DataTreeChangeListener<Node>, Aut
 
         return NetconfTopologySetup.builder()
             .setClusterSingletonServiceProvider(clusterSingletonServiceProvider)
-            .setBaseSchemas(baseSchemas)
+            .setBaseSchemaProvider(baseSchemaProvider)
             .setDataBroker(dataBroker)
             .setInstanceIdentifier(instanceIdentifier)
             .setNode(node)
index 59cf563d0829fc610d38a5c93efcee10c255eb37..08286fe4c9cd66a4c17bd1c011bad9060c4c84c9 100644 (file)
@@ -16,7 +16,7 @@ import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider;
 import org.opendaylight.netconf.client.NetconfClientFactory;
 import org.opendaylight.netconf.client.mdsal.NetconfDevice;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.common.NetconfTimer;
 import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
@@ -34,7 +34,7 @@ public final class NetconfTopologySetup {
     private final String topologyId;
     private final NetconfDevice.SchemaResourcesDTO schemaResourceDTO;
     private final Duration idleTimeout;
-    private final BaseNetconfSchemas baseSchemas;
+    private final BaseNetconfSchemaProvider baseSchemaProvider;
 
     private NetconfTopologySetup(final Builder builder) {
         clusterSingletonServiceProvider = builder.getClusterSingletonServiceProvider();
@@ -48,7 +48,7 @@ public final class NetconfTopologySetup {
         topologyId = builder.getTopologyId();
         schemaResourceDTO = builder.getSchemaResourceDTO();
         idleTimeout = builder.getIdleTimeout();
-        baseSchemas = builder.getBaseSchemas();
+        baseSchemaProvider = builder.getBaseSchemaProvider();
     }
 
     public ClusterSingletonServiceProvider getClusterSingletonServiceProvider() {
@@ -95,8 +95,8 @@ public final class NetconfTopologySetup {
         return idleTimeout;
     }
 
-    public BaseNetconfSchemas getBaseSchemas() {
-        return baseSchemas;
+    public BaseNetconfSchemaProvider getBaseSchemaProvider() {
+        return baseSchemaProvider;
     }
 
     public static @NonNull Builder builder() {
@@ -115,18 +115,18 @@ public final class NetconfTopologySetup {
         private NetconfClientFactory netconfClientFactory;
         private NetconfDevice.SchemaResourcesDTO schemaResourceDTO;
         private Duration idleTimeout;
-        private BaseNetconfSchemas baseSchemas;
+        private BaseNetconfSchemaProvider baseSchemaProvider;
 
         private Builder() {
             // Hidden on purpose
         }
 
-        BaseNetconfSchemas getBaseSchemas() {
-            return requireNonNull(baseSchemas, "BaseSchemas not initialized");
+        BaseNetconfSchemaProvider getBaseSchemaProvider() {
+            return requireNonNull(baseSchemaProvider, "BaseSchemas not initialized");
         }
 
-        public Builder setBaseSchemas(final BaseNetconfSchemas baseSchemas) {
-            this.baseSchemas = requireNonNull(baseSchemas);
+        public Builder setBaseSchemaProvider(final BaseNetconfSchemaProvider baseSchemaProvider) {
+            this.baseSchemaProvider = requireNonNull(baseSchemaProvider);
             return this;
         }
 
index 3da2be42e47865007afb46857c38ccf9dd13024a..b1813d0252f3eb4068eccb0f4463a1b4e8cab296 100644 (file)
@@ -7,23 +7,11 @@
  */
 package org.opendaylight.netconf.topology.singleton.impl;
 
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
-import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
-import org.opendaylight.yangtools.yang.parser.api.YangParserException;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
+import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemaProvider;
 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
 
 public abstract class AbstractBaseSchemasTest {
-    protected static BaseNetconfSchemas BASE_SCHEMAS;
-
-    @BeforeClass
-    public static void initBaseSchemas() throws YangParserException {
-        BASE_SCHEMAS = new DefaultBaseNetconfSchemas(new DefaultYangParserFactory());
-    }
-
-    @AfterClass
-    public static void freeBaseSchemas() {
-        BASE_SCHEMAS = null;
-    }
+    protected static BaseNetconfSchemaProvider BASE_SCHEMAS =
+        new DefaultBaseNetconfSchemaProvider(new DefaultYangParserFactory());
 }
index 5db53a0019b6506451d691380b9dcc7a3a62d910..656028af8a1d7b976b769ff63f5be5cdf1882daa 100644 (file)
@@ -187,7 +187,7 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
             .setActorSystem(system)
             .setIdleTimeout(Duration.ofSeconds(1))
             .setSchemaResourceDTO(schemaResourceDTO)
-            .setBaseSchemas(BASE_SCHEMAS)
+            .setBaseSchemaProvider(BASE_SCHEMAS)
             .build();
 
         final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService);
@@ -226,7 +226,7 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
                 new InetSocketAddress(InetAddresses.forString("127.0.0.2"), 9999));
 
         final NetconfTopologySetup newSetup = NetconfTopologySetup.builder()
-            .setBaseSchemas(BASE_SCHEMAS)
+            .setBaseSchemaProvider(BASE_SCHEMAS)
             .setSchemaResourceDTO(schemaResourceDTO)
             .setActorSystem(system)
             .build();
@@ -337,7 +337,7 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
         doReturn(mockSchemaRepository).when(schemaResourceDTO2).getSchemaRepository();
         final NetconfTopologySetup setup = NetconfTopologySetup.builder()
                 .setSchemaResourceDTO(schemaResourceDTO2)
-                .setBaseSchemas(BASE_SCHEMAS)
+                .setBaseSchemaProvider(BASE_SCHEMAS)
                 .setActorSystem(system)
                 .build();
 
@@ -424,7 +424,7 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
             .setActorSystem(system)
             .setSchemaResourceDTO(schemaResourceDTO2)
             .setIdleTimeout(Duration.ofSeconds(1))
-            .setBaseSchemas(BASE_SCHEMAS)
+            .setBaseSchemaProvider(BASE_SCHEMAS)
             .build();
         final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService);
         ActorRef actor = TestActorRef.create(system, props, "master_messages_2");
@@ -673,7 +673,7 @@ public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
         final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props(NetconfTopologySetup.builder()
                 .setSchemaResourceDTO(schemaResourceDTO2)
                 .setActorSystem(system)
-                .setBaseSchemas(BASE_SCHEMAS)
+                .setBaseSchemaProvider(BASE_SCHEMAS)
                 .build(), remoteDeviceId, TIMEOUT, mockMountPointService));
 
         doReturn(Futures.immediateFuture(mockSchemaContext))
index 92ac0b78de816c0cd843c205f36f8c4bdd083ca6..168bd613503f357ae6de9843fc1cb96850c61cde 100644 (file)
@@ -164,7 +164,7 @@ public class NetconfNodeManagerTest extends AbstractBaseSchemasTest {
                 .setDataBroker(mockDataBroker)
                 .setSchemaResourceDTO(new NetconfDevice.SchemaResourcesDTO(
                     masterSchemaRepository, masterSchemaRepository, mockSchemaContextFactory, mockSchemasResolver))
-                .setBaseSchemas(BASE_SCHEMAS)
+                .setBaseSchemaProvider(BASE_SCHEMAS)
                 .build();
 
         testMasterActorRef = TestActorRef.create(masterSystem, Props.create(TestMasterActor.class, masterSetup,
@@ -180,7 +180,7 @@ public class NetconfNodeManagerTest extends AbstractBaseSchemasTest {
                 .setDataBroker(mockDataBroker)
                 .setSchemaResourceDTO(new NetconfDevice.SchemaResourcesDTO(
                     slaveSchemaRepository, slaveSchemaRepository, mockSchemaContextFactory, mockSchemasResolver))
-                .setBaseSchemas(BASE_SCHEMAS)
+                .setBaseSchemaProvider(BASE_SCHEMAS)
                 .build();
 
         netconfNodeManager = new NetconfNodeManager(slaveSetup, DEVICE_ID, responseTimeout,
index df5605d01842b1f6774faec6253d456dacd53d9a..f250c54a7b821cd137e9775d5a7158b9d61e094f 100644 (file)
@@ -17,7 +17,7 @@ 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.NetconfClientFactory;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
@@ -43,7 +43,7 @@ public abstract class AbstractNetconfTopology {
     private final NetconfClientFactory clientFactory;
     private final DeviceActionFactory deviceActionFactory;
     private final SchemaResourceManager schemaManager;
-    private final BaseNetconfSchemas baseSchemas;
+    private final BaseNetconfSchemaProvider baseSchemaProvider;
     private final NetconfClientConfigurationBuilderFactory builderFactory;
     private final NetconfTimer timer;
 
@@ -56,7 +56,7 @@ public abstract class AbstractNetconfTopology {
             final NetconfTimer timer, final NetconfTopologySchemaAssembler schemaAssembler,
             final SchemaResourceManager schemaManager, final DataBroker dataBroker,
             final DOMMountPointService mountPointService, final NetconfClientConfigurationBuilderFactory builderFactory,
-            final DeviceActionFactory deviceActionFactory, final BaseNetconfSchemas baseSchemas) {
+            final DeviceActionFactory deviceActionFactory, final BaseNetconfSchemaProvider baseSchemaProvider) {
         this.topologyId = requireNonNull(topologyId);
         this.clientFactory = requireNonNull(clientFactory);
         this.timer = requireNonNull(timer);
@@ -66,7 +66,7 @@ public abstract class AbstractNetconfTopology {
         this.dataBroker = requireNonNull(dataBroker);
         this.mountPointService = mountPointService;
         this.builderFactory = requireNonNull(builderFactory);
-        this.baseSchemas = requireNonNull(baseSchemas);
+        this.baseSchemaProvider = requireNonNull(baseSchemaProvider);
 
         // 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.
@@ -120,8 +120,9 @@ public abstract class AbstractNetconfTopology {
 
         final NetconfNodeHandler nodeHandler;
         try {
-            nodeHandler = new NetconfNodeHandler(clientFactory, timer, baseSchemas, schemaManager, schemaAssembler,
-                builderFactory, deviceActionFactory, deviceSalFacade, deviceId, nodeId, netconfNode, nodeOptional);
+            nodeHandler = new NetconfNodeHandler(clientFactory, timer, baseSchemaProvider, schemaManager,
+                schemaAssembler, builderFactory, deviceActionFactory, deviceSalFacade, deviceId, nodeId, netconfNode,
+                nodeOptional);
         } catch (IllegalArgumentException e) {
             // This is a workaround for NETCONF-1114 where the encrypted password's lexical structure is not enforced
             // in the datastore and it ends up surfacing when we decrypt the password.
index d3962ac22d17d278e1dcce7c738d27b2879dd615..6ec5205a4eb9af26cf33bb2da79b337ca2b4c71e 100644 (file)
@@ -33,7 +33,7 @@ import org.opendaylight.netconf.client.mdsal.NetconfDeviceBuilder;
 import org.opendaylight.netconf.client.mdsal.NetconfDeviceCommunicator;
 import org.opendaylight.netconf.client.mdsal.NetconfDeviceSchema;
 import org.opendaylight.netconf.client.mdsal.SchemalessNetconfDevice;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDevice;
@@ -128,7 +128,7 @@ public final class NetconfNodeHandler extends AbstractRegistration implements Re
     private Task currentTask;
 
     public NetconfNodeHandler(final NetconfClientFactory clientFactory, final NetconfTimer timer,
-            final BaseNetconfSchemas baseSchemas, final SchemaResourceManager schemaManager,
+            final BaseNetconfSchemaProvider baseSchemaProvider, final SchemaResourceManager schemaManager,
             final NetconfTopologySchemaAssembler schemaAssembler,
             final NetconfClientConfigurationBuilderFactory builderFactory,
             final DeviceActionFactory deviceActionFactory, final RemoteDeviceHandler delegate,
@@ -167,7 +167,7 @@ public final class NetconfNodeHandler extends AbstractRegistration implements Re
 
         final RemoteDevice<NetconfDeviceCommunicator> device;
         if (node.requireSchemaless()) {
-            device = new SchemalessNetconfDevice(baseSchemas, deviceId, salFacade);
+            device = new SchemalessNetconfDevice(baseSchemaProvider, deviceId, salFacade);
             yanglibRegistrations = List.of();
         } else {
             final var resources = schemaManager.getSchemaResources(node.getSchemaCacheDirectory(), nodeId.getValue());
@@ -178,7 +178,7 @@ public final class NetconfNodeHandler extends AbstractRegistration implements Re
                 .setId(deviceId)
                 .setSalFacade(salFacade)
                 .setDeviceActionFactory(deviceActionFactory)
-                .setBaseSchemas(baseSchemas)
+                .setBaseSchemas(baseSchemaProvider)
                 .build();
             yanglibRegistrations = registerDeviceSchemaSources(deviceId, node, resources);
         }
index 1442988cce9214309c822e7c1796de75021a80f9..531e5ba436251142909bc3075732bead6dfe7a9c 100644 (file)
@@ -43,7 +43,7 @@ import org.opendaylight.netconf.client.NetconfClientFactory;
 import org.opendaylight.netconf.client.NetconfClientSession;
 import org.opendaylight.netconf.client.mdsal.NetconfDeviceCapabilities;
 import org.opendaylight.netconf.client.mdsal.NetconfDeviceSchema;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
@@ -53,7 +53,7 @@ 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;
 import org.opendaylight.netconf.client.mdsal.api.SslContextFactoryProvider;
-import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemaProvider;
 import org.opendaylight.netconf.common.NetconfTimer;
 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;
@@ -76,7 +76,7 @@ public class NetconfNodeHandlerTest {
         new InetSocketAddress(InetAddresses.forString("127.0.0.1"), 9999));
     private static final NodeId NODE_ID = new NodeId("testing-node");
 
-    private static BaseNetconfSchemas BASE_SCHEMAS;
+    private static BaseNetconfSchemaProvider BASE_SCHEMAS;
 
     // Core setup
     @Mock
@@ -121,7 +121,7 @@ public class NetconfNodeHandlerTest {
 
     @BeforeClass
     public static void beforeClass() throws Exception {
-        BASE_SCHEMAS = new DefaultBaseNetconfSchemas(new DefaultYangParserFactory());
+        BASE_SCHEMAS = new DefaultBaseNetconfSchemaProvider(new DefaultYangParserFactory());
     }
 
     @BeforeClass
index 98521c1bb1478f2d37e833a03a07a59006c98416..31075b5d1392131bb362438a25301eebf858605c 100644 (file)
@@ -12,10 +12,10 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.collect.Sets;
 import java.util.HashSet;
 import java.util.concurrent.Callable;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchema;
 import org.opendaylight.netconf.client.mdsal.api.NetconfDeviceSchemasResolver;
 import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
-import org.opendaylight.netconf.client.mdsal.impl.BaseSchema;
 import org.opendaylight.netconf.client.mdsal.spi.NetconfDeviceRpc;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -29,10 +29,10 @@ final class DeviceSourcesResolver implements Callable<DeviceSources> {
     private final NetconfSessionPreferences remoteSessionCapabilities;
     private final NetconfDeviceSchemasResolver stateSchemasResolver;
     private final NetconfDeviceRpc deviceRpc;
-    private final BaseSchema baseSchema;
+    private final BaseNetconfSchema baseSchema;
     private final RemoteDeviceId id;
 
-    DeviceSourcesResolver(final RemoteDeviceId id, final BaseSchema baseSchema, final NetconfDeviceRpc deviceRpc,
+    DeviceSourcesResolver(final RemoteDeviceId id, final BaseNetconfSchema baseSchema, final NetconfDeviceRpc deviceRpc,
             final NetconfSessionPreferences remoteSessionCapabilities,
             final NetconfDeviceSchemasResolver stateSchemasResolver) {
         this.id = requireNonNull(id);
index 124eb16b7614ccddcff5da282e3395949eb9d23b..3caa773c960afff5853113b7a5dfce3ea6a7a89a 100644 (file)
@@ -39,7 +39,8 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
 import org.opendaylight.netconf.api.CapabilityURN;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchema;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.NetconfDeviceSchemasResolver;
 import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
@@ -49,7 +50,6 @@ import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices.Rpcs;
-import org.opendaylight.netconf.client.mdsal.impl.BaseSchema;
 import org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil;
 import org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformer;
 import org.opendaylight.netconf.client.mdsal.spi.NetconfDeviceRpc;
@@ -103,20 +103,20 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     private final NetconfDeviceSchemasResolver stateSchemasResolver;
     private final NotificationHandler notificationHandler;
     private final boolean reconnectOnSchemasChange;
-    private final BaseNetconfSchemas baseSchemas;
+    private final BaseNetconfSchemaProvider baseSchemas;
 
     @GuardedBy("this")
     private ListenableFuture<List<Object>> schemaFuturesList;
     @GuardedBy("this")
     private boolean connected = false;
 
-    public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final BaseNetconfSchemas baseSchemas,
+    public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final BaseNetconfSchemaProvider baseSchemas,
             final RemoteDeviceId id, final RemoteDeviceHandler salFacade, final Executor globalProcessingExecutor,
             final boolean reconnectOnSchemasChange) {
         this(schemaResourcesDTO, baseSchemas, id, salFacade, globalProcessingExecutor, reconnectOnSchemasChange, null);
     }
 
-    public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final BaseNetconfSchemas baseSchemas,
+    public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final BaseNetconfSchemaProvider baseSchemas,
             final RemoteDeviceId id, final RemoteDeviceHandler salFacade, final Executor globalProcessingExecutor,
             final boolean reconnectOnSchemasChange, final DeviceActionFactory deviceActionFactory) {
         this.baseSchemas = requireNonNull(baseSchemas);
@@ -141,9 +141,9 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
         setConnected(true);
         LOG.debug("{}: Session to remote device established with {}", id, remoteSessionCapabilities);
 
-        final BaseSchema baseSchema = resolveBaseSchema(remoteSessionCapabilities.isNotificationsSupported());
-        final NetconfDeviceRpc initRpc = new NetconfDeviceRpc(baseSchema.modelContext(), listener,
-            new NetconfMessageTransformer(baseSchema.getMountPointContext(), false, baseSchema));
+        final var baseSchema = baseSchemas.baseSchemaForCapabilities(remoteSessionCapabilities);
+        final var initRpc = new NetconfDeviceRpc(baseSchema.modelContext(), listener,
+            new NetconfMessageTransformer(baseSchema.mountPointContext(), false, baseSchema));
         final var sourceResolverFuture = Futures.submit(new DeviceSourcesResolver(id, baseSchema, initRpc,
                 remoteSessionCapabilities, stateSchemasResolver), processingExecutor);
 
@@ -165,7 +165,7 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
         Futures.addCallback(netconfDeviceSchemaFuture, new FutureCallback<>() {
                 @Override
                 public void onSuccess(final NetconfDeviceSchema result) {
-                    handleSalInitializationSuccess(listener, result, remoteSessionCapabilities,
+                    handleSalInitializationSuccess(listener, baseSchema, result, remoteSessionCapabilities,
                         getDeviceSpecificRpc(result.mountContext(), listener, baseSchema));
                 }
 
@@ -221,8 +221,8 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     }
 
     private synchronized void handleSalInitializationSuccess(final RemoteDeviceCommunicator listener,
-            final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences remoteSessionCapabilities,
-            final Rpcs deviceRpc) {
+            final BaseNetconfSchema baseSchema, final NetconfDeviceSchema deviceSchema,
+            final NetconfSessionPreferences remoteSessionCapabilities, final Rpcs deviceRpc) {
         // NetconfDevice.SchemaSetup can complete after NetconfDeviceCommunicator was closed. In that case do nothing,
         // since salFacade.onDeviceDisconnected was already called.
         if (!connected) {
@@ -230,8 +230,7 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
             return;
         }
 
-        final var messageTransformer = new NetconfMessageTransformer(deviceSchema.mountContext(), true,
-            resolveBaseSchema(remoteSessionCapabilities.isNotificationsSupported()));
+        final var messageTransformer = new NetconfMessageTransformer(deviceSchema.mountContext(), true, baseSchema);
 
         // Order is important here: salFacade has to see the device come up and then the notificationHandler can deliver
         // whatever notifications have been held back
@@ -276,7 +275,7 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     }
 
     private ListenableFuture<@NonNull MountPointContext> createMountPointContext(
-            final EffectiveModelContext schemaContext, final BaseSchema baseSchema,
+            final EffectiveModelContext schemaContext, final BaseNetconfSchema baseSchema,
             final NetconfDeviceCommunicator listener) {
         final MountPointContext emptyContext = MountPointContext.of(schemaContext);
         if (schemaContext.findModule(SchemaMountConstants.RFC8528_MODULE).isEmpty()) {
@@ -319,12 +318,8 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
         notificationHandler.handleNotification(notification);
     }
 
-    private BaseSchema resolveBaseSchema(final boolean notificationSupport) {
-        return notificationSupport ? baseSchemas.baseSchemaWithNotifications() : baseSchemas.baseSchema();
-    }
-
     protected NetconfDeviceRpc getDeviceSpecificRpc(final MountPointContext result,
-            final RemoteDeviceCommunicator listener, final BaseSchema schema) {
+            final RemoteDeviceCommunicator listener, final BaseNetconfSchema schema) {
         return new NetconfDeviceRpc(result.modelContext(), listener,
             new NetconfMessageTransformer(result, true, schema));
     }
index 7ce98d0b7550a9f41ca6a2780152f887ebb0f2b0..e97b231317dcb9d2a2cb96ead782e2b7ab68f7fd 100644 (file)
@@ -11,7 +11,7 @@ import static java.util.Objects.requireNonNull;
 
 import java.util.concurrent.Executor;
 import org.opendaylight.netconf.client.mdsal.NetconfDevice.SchemaResourcesDTO;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
@@ -23,7 +23,7 @@ public class NetconfDeviceBuilder {
     private RemoteDeviceHandler salFacade;
     private Executor globalProcessingExecutor;
     private DeviceActionFactory deviceActionFactory;
-    private BaseNetconfSchemas baseSchemas;
+    private BaseNetconfSchemaProvider baseSchemas;
 
     public NetconfDeviceBuilder setReconnectOnSchemasChange(final boolean reconnectOnSchemasChange) {
         this.reconnectOnSchemasChange = reconnectOnSchemasChange;
@@ -55,7 +55,7 @@ public class NetconfDeviceBuilder {
         return this;
     }
 
-    public NetconfDeviceBuilder setBaseSchemas(final BaseNetconfSchemas baseSchemas) {
+    public NetconfDeviceBuilder setBaseSchemas(final BaseNetconfSchemaProvider baseSchemas) {
         this.baseSchemas = requireNonNull(baseSchemas);
         return this;
     }
index f381ca51d2b344b93b3fdd60e585fb52700d32ca..2347c4ed5b4c60611df7a8937552fb187f2e2cf1 100644 (file)
@@ -9,9 +9,8 @@ package org.opendaylight.netconf.client.mdsal;
 
 import static java.util.Objects.requireNonNull;
 
-import com.google.common.annotations.VisibleForTesting;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDevice;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
@@ -23,48 +22,41 @@ import org.opendaylight.netconf.client.mdsal.impl.SchemalessMessageTransformer;
 import org.opendaylight.netconf.client.mdsal.spi.SchemalessNetconfDeviceRpc;
 
 public class SchemalessNetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
-    private final BaseNetconfSchemas baseSchemas;
+    private final BaseNetconfSchemaProvider baseSchemas;
     private final RemoteDeviceId id;
     private final RemoteDeviceHandler salFacade;
-    private final SchemalessMessageTransformer messageTransformer;
-    private final BaseRpcSchemalessTransformer rpcTransformer;
 
-    public SchemalessNetconfDevice(final BaseNetconfSchemas baseSchemas, final RemoteDeviceId id,
-            final RemoteDeviceHandler salFacade) {
-        this.baseSchemas = requireNonNull(baseSchemas);
-        this.id = id;
-        this.salFacade = salFacade;
-        final MessageCounter counter = new MessageCounter();
-        rpcTransformer = new BaseRpcSchemalessTransformer(baseSchemas, counter);
-        messageTransformer = new SchemalessMessageTransformer(counter);
-    }
+    private SchemalessMessageTransformer messageTransformer;
 
-    @VisibleForTesting
-    SchemalessNetconfDevice(final BaseNetconfSchemas baseSchemas, final RemoteDeviceId id,
-            final RemoteDeviceHandler salFacade, final SchemalessMessageTransformer messageTransformer) {
+    public SchemalessNetconfDevice(final BaseNetconfSchemaProvider baseSchemas, final RemoteDeviceId id,
+            final RemoteDeviceHandler salFacade) {
         this.baseSchemas = requireNonNull(baseSchemas);
-        this.id = id;
-        this.salFacade = salFacade;
-        final MessageCounter counter = new MessageCounter();
-        rpcTransformer = new BaseRpcSchemalessTransformer(baseSchemas, counter);
-        this.messageTransformer = messageTransformer;
+        this.id = requireNonNull(id);
+        this.salFacade = requireNonNull(salFacade);
     }
 
     @Override
     public void onRemoteSessionUp(final NetconfSessionPreferences remoteSessionCapabilities,
             final NetconfDeviceCommunicator netconfDeviceCommunicator) {
+        final var baseSchema = baseSchemas.baseSchemaForCapabilities(remoteSessionCapabilities);
+        final var mountContext = baseSchema.mountPointContext();
+
+        final var counter = new MessageCounter();
+        final var rpcTransformer = new BaseRpcSchemalessTransformer(baseSchema, counter);
+        messageTransformer = new SchemalessMessageTransformer(counter);
+
         salFacade.onDeviceConnected(
             // FIXME: or bound from base schema rather?
-            new NetconfDeviceSchema(NetconfDeviceCapabilities.empty(),
-            baseSchemas.baseSchema().getMountPointContext()),
-            remoteSessionCapabilities, new RemoteDeviceServices(
-                new SchemalessNetconfDeviceRpc(id,netconfDeviceCommunicator, rpcTransformer, messageTransformer),
+            new NetconfDeviceSchema(NetconfDeviceCapabilities.empty(), mountContext), remoteSessionCapabilities,
+            new RemoteDeviceServices(
+                new SchemalessNetconfDeviceRpc(id, netconfDeviceCommunicator, rpcTransformer, messageTransformer),
                 null));
     }
 
     @Override
     public void onRemoteSessionDown() {
         salFacade.onDeviceDisconnected();
+        messageTransformer = null;
     }
 
     @Override
diff --git a/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchema.java b/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchema.java
new file mode 100644 (file)
index 0000000..7584213
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2024 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 com.google.common.collect.ImmutableMap;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.MountPointContext;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+
+/**
+ * A {@link MountPointContext} corresponding to a NETCONF baseline advertized by a device. This baseline is sufficient
+ * to invoke basic NETCONF operations and perform schema discovery.
+ */
+@NonNullByDefault
+public interface BaseNetconfSchema extends Immutable {
+    /**
+     * Return the {@link MountPointContext}.
+     *
+     * @return the mount point context
+     */
+    MountPointContext mountPointContext();
+
+    /**
+     * Return the {@link MountPointContext}. This is a convenience equivalent to
+     * {@code mountPointContext().modelContext()}.
+     *
+     * @return the mount point context
+     */
+    default EffectiveModelContext modelContext() {
+        return mountPointContext().modelContext();
+    }
+
+    /**
+     * Return the set of RPCs available in {@link #modelContext()}.
+     *
+     * @return the set of available RPCs
+     */
+    ImmutableMap<QName, ? extends RpcDefinition> mappedRpcs();
+}
diff --git a/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchemaProvider.java b/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchemaProvider.java
new file mode 100644 (file)
index 0000000..ff7883c
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020 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 com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * A provider of {@link BaseNetconfSchema} instances.
+ */
+@Beta
+@NonNullByDefault
+public interface BaseNetconfSchemaProvider {
+    /**
+     * Return a {@link BaseNetconfSchema} corresponding to a set of capabilities advertized by a NETCONF device.
+     *
+     * @param sessionPreferences the set of advertized capabilities
+     * @return A {@link BaseNetconfSchema}
+     * @throws NullPointerException if {@code capabilityURNs} is {@code null}
+     */
+    BaseNetconfSchema baseSchemaForCapabilities(NetconfSessionPreferences sessionPreferences);
+}
diff --git a/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchemas.java b/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/api/BaseNetconfSchemas.java
deleted file mode 100644 (file)
index 4e32d7d..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2020 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 com.google.common.annotations.Beta;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.opendaylight.netconf.client.mdsal.impl.BaseSchema;
-
-@Beta
-@NonNullByDefault
-public interface BaseNetconfSchemas {
-
-    BaseSchema baseSchema();
-
-    BaseSchema baseSchemaWithNotifications();
-}
index 17ba164267a14c94beffcbb234064288b86daa48..232e85b72e7055e1de7f054226752deb0d854e18 100644 (file)
@@ -9,8 +9,8 @@ package org.opendaylight.netconf.client.mdsal.impl;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Objects.requireNonNull;
 
-import com.google.common.collect.ImmutableMap;
 import java.io.IOException;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.dom.DOMResult;
@@ -20,15 +20,13 @@ import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.xml.XmlElement;
 import org.opendaylight.netconf.api.xml.XmlUtil;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchema;
 import org.opendaylight.netconf.client.mdsal.api.RpcTransformer;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -37,21 +35,18 @@ import org.w3c.dom.Element;
  * Transforms base netconf RPCs.
  */
 public class BaseRpcSchemalessTransformer implements RpcTransformer<NormalizedNode, DOMRpcResult> {
-    private final ImmutableMap<QName, ? extends RpcDefinition> mappedRpcs;
-    private final EffectiveModelContext modelContext;
+    private final BaseNetconfSchema baseSchema;
     private final MessageCounter counter;
 
-    public BaseRpcSchemalessTransformer(final BaseNetconfSchemas baseSchemas, final MessageCounter counter) {
-        final var baseSchema = baseSchemas.baseSchema();
-        mappedRpcs = baseSchema.getMappedRpcs();
-        modelContext = baseSchema.modelContext();
-        this.counter = counter;
+    public BaseRpcSchemalessTransformer(final BaseNetconfSchema baseSchema, final MessageCounter counter) {
+        this.baseSchema = requireNonNull(baseSchema);
+        this.counter = requireNonNull(counter);
     }
 
     @Override
     public NetconfMessage toRpcRequest(final QName rpc, final NormalizedNode payload) {
         // In case no input for rpc is defined, we can simply construct the payload here
-
+        final var mappedRpcs = baseSchema.mappedRpcs();
         final var mappedRpc = checkNotNull(mappedRpcs.get(rpc),
             "Unknown rpc %s, available rpcs: %s", rpc, mappedRpcs.keySet());
         final DOMResult domResult = NetconfMessageTransformUtil.prepareDomResultForRpcRequest(rpc, counter);
@@ -66,7 +61,7 @@ public class BaseRpcSchemalessTransformer implements RpcTransformer<NormalizedNo
         final DOMResult result = domResult;
         try {
             NetconfMessageTransformUtil.writeNormalizedOperationInput((ContainerNode) payload, result, Absolute.of(rpc),
-                modelContext);
+                baseSchema.modelContext());
         } catch (final XMLStreamException | IOException | IllegalStateException e) {
             throw new IllegalStateException("Unable to serialize input of " + rpc, e);
         }
similarity index 61%
rename from plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/BaseSchema.java
rename to plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultBaseNetconfSchema.java
index ed3cd04cde82c3982fcbdcc2dfd3fb6a55719436..81f57350f5fb9a619454f43f449a8cbd76ff8028 100644 (file)
@@ -10,30 +10,31 @@ package org.opendaylight.netconf.client.mdsal.impl;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchema;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.schema.MountPointContext;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 
-public final class BaseSchema implements Immutable {
+/**
+ * An {@link EffectiveModelContext} corresponding to a NETCONF baseline advertized by a device..
+ */
+public final class DefaultBaseNetconfSchema implements BaseNetconfSchema {
     private final @NonNull ImmutableMap<QName, ? extends RpcDefinition> mappedRpcs;
-    private final @NonNull MountPointContext mountContext;
+    private final @NonNull MountPointContext mountPointContext;
 
-    BaseSchema(final EffectiveModelContext context) {
-        mountContext = MountPointContext.of(context);
+    DefaultBaseNetconfSchema(final EffectiveModelContext context) {
+        mountPointContext = MountPointContext.of(context);
         mappedRpcs = Maps.uniqueIndex(context.getOperations(), RpcDefinition::getQName);
     }
 
-    public @NonNull EffectiveModelContext modelContext() {
-        return mountContext.modelContext();
+    @Override
+    public MountPointContext mountPointContext() {
+        return mountPointContext;
     }
 
-    @NonNull ImmutableMap<QName, ? extends RpcDefinition> getMappedRpcs() {
+    @Override
+    public ImmutableMap<QName, ? extends RpcDefinition> mappedRpcs() {
         return mappedRpcs;
     }
-
-    public @NonNull MountPointContext getMountPointContext() {
-        return mountContext;
-    }
 }
diff --git a/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultBaseNetconfSchemaProvider.java b/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultBaseNetconfSchemaProvider.java
new file mode 100644 (file)
index 0000000..e652444
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2020 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.impl;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.runtime.spi.ModuleInfoSnapshotBuilder;
+import org.opendaylight.netconf.api.CapabilityURN;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.Candidate;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.ConfirmedCommit;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.IetfNetconfData;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.RollbackOnError;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.Startup;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.Url;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.Validate$F;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.WritableRunning;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.Xpath;
+import org.opendaylight.yangtools.yang.binding.YangFeature;
+import org.opendaylight.yangtools.yang.parser.api.YangParserException;
+import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component
+@Singleton
+public final class DefaultBaseNetconfSchemaProvider implements BaseNetconfSchemaProvider {
+    private record Capabilities(
+            boolean writableRunning,
+            boolean candidate,
+            boolean confirmedCommit,
+            boolean rollbackOnError,
+            boolean validate,
+            boolean startup,
+            boolean url,
+            boolean xpath,
+            boolean notifications,
+            boolean library,
+            boolean monitoring) {
+        // Nothing else
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultBaseNetconfSchemaProvider.class);
+
+    private final LoadingCache<Capabilities, DefaultBaseNetconfSchema> baseSchemas = CacheBuilder.newBuilder()
+        .weakValues().build(new CacheLoader<>() {
+            @Override
+            public DefaultBaseNetconfSchema load(final Capabilities key) throws YangParserException {
+                LOG.debug("Loading base schema for {}", key);
+                final var sw = Stopwatch.createStarted();
+
+                final var builder = new ModuleInfoSnapshotBuilder(parserFactory)
+                    .add(org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601
+                        .YangModuleInfoImpl.getInstance());
+
+                final var netconfFeatures = ImmutableSet.<YangFeature<?, @NonNull IetfNetconfData>>builder();
+                if (key.writableRunning) {
+                    netconfFeatures.add(WritableRunning.VALUE);
+                }
+                if (key.candidate) {
+                    netconfFeatures.add(Candidate.VALUE);
+                }
+                if (key.confirmedCommit) {
+                    netconfFeatures.add(ConfirmedCommit.VALUE);
+                }
+                if (key.rollbackOnError) {
+                    netconfFeatures.add(RollbackOnError.VALUE);
+                }
+                if (key.validate) {
+                    netconfFeatures.add(Validate$F.VALUE);
+                }
+                if (key.startup) {
+                    netconfFeatures.add(Startup.VALUE);
+                }
+                if (key.url) {
+                    netconfFeatures.add(Url.VALUE);
+                }
+                if (key.xpath) {
+                    netconfFeatures.add(Xpath.VALUE);
+                }
+                builder.addModuleFeatures(IetfNetconfData.class, netconfFeatures.build());
+
+                if (key.library) {
+                    builder.add(org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104
+                        .YangModuleInfoImpl.getInstance());
+                }
+                if (key.monitoring) {
+                    builder.add(org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring
+                        .rev101004.YangModuleInfoImpl.getInstance());
+                }
+                if (key.notifications) {
+                    builder
+                        .add(org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714
+                            .YangModuleInfoImpl.getInstance())
+                        .add(org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications
+                            .rev120206.YangModuleInfoImpl.getInstance());
+                }
+
+                final var snapshot = builder.build();
+                LOG.debug("Schema for {} assembled in {}", key, sw);
+                return new DefaultBaseNetconfSchema(snapshot.modelContext());
+            }
+        });
+    private final YangParserFactory parserFactory;
+
+    @Inject
+    @Activate
+    public DefaultBaseNetconfSchemaProvider(@Reference final YangParserFactory parserFactory) {
+        this.parserFactory = requireNonNull(parserFactory);
+    }
+
+    @Override
+    public DefaultBaseNetconfSchema baseSchemaForCapabilities(final NetconfSessionPreferences sessionPreferences) {
+        return baseSchemas.getUnchecked(new Capabilities(
+            sessionPreferences.isRunningWritable(),
+            sessionPreferences.isCandidateSupported(),
+            sessionPreferences.containsNonModuleCapability(CapabilityURN.CONFIRMED_COMMIT_1_1)
+                || sessionPreferences.containsNonModuleCapability(CapabilityURN.CONFIRMED_COMMIT),
+            sessionPreferences.isRollbackSupported(),
+            sessionPreferences.containsNonModuleCapability(CapabilityURN.VALIDATE_1_1)
+                || sessionPreferences.containsNonModuleCapability(CapabilityURN.VALIDATE),
+            sessionPreferences.containsNonModuleCapability(CapabilityURN.STARTUP),
+            sessionPreferences.containsNonModuleCapability(CapabilityURN.URL),
+            sessionPreferences.containsNonModuleCapability(CapabilityURN.XPATH),
+            sessionPreferences.isNotificationsSupported(),
+            sessionPreferences.containsNonModuleCapability(CapabilityURN.YANG_LIBRARY)
+                || sessionPreferences.containsNonModuleCapability(CapabilityURN.YANG_LIBRARY_1_1),
+            sessionPreferences.isMonitoringSupported()));
+    }
+}
diff --git a/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultBaseNetconfSchemas.java b/plugins/netconf-client-mdsal/src/main/java/org/opendaylight/netconf/client/mdsal/impl/DefaultBaseNetconfSchemas.java
deleted file mode 100644 (file)
index 64d8557..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2020 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.impl;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.List;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
-import org.opendaylight.yangtools.yang.parser.api.YangParserException;
-import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-
-@Component
-@Singleton
-@NonNullByDefault
-public record DefaultBaseNetconfSchemas(BaseSchema baseSchema, BaseSchema baseSchemaWithNotifications)
-        implements BaseNetconfSchemas {
-    public DefaultBaseNetconfSchemas {
-        requireNonNull(baseSchema);
-        requireNonNull(baseSchemaWithNotifications);
-    }
-
-    @Inject
-    @Activate
-    public DefaultBaseNetconfSchemas(@Reference final YangParserFactory parserFactory) throws YangParserException {
-        this(
-            new BaseSchema(BindingRuntimeHelpers.createEffectiveModel(parserFactory, List.of(
-                org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601
-                    .YangModuleInfoImpl.getInstance(),
-                org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004
-                    .YangModuleInfoImpl.getInstance()))),
-            new BaseSchema(BindingRuntimeHelpers.createEffectiveModel(parserFactory, List.of(
-                org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714
-                    .YangModuleInfoImpl.getInstance(),
-                org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601
-                    .YangModuleInfoImpl.getInstance(),
-                org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004
-                    .YangModuleInfoImpl.getInstance(),
-                org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206
-                    .YangModuleInfoImpl.getInstance()))));
-    }
-}
index a09d4443bc4cc183026a2b2fa0f642917dbe1148..44c37ea8640ffcf9cd9edaf405955f7b19f2d234 100644 (file)
@@ -54,6 +54,7 @@ import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.xml.MissingNameSpaceException;
 import org.opendaylight.netconf.api.xml.XmlElement;
 import org.opendaylight.netconf.client.mdsal.api.ActionTransformer;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchema;
 import org.opendaylight.netconf.client.mdsal.api.NotificationTransformer;
 import org.opendaylight.netconf.client.mdsal.api.RpcTransformer;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.GetConfig;
@@ -109,7 +110,7 @@ public class NetconfMessageTransformer
 
     private final MountPointContext mountContext;
     private final DataSchemaContextTree contextTree;
-    private final BaseSchema baseSchema;
+    private final BaseNetconfSchema baseSchema;
     private final MessageCounter counter;
     private final ImmutableMap<QName, ? extends RpcDefinition> mappedRpcs;
     private final Multimap<QName, ? extends NotificationDefinition> mappedNotifications;
@@ -117,7 +118,7 @@ public class NetconfMessageTransformer
     private final ImmutableMap<Absolute, ActionDefinition> actions;
 
     public NetconfMessageTransformer(final MountPointContext mountContext, final boolean strictParsing,
-                                     final BaseSchema baseSchema) {
+                                     final BaseNetconfSchema baseSchema) {
         counter = new MessageCounter();
         this.mountContext = requireNonNull(mountContext);
 
@@ -333,7 +334,7 @@ public class NetconfMessageTransformer
         final boolean needToUseBaseCtx = mappedRpcs.get(rpc) == null && isBaseOrNotificationRpc(rpc);
         final ImmutableMap<QName, ? extends RpcDefinition> currentMappedRpcs;
         if (needToUseBaseCtx) {
-            currentMappedRpcs = baseSchema.getMappedRpcs();
+            currentMappedRpcs = baseSchema.mappedRpcs();
         } else {
             currentMappedRpcs = mappedRpcs;
         }
@@ -417,7 +418,7 @@ public class NetconfMessageTransformer
             // If no, use pre built base netconf operations model
             final ImmutableMap<QName, ? extends RpcDefinition> currentMappedRpcs;
             if (mappedRpcs.get(rpc) == null && isBaseOrNotificationRpc(rpc)) {
-                currentMappedRpcs = baseSchema.getMappedRpcs();
+                currentMappedRpcs = baseSchema.mappedRpcs();
             } else {
                 currentMappedRpcs = mappedRpcs;
             }
index 35b267e0e63078d9bc1f833877088205c8242c98..c67c344d7561c55bf97ca35cb9f5452b7948df97 100644 (file)
@@ -9,17 +9,17 @@ package org.opendaylight.netconf.client.mdsal;
 
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
-import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
+import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemaProvider;
 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
 
 public abstract class AbstractBaseSchemasTest {
-    protected static BaseNetconfSchemas BASE_SCHEMAS;
+    protected static BaseNetconfSchemaProvider BASE_SCHEMAS;
 
     @BeforeClass
     public static void initBaseSchemas() throws YangParserException {
-        BASE_SCHEMAS = new DefaultBaseNetconfSchemas(new DefaultYangParserFactory());
+        BASE_SCHEMAS = new DefaultBaseNetconfSchemaProvider(new DefaultYangParserFactory());
     }
 
     @AfterClass
index f4c0f904a03a531838e9467adf652746c912271a..2a2497364cc0a5a2d74479c8b1469369bfaad55e 100644 (file)
@@ -12,12 +12,14 @@ import static org.junit.Assert.assertNotNull;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.mdsal.dom.api.DOMEvent;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.messages.NotificationMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformer;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
@@ -41,7 +43,8 @@ public class NetconfNestedNotificationTest extends AbstractBaseSchemasTest {
 
         final NetconfMessage notificationMessage = prepareNotification("/nested-notification-payload.xml");
         NetconfMessageTransformer messageTransformer = new NetconfMessageTransformer(
-            MountPointContext.of(context), true, BASE_SCHEMAS.baseSchema());
+            MountPointContext.of(context), true,
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())));
         final DOMNotification domNotification = messageTransformer.toNotification(notificationMessage);
         final ContainerNode root = domNotification.getBody();
         assertNotNull(root);
index 67f5eb97d30c796eedbfc2a7b94d67b3bd834a10..0d091216207724f99ae4c36d994c14b2b8965bdf 100644 (file)
@@ -78,7 +78,7 @@ public class NetconfStateSchemasTest extends AbstractBaseSchemasTest {
 
     @Before
     public void setUp() throws Exception {
-        modelContext = BASE_SCHEMAS.baseSchemaWithNotifications().modelContext();
+        modelContext = BASE_SCHEMAS.baseSchemaForCapabilities(CAPS).modelContext();
 
         final var resultHolder = new NormalizationResultHolder();
         final var writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
index 3255f429be1544898e24c54b82c578543c55784c..861e0bd2bc88488521152dc1867889b37e0fe938 100644 (file)
@@ -14,12 +14,14 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.InputStream;
 import java.util.Collection;
+import java.util.Set;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.mdsal.dom.api.DOMEvent;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.messages.NotificationMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformer;
 import org.opendaylight.yangtools.yang.data.api.schema.MountPointContext;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
@@ -64,7 +66,7 @@ public class NetconfToNotificationTest extends AbstractBaseSchemasTest {
     public void testMostRecentWrongYangModel() throws Exception {
         final var schemaContext = getNotificationSchemaContext(getClass(), true);
         messageTransformer = new NetconfMessageTransformer(MountPointContext.of(schemaContext), true,
-            BASE_SCHEMAS.baseSchema());
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())));
         assertThrows(IllegalArgumentException.class, () -> messageTransformer.toNotification(userNotification));
     }
 
@@ -72,7 +74,7 @@ public class NetconfToNotificationTest extends AbstractBaseSchemasTest {
     public void testToNotificationFunction() throws Exception {
         final var schemaContext = getNotificationSchemaContext(getClass(), false);
         messageTransformer = new NetconfMessageTransformer(MountPointContext.of(schemaContext), true,
-            BASE_SCHEMAS.baseSchema());
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())));
         final var domNotification = messageTransformer.toNotification(userNotification);
         final var root = domNotification.getBody();
         assertNotNull(root);
index a2f89b82aafafc482d161397b3a28476f4998440..31f3338b57131adb25d5b1c1fb235ad4c3d56005 100644 (file)
@@ -14,11 +14,13 @@ import static org.junit.Assert.assertTrue;
 import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.toId;
 
 import java.util.Collection;
+import java.util.Set;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformer;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
@@ -60,7 +62,7 @@ public class NetconfToRpcRequestTest extends AbstractBaseSchemasTest {
     @Before
     public void before() {
         messageTransformer = new NetconfMessageTransformer(MountPointContext.of(cfgCtx), true,
-            BASE_SCHEMAS.baseSchema());
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())));
     }
 
     @Test
index 0cdc50799b195d14453bcf618ab6a9a25b0951fa..3dac5c7f22cbb73ba534cdbe84e49b445c572853 100644 (file)
@@ -8,25 +8,27 @@
 package org.opendaylight.netconf.client.mdsal;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import com.google.common.collect.Lists;
 import java.net.InetSocketAddress;
 import java.util.Collection;
+import java.util.List;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
 import org.opendaylight.netconf.api.CapabilityURN;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
+import org.opendaylight.netconf.api.xml.XmlUtil;
 import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices;
-import org.opendaylight.netconf.client.mdsal.impl.SchemalessMessageTransformer;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.w3c.dom.Document;
 
 public class SchemalessNetconfDeviceTest extends AbstractBaseSchemasTest {
 
@@ -38,24 +40,28 @@ public class SchemalessNetconfDeviceTest extends AbstractBaseSchemasTest {
     public void testSessionOnMethods() throws Exception {
         final RemoteDeviceHandler facade = getFacade();
         final NetconfDeviceCommunicator listener = mockCloseableClass(NetconfDeviceCommunicator.class);
-        final SchemalessMessageTransformer messageTransformer = mock(SchemalessMessageTransformer.class);
         final RemoteDeviceId remoteDeviceId = new RemoteDeviceId("test-D",
                 InetSocketAddress.createUnresolved("localhost", 22));
 
-        final SchemalessNetconfDevice device = new SchemalessNetconfDevice(BASE_SCHEMAS, remoteDeviceId, facade,
-            messageTransformer);
+        final SchemalessNetconfDevice device = new SchemalessNetconfDevice(BASE_SCHEMAS, remoteDeviceId, facade);
 
         final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
-                Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
-
-        final NetconfMessage netconfMessage = mock(NetconfMessage.class);
+                List.of(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
 
         device.onRemoteSessionUp(sessionCaps, listener);
         verify(facade).onDeviceConnected(
                 any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class));
 
+        final NetconfMessage netconfMessage = mock(NetconfMessage.class);
+        final Document document = XmlUtil.readXmlToDocument("""
+            <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
+              <eventTime>2021-11-11T11:26:16Z</eventTime>
+              <netconf-config-change xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications"/>
+            </notification>""");
+        doReturn(document).when(netconfMessage).getDocument();
+
         device.onNotification(netconfMessage);
-        verify(facade).onNotification(isNull());
+        verify(facade).onNotification(any());
 
         device.onRemoteSessionDown();
         verify(facade).onDeviceDisconnected();
index bdcd255c77fc080715689e774c42bf53c6effed1..4725bd68d6439295c20ce18c427ac94636d2787d 100644 (file)
@@ -11,11 +11,13 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 
+import java.util.Set;
 import javax.xml.transform.dom.DOMSource;
 import org.junit.Test;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
 import org.opendaylight.netconf.client.mdsal.AbstractBaseSchemasTest;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditConfig;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.GetConfig;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.copy.config.input.target.ConfigTarget;
@@ -31,7 +33,8 @@ import org.xmlunit.builder.DiffBuilder;
 
 public class BaseRpcSchemalessTransformerTest extends AbstractBaseSchemasTest {
     private final BaseRpcSchemalessTransformer transformer =
-        new BaseRpcSchemalessTransformer(BASE_SCHEMAS, new MessageCounter());
+        new BaseRpcSchemalessTransformer(BASE_SCHEMAS.baseSchemaForCapabilities(
+            NetconfSessionPreferences.fromStrings(Set.of())), new MessageCounter());
 
     @Test
     public void toRpcRequest() throws Exception {
index fdf2c3bb0a515731f08236fd447b6218154ff385..2c9415d2ff3d974e6fd32d16df4f1c7442b781d4 100644 (file)
@@ -22,6 +22,7 @@ import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import org.custommonkey.xmlunit.Diff;
 import org.custommonkey.xmlunit.XMLUnit;
@@ -35,6 +36,7 @@ import org.opendaylight.netconf.api.EffectiveOperation;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
 import org.opendaylight.netconf.client.mdsal.AbstractTestModelTest;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceCommunicator;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
 import org.opendaylight.netconf.client.mdsal.spi.NetconfDeviceRpc;
@@ -110,7 +112,8 @@ public class NetconfBaseOpsTest extends AbstractTestModelTest {
         when(listener.sendRequest(any(), eq(Unlock.QNAME))).thenReturn(RpcResultBuilder.success(ok).buildFuture());
         when(listener.sendRequest(any(), eq(Commit.QNAME))).thenReturn(RpcResultBuilder.success(ok).buildFuture());
         final var rpc = new NetconfDeviceRpc(SCHEMA_CONTEXT, listener, new NetconfMessageTransformer(
-            MountPointContext.of(SCHEMA_CONTEXT), true, BASE_SCHEMAS.baseSchema()));
+            MountPointContext.of(SCHEMA_CONTEXT), true,
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of()))));
         callback = new NetconfRpcFutureCallback("prefix",
             new RemoteDeviceId("device-1", InetSocketAddress.createUnresolved("localhost", 17830)));
         baseOps = new NetconfBaseOps(rpc, MountPointContext.of(SCHEMA_CONTEXT));
index cb432a8e3d19ab02008644ecaea069bcd8724d9c..57927ae162d3677621b02d0624ea3a649ac61182 100644 (file)
@@ -36,10 +36,12 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.netconf.api.CapabilityURN;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
 import org.opendaylight.netconf.client.mdsal.AbstractBaseSchemasTest;
 import org.opendaylight.netconf.client.mdsal.MonitoringSchemaSourceProvider;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.common.mdsal.NormalizedDataUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.Commit;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.DiscardChanges;
@@ -186,7 +188,7 @@ public class NetconfMessageTransformerTest extends AbstractBaseSchemasTest {
 
         netconfMessageTransformer = getTransformer(SCHEMA);
         actionNetconfMessageTransformer = new NetconfMessageTransformer(MountPointContext.of(ACTION_SCHEMA), true,
-            BASE_SCHEMAS.baseSchema());
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())));
     }
 
     @Test
@@ -208,7 +210,8 @@ public class NetconfMessageTransformerTest extends AbstractBaseSchemasTest {
     @Test
     public void testCreateSubscriberNotificationSchemaNotPresent() throws Exception {
         final var transformer = new NetconfMessageTransformer(MountPointContext.of(SCHEMA), true,
-            BASE_SCHEMAS.baseSchemaWithNotifications());
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(
+                Set.of(CapabilityURN.NOTIFICATION))));
         var netconfMessage = transformer.toRpcRequest(CreateSubscription.QNAME, ImmutableNodes.newContainerBuilder()
             .withNodeIdentifier(new NodeIdentifier(CreateSubscriptionInput.QNAME))
             .build());
@@ -419,9 +422,11 @@ public class NetconfMessageTransformerTest extends AbstractBaseSchemasTest {
         final var id = YangInstanceIdentifier.builder()
                 .node(NetconfState.QNAME).node(Schemas.QNAME).node(Schema.QNAME)
                 .nodeWithKey(Schema.QNAME, keys).build();
-        final var editConfigStructure =
-                createEditConfigStructure(BASE_SCHEMAS.baseSchemaWithNotifications().modelContext(), id,
-                    Optional.empty(), Optional.ofNullable(schemaNode));
+        final var editConfigStructure = createEditConfigStructure(BASE_SCHEMAS.baseSchemaForCapabilities(
+            NetconfSessionPreferences.fromStrings(Set.of(
+                CapabilityURN.CANDIDATE,
+                "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring"
+                    + "&revision=2010-10-04"))).modelContext(), id, Optional.empty(), Optional.ofNullable(schemaNode));
 
         final var target = NetconfBaseOps.getTargetNode(NETCONF_CANDIDATE_NODEID);
 
@@ -529,7 +534,8 @@ public class NetconfMessageTransformerTest extends AbstractBaseSchemasTest {
     }
 
     private static NetconfMessageTransformer getTransformer(final EffectiveModelContext schema) {
-        return new NetconfMessageTransformer(MountPointContext.of(schema), true, BASE_SCHEMAS.baseSchema());
+        return new NetconfMessageTransformer(MountPointContext.of(schema), true,
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())));
     }
 
     @Test
index 7153f05f5d1f7b8accdb36a349f48b2a29207c4d..961e82e9a5a698f0bb2d3cdaabb01c12943e6cc5 100644 (file)
@@ -18,6 +18,7 @@ import com.google.common.util.concurrent.Futures;
 import java.net.InetSocketAddress;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -63,7 +64,7 @@ public class NetconfDataTreeServiceImplTest extends AbstractTestModelTest {
         netconService = getNetconService();
         final var model = BindingRuntimeHelpers.createEffectiveModel(IetfNetconfData.class, NetconfState.class);
         netconfMessageTransformer = new NetconfMessageTransformer(MountPointContext.of(model), true,
-                BASE_SCHEMAS.baseSchema());
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())));
     }
 
     @Test
index 6810854c44e70972238966f44bb4cf517b02d1e0..ada641af17737760bc45185ff9bf14f0b01ec76e 100644 (file)
@@ -19,6 +19,7 @@ import static org.mockito.Mockito.when;
 
 import com.google.common.util.concurrent.Futures;
 import java.util.Collection;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -35,6 +36,7 @@ import org.opendaylight.mdsal.dom.api.DOMRpcResult;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
 import org.opendaylight.netconf.client.mdsal.AbstractBaseSchemasTest;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceCommunicator;
 import org.opendaylight.netconf.client.mdsal.api.RpcTransformer;
 import org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil;
@@ -78,8 +80,8 @@ public class NetconfDeviceRpcTest extends AbstractBaseSchemasTest {
 
     @Before
     public void setUp() throws Exception {
-        final var transformer = new NetconfMessageTransformer(
-            MountPointContext.of(SCHEMA_CONTEXT), true, BASE_SCHEMAS.baseSchema());
+        final var transformer = new NetconfMessageTransformer(MountPointContext.of(SCHEMA_CONTEXT), true,
+            BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())));
         final var reply = new NetconfMessage(XmlUtil.readXmlToDocument(
                 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
                         + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"101\">\n"
index 2b95082f6ac5e81cc5913be380ca0e4967d15b21..bf9460a294398fe0aba8c626fe5cf2298cf2d8b2 100644 (file)
@@ -23,6 +23,7 @@ import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransform
 
 import com.google.common.util.concurrent.Futures;
 import java.net.InetSocketAddress;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import org.junit.Before;
 import org.junit.Test;
@@ -32,7 +33,9 @@ import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.netconf.api.CapabilityURN;
 import org.opendaylight.netconf.client.mdsal.AbstractBaseSchemasTest;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices.Rpcs;
 import org.opendaylight.netconf.client.mdsal.impl.NetconfBaseOps;
@@ -68,6 +71,12 @@ public class NetconfDeviceWriteOnlyTxTest extends AbstractBaseSchemasTest {
             .when(rpc).invokeNetconf(any(), any());
     }
 
+    private static MountPointContext baseMountPointContext() {
+        return BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of(
+            "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04")))
+            .mountPointContext();
+    }
+
     @Test
     public void testIgnoreNonVisibleData() {
         final var tx = new WriteCandidateTx(ID, new NetconfBaseOps(rpc, mock(MountPointContext.class)), false, true);
@@ -119,8 +128,10 @@ public class NetconfDeviceWriteOnlyTxTest extends AbstractBaseSchemasTest {
             Futures.immediateFailedFuture(new IllegalStateException("Failed tx")))
             .when(rpc).invokeNetconf(any(), any());
 
-        final var tx = new WriteRunningTx(ID,
-            new NetconfBaseOps(rpc, BASE_SCHEMAS.baseSchemaWithNotifications().getMountPointContext()), false, true);
+        final var tx = new WriteRunningTx(ID, new NetconfBaseOps(rpc, BASE_SCHEMAS.baseSchemaForCapabilities(
+            NetconfSessionPreferences.fromStrings(Set.of(CapabilityURN.NOTIFICATION,
+                "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring"
+                    + "&revision=2010-10-04"))).mountPointContext()), false, true);
         tx.init();
 
         tx.delete(LogicalDatastoreType.CONFIGURATION, STATE);
@@ -136,8 +147,7 @@ public class NetconfDeviceWriteOnlyTxTest extends AbstractBaseSchemasTest {
     public void testListenerSuccess() throws Exception {
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult((ContainerNode) null)))
             .when(rpc).invokeNetconf(any(), any());
-        final var tx = new WriteCandidateTx(ID,
-            new NetconfBaseOps(rpc, BASE_SCHEMAS.baseSchema().getMountPointContext()), false, true);
+        final var tx = new WriteCandidateTx(ID, new NetconfBaseOps(rpc, baseMountPointContext()), false, true);
         tx.init();
 
         final var listener = mock(TxListener.class);
@@ -152,8 +162,7 @@ public class NetconfDeviceWriteOnlyTxTest extends AbstractBaseSchemasTest {
 
     @Test
     public void testListenerCancellation() throws Exception {
-        final var tx = new WriteCandidateTx(ID,
-            new NetconfBaseOps(rpc, BASE_SCHEMAS.baseSchema().getMountPointContext()), false, true);
+        final var tx = new WriteCandidateTx(ID, new NetconfBaseOps(rpc, baseMountPointContext()), false, true);
         tx.init();
 
         final var listener = mock(TxListener.class);
@@ -170,8 +179,7 @@ public class NetconfDeviceWriteOnlyTxTest extends AbstractBaseSchemasTest {
     public void testListenerFailure() throws Exception {
         final var cause = new IllegalStateException("Failed tx");
         doReturn(Futures.immediateFailedFuture(cause)).when(rpc).invokeNetconf(any(), any());
-        final var tx = new WriteCandidateTx(ID,
-            new NetconfBaseOps(rpc, BASE_SCHEMAS.baseSchema().getMountPointContext()), false, true);
+        final var tx = new WriteCandidateTx(ID, new NetconfBaseOps(rpc, baseMountPointContext()), false, true);
         tx.init();
 
         final var listener = mock(TxListener.class);
index 6568ddd7db8f7479fa4b36c76f824ea52565d259..892ff0e8feaf65f2f073a7569ce3635bfe7cb8da 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netconf.client.mdsal.spi;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
@@ -14,6 +15,7 @@ import static org.mockito.Mockito.verify;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.net.InetSocketAddress;
+import java.util.Set;
 import javax.xml.transform.dom.DOMSource;
 import org.junit.Before;
 import org.junit.Test;
@@ -24,6 +26,7 @@ import org.mockito.junit.MockitoJUnitRunner;
 import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
 import org.opendaylight.netconf.client.mdsal.AbstractBaseSchemasTest;
+import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceCommunicator;
 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
 import org.opendaylight.netconf.client.mdsal.impl.BaseRpcSchemalessTransformer;
@@ -31,13 +34,9 @@ import org.opendaylight.netconf.client.mdsal.impl.MessageCounter;
 import org.opendaylight.netconf.client.mdsal.impl.SchemalessMessageTransformer;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 @RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class SchemalessNetconfDeviceRpcTest extends AbstractBaseSchemasTest {
-    private static final Logger LOG = LoggerFactory.getLogger(SchemalessNetconfDeviceRpcTest.class);
-
     @Mock
     private RemoteDeviceCommunicator listener;
 
@@ -51,8 +50,9 @@ public class SchemalessNetconfDeviceRpcTest extends AbstractBaseSchemasTest {
         final MessageCounter counter = new MessageCounter();
         deviceRpc = new SchemalessNetconfDeviceRpc(
                 new RemoteDeviceId("device1", InetSocketAddress.createUnresolved("0.0.0.0", 17830)), listener,
-                new BaseRpcSchemalessTransformer(BASE_SCHEMAS, counter), new SchemalessMessageTransformer(counter));
-
+                new BaseRpcSchemalessTransformer(
+                    BASE_SCHEMAS.baseSchemaForCapabilities(NetconfSessionPreferences.fromStrings(Set.of())), counter),
+                new SchemalessMessageTransformer(counter));
     }
 
     @Test
@@ -73,6 +73,20 @@ public class SchemalessNetconfDeviceRpcTest extends AbstractBaseSchemasTest {
         final var msgCaptor = ArgumentCaptor.forClass(NetconfMessage.class);
         final var qnameCaptor = ArgumentCaptor.forClass(QName.class);
         verify(listener).sendRequest(msgCaptor.capture(), qnameCaptor.capture());
-        LOG.info(XmlUtil.toString(msgCaptor.getValue().getDocument()));
+        assertEquals("""
+            <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-0">
+                <get-config xmlns="dd">
+                    <source>
+                        <running/>
+                    </source>
+                    <filter type="subtree">
+                        <mainroot xmlns="urn:dummy:mod-0">
+                            <maincontent/>
+                            <choiceList/>
+                        </mainroot>
+                    </filter>
+                </get-config>
+            </rpc>
+            """, XmlUtil.toString(msgCaptor.getValue().getDocument()));
     }
 }