Merge "Bug 6023 - Adress for config subsystem netconf endpoint is not configurable"
authorTomas Cere <tcere@cisco.com>
Thu, 20 Oct 2016 13:01:27 +0000 (13:01 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 20 Oct 2016 13:01:27 +0000 (13:01 +0000)
23 files changed:
netconf/messagebus-netconf/src/main/java/org/opendaylight/netconf/messagebus/eventsources/netconf/NetconfEventSourceRegistration.java
netconf/messagebus-netconf/src/test/java/org/opendaylight/netconf/messagebus/eventsources/netconf/NetconfTestUtils.java
netconf/netconf-console/src/main/java/org/opendaylight/netconf/console/impl/NetconfCommandsImpl.java
netconf/netconf-console/src/test/java/org/opendaylight/netconf/console/impl/NetconfCommandsImplTest.java
netconf/netconf-console/src/test/resources/schemas/netconf-node-topology.yang
netconf/netconf-notifications-api/src/test/java/org/opendaylight/netconf/notifications/NetconfNotificationTest.java [new file with mode: 0644]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/AbstractNetconfTopology.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfNodeManagerCallback.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDevice.java
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/ActorTest.java
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/NetconfNodeOperationalDataAggregatorTest.java
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/TopologyNodeWriterTest.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCapabilities.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferences.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java
netconf/sal-netconf-connector/src/main/yang/netconf-node-topology.yang
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicatorTest.java
netconf/sal-netconf-connector/src/test/resources/schemas/netconf-node-topology.yang
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/PostDataTransactionUtil.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/PostDataTransactionUtilTest.java

index 52b8a6a0859b0ca4cb618280912cc1472dca6125..8fcb44cfc120ff6f29fcfc4c1c5a3c6f6a809feb 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.messagebus.spi.EventSourceRegistration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
+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.network.topology.topology.topology.types.TopologyNetconf;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -66,12 +67,12 @@ public class NetconfEventSourceRegistration implements AutoCloseable {
         if (netconfNode.getAvailableCapabilities() == null) {
             return false;
         }
-        final List<String> capabilities = netconfNode.getAvailableCapabilities().getAvailableCapability();
+        final List<AvailableCapability> capabilities = netconfNode.getAvailableCapabilities().getAvailableCapability();
         if (capabilities == null || capabilities.isEmpty()) {
             return false;
         }
-        for (final String capability : netconfNode.getAvailableCapabilities().getAvailableCapability()) {
-            if (capability.startsWith(NotificationCapabilityPrefix)) {
+        for (final AvailableCapability capability : netconfNode.getAvailableCapabilities().getAvailableCapability()) {
+            if (capability.getCapability().startsWith(NotificationCapabilityPrefix)) {
                 return true;
             }
         }
index a403681b7624703483e1240f62c627af171300c1..3124d6b1f064071f0dafa3a859b8300e44f1d675 100644 (file)
@@ -24,6 +24,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
+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.network.topology.topology.topology.types.TopologyNetconf;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -55,8 +57,8 @@ public final class NetconfTestUtils {
         DomainName dn = new DomainName(hostName);
         Host host = new Host(dn);
 
-        List<String> avCapList = new ArrayList<>();
-        avCapList.add(notificationCapabilityPrefix + "_availableCapabilityString1");
+        List<AvailableCapability> avCapList = new ArrayList<>();
+        avCapList.add(new AvailableCapabilityBuilder().setCapability(notificationCapabilityPrefix + "_availableCapabilityString1").build());
         AvailableCapabilities avCaps = new AvailableCapabilitiesBuilder().setAvailableCapability(avCapList).build();
         NetconfNode nn = new NetconfNodeBuilder().setConnectionStatus(cs).setHost(host).setAvailableCapabilities(avCaps)
             .build();
index baf98f06d677705b5668998e40382eab055cb63f..d830e9d097b0f14a6a94a2ea20b7fd5a2a026ae0 100644 (file)
@@ -17,8 +17,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.stream.Collectors;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -33,20 +33,15 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
+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.credentials.Credentials;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.ModuleType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.Modules;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.Module;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.connector.netconf.rev150803.SalNetconfConnector;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 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.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -97,7 +92,8 @@ public class NetconfCommandsImpl implements NetconfCommands {
                     attributes.put(NetconfConsoleConstants.NETCONF_IP, ImmutableList.of(netconfNode.getHost().getIpAddress().getIpv4Address().getValue()));
                     attributes.put(NetconfConsoleConstants.NETCONF_PORT, ImmutableList.of(netconfNode.getPort().getValue().toString()));
                     attributes.put(NetconfConsoleConstants.STATUS, ImmutableList.of(netconfNode.getConnectionStatus().name()));
-                    attributes.put(NetconfConsoleConstants.AVAILABLE_CAPABILITIES, netconfNode.getAvailableCapabilities().getAvailableCapability());
+                    attributes.put(NetconfConsoleConstants.AVAILABLE_CAPABILITIES,
+                            netconfNode.getAvailableCapabilities().getAvailableCapability().stream().map(AvailableCapability::getCapability).collect(Collectors.toList()));
                     device.put(node.getNodeId().getValue(), attributes);
                 }
             }
@@ -117,7 +113,8 @@ public class NetconfCommandsImpl implements NetconfCommands {
                 attributes.put(NetconfConsoleConstants.NETCONF_IP, ImmutableList.of(netconfNode.getHost().getIpAddress().getIpv4Address().getValue()));
                 attributes.put(NetconfConsoleConstants.NETCONF_PORT, ImmutableList.of(netconfNode.getPort().getValue().toString()));
                 attributes.put(NetconfConsoleConstants.STATUS, ImmutableList.of(netconfNode.getConnectionStatus().name()));
-                attributes.put(NetconfConsoleConstants.AVAILABLE_CAPABILITIES, netconfNode.getAvailableCapabilities().getAvailableCapability());
+                attributes.put(NetconfConsoleConstants.AVAILABLE_CAPABILITIES,
+                        netconfNode.getAvailableCapabilities().getAvailableCapability().stream().map(AvailableCapability::getCapability).collect(Collectors.toList()));
                 device.put(node.getNodeId().getValue(), attributes);
             }
         }
index 96c5b271e1962ff0dac318acd039f9cb20408fa6..1ccd575c78096d75b938360f9e679b3256605310 100644 (file)
@@ -52,6 +52,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
+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.network.topology.topology.topology.types.TopologyNetconf;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
@@ -248,8 +250,10 @@ public class NetconfCommandsImplTest {
         final Host host = HostBuilder.getDefaultInstance(ip);
         final PortNumber port = new PortNumber(portNumber);
 
-        final List<String> avCapList = new ArrayList<>();
-        avCapList.add(notificationCapabilityPrefix + "_availableCapabilityString1");
+        final List<AvailableCapability> avCapList = new ArrayList<>();
+        avCapList.add(new AvailableCapabilityBuilder()
+                .setCapabilityOrigin(AvailableCapability.CapabilityOrigin.UserDefined)
+                .setCapability(notificationCapabilityPrefix + "_availableCapabilityString1").build());
         final AvailableCapabilities avCaps = new AvailableCapabilitiesBuilder().setAvailableCapability(avCapList).build();
 
         final NetconfNode nn = new NetconfNodeBuilder().setConnectionStatus(cs).setHost(host).setPort(port).
@@ -290,7 +294,9 @@ public class NetconfCommandsImplTest {
 
     private List<InputStream> getYangSchemas() {
         final List<String> schemaPaths = Arrays.asList("/schemas/network-topology@2013-10-21.yang",
-                "/schemas/ietf-inet-types@2013-07-15.yang", "/schemas/yang-ext.yang", "/schemas/netconf-node-topology.yang");
+                "/schemas/ietf-inet-types@2013-07-15.yang", "/schemas/yang-ext.yang",
+                "/schemas/netconf-node-topology.yang");
+
         final List<InputStream> schemas = new ArrayList<>();
         for (String schemaPath : schemaPaths) {
             final InputStream resourceAsStream = getClass().getResourceAsStream(schemaPath);
index 62b88b974f2091e575b6a4f70b59ad4b1b7b1e55..07461d48d75f67327cf0c6e380a4af454fa748ee 100644 (file)
@@ -162,8 +162,16 @@ module netconf-node-topology {
 
         container available-capabilities {
             config false;
-            leaf-list available-capability {
-                type string;
+            list available-capability {
+                leaf capability {
+                    type string;
+                }
+                leaf capability-origin {
+                    type enumeration {
+                        enum user-defined;
+                        enum device-advertised;
+                    }
+                }
             }
         }
 
diff --git a/netconf/netconf-notifications-api/src/test/java/org/opendaylight/netconf/notifications/NetconfNotificationTest.java b/netconf/netconf-notifications-api/src/test/java/org/opendaylight/netconf/notifications/NetconfNotificationTest.java
new file mode 100644 (file)
index 0000000..345b37a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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.notifications;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class NetconfNotificationTest {
+
+    @Test
+    public void testWrapNotification() throws Exception {
+        final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+        final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+
+        final Document document = docBuilder.newDocument();
+
+        final Element rootElement = document.createElement("test-root");
+        document.appendChild(rootElement);
+
+        final Date eventTime = new Date();
+        eventTime.setTime(10000000);
+
+        final NetconfNotification netconfNotification = new NetconfNotification(document, eventTime);
+        final Document resultDoc = netconfNotification.getDocument();
+        final NodeList nodeList = resultDoc.getElementsByTagNameNS(NetconfNotification.NOTIFICATION_NAMESPACE,
+                NetconfNotification.NOTIFICATION);
+
+        assertNotNull(nodeList);
+        // expected only the one NOTIFICATION tag
+        assertEquals(1, nodeList.getLength());
+
+        final Element entireNotification = (Element) nodeList.item(0);
+        final NodeList childNodes = entireNotification.getElementsByTagNameNS(
+                NetconfNotification.NOTIFICATION_NAMESPACE, NetconfNotification.EVENT_TIME);
+
+        assertNotNull(childNodes);
+        // expected only the one EVENT_TIME tag
+        assertEquals(1, childNodes.getLength());
+
+        final Element eventTimeElement = (Element) childNodes.item(0);
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+        assertEquals(eventTime.getTime(), sdf.parse(eventTimeElement.getTextContent()).getTime());
+
+        assertEquals(eventTime, netconfNotification.getEventTime());
+
+    }
+}
index f0c56f3ca79301defcca62328ba63378083dbf84..e9193d0579874d980e5c5bc83d94bde1e3776738 100644 (file)
@@ -64,6 +64,7 @@ import org.opendaylight.protocol.framework.TimedReconnectStrategy;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability.CapabilityOrigin;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
@@ -481,7 +482,7 @@ public abstract class AbstractNetconfTopology implements NetconfTopology, Bindin
             return Optional.absent();
         }
 
-        final NetconfSessionPreferences parsedOverrideCapabilities = NetconfSessionPreferences.fromStrings(capabilities);
+        final NetconfSessionPreferences parsedOverrideCapabilities = NetconfSessionPreferences.fromStrings(capabilities, CapabilityOrigin.UserDefined);
         Preconditions.checkState(parsedOverrideCapabilities.getNonModuleCaps().isEmpty(), "Capabilities to override can " +
                 "only contain module based capabilities, non-module capabilities will be retrieved from the device," +
                 " configured non-module capabilities: " + parsedOverrideCapabilities.getNonModuleCaps());
index 89e1dfa15b3349b192a4e4fa1c66adb9948ee288..6083281da95444856393e68542e5a15347a7f2b0 100644 (file)
@@ -55,6 +55,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
+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.clustered.connection.status.NodeStatus.Status;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
@@ -82,13 +83,6 @@ public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfC
                     .setFailureReason(input.getValue()).build();
         }
     };
-    public static final Function<QName, String> AVAILABLE_CAPABILITY_TRANSFORMER = new Function<QName, String>() {
-        @Override
-        public String apply(QName qName) {
-            // intern string representation of a capability to avoid duplicates
-            return qName.toString().intern();
-        }
-    };
 
     private static final String UNKNOWN_REASON = "Unknown reason";
 
@@ -168,7 +162,7 @@ public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfC
                                 .setHost(netconfNode.getHost())
                                 .setPort(netconfNode.getPort())
                                 .setConnectionStatus(ConnectionStatus.Connecting)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                 .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                 .setClusteredConnectionStatus(
                                         new ClusteredConnectionStatusBuilder()
@@ -200,7 +194,7 @@ public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfC
                                 .setHost(netconfNode.getHost())
                                 .setPort(netconfNode.getPort())
                                 .setConnectionStatus(ConnectionStatus.UnableToConnect)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                 .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                 .setClusteredConnectionStatus(
                                         new ClusteredConnectionStatusBuilder()
@@ -268,7 +262,7 @@ public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfC
                                                         .build())
                                         .setHost(netconfNode.getHost())
                                         .setPort(netconfNode.getPort())
-                                        .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                        .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                         .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                         .build()).build();
                 return currentOperationalNode;
@@ -326,7 +320,7 @@ public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfC
                                                         .build())
                                         .setHost(netconfNode.getHost())
                                         .setPort(netconfNode.getPort())
-                                        .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                        .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                         .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                         .build())
                         .build();
@@ -371,9 +365,9 @@ public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfC
             topologyDispatcher.registerMountPoint(cachedContext, new NodeId(nodeId), masterDataBrokerRef);
         }
 
-        List<String> capabilityList = new ArrayList<>();
+        List<AvailableCapability> capabilityList = new ArrayList<>();
         capabilityList.addAll(netconfSessionPreferences.getNetconfDeviceCapabilities().getNonModuleBasedCapabilities());
-        capabilityList.addAll(FluentIterable.from(netconfSessionPreferences.getNetconfDeviceCapabilities().getResolvedCapabilities()).transform(AVAILABLE_CAPABILITY_TRANSFORMER).toList());
+        capabilityList.addAll(netconfSessionPreferences.getNetconfDeviceCapabilities().getResolvedCapabilities());
         final AvailableCapabilitiesBuilder avCapabalitiesBuilder = new AvailableCapabilitiesBuilder();
         avCapabalitiesBuilder.setAvailableCapability(capabilityList);
 
@@ -421,7 +415,7 @@ public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfC
                 .addAugmentation(NetconfNode.class,
                         new NetconfNodeBuilder()
                                 .setConnectionStatus(ConnectionStatus.Connecting)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                 .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                 .setClusteredConnectionStatus(
                                         new ClusteredConnectionStatusBuilder()
@@ -450,7 +444,7 @@ public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfC
                 .addAugmentation(NetconfNode.class,
                         new NetconfNodeBuilder()
                                 .setConnectionStatus(ConnectionStatus.UnableToConnect)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                 .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                 .setClusteredConnectionStatus(
                                         new ClusteredConnectionStatusBuilder()
index cf0a8577ba17026132defc29606561f6f447ffbd..0542bf2406a8e7ca4310af99cde66b8d2ff79722 100644 (file)
@@ -35,6 +35,8 @@ import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
+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.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
@@ -135,12 +137,15 @@ public class ClusteredNetconfDevice extends NetconfDevice implements EntityOwner
                 LOG.debug("{}: Schema context built successfully.", id);
 
                 final NetconfDeviceCapabilities deviceCap = sessionPreferences.getNetconfDeviceCapabilities();
-                final Set<QName> providedSourcesQnames = Sets.newHashSet();
+                final Set<AvailableCapability> providedSourcesQnames = Sets.newHashSet();
+                final Set<AvailableCapability> providedSourcesNonModuleCaps = Sets.newHashSet();
                 for(ModuleIdentifier id : schemaContext.getAllModuleIdentifiers()) {
-                    providedSourcesQnames.add(QName.create(id.getQNameModule(), id.getName()));
+                    providedSourcesQnames.add(new AvailableCapabilityBuilder()
+                            .setCapability(QName.create(id.getQNameModule(), id.getName()).toString()).build());
                 }
-
-                deviceCap.addNonModuleBasedCapabilities(sessionPreferences.getNonModuleCaps());
+                sessionPreferences.getNonModuleCaps().forEach(e -> providedSourcesNonModuleCaps.add(new AvailableCapabilityBuilder()
+                        .setCapability(e).build()));
+                deviceCap.addNonModuleBasedCapabilities(providedSourcesNonModuleCaps);
                 deviceCap.addCapabilities(providedSourcesQnames);
 
                 ClusteredNetconfDevice.super.handleSalInitializationSuccess(
index ced7d016f3cd076782143e654bef595dfd75ddb0..1e0ba1ab93bb8639f268ba1085d599a533aa0b36 100644 (file)
@@ -73,6 +73,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
+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.clustered.connection.status.NodeStatus.Status;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
@@ -405,7 +406,7 @@ public class ActorTest {
                                     .setHost(netconfNode.getHost())
                                     .setPort(netconfNode.getPort())
                                     .setConnectionStatus(ConnectionStatus.Connecting)
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                     .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                     .setClusteredConnectionStatus(
                                             new ClusteredConnectionStatusBuilder()
@@ -431,7 +432,7 @@ public class ActorTest {
                                     .setHost(netconfNode.getHost())
                                     .setPort(netconfNode.getPort())
                                     .setConnectionStatus(ConnectionStatus.UnableToConnect)
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                     .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                     .setClusteredConnectionStatus(
                                             new ClusteredConnectionStatusBuilder()
@@ -458,7 +459,7 @@ public class ActorTest {
                                     .setConnectionStatus(ConnectionStatus.Connected)
                                     .setHost(augmentation.getHost())
                                     .setPort(augmentation.getPort())
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                     .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                     .setClusteredConnectionStatus(
                                             new ClusteredConnectionStatusBuilder()
@@ -485,7 +486,7 @@ public class ActorTest {
                                     .setConnectionStatus(ConnectionStatus.Connected)
                                     .setHost(augmentation.getHost())
                                     .setPort(augmentation.getPort())
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                     .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                     .setClusteredConnectionStatus(
                                             new ClusteredConnectionStatusBuilder()
@@ -565,7 +566,7 @@ public class ActorTest {
                                     .setConnectionStatus(ConnectionStatus.Connected)
                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
                                     .setPort(new PortNumber(2555))
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                     .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                     .build())
                     .build());
@@ -582,7 +583,7 @@ public class ActorTest {
                                     .setConnectionStatus(ConnectionStatus.Connected)
                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
                                     .setPort(new PortNumber(65535))
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                     .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                     .build())
                     .build());
@@ -620,7 +621,7 @@ public class ActorTest {
                                     .setConnectionStatus(ConnectionStatus.Connecting)
                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
                                     .setPort(new PortNumber(65535))
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                     .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                     .build())
                     .build();
@@ -636,7 +637,7 @@ public class ActorTest {
                                     .setConnectionStatus(ConnectionStatus.UnableToConnect)
                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
                                     .setPort(new PortNumber(65535))
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                     .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                     .build())
                     .build();
index d0976b489d6f92c6815e663b8ccd915ca3216568..fa5b5a425718fc8e637843f0bb69b26e072cf1b3 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
+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.clustered.connection.status.NodeStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
@@ -45,7 +46,7 @@ public class NetconfNodeOperationalDataAggregatorTest {
     @Test
     public void testCombineCreateAttempts() throws ExecutionException, InterruptedException {
         NetconfNode testingNode = new NetconfNodeBuilder().setAvailableCapabilities(
-                new AvailableCapabilitiesBuilder().setAvailableCapability(Lists.<String>newArrayList()).build())
+                new AvailableCapabilitiesBuilder().setAvailableCapability(Lists.<AvailableCapability>newArrayList()).build())
                 .setClusteredConnectionStatus(new ClusteredConnectionStatusBuilder().setNodeStatus(Lists.newArrayList(
                         new NodeStatusBuilder().setStatus(NodeStatus.Status.Connected).build())).build())
                 .setConnectionStatus(NetconfNodeConnectionStatus.ConnectionStatus.Connected).build();
@@ -62,7 +63,7 @@ public class NetconfNodeOperationalDataAggregatorTest {
     @Test
     public void testSuccessfulCombineUpdateAttempts() throws ExecutionException, InterruptedException {
         NetconfNode testingNode = new NetconfNodeBuilder().setAvailableCapabilities(
-                new AvailableCapabilitiesBuilder().setAvailableCapability(Lists.<String>newArrayList()).build())
+                new AvailableCapabilitiesBuilder().setAvailableCapability(Lists.<AvailableCapability>newArrayList()).build())
                 .setClusteredConnectionStatus(new ClusteredConnectionStatusBuilder().setNodeStatus(Lists.newArrayList(
                         new NodeStatusBuilder().setStatus(NodeStatus.Status.Connected).build())).build())
                 .setConnectionStatus(NetconfNodeConnectionStatus.ConnectionStatus.Connected).build();
index 4e1145720e474d1e9f55e891b052439e5102755c..67ba5ebf0f62cfa4c74a57ebb08d348dfed341bb 100644 (file)
@@ -37,6 +37,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
+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.clustered.connection.status.NodeStatus.Status;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
@@ -98,7 +99,7 @@ public class TopologyNodeWriterTest {
                                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
                                 .setPort(new PortNumber(17830))
                                 .setConnectionStatus(ConnectionStatus.Connected)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
+                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
                                 .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
                                 .setClusteredConnectionStatus(
                                         new ClusteredConnectionStatusBuilder()
index 88eb368b9bb0a3a3a754f9e679f89b87c8876ec9..ffb5c7501763a2bf8b1222158f770591f5c403ba 100644 (file)
@@ -87,7 +87,7 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
 
     private boolean isHostAddressPresent(final Host address) {
         return address.getDomainName() != null ||
-               address.getIpAddress() != null && (address.getIpAddress().getIpv4Address() != null || address.getIpAddress().getIpv6Address() != null);
+                address.getIpAddress() != null && (address.getIpAddress().getIpv4Address() != null || address.getIpAddress().getIpv6Address() != null);
     }
 
     @Override
index 31aa51a3b9caaa239d3fd9880b34f6b5072cf6c7..d11c2a82c1f681ba0efd24804e0622f561fdb50c 100644 (file)
@@ -50,6 +50,8 @@ 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.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -452,8 +454,14 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
                     final SchemaContext result = schemaBuilderFuture.checkedGet();
                     LOG.debug("{}: Schema context built successfully from {}", id, requiredSources);
                     final Collection<QName> filteredQNames = Sets.difference(deviceSources.getRequiredSourcesQName(), capabilities.getUnresolvedCapabilites().keySet());
-                    capabilities.addCapabilities(filteredQNames);
-                    capabilities.addNonModuleBasedCapabilities(remoteSessionCapabilities.getNonModuleCaps());
+                    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(AvailableCapability.CapabilityOrigin.DeviceAdvertised).build())
+                            .collect(Collectors.toList()));
+
                     handleSalInitializationSuccess(result, remoteSessionCapabilities, getDeviceSpecificRpc(result));
                     return;
                 } catch (final Throwable t) {
index e349a939c29380e5fcb010a069b51f3a0812cc7c..5b1dd458c1144d3562e12eb91e54fb2dc7ccea02 100644 (file)
@@ -13,14 +13,14 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+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.unavailable.capabilities.UnavailableCapability.FailureReason;
 import org.opendaylight.yangtools.yang.common.QName;
 
 public final class NetconfDeviceCapabilities {
     private final Map<QName, FailureReason> unresolvedCapabilites;
-    private final Set<QName> resolvedCapabilities;
-
-    private final Set<String> nonModuleBasedCapabilities;
+    private final Set<AvailableCapability>  resolvedCapabilities;
+    private final Set<AvailableCapability> nonModuleBasedCapabilities;
 
     public NetconfDeviceCapabilities() {
         this.unresolvedCapabilites = new HashMap<>();
@@ -38,15 +38,15 @@ public final class NetconfDeviceCapabilities {
         }
     }
 
-    public void addCapabilities(Collection<QName> availableSchemas) {
+    public void addCapabilities(Collection<AvailableCapability>  availableSchemas) {
         resolvedCapabilities.addAll(availableSchemas);
     }
 
-    public void addNonModuleBasedCapabilities(Collection<String> nonModuleCapabilities) {
+    public void addNonModuleBasedCapabilities(Collection<AvailableCapability> nonModuleCapabilities) {
         this.nonModuleBasedCapabilities.addAll(nonModuleCapabilities);
     }
 
-    public Set<String> getNonModuleBasedCapabilities() {
+    public Set<AvailableCapability> getNonModuleBasedCapabilities() {
         return nonModuleBasedCapabilities;
     }
 
@@ -54,7 +54,7 @@ public final class NetconfDeviceCapabilities {
         return unresolvedCapabilites;
     }
 
-    public Set<QName> getResolvedCapabilities() {
+    public Set<AvailableCapability>  getResolvedCapabilities() {
         return resolvedCapabilities;
     }
 
index 084481eec736096ff700801aeb2efc1d75a9b75b..7fb1b05db32f32d96622e36fcbfdb6736921e17e 100644 (file)
@@ -14,16 +14,20 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import java.net.URI;
 import java.util.Collection;
-import java.util.HashSet;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 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;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -67,15 +71,19 @@ public final class NetconfSessionPreferences {
         }
     };
 
-    private final Set<QName> moduleBasedCaps;
+    private final Map<QName, CapabilityOrigin> moduleBasedCaps;
     private final Set<String> nonModuleCaps;
 
-    NetconfSessionPreferences(final Set<String> nonModuleCaps, final Set<QName> moduleBasedCaps) {
+    NetconfSessionPreferences(final Set<String> nonModuleCaps, final Map<QName, CapabilityOrigin> moduleBasedCaps) {
         this.nonModuleCaps = Preconditions.checkNotNull(nonModuleCaps);
         this.moduleBasedCaps = Preconditions.checkNotNull(moduleBasedCaps);
     }
 
     public Set<QName> getModuleBasedCaps() {
+        return moduleBasedCaps.keySet();
+    }
+
+    public Map<QName, CapabilityOrigin> getModuleBasedCapsOrigin() {
         return moduleBasedCaps;
     }
 
@@ -100,7 +108,7 @@ public final class NetconfSessionPreferences {
     }
 
     public boolean containsModuleCapability(final QName capability) {
-        return moduleBasedCaps.contains(capability);
+        return moduleBasedCaps.containsKey(capability);
     }
 
     @Override
@@ -145,9 +153,9 @@ public final class NetconfSessionPreferences {
      * @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);
-        mergedCaps.addAll(netconfSessionModuleCapabilities.getModuleBasedCaps());
+        final Map<QName, CapabilityOrigin> mergedCaps = Maps.newHashMapWithExpectedSize(moduleBasedCaps.size() + netconfSessionModuleCapabilities.getModuleBasedCaps().size());
+        mergedCaps.putAll(moduleBasedCaps);
+        mergedCaps.putAll(netconfSessionModuleCapabilities.getModuleBasedCapsOrigin());
         return new NetconfSessionPreferences(getNonModuleCaps(), mergedCaps);
     }
 
@@ -159,7 +167,11 @@ public final class NetconfSessionPreferences {
      * @return new instance of preferences with replaced module-based capabilities
      */
     public NetconfSessionPreferences replaceModuleCaps(final NetconfSessionPreferences netconfSessionPreferences) {
-        return new NetconfSessionPreferences(getNonModuleCaps(), netconfSessionPreferences.getModuleBasedCaps());
+        return new NetconfSessionPreferences(getNonModuleCaps(), netconfSessionPreferences.getModuleBasedCapsOrigin());
+    }
+
+    public NetconfSessionPreferences replaceModuleCaps(Map<QName, CapabilityOrigin> newModuleBasedCaps) {
+        return new NetconfSessionPreferences(getNonModuleCaps(), newModuleBasedCaps);
     }
 
     public static NetconfSessionPreferences fromNetconfSession(final NetconfClientSession session) {
@@ -175,7 +187,12 @@ public final class NetconfSessionPreferences {
     }
 
     public static NetconfSessionPreferences fromStrings(final Collection<String> capabilities) {
-        final Set<QName> moduleBasedCaps = new HashSet<>();
+        // we do not know origin of capabilities from only Strings, so we set it to default value
+        return fromStrings(capabilities, CapabilityOrigin.DeviceAdvertised);
+    }
+
+    public static NetconfSessionPreferences fromStrings(final Collection<String> capabilities, CapabilityOrigin capabilityOrigin) {
+        final Map<QName, CapabilityOrigin> moduleBasedCaps = new HashMap<>();
         final Set<String> nonModuleCaps = Sets.newHashSet(capabilities);
 
         for (final String capability : capabilities) {
@@ -193,7 +210,7 @@ public final class NetconfSessionPreferences {
 
             String revision = REVISION_PARAM.from(queryParams);
             if (!Strings.isNullOrEmpty(revision)) {
-                addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName));
+                addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName), capabilityOrigin);
                 continue;
             }
 
@@ -207,23 +224,22 @@ public final class NetconfSessionPreferences {
                 revision = BROKEN_REVISON_PARAM.from(queryParams);
                 if (Strings.isNullOrEmpty(revision)) {
                     LOG.warn("Netconf device returned revision incorrectly escaped for {}, ignoring it", capability);
-                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName));
+                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName), capabilityOrigin);
                 } else {
-                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName));
+                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName), capabilityOrigin);
                 }
                 continue;
             }
 
             // Fallback, no revision provided for module
-            addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName));
+            addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName), capabilityOrigin);
         }
 
-        return new NetconfSessionPreferences(ImmutableSet.copyOf(nonModuleCaps), ImmutableSet.copyOf(moduleBasedCaps));
+        return new NetconfSessionPreferences(ImmutableSet.copyOf(nonModuleCaps), ImmutableMap.copyOf(moduleBasedCaps));
     }
 
-
-    private static void addModuleQName(final Set<QName> moduleBasedCaps, final Set<String> nonModuleCaps, final String capability, final QName qName) {
-        moduleBasedCaps.add(qName);
+    private static void addModuleQName(final Map<QName, CapabilityOrigin> moduleBasedCaps, final Set<String> nonModuleCaps, final String capability, final QName qName, CapabilityOrigin capabilityOrigin) {
+        moduleBasedCaps.put(qName, capabilityOrigin);
         nonModuleCaps.remove(capability);
     }
 
index b440b1d900fa7b81c9419ae68c2e2fa05aa5fad2..7073da98a07f6221e0bfad84b677f97b77014465 100644 (file)
@@ -31,6 +31,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
+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.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.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapabilityBuilder;
@@ -62,13 +63,6 @@ final class NetconfDeviceTopologyAdapter implements AutoCloseable {
                     .setFailureReason(input.getValue()).build();
         }
     };
-    public static final Function<QName, String> AVAILABLE_CAPABILITY_TRANSFORMER = new Function<QName, String>() {
-        @Override
-        public String apply(QName qName) {
-            // intern string representation of a capability to avoid duplicates
-            return qName.toString().intern();
-        }
-    };
 
     private final RemoteDeviceId id;
     private BindingTransactionChain txChain;
@@ -152,9 +146,10 @@ final class NetconfDeviceTopologyAdapter implements AutoCloseable {
     }
 
     private NetconfNode buildDataForNetconfNode(boolean up, NetconfDeviceCapabilities capabilities) {
-        List<String> capabilityList = new ArrayList<>();
+        List<AvailableCapability> capabilityList = new ArrayList<>();
         capabilityList.addAll(capabilities.getNonModuleBasedCapabilities());
-        capabilityList.addAll(FluentIterable.from(capabilities.getResolvedCapabilities()).transform(AVAILABLE_CAPABILITY_TRANSFORMER).toList());
+        capabilityList.addAll(capabilities.getResolvedCapabilities());
+
         final AvailableCapabilitiesBuilder avCapabalitiesBuilder = new AvailableCapabilitiesBuilder();
         avCapabalitiesBuilder.setAvailableCapability(capabilityList);
 
index 62b88b974f2091e575b6a4f70b59ad4b1b7b1e55..07461d48d75f67327cf0c6e380a4af454fa748ee 100644 (file)
@@ -162,8 +162,16 @@ module netconf-node-topology {
 
         container available-capabilities {
             config false;
-            leaf-list available-capability {
-                type string;
+            list available-capability {
+                leaf capability {
+                    type string;
+                }
+                leaf capability-origin {
+                    type enumeration {
+                        enum user-defined;
+                        enum device-advertised;
+                    }
+                }
             }
         }
 
index ae6726b7802f64efcdde29e272711e85a315af1c..9708888f5d0c44fb24eab62ea88e101f21b0c8fe 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.netconf.sal.connect.netconf;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyCollectionOf;
 import static org.mockito.Matchers.eq;
@@ -30,10 +31,13 @@ import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -48,11 +52,13 @@ import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemas;
 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemasResolver;
 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.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.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -65,8 +71,8 @@ import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
@@ -329,6 +335,40 @@ public class NetconfDeviceTest {
         verify(facade, timeout(5000).times(2)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
     }
 
+    @Test
+    public void testNetconfDeviceAvailableCapabilitiesBuilding() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
+        final NetconfDeviceCommunicator listener = getListener();
+
+        final SchemaContextFactory schemaContextProviderFactory = getSchemaFactory();
+
+        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
+                = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, stateSchemasResolver);
+        final NetconfDevice device = new NetconfDeviceBuilder()
+                .setReconnectOnSchemasChange(true)
+                .setSchemaResourcesDTO(schemaResourcesDTO)
+                .setGlobalProcessingExecutor(getExecutor())
+                .setId(getId())
+                .setSalFacade(facade)
+                .build();
+        NetconfDevice netconfSpy = Mockito.spy(device);
+
+        final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
+                Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
+        Map<QName, AvailableCapability.CapabilityOrigin> moduleBasedCaps = new HashMap<>();
+        moduleBasedCaps.putAll(sessionCaps.getModuleBasedCapsOrigin());
+        moduleBasedCaps.put(QName.create("test:qname:side:loading"), AvailableCapability.CapabilityOrigin.UserDefined);
+
+        netconfSpy.onRemoteSessionUp(sessionCaps.replaceModuleCaps(moduleBasedCaps), listener);
+
+        ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfSessionPreferences.class);
+        verify(netconfSpy, timeout(5000)).handleSalInitializationSuccess(any(SchemaContext.class), (NetconfSessionPreferences) argument.capture(), any(DOMRpcService.class));
+        NetconfDeviceCapabilities netconfDeviceCaps = ((NetconfSessionPreferences) argument.getValue()).getNetconfDeviceCapabilities();
+
+        netconfDeviceCaps.getResolvedCapabilities().forEach(entry -> assertEquals("Builded 'AvailableCapability' schemas should match input capabilities.",
+                moduleBasedCaps.get(QName.create(entry.getCapability())).getName(), entry.getCapabilityOrigin().getName()));
+    }
+
     private SchemaContextFactory getSchemaFactory() {
         final SchemaContextFactory schemaFactory = mockClass(SchemaContextFactory.class);
         doReturn(Futures.immediateCheckedFuture(getSchema())).when(schemaFactory).createSchemaContext(any(Collection.class));
index 7938f429a65c3b16bf0c6d85329777b04f0661e5..bf18b6f30277059a1012baa336ad51221209092d 100644 (file)
@@ -145,7 +145,7 @@ public class NetconfDeviceCommunicatorTest {
         assertEquals( "containsModuleCapability", false, actualCapabilites.containsNonModuleCapability(testCapability) );
         assertEquals( "getModuleBasedCaps", Sets.newHashSet(
                             QName.create( "urn:opendaylight:params:xml:ns:test", "2014-06-02", "test-module" )),
-                      actualCapabilites.getModuleBasedCaps() );
+                      actualCapabilites.getModuleBasedCaps());
         assertEquals( "isRollbackSupported", true, actualCapabilites.isRollbackSupported() );
         assertEquals( "isMonitoringSupported", true, actualCapabilites.isMonitoringSupported() );
     }
index 62b88b974f2091e575b6a4f70b59ad4b1b7b1e55..81fe494e615508101e482caa97e69f55c2f6ad96 100644 (file)
@@ -162,8 +162,16 @@ module netconf-node-topology {
 
         container available-capabilities {
             config false;
-            leaf-list available-capability {
-                type string;
+            list available-capability {
+                leaf capability {
+                    type string;
+                }
+                leaf capability-origin {
+                    type enumeration {
+                        enum user-defined;
+                        enum device-advertised;
+                    }
+                }
             }
         }
 
@@ -240,4 +248,4 @@ module netconf-node-topology {
 
         uses netconf-node-fields;
     }
-}
+}
\ No newline at end of file
index fc9c676c4ea36a4bcaeb60bd591765d019a57813..f0958d79e9345a77d1ec25756802d57c26ef0b34 100644 (file)
@@ -17,20 +17,10 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
-import org.opendaylight.restconf.RestConnectorProvider;
 import org.opendaylight.restconf.common.references.SchemaContextRef;
 import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
 import org.opendaylight.restconf.utils.parser.ParserIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -93,64 +83,35 @@ public final class PostDataTransactionUtil {
             final SchemaContext schemaContext) {
         final DOMTransactionChain transactionChain = transactionNode.getTransactionChain();
         final DOMDataReadWriteTransaction transaction = transactionChain.newReadWriteTransaction();
-        final NormalizedNode<?, ?> node = ImmutableNodes.fromInstanceId(schemaContext, path);
-        transaction.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(node.getIdentifier()), node);
-        TransactionUtil.ensureParentsByMerge(path, schemaContext, transaction);
 
         if (data instanceof MapNode) {
+            boolean merge = false;
             for (final MapEntryNode child : ((MapNode) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
-            }
-        } else if (data instanceof AugmentationNode) {
-            for (final DataContainerChild<? extends PathArgument, ?> child : ((AugmentationNode) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
-            }
-        } else if (data instanceof ChoiceNode) {
-            for (final DataContainerChild<? extends PathArgument, ?> child : ((ChoiceNode) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
-            }
-        } else if (data instanceof LeafSetNode<?>) {
-            for (final LeafSetEntryNode<?> child : ((LeafSetNode<?>) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
-            }
-        } else if (data instanceof ContainerNode) {
-            for (final DataContainerChild<? extends PathArgument, ?> child : ((ContainerNode) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
+                final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
+                TransactionUtil.checkItemDoesNotExists(
+                        transactionChain, transaction, LogicalDatastoreType.CONFIGURATION, childPath,
+                        RestconfDataServiceConstant.PostData.POST_TX_TYPE);
+                if (!merge) {
+                    merge = true;
+                    TransactionUtil.ensureParentsByMerge(path, schemaContext, transaction);
+                    final NormalizedNode<?, ?> emptySubTree = ImmutableNodes.fromInstanceId(schemaContext, path);
+                    transaction.merge(LogicalDatastoreType.CONFIGURATION,
+                            YangInstanceIdentifier.create(emptySubTree.getIdentifier()), emptySubTree);
+                }
+                transaction.put(LogicalDatastoreType.CONFIGURATION, childPath, child);
             }
         } else {
-            transaction.cancel();
-            RestConnectorProvider.resetTransactionChainForAdapaters(transactionChain);
+            TransactionUtil.checkItemDoesNotExists(
+                    transactionChain, transaction, LogicalDatastoreType.CONFIGURATION, path,
+                    RestconfDataServiceConstant.PostData.POST_TX_TYPE);
 
-            final String errMsg = "Only Map, Choice, Augmentation, LeafSet and Container nodes are supported";
-            LOG.trace("{}:{}", errMsg, path);
-            throw new RestconfDocumentedException(
-                    "Node not supported", RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.BAD_ELEMENT, path);
+            TransactionUtil.ensureParentsByMerge(path, schemaContext, transaction);
+            transaction.put(LogicalDatastoreType.CONFIGURATION, path, data);
         }
 
         return transaction.submit();
     }
 
-    /**
-     * Prepare data for submit
-     *
-     * @param child
-     *            - data
-     * @param transactionChain
-     *            - transaction chain
-     * @param readWriteTx
-     *            - transaction
-     * @param path
-     *            - path to data
-     */
-    private static void putChild(final NormalizedNode<?, ?> child, final DOMTransactionChain transactionChain,
-                                 final DOMDataReadWriteTransaction readWriteTx, final YangInstanceIdentifier path) {
-        final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
-        TransactionUtil.checkItemDoesNotExists(
-                transactionChain, readWriteTx, LogicalDatastoreType.CONFIGURATION, childPath,
-                RestconfDataServiceConstant.PostData.POST_TX_TYPE);
-        readWriteTx.put(LogicalDatastoreType.CONFIGURATION, childPath, child);
-    }
-
     /**
      * Get location from {@link YangInstanceIdentifier} and {@link UriInfo}
      *
index 51270bc51b220858dd629739c2ef4724f3268e9d..a86d9ce7a84a23d26aa0a91e5a0ad60aeef849b2 100644 (file)
@@ -12,7 +12,7 @@ import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
-import com.google.common.base.Optional;
+
 import com.google.common.util.concurrent.Futures;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
@@ -38,7 +38,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
@@ -125,7 +124,7 @@ public class PostDataTransactionUtilTest {
         final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(this.iid2, null, null, this.schema);
         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildBaseCont);
 
-        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        doReturn(Futures.immediateCheckedFuture(false)).when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
         final YangInstanceIdentifier.NodeIdentifier identifier = ((ContainerNode) ((SingletonSet) payload.getData().getValue()).iterator().next()).getIdentifier();
         final YangInstanceIdentifier node = payload.getInstanceIdentifierContext().getInstanceIdentifier().node(identifier);
         doReturn(Futures.immediateCheckedFuture(false)).when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
@@ -134,8 +133,8 @@ public class PostDataTransactionUtilTest {
         final TransactionVarsWrapper wrapper = new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain);
         final Response response = PostDataTransactionUtil.postData(this.uriInfo, payload, wrapper, this.refSchemaCtx);
         assertEquals(201, response.getStatus());
-        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
-        verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, node, (NormalizedNode<?, ?>) ((SingletonSet) payload.getData().getValue()).iterator().next());
+        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
     }
 
     @Test
@@ -143,7 +142,6 @@ public class PostDataTransactionUtilTest {
         final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(this.iid2, null, null, this.schema);
         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildList);
 
-        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
         final MapNode data = (MapNode) payload.getData();
         final YangInstanceIdentifier.NodeIdentifierWithPredicates identifier = data.getValue().iterator().next().getIdentifier();
         final YangInstanceIdentifier node = payload.getInstanceIdentifierContext().getInstanceIdentifier().node(identifier);
@@ -162,7 +160,7 @@ public class PostDataTransactionUtilTest {
         final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(this.iid2, null, null, this.schema);
         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildBaseCont);
 
-        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        doReturn(Futures.immediateCheckedFuture(false)).when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
         final YangInstanceIdentifier.NodeIdentifier identifier = ((ContainerNode) ((SingletonSet) payload.getData().getValue()).iterator().next()).getIdentifier();
         final YangInstanceIdentifier node = payload.getInstanceIdentifierContext().getInstanceIdentifier().node(identifier);
         doReturn(Futures.immediateCheckedFuture(false)).when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
@@ -172,8 +170,8 @@ public class PostDataTransactionUtilTest {
         final TransactionVarsWrapper wrapper = new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain);
         final Response response = PostDataTransactionUtil.postData(this.uriInfo, payload, wrapper, this.refSchemaCtx);
         assertEquals(Response.Status.INTERNAL_SERVER_ERROR, response.getStatusInfo());
-        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
-        verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, node, (NormalizedNode<?, ?>) ((SingletonSet) payload.getData().getValue()).iterator().next());
+        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, iid2);
+        verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
     }
 
 }