caching the same capabilities for devices using Interner. 28/37728/6
authormiroslav.kovac <miroslav.kovac@pantheon.tech>
Fri, 15 Apr 2016 07:07:47 +0000 (09:07 +0200)
committermiroslav.kovac <miroslav.kovac@pantheon.tech>
Tue, 19 Apr 2016 13:15:24 +0000 (15:15 +0200)
Change-Id: I70ad61ad714e679b237ab01778690ab4fd1391f1
Signed-off-by: miroslav.kovac <miroslav.kovac@pantheon.tech>
netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiator.java
netconf/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiatorTest.java
netconf/netconf-client/src/test/resources/helloMessage1.xml [new file with mode: 0644]
netconf/netconf-client/src/test/resources/helloMessage2.xml [new file with mode: 0644]
netconf/netconf-client/src/test/resources/helloMessage3.xml [new file with mode: 0644]

index 4ae7dea12c77e4970ff785301948a82ef0d67596..55d92d6df6e33bc25ea471067bce24976d6db529 100644 (file)
@@ -9,7 +9,9 @@
 package org.opendaylight.netconf.client;
 
 import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Interner;
+import com.google.common.collect.Interners;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelFutureListener;
@@ -17,20 +19,20 @@ import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.util.Timer;
 import io.netty.util.concurrent.Promise;
-import java.util.Collection;
+import java.util.Set;
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpression;
 import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.netconf.api.NetconfClientSessionPreferences;
+import org.opendaylight.netconf.api.NetconfDocumentedException;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
+import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
 import org.opendaylight.netconf.nettyutil.AbstractNetconfSessionNegotiator;
 import org.opendaylight.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
-import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
 import org.opendaylight.netconf.util.messages.NetconfMessageUtil;
 import org.opendaylight.netconf.util.xml.XMLNetconfUtil;
-import org.opendaylight.netconf.api.NetconfClientSessionPreferences;
-import org.opendaylight.netconf.api.NetconfDocumentedException;
-import org.opendaylight.netconf.api.NetconfMessage;
-import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -50,6 +52,8 @@ public class NetconfClientSessionNegotiator extends
 
     private static final String EXI_1_0_CAPABILITY_MARKER = "exi:1.0";
 
+    private static final Interner<Set<String>> INTERNER = Interners.newWeakInterner();
+
     protected NetconfClientSessionNegotiator(final NetconfClientSessionPreferences sessionPreferences,
                                              final Promise<NetconfClientSession> promise,
                                              final Channel channel,
@@ -134,13 +138,14 @@ public class NetconfClientSessionNegotiator extends
 
     @Override
     protected NetconfClientSession getSession(final NetconfClientSessionListener sessionListener, final Channel channel,
-            final NetconfHelloMessage message) throws NetconfDocumentedException {
-        long sessionId = extractSessionId(message.getDocument());
+                                              final NetconfHelloMessage message) throws NetconfDocumentedException {
+        final long sessionId = extractSessionId(message.getDocument());
 
         // Copy here is important: it disconnects the strings from the document
-        Collection<String> capabilities = ImmutableList.copyOf(NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument()));
+        Set<String> capabilities = ImmutableSet.copyOf(NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument()));
+
+        capabilities = INTERNER.intern(capabilities);
 
-        // FIXME: scalability: we could instantiate a cache to share the same collections
         return new NetconfClientSession(sessionListener, channel, sessionId, capabilities);
     }
 
index 01c50c11e8269a51fc3992ed53e8d9c43b44506b..9632d176af12e0345cdda287a79293503928436a 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.netconf.client;
 
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertNotEquals;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.anyString;
@@ -18,6 +21,7 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelHandler;
@@ -31,20 +35,23 @@ import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timer;
 import io.netty.util.concurrent.GenericFutureListener;
 import io.netty.util.concurrent.Promise;
+import java.io.InputStream;
 import java.util.Set;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.internal.util.collections.Sets;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.netconf.api.NetconfClientSessionPreferences;
 import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
+import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
 import org.opendaylight.netconf.nettyutil.handler.ChunkedFramingMechanismEncoder;
 import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToHelloMessageDecoder;
 import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
 import org.opendaylight.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
-import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
-import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.netconf.util.messages.NetconfMessageUtil;
 import org.opendaylight.netconf.util.test.XmlFileLoader;
 import org.openexi.proc.common.EXIOptions;
 import org.w3c.dom.Document;
@@ -131,6 +138,19 @@ public class NetconfClientSessionNegotiatorTest {
         return new NetconfClientSessionNegotiator(preferences, promise, channel, timer, sessionListener, timeout);
     }
 
+    private NetconfHelloMessage createHelloMsg(final String name) throws Exception {
+        final InputStream stream = NetconfClientSessionNegotiatorTest.class.getResourceAsStream(name);
+        final Document doc = XmlUtil.readXmlToDocument(stream);
+
+        return new NetconfHelloMessage(doc);
+    }
+
+    private Set<String> createCapabilities(String name) throws Exception {
+        NetconfHelloMessage hello = createHelloMsg(name);
+
+        return ImmutableSet.copyOf(NetconfMessageUtil.extractCapabilitiesFromHello(hello.getDocument()));
+    }
+
     @Test
     public void testNetconfClientSessionNegotiator() throws Exception {
         Promise promise = mock(Promise.class);
@@ -175,4 +195,28 @@ public class NetconfClientSessionNegotiatorTest {
         // two calls for exiMessage, 2 for hello message
         verify(pipeline, times(4)).replace(anyString(), anyString(), any(ChannelHandler.class));
     }
+
+    @Test
+    public void testNetconfClientSessionNegotiatorGetCached() throws Exception {
+        Promise promise = mock(Promise.class);
+        doReturn(promise).when(promise).setSuccess(anyObject());
+        NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
+        NetconfClientSessionNegotiator negotiator = createNetconfClientSessionNegotiator(promise, null);
+
+        Set<String> set =  createCapabilities("/helloMessage3.xml");
+
+        final Set<String> cachedS1 = (Set<String>) negotiator.getSession(sessionListener,channel,createHelloMsg("/helloMessage1.xml")).getServerCapabilities();
+
+        //helloMessage2 and helloMessage3 are the same with different order
+        final Set<String> cachedS2 = (Set<String>) negotiator.getSession(sessionListener,channel,createHelloMsg("/helloMessage2.xml")).getServerCapabilities();
+        final Set<String> cachedS3 = (Set<String>) negotiator.getSession(sessionListener,channel,createHelloMsg("/helloMessage3.xml")).getServerCapabilities();
+
+        assertEquals(cachedS3, set);
+        assertNotEquals(cachedS1, set);
+        assertEquals(cachedS2, set);
+        assertEquals(cachedS3, cachedS2);
+        assertNotEquals(cachedS3, cachedS1);
+        assertNotEquals(cachedS2, cachedS1);
+        assertTrue(cachedS2 == cachedS3);
+    }
 }
diff --git a/netconf/netconf-client/src/test/resources/helloMessage1.xml b/netconf/netconf-client/src/test/resources/helloMessage1.xml
new file mode 100644 (file)
index 0000000..9cc3feb
--- /dev/null
@@ -0,0 +1,94 @@
+<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <capabilities>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24</capability>
+        <capability>urn:ietf:params:xml:ns:yang:iana-if-type?module=iana-if-type&amp;revision=2014-05-08</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-interfaces?module=ietf-interfaces&amp;revision=2014-05-08</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible?module=threadpool-impl-flexible&amp;revision=2013-12-01</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher?module=odl-netconfig-client-cfg&amp;revision=2014-04-08</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification?module=netconf-northbound-notification&amp;revision=2015-08-06</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl?module=netconf-northbound-impl&amp;revision=2015-01-12</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification:impl?module=netconf-northbound-notification-impl&amp;revision=2015-08-07</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:concurrent-data-broker?module=odl-concurrent-data-broker-cfg&amp;revision=2014-11-24</capability>
+        <capability>urn:TBD:params:xml:ns:yang:nt:l3-unicast-igp-topology?module=l3-unicast-igp-topology&amp;revision=2013-10-21</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:topology:shared:schema:repository?module=shared-schema-repository&amp;revision=2015-07-27</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:cluster:admin?module=cluster-admin&amp;revision=2015-10-13</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:general-entity?module=general-entity&amp;revision=2015-08-20</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&amp;revision=2013-07-09</capability>
+        <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&amp;revision=2013-06-17</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-network-topology?module=ietf-network-topology&amp;revision=2015-06-08</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?module=ietf-netconf-notifications&amp;revision=2012-02-06</capability>
+        <capability>urn:TBD:params:xml:ns:yang:ospf-topology?module=ospf-topology&amp;revision=2013-10-21</capability>
+        <capability>config:aaa:authn:netconf:plugin?module=aaa-authn-netconf-plugin&amp;revision=2015-07-15</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:auth?module=netconf-auth&amp;revision=2015-07-15</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store?module=opendaylight-operational-dom-datastore&amp;revision=2014-06-17</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ospf-topology?module=ospf-topology&amp;revision=2013-07-12</capability>
+        <capability>urn:ietf:params:netconf:capability:exi:1.0</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper?module=netconf-northbound-mapper&amp;revision=2015-01-14</capability>
+        <capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&amp;revision=2011-06-01</capability>
+        <capability>urn:TBD:params:xml:ns:yang:network-topology?module=network-topology&amp;revision=2013-10-21</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl?module=shutdown-impl&amp;revision=2013-12-18</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:topology?module=netconf-topology&amp;revision=2015-07-27</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&amp;revision=2013-04-05</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2013-07-15</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh?module=netconf-northbound-ssh&amp;revision=2015-01-14</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:shutdown?module=shutdown&amp;revision=2013-12-18</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:aaa:credential-store?module=credential-store&amp;revision=2015-02-26</capability>
+        <capability>urn:TBD:params:xml:ns:yang:network-topology?module=network-topology&amp;revision=2013-07-12</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:pingpong?module=opendaylight-pingpong-broker&amp;revision=2014-11-07</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&amp;revision=2013-11-07</capability>
+        <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-restconf?module=ietf-restconf&amp;revision=2013-10-19</capability>
+        <capability>urn:opendaylight:netconf-node-inventory?module=netconf-node-inventory&amp;revision=2014-01-08</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:entity-ownership-service?module=opendaylight-entity-ownership-service&amp;revision=2015-08-10</capability>
+        <capability>urn:TBD:params:xml:ns:yang:nt:l3-unicast-igp-topology?module=l3-unicast-igp-topology&amp;revision=2013-07-12</capability>
+        <capability>urn:TBD:params:xml:ns:yang:network:ted?module=ted&amp;revision=2013-07-12</capability>
+        <capability>urn:TBD:params:xml:ns:yang:network:isis-topology?module=isis-topology&amp;revision=2013-10-21</capability>
+        <capability>config:aaa:authn:idmlight?module=aaa-idmlight&amp;revision=2015-12-04</capability>
+        <capability>urn:TBD:params:xml:ns:yang:network:isis-topology?module=isis-topology&amp;revision=2013-07-12</capability>
+        <capability>config:aaa:authn:h2:store?module=aaa-h2-store&amp;revision=2015-11-28</capability>
+        <capability>urn:TBD:params:xml:ns:yang:network:ted?module=ted&amp;revision=2013-10-21</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp?module=netconf-northbound-tcp&amp;revision=2015-04-23</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology?module=clustered-netconf-topology&amp;revision=2015-11-04</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:clustering:entity-owners?module=entity-owners&amp;revision=2015-08-04</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:fixed?module=threadpool-impl-fixed&amp;revision=2013-12-01</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:actor-system-provider:service?module=actor-system-provider-service&amp;revision=2015-10-05</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&amp;revision=2015-08-03</capability>
+        <capability>urn:opendaylight:netconf-node-topology?module=netconf-node-topology&amp;revision=2015-01-14</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:distributed-entity-ownership-service?module=distributed-entity-ownership-service&amp;revision=2015-08-10</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider?module=opendaylight-inmemory-datastore-provider&amp;revision=2014-06-17</capability>
+        <capability>urn:opendaylight:inventory?module=opendaylight-inventory&amp;revision=2013-08-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&amp;revision=2013-11-19</capability>
+        <capability>urn:ietf:params:xml:ns:netconf:notification:1.0?module=notifications&amp;revision=2008-07-14</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:cluster-admin-provider?module=cluster-admin-provider&amp;revision=2015-10-13</capability>
+        <capability>urn:ietf:params:xml:ns:netmod:notification?module=nc-notifications&amp;revision=2008-07-14</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension?module=ietf-netconf-monitoring-extension&amp;revision=2013-12-10</capability>
+        <capability>urn:ietf:params:netconf:base:1.1</capability>
+        <capability>urn:ietf:params:netconf:base:1.0</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:distributed-datastore-provider?module=distributed-datastore-provider&amp;revision=2014-06-12</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:remote-rpc-connector?module=remote-rpc-connector&amp;revision=2014-07-07</capability>
+        <capability>urn:ietf:params:netconf:capability:notification:1.0</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store?module=opendaylight-config-dom-datastore&amp;revision=2014-06-17</capability>
+        <capability>urn:ietf:params:xml:ns:yang:iana-afn-safi?module=iana-afn-safi&amp;revision=2013-07-04</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf?module=odl-netconf-cfg&amp;revision=2014-04-08</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound?module=netconf-northbound&amp;revision=2015-01-14</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled?module=threadpool-impl-scheduled&amp;revision=2013-12-01</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:actor-system-provider:impl?module=actor-system-provider-impl&amp;revision=2015-10-05</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&amp;revision=2013-04-09</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-network?module=ietf-network&amp;revision=2015-06-08</capability>
+        <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&amp;revision=2013-08-27</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:protocol:framework?module=protocol-framework&amp;revision=2014-03-13</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2013-07-15</capability>
+    </capabilities>
+    <session-id>1</session-id>
+</hello>
+
diff --git a/netconf/netconf-client/src/test/resources/helloMessage2.xml b/netconf/netconf-client/src/test/resources/helloMessage2.xml
new file mode 100644 (file)
index 0000000..e95f5bb
--- /dev/null
@@ -0,0 +1,14 @@
+<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <capabilities>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension?module=ietf-netconf-monitoring-extension&amp;revision=2013-12-10</capability>
+        <capability>urn:ietf:params:netconf:capability:exi:1.0</capability>
+        <capability>http://example.com/system?module=empolyees&amp;revision=2007-06-09</capability>
+        <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24</capability>
+        <capability>urn:ietf:params:netconf:base:1.1</capability>
+        <capability>urn:ietf:params:netconf:base:1.0</capability>
+    </capabilities>
+    <session-id>1</session-id>
+</hello>
diff --git a/netconf/netconf-client/src/test/resources/helloMessage3.xml b/netconf/netconf-client/src/test/resources/helloMessage3.xml
new file mode 100644 (file)
index 0000000..6ee373d
--- /dev/null
@@ -0,0 +1,14 @@
+<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <capabilities>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension?module=ietf-netconf-monitoring-extension&amp;revision=2013-12-10</capability>
+        <capability>urn:ietf:params:netconf:capability:exi:1.0</capability>
+        <capability>http://example.com/system?module=empolyees&amp;revision=2007-06-09</capability>
+        <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24</capability>
+        <capability>urn:ietf:params:netconf:base:1.0</capability>
+        <capability>urn:ietf:params:netconf:base:1.1</capability>
+    </capabilities>
+    <session-id>1</session-id>
+</hello>