From 0cf6d180df77a544362e2480beb4b9119b50a8c6 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 6 Dec 2022 12:13:46 +0100 Subject: [PATCH] Disconnect NetconfDeviceCapabilities and NetconfSessionPreferences NetconfDeviceCapabilities are schema-dependent and dynamically derived during schema match. Split these two, so that both can become completely immutable. This requires reworking NetconfDevice, so that it keeps the fields needed for tracking internally. JIRA: NETCONF-920 Change-Id: Iaed0452680a625b5bf62f5a4d617aad30d86c971 Signed-off-by: Robert Varga --- .../singleton/impl/MasterSalFacade.java | 42 +++-- .../impl/MountPointEndToEndTest.java | 19 ++- .../sal/connect/api/RemoteDeviceHandler.java | 10 +- .../sal/connect/netconf/NetconfDevice.java | 116 ++++++++----- .../connect/netconf/NetconfDeviceSchema.java | 28 ++++ .../netconf/SchemalessNetconfDevice.java | 8 +- .../listener/NetconfDeviceCapabilities.java | 60 ++----- .../listener/NetconfDeviceCommunicator.java | 6 +- .../listener/NetconfSessionPreferences.java | 10 +- .../netconf/sal/KeepaliveSalFacade.java | 12 +- .../netconf/sal/NetconfDeviceSalFacade.java | 23 +-- .../sal/NetconfDeviceTopologyAdapter.java | 6 +- .../connect/netconf/NetconfDeviceTest.java | 49 +++--- .../netconf/SchemalessNetconfDeviceTest.java | 5 +- .../NetconfSessionPreferencesTest.java | 157 ++++++++---------- ...KeepaliveSalFacadeResponseWaitingTest.java | 4 +- ...fDeficeTopologyAdapterIntegrationTest.java | 2 +- .../sal/NetconfDeviceSalFacadeTest.java | 8 +- .../sal/NetconfDeviceTopologyAdapterTest.java | 2 +- 19 files changed, 295 insertions(+), 272 deletions(-) create mode 100644 netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceSchema.java diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java index ef666312a2..7f8d5bed5a 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java @@ -24,6 +24,7 @@ import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.netconf.dom.api.NetconfDataTreeService; import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceSchema; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; import org.opendaylight.netconf.sal.connect.netconf.sal.AbstractNetconfDataTreeService; @@ -48,7 +49,7 @@ class MasterSalFacade implements RemoteDeviceHandler, AutoCloseable { private final ActorRef masterActorRef; private final ActorSystem actorSystem; - private MountPointContext currentMountContext = null; + private NetconfDeviceSchema currentSchema = null; private NetconfSessionPreferences netconfSessionPreferences = null; private DOMRpcService deviceRpc = null; private DOMDataBroker deviceDataBroker = null; @@ -69,20 +70,20 @@ class MasterSalFacade implements RemoteDeviceHandler, AutoCloseable { } @Override - public void onDeviceConnected(final MountPointContext mountContext, + public void onDeviceConnected(final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences sessionPreferences, final DOMRpcService domRpcService, final DOMActionService domActionService) { deviceAction = domActionService; LOG.debug("{}: YANG 1.1 actions are supported in clustered netconf topology, " + "DOMActionService exposed for the device", id); - onDeviceConnected(mountContext, sessionPreferences, domRpcService); + onDeviceConnected(deviceSchema, sessionPreferences, domRpcService); } @Override - public void onDeviceConnected(final MountPointContext mountContext, + public void onDeviceConnected(final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences sessionPreferences, final DOMRpcService domRpcService) { - currentMountContext = mountContext; + currentSchema = requireNonNull(deviceSchema); netconfSessionPreferences = sessionPreferences; deviceRpc = domRpcService; @@ -101,13 +102,12 @@ class MasterSalFacade implements RemoteDeviceHandler, AutoCloseable { LOG.error("{}: CreateInitialMasterActorData to {} failed", id, masterActorRef, failure); } }, actorSystem.dispatcher()); - } @Override public void onDeviceDisconnected() { LOG.info("Device {} disconnected - unregistering master mount point", id); - salProvider.getTopologyDatastoreAdapter().updateDeviceData(false, new NetconfDeviceCapabilities()); + salProvider.getTopologyDatastoreAdapter().updateDeviceData(false, NetconfDeviceCapabilities.empty()); unregisterMasterMountPoint(); } @@ -130,12 +130,16 @@ class MasterSalFacade implements RemoteDeviceHandler, AutoCloseable { private void registerMasterMountPoint() { requireNonNull(id); - requireNonNull(currentMountContext, "Device has no remote schema context yet. Probably not fully connected."); - requireNonNull(netconfSessionPreferences, "Device has no capabilities yet. Probably not fully connected."); + + final var mountContext = requireNonNull(currentSchema, + "Device has no remote schema context yet. Probably not fully connected.") + .mountContext(); + final var preferences = requireNonNull(netconfSessionPreferences, + "Device has no capabilities yet. Probably not fully connected."); final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService(); - deviceDataBroker = newDeviceDataBroker(); - netconfService = newNetconfDataTreeService(); + deviceDataBroker = newDeviceDataBroker(mountContext, preferences); + netconfService = newNetconfDataTreeService(mountContext, preferences); // We need to create ProxyDOMDataBroker so accessing mountpoint // on leader node would be same as on follower node @@ -143,21 +147,23 @@ class MasterSalFacade implements RemoteDeviceHandler, AutoCloseable { actorResponseWaitTime); final NetconfDataTreeService proxyNetconfService = new ProxyNetconfDataTreeService(id, masterActorRef, actorSystem.dispatcher(), actorResponseWaitTime); - salProvider.getMountInstance().onTopologyDeviceConnected(currentMountContext.getEffectiveModelContext(), + salProvider.getMountInstance().onTopologyDeviceConnected(mountContext.getEffectiveModelContext(), proxyDataBroker, proxyNetconfService, deviceRpc, notificationService, deviceAction); } - protected DOMDataBroker newDeviceDataBroker() { - return new NetconfDeviceDataBroker(id, currentMountContext, deviceRpc, netconfSessionPreferences); + protected DOMDataBroker newDeviceDataBroker(final MountPointContext mountContext, + final NetconfSessionPreferences preferences) { + return new NetconfDeviceDataBroker(id, mountContext, deviceRpc, preferences); } - protected NetconfDataTreeService newNetconfDataTreeService() { - return AbstractNetconfDataTreeService.of(id, currentMountContext, deviceRpc, netconfSessionPreferences); + protected NetconfDataTreeService newNetconfDataTreeService(final MountPointContext mountContext, + final NetconfSessionPreferences preferences) { + return AbstractNetconfDataTreeService.of(id, mountContext, deviceRpc, preferences); } private Future sendInitialDataToActor() { final List sourceIdentifiers = List.copyOf(SchemaContextUtil.getConstituentModuleIdentifiers( - currentMountContext.getEffectiveModelContext())); + currentSchema.mountContext().getEffectiveModelContext())); LOG.debug("{}: Sending CreateInitialMasterActorData with sourceIdentifiers {} to {}", id, sourceIdentifiers, masterActorRef); @@ -171,7 +177,7 @@ class MasterSalFacade implements RemoteDeviceHandler, AutoCloseable { final String masterAddress = Cluster.get(actorSystem).selfAddress().toString(); LOG.debug("{}: updateDeviceData with master address {}", id, masterAddress); salProvider.getTopologyDatastoreAdapter().updateClusteredDeviceData(true, masterAddress, - netconfSessionPreferences.getNetconfDeviceCapabilities()); + currentSchema.capabilities()); } private void unregisterMasterMountPoint() { diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java index c63bc5e7ab..ba474efeda 100644 --- a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java +++ b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java @@ -100,6 +100,8 @@ import org.opendaylight.netconf.nettyutil.ReconnectFuture; import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory; import org.opendaylight.netconf.sal.connect.api.SchemaResourceManager; import org.opendaylight.netconf.sal.connect.impl.DefaultSchemaResourceManager; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceSchema; +import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.topology.singleton.impl.utils.ClusteringRpcException; @@ -131,6 +133,7 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; import org.opendaylight.yangtools.rfc8528.data.util.EmptyMountPointContext; import org.opendaylight.yangtools.util.concurrent.FluentFutures; import org.opendaylight.yangtools.yang.binding.DataObject; @@ -303,7 +306,8 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest { final var spiedContext = spy(context); doAnswer(invocation -> { final var spiedFacade = (MasterSalFacade) spy(invocation.callRealMethod()); - doReturn(deviceDOMDataBroker).when(spiedFacade).newDeviceDataBroker(); + doReturn(deviceDOMDataBroker).when(spiedFacade) + .newDeviceDataBroker(any(MountPointContext.class), any(NetconfSessionPreferences.class)); masterSalFacadeFuture.set(spiedFacade); return spiedFacade; }).when(spiedContext).newMasterSalFacade(); @@ -381,10 +385,11 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest { writeNetconfNode(TEST_DEFAULT_SUBDIR, masterDataBroker); final var masterSalFacade = masterSalFacadeFuture.get(5, TimeUnit.SECONDS); - masterSalFacade.onDeviceConnected(new EmptyMountPointContext(deviceSchemaContext), - NetconfSessionPreferences.fromStrings( - List.of(NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString())), - deviceRpcService.getRpcService()); + masterSalFacade.onDeviceConnected(new NetconfDeviceSchema(NetconfDeviceCapabilities.empty(), + new EmptyMountPointContext(deviceSchemaContext)), + NetconfSessionPreferences.fromStrings( + List.of(NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString())), + deviceRpcService.getRpcService()); final var masterMountPoint = awaitMountPoint(masterMountPointService); @@ -457,8 +462,8 @@ public class MountPointEndToEndTest extends AbstractBaseSchemasTest { verify(masterMountPointListener, timeout(5000)).onMountPointRemoved(yangNodeInstanceId); final var masterSalFacade = masterSalFacadeFuture.get(5, TimeUnit.SECONDS); - masterSalFacade.onDeviceConnected(new EmptyMountPointContext(deviceSchemaContext), - NetconfSessionPreferences.fromStrings(List.of( + masterSalFacade.onDeviceConnected(new NetconfDeviceSchema(NetconfDeviceCapabilities.empty(), + new EmptyMountPointContext(deviceSchemaContext)), NetconfSessionPreferences.fromStrings(List.of( NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString())), deviceRpcService.getRpcService()); diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/api/RemoteDeviceHandler.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/api/RemoteDeviceHandler.java index e344d254ea..b7e3945cc1 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/api/RemoteDeviceHandler.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/api/RemoteDeviceHandler.java @@ -10,18 +10,18 @@ package org.opendaylight.netconf.sal.connect.api; import org.opendaylight.mdsal.dom.api.DOMActionService; import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMRpcService; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceSchema; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; -import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; public interface RemoteDeviceHandler extends AutoCloseable { /** * When device connected, init new mount point with specific schema context and DOM services. * - * @param remoteSchemaContext - schema context of connected device + * @param deviceSchema - {@link NetconfDeviceSchema} of connected device * @param sessionPreferences - session of device * @param deviceRpc - {@link DOMRpcService} of device */ - default void onDeviceConnected(final MountPointContext remoteSchemaContext, + default void onDeviceConnected(final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences sessionPreferences, final DOMRpcService deviceRpc) { // DO NOTHING } @@ -29,12 +29,12 @@ public interface RemoteDeviceHandler extends AutoCloseable { /** * When device connected, init new mount point with specific schema context and DOM services. * - * @param mountContext - MountPointContext of connected device + * @param deviceSchema - {@link NetconfDeviceSchema} of connected device * @param sessionPreferences - session of device * @param deviceRpc - {@link DOMRpcService} of device * @param deviceAction - {@link DOMActionService} of device */ - default void onDeviceConnected(final MountPointContext mountContext, + default void onDeviceConnected(final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences sessionPreferences, final DOMRpcService deviceRpc, final DOMActionService deviceAction) { // DO NOTHING diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java index 89ce12533b..bf7a7931b6 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java @@ -13,6 +13,8 @@ import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTr import com.google.common.base.Predicates; import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @@ -23,13 +25,16 @@ import com.google.common.util.concurrent.SettableFuture; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import org.checkerframework.checker.lock.qual.GuardedBy; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.netconf.api.NetconfMessage; @@ -50,8 +55,10 @@ import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessag import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability.FailureReason; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; import org.opendaylight.yangtools.rfc8528.data.util.EmptyMountPointContext; @@ -151,18 +158,20 @@ public class NetconfDevice implements RemoteDevice { } // Set up the SchemaContext for the device - final ListenableFuture futureSchema = Futures.transformAsync(sourceResolverFuture, + final ListenableFuture futureSchema = Futures.transformAsync(sourceResolverFuture, deviceSources -> assembleSchemaContext(deviceSources, remoteSessionCapabilities), processingExecutor); // Potentially acquire mount point list and interpret it - final ListenableFuture futureContext = Futures.transformAsync(futureSchema, - schemaContext -> createMountPointContext(schemaContext, baseSchema, listener), processingExecutor); + final ListenableFuture futureContext = Futures.transformAsync(futureSchema, + result -> Futures.transform(createMountPointContext(result.modelContext(), baseSchema, listener), + mount -> new NetconfDeviceSchema(result.capabilities(), mount), processingExecutor), + processingExecutor); - Futures.addCallback(futureContext, new FutureCallback() { + Futures.addCallback(futureContext, new FutureCallback<>() { @Override - public void onSuccess(final MountPointContext result) { + public void onSuccess(final NetconfDeviceSchema result) { handleSalInitializationSuccess(result, remoteSessionCapabilities, - getDeviceSpecificRpc(result, listener, baseSchema), listener); + getDeviceSpecificRpc(result.mountContext(), listener, baseSchema), listener); } @Override @@ -212,19 +221,20 @@ public class NetconfDevice implements RemoteDevice { return remoteSessionCapabilities.isNotificationsSupported() && reconnectOnSchemasChange; } - private synchronized void handleSalInitializationSuccess(final MountPointContext result, + private synchronized void handleSalInitializationSuccess(final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences remoteSessionCapabilities, final DOMRpcService deviceRpc, final RemoteDeviceCommunicator listener) { //NetconfDevice.SchemaSetup can complete after NetconfDeviceCommunicator was closed. In that case do nothing, //since salFacade.onDeviceDisconnected was already called. if (connected) { - messageTransformer = new NetconfMessageTransformer(result, true, + final var mount = deviceSchema.mountContext(); + messageTransformer = new NetconfMessageTransformer(mount, true, resolveBaseSchema(remoteSessionCapabilities.isNotificationsSupported())); // salFacade.onDeviceConnected has to be called before the notification handler is initialized - salFacade.onDeviceConnected(result, remoteSessionCapabilities, deviceRpc, + salFacade.onDeviceConnected(deviceSchema, remoteSessionCapabilities, deviceRpc, deviceActionFactory == null ? null : deviceActionFactory.createDeviceAction( - messageTransformer, listener, result.getEffectiveModelContext())); + messageTransformer, listener, mount.getEffectiveModelContext())); notificationHandler.onRemoteSchemaUp(messageTransformer); LOG.info("{}: Netconf connector initialized successfully", id); @@ -255,7 +265,7 @@ public class NetconfDevice implements RemoteDevice { this.connected = connected; } - private ListenableFuture assembleSchemaContext(final DeviceSources deviceSources, + private ListenableFuture assembleSchemaContext(final DeviceSources deviceSources, final NetconfSessionPreferences remoteSessionCapabilities) { LOG.debug("{}: Resolved device sources to {}", id, deviceSources); @@ -264,8 +274,9 @@ public class NetconfDevice implements RemoteDevice { return new SchemaSetup(deviceSources, remoteSessionCapabilities).startResolution(); } - private ListenableFuture createMountPointContext(final EffectiveModelContext schemaContext, - final BaseSchema baseSchema, final NetconfDeviceCommunicator listener) { + private ListenableFuture<@NonNull MountPointContext> createMountPointContext( + final EffectiveModelContext schemaContext, final BaseSchema baseSchema, + final NetconfDeviceCommunicator listener) { final MountPointContext emptyContext = new EmptyMountPointContext(schemaContext); if (schemaContext.findModule(SchemaMountConstants.RFC8528_MODULE).isEmpty()) { return Futures.immediateFuture(emptyContext); @@ -379,22 +390,37 @@ public class NetconfDevice implements RemoteDevice { } } + /** + * {@link NetconfDeviceCapabilities} and {@link EffectiveModelContext}. + */ + private record SchemaResult( + @NonNull NetconfDeviceCapabilities capabilities, + @NonNull EffectiveModelContext modelContext) { + + SchemaResult { + requireNonNull(capabilities); + requireNonNull(modelContext); + } + } + /** * Schema builder that tries to build schema context from provided sources or biggest subset of it. */ private final class SchemaSetup implements FutureCallback { - private final SettableFuture resultFuture = SettableFuture.create(); + private final SettableFuture resultFuture = SettableFuture.create(); + + private final Set nonModuleBasedCapabilities = new HashSet<>(); + private final Map unresolvedCapabilites = new HashMap<>(); + private final Set resolvedCapabilities = new HashSet<>(); private final DeviceSources deviceSources; private final NetconfSessionPreferences remoteSessionCapabilities; - private final NetconfDeviceCapabilities capabilities; private Collection requiredSources; SchemaSetup(final DeviceSources deviceSources, final NetconfSessionPreferences remoteSessionCapabilities) { this.deviceSources = deviceSources; this.remoteSessionCapabilities = remoteSessionCapabilities; - capabilities = remoteSessionCapabilities.getNetconfDeviceCapabilities(); // If device supports notifications and does not contain necessary modules, add them automatically if (remoteSessionCapabilities.containsNonModuleCapability( @@ -412,12 +438,12 @@ public class NetconfDevice implements RemoteDevice { requiredSources = deviceSources.getRequiredSources(); final Collection missingSources = filterMissingSources(requiredSources); - capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(missingSources), - UnavailableCapability.FailureReason.MissingSource); + addUnresolvedCapabilities(getQNameFromSourceIdentifiers(missingSources), + UnavailableCapability.FailureReason.MissingSource); requiredSources.removeAll(missingSources); } - ListenableFuture startResolution() { + ListenableFuture startResolution() { trySetupSchema(); return resultFuture; } @@ -427,19 +453,24 @@ public class NetconfDevice implements RemoteDevice { LOG.debug("{}: Schema context built successfully from {}", id, requiredSources); final Collection filteredQNames = Sets.difference(deviceSources.getRequiredSourcesQName(), - capabilities.getUnresolvedCapabilites().keySet()); - capabilities.addCapabilities(filteredQNames.stream().map(entry -> new AvailableCapabilityBuilder() - .setCapability(entry.toString()).setCapabilityOrigin( - remoteSessionCapabilities.getModuleBasedCapsOrigin().get(entry)).build()) - .collect(Collectors.toList())); - - capabilities.addNonModuleBasedCapabilities(remoteSessionCapabilities - .getNonModuleCaps().stream().map(entry -> new AvailableCapabilityBuilder() - .setCapability(entry).setCapabilityOrigin( - remoteSessionCapabilities.getNonModuleBasedCapsOrigin().get(entry)).build()) - .collect(Collectors.toList())); - - resultFuture.set(result); + unresolvedCapabilites.keySet()); + resolvedCapabilities.addAll(filteredQNames.stream() + .map(capability -> new AvailableCapabilityBuilder() + .setCapability(capability.toString()) + .setCapabilityOrigin(remoteSessionCapabilities.capabilityOrigin(capability)) + .build()) + .collect(Collectors.toList())); + + nonModuleBasedCapabilities.addAll(remoteSessionCapabilities.getNonModuleCaps().stream() + .map(capability -> new AvailableCapabilityBuilder() + .setCapability(capability) + .setCapabilityOrigin(remoteSessionCapabilities.capabilityOrigin(capability)) + .build()) + .collect(Collectors.toList())); + + + resultFuture.set(new SchemaResult(new NetconfDeviceCapabilities(ImmutableMap.copyOf(unresolvedCapabilites), + ImmutableSet.copyOf(resolvedCapabilities), ImmutableSet.copyOf(nonModuleBasedCapabilities)), result)); } @Override @@ -484,6 +515,12 @@ public class NetconfDevice implements RemoteDevice { }).collect(Collectors.toList()); } + private void addUnresolvedCapabilities(final Collection capabilities, final FailureReason reason) { + for (QName s : capabilities) { + unresolvedCapabilites.put(s, reason); + } + } + private List handleMissingSchemaSourceException( final MissingSchemaSourceException exception) { // In case source missing, try without it @@ -492,11 +529,9 @@ public class NetconfDevice implements RemoteDevice { id, missingSource); LOG.debug("{}: Unable to build schema context, missing source {}, will reattempt without it", id, missingSource, exception); - final Collection qNameOfMissingSource = - getQNameFromSourceIdentifiers(Sets.newHashSet(missingSource)); + final var qNameOfMissingSource = getQNameFromSourceIdentifiers(Sets.newHashSet(missingSource)); if (!qNameOfMissingSource.isEmpty()) { - capabilities.addUnresolvedCapabilities( - qNameOfMissingSource, UnavailableCapability.FailureReason.MissingSource); + addUnresolvedCapabilities(qNameOfMissingSource, UnavailableCapability.FailureReason.MissingSource); } return stripUnavailableSource(missingSource); } @@ -513,14 +548,13 @@ public class NetconfDevice implements RemoteDevice { id, failedSourceId); LOG.warn("{}: Unable to build schema context, failed to resolve source {}, will reattempt without it", id, failedSourceId, resolutionException); - capabilities.addUnresolvedCapabilities( - getQNameFromSourceIdentifiers(Collections.singleton(failedSourceId)), + addUnresolvedCapabilities(getQNameFromSourceIdentifiers(List.of(failedSourceId)), UnavailableCapability.FailureReason.UnableToResolve); return stripUnavailableSource(resolutionException.getFailedSource()); } // unsatisfied imports - final Set unresolvedSources = resolutionException.getUnsatisfiedImports().keySet(); - capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(unresolvedSources), + addUnresolvedCapabilities( + getQNameFromSourceIdentifiers(resolutionException.getUnsatisfiedImports().keySet()), UnavailableCapability.FailureReason.UnableToResolve); LOG.warn("{}: Unable to build schema context, unsatisfied imports {}, will reattempt with resolved only", id, resolutionException.getUnsatisfiedImports()); diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceSchema.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceSchema.java new file mode 100644 index 0000000000..a789c8d406 --- /dev/null +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceSchema.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 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.sal.connect.netconf; + +import static java.util.Objects.requireNonNull; + +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; + +/** + * {@link NetconfDeviceCapabilities} and {@link EffectiveModelContext} pertaining to a {@link NetconfDevice}. + */ +public record NetconfDeviceSchema( + @NonNull NetconfDeviceCapabilities capabilities, + @NonNull MountPointContext mountContext) { + + public NetconfDeviceSchema { + requireNonNull(capabilities); + requireNonNull(mountContext); + } +} diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDevice.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDevice.java index 9a8306dd28..3c4d466deb 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDevice.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDevice.java @@ -13,6 +13,7 @@ import com.google.common.annotations.VisibleForTesting; import org.opendaylight.netconf.api.NetconfMessage; import org.opendaylight.netconf.sal.connect.api.RemoteDevice; import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler; +import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; import org.opendaylight.netconf.sal.connect.netconf.sal.SchemalessNetconfDeviceRpc; @@ -56,8 +57,11 @@ public class SchemalessNetconfDevice implements RemoteDevice unresolvedCapabilites; - private final Set resolvedCapabilities; - private final Set nonModuleBasedCapabilities; - - public NetconfDeviceCapabilities() { - this.unresolvedCapabilites = new HashMap<>(); - this.resolvedCapabilities = new HashSet<>(); - this.nonModuleBasedCapabilities = new HashSet<>(); - } - - public void addUnresolvedCapability(QName source, FailureReason reason) { - unresolvedCapabilites.put(source, reason); - } - - public void addUnresolvedCapabilities(Collection capabilities, FailureReason reason) { - for (QName s : capabilities) { - unresolvedCapabilites.put(s, reason); - } - } +public record NetconfDeviceCapabilities( + @NonNull ImmutableMap unresolvedCapabilites, + @NonNull ImmutableSet resolvedCapabilities, + @NonNull ImmutableSet nonModuleBasedCapabilities) { + private static final @NonNull NetconfDeviceCapabilities EMPTY = + new NetconfDeviceCapabilities(ImmutableMap.of(), ImmutableSet.of(), ImmutableSet.of()); - public void addCapabilities(Collection availableSchemas) { - resolvedCapabilities.addAll(availableSchemas); + public NetconfDeviceCapabilities { + requireNonNull(unresolvedCapabilites); + requireNonNull(resolvedCapabilities); + requireNonNull(nonModuleBasedCapabilities); } - public void addNonModuleBasedCapabilities(Collection nonModuleCapabilities) { - this.nonModuleBasedCapabilities.addAll(nonModuleCapabilities); + public static @NonNull NetconfDeviceCapabilities empty() { + return EMPTY; } - - public Set getNonModuleBasedCapabilities() { - return nonModuleBasedCapabilities; - } - - public Map getUnresolvedCapabilites() { - return unresolvedCapabilites; - } - - public Set getResolvedCapabilities() { - return resolvedCapabilities; - } - } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java index 790385c4cb..1356e97b30 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java @@ -100,10 +100,8 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener, LOG.debug("{}: Session established", id); currentSession = session; - NetconfSessionPreferences netconfSessionPreferences = - NetconfSessionPreferences.fromNetconfSession(session); - LOG.trace("{}: Session advertised capabilities: {}", id, - netconfSessionPreferences); + var netconfSessionPreferences = NetconfSessionPreferences.fromNetconfSession(session); + LOG.trace("{}: Session advertised capabilities: {}", id, netconfSessionPreferences); final var localOverride = overrideNetconfCapabilities; if (localOverride != null) { diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferences.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferences.java index 569ce8d3e3..e80b7f8224 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferences.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferences.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.netconf.client.NetconfClientSession; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability.CapabilityOrigin; @@ -59,7 +60,6 @@ public final class NetconfSessionPreferences { private static final Splitter AMP_SPLITTER = Splitter.on('&'); private static final Predicate CONTAINS_REVISION = input -> input.contains("revision="); - private final NetconfDeviceCapabilities capabilities = new NetconfDeviceCapabilities(); private final ImmutableMap moduleBasedCaps; private final ImmutableMap nonModuleCaps; @@ -85,8 +85,12 @@ public final class NetconfSessionPreferences { return nonModuleCaps; } - public NetconfDeviceCapabilities getNetconfDeviceCapabilities() { - return capabilities; + public @Nullable CapabilityOrigin capabilityOrigin(final QName capability) { + return moduleBasedCaps.get(requireNonNull(capability)); + } + + public @Nullable CapabilityOrigin capabilityOrigin(final String capability) { + return nonModuleCaps.get(requireNonNull(capability)); } // allows partial matches - assuming parameters are in the same order diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java index b90054d7c9..3c2e9c7039 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java @@ -32,12 +32,12 @@ import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener; import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceSchema; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -112,17 +112,17 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler { } @Override - public void onDeviceConnected(final MountPointContext remoteSchemaContext, - final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) { - onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc, null); + public void onDeviceConnected(final NetconfDeviceSchema deviceSchema, + final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) { + onDeviceConnected(deviceSchema, netconfSessionPreferences, deviceRpc, null); } @Override - public void onDeviceConnected(final MountPointContext remoteSchemaContext, + public void onDeviceConnected(final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc, final DOMActionService deviceAction) { currentDeviceRpc = requireNonNull(deviceRpc); - salFacade.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, + salFacade.onDeviceConnected(deviceSchema, netconfSessionPreferences, new KeepaliveDOMRpcService(deviceRpc), deviceAction); LOG.debug("{}: Netconf session initiated, starting keepalives", id); diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java index a75775e029..2c8548e550 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java @@ -17,6 +17,7 @@ import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.netconf.dom.api.NetconfDataTreeService; import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceSchema; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; @@ -65,27 +66,27 @@ public final class NetconfDeviceSalFacade implements RemoteDeviceHandler, AutoCl } @Override - public synchronized void onDeviceConnected(final MountPointContext mountContext, - final NetconfSessionPreferences netconfSessionPreferences, - final DOMRpcService deviceRpc, final DOMActionService deviceAction) { + public synchronized void onDeviceConnected(final NetconfDeviceSchema deviceSchema, + final NetconfSessionPreferences sessionPreferences, final DOMRpcService deviceRpc, + final DOMActionService deviceAction) { + final MountPointContext mountContext = deviceSchema.mountContext(); final EffectiveModelContext schemaContext = mountContext.getEffectiveModelContext(); + final NetconfDeviceDataBroker netconfDeviceDataBroker = - new NetconfDeviceDataBroker(id, mountContext, deviceRpc, netconfSessionPreferences); + new NetconfDeviceDataBroker(id, mountContext, deviceRpc, sessionPreferences); final NetconfDataTreeService netconfService = - AbstractNetconfDataTreeService.of(id, mountContext, deviceRpc, netconfSessionPreferences); + AbstractNetconfDataTreeService.of(id, mountContext, deviceRpc, sessionPreferences); registerLockListener(netconfDeviceDataBroker, netconfService); final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService(); - salProvider.getMountInstance() - .onTopologyDeviceConnected(schemaContext, netconfDeviceDataBroker, netconfService, - deviceRpc, notificationService, deviceAction); - salProvider.getTopologyDatastoreAdapter() - .updateDeviceData(true, netconfSessionPreferences.getNetconfDeviceCapabilities()); + salProvider.getMountInstance().onTopologyDeviceConnected(schemaContext, netconfDeviceDataBroker, netconfService, + deviceRpc, notificationService, deviceAction); + salProvider.getTopologyDatastoreAdapter().updateDeviceData(true, deviceSchema.capabilities()); } @Override public synchronized void onDeviceDisconnected() { - salProvider.getTopologyDatastoreAdapter().updateDeviceData(false, new NetconfDeviceCapabilities()); + salProvider.getTopologyDatastoreAdapter().updateDeviceData(false, NetconfDeviceCapabilities.empty()); salProvider.getMountInstance().onTopologyDeviceDisconnected(); closeLockChangeListener(); } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java index 31c4dd58c7..72a431ec46 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java @@ -147,12 +147,12 @@ public final class NetconfDeviceTopologyAdapter implements TransactionChainListe .setConnectionStatus(up ? ConnectionStatus.Connected : ConnectionStatus.Connecting) .setAvailableCapabilities(new AvailableCapabilitiesBuilder() .setAvailableCapability(ImmutableList.builder() - .addAll(capabilities.getNonModuleBasedCapabilities()) - .addAll(capabilities.getResolvedCapabilities()) + .addAll(capabilities.nonModuleBasedCapabilities()) + .addAll(capabilities.resolvedCapabilities()) .build()) .build()) .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder() - .setUnavailableCapability(capabilities.getUnresolvedCapabilites().entrySet().stream() + .setUnavailableCapability(capabilities.unresolvedCapabilites().entrySet().stream() .map(unresolved -> new UnavailableCapabilityBuilder() // FIXME: better conversion than 'toString' ? .setCapability(unresolved.getKey().toString()) diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java index 79804548de..2584d8027e 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java @@ -63,7 +63,6 @@ import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability; -import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -157,7 +156,7 @@ public class NetconfDeviceTest extends AbstractTestModelTest { getSessionCaps(true, Lists.newArrayList(TEST_CAPABILITY, TEST_CAPABILITY2)); device.onRemoteSessionUp(sessionCaps, listener); - verify(facade, timeout(5000)).onDeviceConnected(any(MountPointContext.class), + verify(facade, timeout(5000)).onDeviceConnected(any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class), isNull()); verify(schemaFactory, times(2)).createEffectiveModelContext(anyCollection()); } @@ -246,7 +245,7 @@ public class NetconfDeviceTest extends AbstractTestModelTest { getSessionCaps(true, Lists.newArrayList(TEST_CAPABILITY, TEST_CAPABILITY2)); device.onRemoteSessionUp(sessionCaps, listener); - verify(facade, timeout(5000)).onDeviceConnected(any(MountPointContext.class), + verify(facade, timeout(5000)).onDeviceConnected(any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class), isNull()); verify(schemaFactory, times(1)).createEffectiveModelContext(anyCollection()); } @@ -327,7 +326,7 @@ public class NetconfDeviceTest extends AbstractTestModelTest { verify(schemaContextProviderFactory, timeout(5000)).createEffectiveModelContext(any(Collection.class)); verify(facade, timeout(5000)).onDeviceConnected( - any(MountPointContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class), + any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class), isNull()); device.onRemoteSessionDown(); @@ -337,7 +336,7 @@ public class NetconfDeviceTest extends AbstractTestModelTest { verify(schemaContextProviderFactory, timeout(5000).times(2)).createEffectiveModelContext(any(Collection.class)); verify(facade, timeout(5000).times(2)).onDeviceConnected( - any(MountPointContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class), + any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class), isNull()); } @@ -400,13 +399,10 @@ public class NetconfDeviceTest extends AbstractTestModelTest { netconfSpy.onRemoteSessionUp(sessionCaps.replaceModuleCaps(moduleBasedCaps), listener); - final ArgumentCaptor argument = - ArgumentCaptor.forClass(NetconfSessionPreferences.class); - verify(facade, timeout(5000)).onDeviceConnected(any(MountPointContext.class), argument.capture(), + final ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class); + verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class), any(DOMRpcService.class), isNull()); - final NetconfDeviceCapabilities netconfDeviceCaps = argument.getValue().getNetconfDeviceCapabilities(); - - netconfDeviceCaps.getResolvedCapabilities() + argument.getValue().capabilities().resolvedCapabilities() .forEach(entry -> assertEquals("Builded 'AvailableCapability' schemas should match input capabilities.", moduleBasedCaps.get( QName.create(entry.getCapability())).getName(), entry.getCapabilityOrigin().getName())); @@ -434,9 +430,8 @@ public class NetconfDeviceTest extends AbstractTestModelTest { netconfSpy.onRemoteSessionUp(sessionCaps, listener); - final ArgumentCaptor argument = - ArgumentCaptor.forClass(NetconfSessionPreferences.class); - verify(facade, timeout(5000)).onDeviceConnected(any(MountPointContext.class), argument.capture(), + final ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class); + verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class), any(DOMRpcService.class), isNull()); List notificationModulesName = Arrays.asList( @@ -445,8 +440,7 @@ public class NetconfDeviceTest extends AbstractTestModelTest { org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715 .$YangModuleInfoImpl.getInstance().getName().toString()); - final Set resolvedCapabilities = argument.getValue().getNetconfDeviceCapabilities() - .getResolvedCapabilities(); + final Set resolvedCapabilities = argument.getValue().capabilities().resolvedCapabilities(); assertEquals(2, resolvedCapabilities.size()); assertTrue(resolvedCapabilities.stream().anyMatch(entry -> notificationModulesName @@ -475,20 +469,19 @@ public class NetconfDeviceTest extends AbstractTestModelTest { netconfSpy.onRemoteSessionUp(sessionCaps, listener); - final ArgumentCaptor argument = - ArgumentCaptor.forClass(NetconfSessionPreferences.class); - verify(facade, timeout(5000)).onDeviceConnected(any(MountPointContext.class), argument.capture(), + final ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class); + verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class), any(DOMRpcService.class), isNull()); - final NetconfDeviceCapabilities netconfDeviceCaps = argument.getValue().getNetconfDeviceCapabilities(); + final NetconfDeviceCapabilities netconfDeviceCaps = argument.getValue().capabilities(); - List notificationModulesName = Arrays.asList( + List notificationModulesName = List.of( org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714 .$YangModuleInfoImpl.getInstance().getName().toString(), org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715 .$YangModuleInfoImpl.getInstance().getName().toString()); - assertFalse(netconfDeviceCaps.getResolvedCapabilities().stream().anyMatch(entry -> notificationModulesName - .contains(entry.getCapability()))); + assertFalse(netconfDeviceCaps.resolvedCapabilities().stream() + .anyMatch(entry -> notificationModulesName.contains(entry.getCapability()))); } @Test @@ -521,12 +514,10 @@ public class NetconfDeviceTest extends AbstractTestModelTest { netconfSpy.onRemoteSessionUp(sessionCaps.replaceModuleCaps(moduleBasedCaps), listener); - final ArgumentCaptor argument = - ArgumentCaptor.forClass(NetconfSessionPreferences.class); - verify(facade, timeout(5000)).onDeviceConnected(any(MountPointContext.class), argument.capture(), + final ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class); + verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class), any(DOMRpcService.class), isNull()); - final Set resolvedCapabilities = argument.getValue().getNetconfDeviceCapabilities() - .getResolvedCapabilities(); + final Set resolvedCapabilities = argument.getValue().capabilities().resolvedCapabilities(); List notificationModulesName = Arrays.asList( org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714 @@ -549,7 +540,7 @@ public class NetconfDeviceTest extends AbstractTestModelTest { private static RemoteDeviceHandler getFacade() throws Exception { final RemoteDeviceHandler remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class); doNothing().when(remoteDeviceHandler).onDeviceConnected( - any(MountPointContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class), + any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class), any(DOMActionService.class)); doNothing().when(remoteDeviceHandler).onDeviceDisconnected(); doNothing().when(remoteDeviceHandler).onNotification(any(DOMNotification.class)); diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDeviceTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDeviceTest.java index ce4f4c8d16..f2e89eb75e 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDeviceTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDeviceTest.java @@ -30,7 +30,6 @@ import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc; import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.SchemalessMessageTransformer; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; -import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; public class SchemalessNetconfDeviceTest extends AbstractBaseSchemasTest { @@ -57,7 +56,7 @@ public class SchemalessNetconfDeviceTest extends AbstractBaseSchemasTest { device.onRemoteSessionUp(sessionCaps, listener); verify(facade).onDeviceConnected( - any(MountPointContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class)); + any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class)); device.onNotification(netconfMessage); verify(facade).onNotification(isNull()); @@ -72,7 +71,7 @@ public class SchemalessNetconfDeviceTest extends AbstractBaseSchemasTest { private static RemoteDeviceHandler getFacade() throws Exception { final RemoteDeviceHandler remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class); doNothing().when(remoteDeviceHandler).onDeviceConnected( - any(MountPointContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class)); + any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class)); doNothing().when(remoteDeviceHandler).onDeviceDisconnected(); doNothing().when(remoteDeviceHandler).onNotification(any(DOMNotification.class)); return remoteDeviceHandler; diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java index 50055813fe..135edf324b 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java @@ -13,39 +13,32 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.google.common.collect.Lists; import java.util.List; import org.junit.Test; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; -import org.opendaylight.yangtools.yang.common.QName; public class NetconfSessionPreferencesTest { - @Test - public void testMerge() throws Exception { - final List caps1 = Lists.newArrayList( - "namespace:1?module=module1&revision=2012-12-12", - "namespace:2?module=module2&revision=2012-12-12", - "urn:ietf:params:xml:ns:yang:" - + "ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04", - "urn:ietf:params:netconf:base:1.0", - "urn:ietf:params:netconf:capability:rollback-on-error:1.0" - ); - final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1); + public void testMerge() { + final var sessionCaps1 = NetconfSessionPreferences.fromStrings(List.of( + "namespace:1?module=module1&revision=2012-12-12", + "namespace:2?module=module2&revision=2012-12-12", + "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring" + + "&revision=2010-10-04", + "urn:ietf:params:netconf:base:1.0", + "urn:ietf:params:netconf:capability:rollback-on-error:1.0")); assertCaps(sessionCaps1, 2, 3); - final List caps2 = Lists.newArrayList( - "namespace:3?module=module3&revision=2012-12-12", - "namespace:4?module=module4&revision=2012-12-12", - "randomNonModuleCap" - ); - final NetconfSessionPreferences sessionCaps2 = NetconfSessionPreferences.fromStrings(caps2); + final var sessionCaps2 = NetconfSessionPreferences.fromStrings(List.of( + "namespace:3?module=module3&revision=2012-12-12", + "namespace:4?module=module4&revision=2012-12-12", + "randomNonModuleCap")); assertCaps(sessionCaps2, 1, 2); - final NetconfSessionPreferences merged = sessionCaps1.addModuleCaps(sessionCaps2); + final var merged = sessionCaps1.addModuleCaps(sessionCaps2); assertCaps(merged, 2, 2 + 1 /*Preserved monitoring*/ + 2 /*already present*/); - for (final QName qualifiedName : sessionCaps2.getModuleBasedCaps()) { - assertThat(merged.getModuleBasedCaps(), hasItem(qualifiedName)); + for (var qname : sessionCaps2.getModuleBasedCaps()) { + assertThat(merged.getModuleBasedCaps(), hasItem(qname)); } assertThat(merged.getModuleBasedCaps(), hasItem(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING)); @@ -55,60 +48,49 @@ public class NetconfSessionPreferencesTest { @Test public void testReplace() throws Exception { - final List caps1 = Lists.newArrayList( - "namespace:1?module=module1&revision=2012-12-12", - "namespace:2?module=module2&revision=2012-12-12", - "urn:ietf:params:xml:ns:yang:" - + "ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04", - "urn:ietf:params:netconf:base:1.0", - "urn:ietf:params:netconf:capability:rollback-on-error:1.0" - ); - final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1); + final var sessionCaps1 = NetconfSessionPreferences.fromStrings(List.of( + "namespace:1?module=module1&revision=2012-12-12", + "namespace:2?module=module2&revision=2012-12-12", + "urn:ietf:params:xml:ns:yang:" + + "ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04", + "urn:ietf:params:netconf:base:1.0", + "urn:ietf:params:netconf:capability:rollback-on-error:1.0")); assertCaps(sessionCaps1, 2, 3); - final List caps2 = Lists.newArrayList( - "namespace:3?module=module3&revision=2012-12-12", - "namespace:4?module=module4&revision=2012-12-12", - "randomNonModuleCap" - ); - final NetconfSessionPreferences sessionCaps2 = NetconfSessionPreferences.fromStrings(caps2); + final var sessionCaps2 = NetconfSessionPreferences.fromStrings(List.of( + "namespace:3?module=module3&revision=2012-12-12", + "namespace:4?module=module4&revision=2012-12-12", + "randomNonModuleCap")); assertCaps(sessionCaps2, 1, 2); - - final NetconfSessionPreferences replaced = sessionCaps1.replaceModuleCaps(sessionCaps2); - assertCaps(replaced, 2, 2); + assertCaps(sessionCaps1.replaceModuleCaps(sessionCaps2), 2, 2); } @Test public void testNonModuleMerge() throws Exception { - final List caps1 = Lists.newArrayList( - "namespace:1?module=module1&revision=2012-12-12", - "namespace:2?module=module2&revision=2012-12-12", - "urn:ietf:params:xml:ns:yang:" - + "ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04", - "urn:ietf:params:netconf:base:1.0", - "urn:ietf:params:netconf:capability:rollback-on-error:1.0", - "urn:ietf:params:netconf:capability:candidate:1.0" - ); - final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1); + final var sessionCaps1 = NetconfSessionPreferences.fromStrings(List.of( + "namespace:1?module=module1&revision=2012-12-12", + "namespace:2?module=module2&revision=2012-12-12", + "urn:ietf:params:xml:ns:yang:" + + "ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04", + "urn:ietf:params:netconf:base:1.0", + "urn:ietf:params:netconf:capability:rollback-on-error:1.0", + "urn:ietf:params:netconf:capability:candidate:1.0")); assertCaps(sessionCaps1, 3, 3); assertTrue(sessionCaps1.isCandidateSupported()); - final List caps2 = Lists.newArrayList( - "namespace:3?module=module3&revision=2012-12-12", - "namespace:4?module=module4&revision=2012-12-12", - "urn:ietf:params:netconf:capability:writable-running:1.0", - "urn:ietf:params:netconf:capability:notification:1.0" - ); - final NetconfSessionPreferences sessionCaps2 = NetconfSessionPreferences.fromStrings(caps2); + final var sessionCaps2 = NetconfSessionPreferences.fromStrings(List.of( + "namespace:3?module=module3&revision=2012-12-12", + "namespace:4?module=module4&revision=2012-12-12", + "urn:ietf:params:netconf:capability:writable-running:1.0", + "urn:ietf:params:netconf:capability:notification:1.0")); assertCaps(sessionCaps2, 2, 2); assertTrue(sessionCaps2.isRunningWritable()); - final NetconfSessionPreferences merged = sessionCaps1.addNonModuleCaps(sessionCaps2); + final var merged = sessionCaps1.addNonModuleCaps(sessionCaps2); assertCaps(merged, 3 + 2, 3); - for (final String capability : sessionCaps2.getNonModuleCaps()) { - assertThat(merged.getNonModuleCaps(), hasItem(capability)); - } + sessionCaps2.getNonModuleCaps().forEach( + capability -> assertThat(merged.getNonModuleCaps(), hasItem(capability))); assertThat(merged.getNonModuleCaps(), hasItem("urn:ietf:params:netconf:base:1.0")); assertThat(merged.getNonModuleCaps(), hasItem("urn:ietf:params:netconf:capability:rollback-on-error:1.0")); @@ -121,30 +103,26 @@ public class NetconfSessionPreferencesTest { @Test public void testNonmoduleReplace() throws Exception { - final List caps1 = Lists.newArrayList( - "namespace:1?module=module1&revision=2012-12-12", - "namespace:2?module=module2&revision=2012-12-12", - "urn:ietf:params:xml:ns:yang:" - + "ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04", - "urn:ietf:params:netconf:base:1.0", - "urn:ietf:params:netconf:capability:rollback-on-error:1.0", - "urn:ietf:params:netconf:capability:candidate:1.0" - ); - final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1); + final var sessionCaps1 = NetconfSessionPreferences.fromStrings(List.of( + "namespace:1?module=module1&revision=2012-12-12", + "namespace:2?module=module2&revision=2012-12-12", + "urn:ietf:params:xml:ns:yang:" + + "ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04", + "urn:ietf:params:netconf:base:1.0", + "urn:ietf:params:netconf:capability:rollback-on-error:1.0", + "urn:ietf:params:netconf:capability:candidate:1.0")); assertCaps(sessionCaps1, 3, 3); assertTrue(sessionCaps1.isCandidateSupported()); - final List caps2 = Lists.newArrayList( - "namespace:3?module=module3&revision=2012-12-12", - "namespace:4?module=module4&revision=2012-12-12", - "randomNonModuleCap", - "urn:ietf:params:netconf:capability:writable-running:1.0" - ); - final NetconfSessionPreferences sessionCaps2 = NetconfSessionPreferences.fromStrings(caps2); + final var sessionCaps2 = NetconfSessionPreferences.fromStrings(List.of( + "namespace:3?module=module3&revision=2012-12-12", + "namespace:4?module=module4&revision=2012-12-12", + "randomNonModuleCap", + "urn:ietf:params:netconf:capability:writable-running:1.0")); assertCaps(sessionCaps2, 2, 2); assertTrue(sessionCaps2.isRunningWritable()); - final NetconfSessionPreferences replaced = sessionCaps1.replaceNonModuleCaps(sessionCaps2); + final var replaced = sessionCaps1.replaceNonModuleCaps(sessionCaps2); assertCaps(replaced, 2, 3); assertFalse(replaced.isCandidateSupported()); assertTrue(replaced.isRunningWritable()); @@ -152,18 +130,15 @@ public class NetconfSessionPreferencesTest { @Test public void testCapabilityNoRevision() throws Exception { - final List caps1 = Lists.newArrayList( - "namespace:2?module=module2", - "namespace:2?module=module2&revision=2012-12-12", - "namespace:2?module=module1&RANDOMSTRING;revision=2013-12-12", - // Revision parameter present, but no revision defined - "namespace:2?module=module4&RANDOMSTRING;revision=", - // This one should be ignored(same as first), since revision is in wrong format - "namespace:2?module=module2&RANDOMSTRING;revision=2013-12-12" - ); - - final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1); - assertCaps(sessionCaps1, 0, 4); + assertCaps(NetconfSessionPreferences.fromStrings(List.of( + "namespace:2?module=module2", + "namespace:2?module=module2&revision=2012-12-12", + "namespace:2?module=module1&RANDOMSTRING;revision=2013-12-12", + // Revision parameter present, but no revision defined + "namespace:2?module=module4&RANDOMSTRING;revision=", + // This one should be ignored(same as first), since revision is in wrong format + "namespace:2?module=module2&RANDOMSTRING;revision=2013-12-12")), + 0, 4); } private static void assertCaps(final NetconfSessionPreferences sessionCaps1, final int nonModuleCaps, diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacadeResponseWaitingTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacadeResponseWaitingTest.java index 129202b887..9b71f19ab3 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacadeResponseWaitingTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacadeResponseWaitingTest.java @@ -32,11 +32,11 @@ import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult; import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceSchema; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; -import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; @@ -109,7 +109,7 @@ public class KeepaliveSalFacadeResponseWaitingTest { private DOMRpcService localDeviceRpc; @Override - public void onDeviceConnected(final MountPointContext remoteSchemaContext, + public void onDeviceConnected(final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService currentDeviceRpc, final DOMActionService deviceAction) { localDeviceRpc = currentDeviceRpc; diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeficeTopologyAdapterIntegrationTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeficeTopologyAdapterIntegrationTest.java index 8b31a315e5..7c6a7e69c6 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeficeTopologyAdapterIntegrationTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeficeTopologyAdapterIntegrationTest.java @@ -106,7 +106,7 @@ public class NetconfDeficeTopologyAdapterIntegrationTest { wtx.put(LogicalDatastoreType.OPERATIONAL, pathToAugmentedLeaf, augmentNode); wtx.commit().get(5, TimeUnit.SECONDS); - adapter.updateDeviceData(true, new NetconfDeviceCapabilities()); + adapter.updateDeviceData(true, NetconfDeviceCapabilities.empty()); assertEquals(Optional.of(dataTestId), domDataBroker.newReadOnlyTransaction() .read(LogicalDatastoreType.OPERATIONAL, pathToAugmentedLeaf) diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java index d8cda9fab0..e833f556b8 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java @@ -36,6 +36,8 @@ import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.netconf.dom.api.NetconfDataTreeService; +import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceSchema; +import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; @@ -112,8 +114,10 @@ public class NetconfDeviceSalFacadeTest { List.of(NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString())); final DOMRpcService deviceRpc = mock(DOMRpcService.class); - deviceFacade.onDeviceConnected(new EmptyMountPointContext(schemaContext), netconfSessionPreferences, deviceRpc, - null); + deviceFacade.onDeviceConnected( + new NetconfDeviceSchema(NetconfDeviceCapabilities.empty(), new EmptyMountPointContext(schemaContext)), + netconfSessionPreferences, deviceRpc, null); + verifyConnectionStatusUpdate(ConnectionStatus.Connected); verify(mountInstance, times(1)).onTopologyDeviceConnected(eq(schemaContext), any(DOMDataBroker.class), any(NetconfDataTreeService.class), eq(deviceRpc), diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java index 5fed5f6703..e3281fb490 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java @@ -77,7 +77,7 @@ public class NetconfDeviceTopologyAdapterTest { @Test public void testDeviceUpdate() throws Exception { - adapter.updateDeviceData(true, new NetconfDeviceCapabilities()); + adapter.updateDeviceData(true, NetconfDeviceCapabilities.empty()); verify(mockChain, times(2)).newWriteOnlyTransaction(); verify(mockTx, times(1)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class)); -- 2.36.6