BUG-5269 Enable device capabilities override 55/33455/5
authorMaros Marsalek <mmarsale@cisco.com>
Wed, 6 Jan 2016 14:49:19 +0000 (15:49 +0100)
committerMaros Marsalek <mmarsale@cisco.com>
Mon, 8 Feb 2016 14:23:11 +0000 (14:23 +0000)
So far, merge was the dafult strategy. From now on, override
is also possible.

Useful when it's necessary to completely replace device models
with user/app models.

Change-Id: I4b1bb68b8257e4a6889f54f7be0e6baee5d7617d
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferences.java
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/UserPrefenreces.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java

index 9feae9a6d246a218dcb43b2deca1484a23c9810a..bf834c3d8ecfca1cee6ccef5e221f2538151e13e 100644 (file)
@@ -38,6 +38,7 @@ import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
 import org.opendaylight.netconf.sal.connect.netconf.NetconfStateSchemas;
 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.listener.UserPrefenreces;
 import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalFacade;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
@@ -243,7 +244,9 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
                 new NetconfDevice(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, getReconnectOnChangedSchema());
 
         final NetconfDeviceCommunicator listener = userCapabilities.isPresent() ?
-                new NetconfDeviceCommunicator(id, device, userCapabilities.get()) : new NetconfDeviceCommunicator(id, device);
+                new NetconfDeviceCommunicator(id, device,
+                        new UserPrefenreces(userCapabilities.get(), getYangModuleCapabilities().getOverride())):
+                new NetconfDeviceCommunicator(id, device);
 
         if (shouldSendKeepalive()) {
             ((KeepaliveSalFacade) salFacade).setListener(listener);
index 27b05ee5ef36d8378a99a4614730aeca2a501f2b..3b82aa6d8e95fee8ed007e8ac2d56b5fa0840aa8 100644 (file)
@@ -49,7 +49,7 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
     private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceCommunicator.class);
 
     protected final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice;
-    private final Optional<NetconfSessionPreferences> overrideNetconfCapabilities;
+    private final Optional<UserPrefenreces> overrideNetconfCapabilities;
     protected final RemoteDeviceId id;
     private final Lock sessionLock = new ReentrantLock();
 
@@ -61,17 +61,17 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
     private SettableFuture<NetconfDeviceCapabilities> firstConnectionFuture;
 
     public NetconfDeviceCommunicator(final RemoteDeviceId id, final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice,
-            final NetconfSessionPreferences NetconfSessionPreferences) {
+            final UserPrefenreces NetconfSessionPreferences) {
         this(id, remoteDevice, Optional.of(NetconfSessionPreferences));
     }
 
     public NetconfDeviceCommunicator(final RemoteDeviceId id,
                                      final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice) {
-        this(id, remoteDevice, Optional.<NetconfSessionPreferences>absent());
+        this(id, remoteDevice, Optional.<UserPrefenreces>absent());
     }
 
     private NetconfDeviceCommunicator(final RemoteDeviceId id, final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice,
-            final Optional<NetconfSessionPreferences> overrideNetconfCapabilities) {
+            final Optional<UserPrefenreces> overrideNetconfCapabilities) {
         this.id = id;
         this.remoteDevice = remoteDevice;
         this.overrideNetconfCapabilities = overrideNetconfCapabilities;
@@ -91,7 +91,9 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
                     netconfSessionPreferences);
 
             if(overrideNetconfCapabilities.isPresent()) {
-                netconfSessionPreferences = netconfSessionPreferences.addModuleCaps(overrideNetconfCapabilities.get());
+                netconfSessionPreferences = overrideNetconfCapabilities.get().isOverride() ?
+                        netconfSessionPreferences.replaceModuleCaps(overrideNetconfCapabilities.get().getSessionPreferences()) :
+                        netconfSessionPreferences.addModuleCaps(overrideNetconfCapabilities.get().getSessionPreferences());
                 LOG.debug(
                         "{}: Session capabilities overridden, capabilities that will be used: {}",
                         id, netconfSessionPreferences);
index 5016067cd1862eacf6805f282069582d3adbc6a5..3e1198b0413134884e43ad26c3125a634e753e22 100644 (file)
@@ -69,7 +69,7 @@ public final class NetconfSessionPreferences {
     private final Set<QName> moduleBasedCaps;
     private final Set<String> nonModuleCaps;
 
-    private NetconfSessionPreferences(final Set<String> nonModuleCaps, final Set<QName> moduleBasedCaps) {
+    NetconfSessionPreferences(final Set<String> nonModuleCaps, final Set<QName> moduleBasedCaps) {
         this.nonModuleCaps = Preconditions.checkNotNull(nonModuleCaps);
         this.moduleBasedCaps = Preconditions.checkNotNull(moduleBasedCaps);
     }
@@ -124,6 +124,13 @@ public final class NetconfSessionPreferences {
                 || containsNonModuleCapability(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString());
     }
 
+    /**
+     * Merge module-based list of capabilities with current list of module-based capabilities
+     *
+     * @param netconfSessionModuleCapabilities capabilities to merge into this
+     *
+     * @return new instance of preferences with merged module-based capabilities
+     */
     public NetconfSessionPreferences addModuleCaps(final NetconfSessionPreferences netconfSessionModuleCapabilities) {
         final HashSet<QName> mergedCaps = Sets.newHashSetWithExpectedSize(moduleBasedCaps.size() + netconfSessionModuleCapabilities.getModuleBasedCaps().size());
         mergedCaps.addAll(moduleBasedCaps);
@@ -131,6 +138,17 @@ public final class NetconfSessionPreferences {
         return new NetconfSessionPreferences(getNonModuleCaps(), mergedCaps);
     }
 
+    /**
+     * Override current list of module-based capabilities
+     *
+     * @param netconfSessionPreferences capabilities to override in this
+     *
+     * @return new instance of preferences with replaced module-based capabilities
+     */
+    public NetconfSessionPreferences replaceModuleCaps(final NetconfSessionPreferences netconfSessionPreferences) {
+        return new NetconfSessionPreferences(getNonModuleCaps(), netconfSessionPreferences.getModuleBasedCaps());
+    }
+
     public static NetconfSessionPreferences fromNetconfSession(final NetconfClientSession session) {
         return fromStrings(session.getServerCapabilities());
     }
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/UserPrefenreces.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/UserPrefenreces.java
new file mode 100644 (file)
index 0000000..f2ef809
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.sal.connect.netconf.listener;
+
+import javax.annotation.Nonnull;
+
+/**
+ * DTO with user capabilities to override or merge with device specific capabilities
+ */
+public class UserPrefenreces {
+
+    private final NetconfSessionPreferences sessionPreferences;
+    private final boolean override;
+
+    public UserPrefenreces(@Nonnull final NetconfSessionPreferences sessionPreferences, boolean override) {
+        this.sessionPreferences = sessionPreferences;
+        this.override = override;
+    }
+
+    public NetconfSessionPreferences getSessionPreferences() {
+        return sessionPreferences;
+    }
+
+    public boolean isOverride() {
+        return override;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer("UserPrefenreces{");
+        sb.append("sessionPreferences=").append(sessionPreferences);
+        sb.append(", override=").append(override);
+        sb.append('}');
+        return sb.toString();
+    }
+}
index b19597052854a42d89927d1b5c4639a4bbd45331..28c504f09315b9c9f7ccd66dc97885b8eb2e2d33 100644 (file)
@@ -71,6 +71,12 @@ module odl-sal-netconf-connector-cfg {
             }
 
             container yang-module-capabilities {
+                leaf override {
+                    type boolean;
+                    default false;
+                    description "Whether to override or merge this list of capabilities with capabilities from device";
+                }
+
                 leaf-list capability {
                     type string;
                     description "Set a list of capabilities to override capabilities provided in device's hello message.
index 0e5150949d4981853d27a2215e635d41e02bb912..d9dd0c5f36826e5216c144b1677991d667902870 100644 (file)
@@ -51,6 +51,30 @@ public class NetconfSessionPreferencesTest {
         assertThat(merged.getNonModuleCaps(), hasItem("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
     }
 
+    @Test
+    public void testReplace() throws Exception {
+        final List<String> caps1 = Lists.newArrayList(
+                "namespace:1?module=module1&revision=2012-12-12",
+                "namespace:2?module=module2&amp;revision=2012-12-12",
+                "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;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);
+        assertCaps(sessionCaps1, 2, 3);
+
+        final List<String> 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);
+        assertCaps(sessionCaps2, 1, 2);
+
+        final NetconfSessionPreferences replaced = sessionCaps1.replaceModuleCaps(sessionCaps2);
+        assertCaps(replaced, 2, 2);
+    }
+
     @Test
     public void testCapabilityNoRevision() throws Exception {
         final List<String> caps1 = Lists.newArrayList(