BUG-693 Config module for netconf client dispatcher. 25/6025/7
authorMaros Marsalek <mmarsale@cisco.com>
Wed, 23 Apr 2014 13:12:47 +0000 (15:12 +0200)
committerMaros Marsalek <mmarsale@cisco.com>
Mon, 5 May 2014 07:29:02 +0000 (09:29 +0200)
netconf/
NetconfClientDispatcher and NetconfSSHClientDispatcher merged into NetconfClientDispatcherImpl.
Introduced NetconfClientConfiguration to contain all configuration attributes for netconf clients.
Introduced interface for NetconfClientDispatchers.
Removed NetconfITSecureTest since it did not test secure connection.

config/
Added netconf-config-api maven module, which contains service definition of client-dispatcher.
Added netconf-config-dispatcher maven module, which contains config module for client-dispatcher.

md-sal/
Updated configuration for sal-netconf-connector with client dispatcher dependency (backwards compatibility preserved).

Change-Id: I05e784af6a9b8e11fad21d3bad0311c110754d31
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
38 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/config/netconf-config-dispatcher/pom.xml [new file with mode: 0644]
opendaylight/config/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModule.java [new file with mode: 0644]
opendaylight/config/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleFactory.java [new file with mode: 0644]
opendaylight/config/netconf-config-dispatcher/src/main/yang/odl-netconf-cfg.yang [new file with mode: 0644]
opendaylight/config/netconf-config-dispatcher/src/main/yang/odl-netconfig-client-cfg.yang [new file with mode: 0644]
opendaylight/config/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf-connector.xml [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/04-netconf-connector.xml [deleted file]
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java
opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang
opendaylight/netconf/netconf-client/pom.xml
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java [deleted file]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcherImpl.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfSshClientDispatcher.java [deleted file]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SshClientChannelInitializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/TcpClientChannelInitializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfClientConfiguration.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfClientConfigurationBuilder.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfReconnectingClientConfiguration.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfReconnectingClientConfigurationBuilder.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/test/TestingNetconfClient.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/HardcodedYangStoreService.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java

index e089166..8588a60 100644 (file)
         <artifactId>netconf-client</artifactId>
         <version>${netconf.version}</version>
       </dependency>
+
+      <!--Netconf config-->
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>netconf-config-dispatcher</artifactId>
+        <version>${netconf.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>netconf-impl</artifactId>
diff --git a/opendaylight/config/netconf-config-dispatcher/pom.xml b/opendaylight/config/netconf-config-dispatcher/pom.xml
new file mode 100644 (file)
index 0000000..65ebdaf
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2013 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-plugin-parent</artifactId>
+    <version>0.2.5-SNAPSHOT</version>
+    <relativePath>../config-plugin-parent</relativePath>
+  </parent>
+
+  <artifactId>netconf-config-dispatcher</artifactId>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-client</artifactId>
+      <version>${netconf.version}</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>org.opendaylight.controller.config.yang.config.netconf,
+                      org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.netconf.rev140408,</Export-Package>
+            <Import-Package>*</Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/opendaylight/config/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModule.java b/opendaylight/config/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModule.java
new file mode 100644 (file)
index 0000000..344ef3d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 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.controller.config.yang.config.netconf.client.dispatcher;
+
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+
+/**
+*
+*/
+public final class NetconfClientDispatcherModule extends org.opendaylight.controller.config.yang.config.netconf.client.dispatcher.AbstractNetconfClientDispatcherModule
+ {
+
+    public NetconfClientDispatcherModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NetconfClientDispatcherModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+            NetconfClientDispatcherModule oldModule, java.lang.AutoCloseable oldInstance) {
+
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    protected void customValidation(){
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return new NetconfClientDispatcherImpl(getBossThreadGroupDependency(), getWorkerThreadGroupDependency(), getTimerDependency());
+    }
+}
diff --git a/opendaylight/config/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleFactory.java b/opendaylight/config/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleFactory.java
new file mode 100644 (file)
index 0000000..cfd4ef6
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 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.controller.config.yang.config.netconf.client.dispatcher;
+
+/**
+*
+*/
+public class NetconfClientDispatcherModuleFactory extends org.opendaylight.controller.config.yang.config.netconf.client.dispatcher.AbstractNetconfClientDispatcherModuleFactory
+{
+
+
+}
diff --git a/opendaylight/config/netconf-config-dispatcher/src/main/yang/odl-netconf-cfg.yang b/opendaylight/config/netconf-config-dispatcher/src/main/yang/odl-netconf-cfg.yang
new file mode 100644 (file)
index 0000000..16c2bcb
--- /dev/null
@@ -0,0 +1,31 @@
+// vi: set smarttab et sw=4 tabstop=4:
+module odl-netconf-cfg {
+
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf";
+    prefix "cfg-net";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "This module contains the base YANG definitions for
+        netconf related services.
+
+        Copyright (c)2013 Cisco Systems, Inc. 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";
+
+    revision "2014-04-08" {
+        description
+            "Initial revision.";
+    }
+
+    identity netconf-client-dispatcher {
+
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.netconf.client.NetconfClientDispatcher";
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/config/netconf-config-dispatcher/src/main/yang/odl-netconfig-client-cfg.yang b/opendaylight/config/netconf-config-dispatcher/src/main/yang/odl-netconfig-client-cfg.yang
new file mode 100644 (file)
index 0000000..e00bdeb
--- /dev/null
@@ -0,0 +1,64 @@
+// vi: set smarttab et sw=4 tabstop=4:
+module odl-netconfig-client-cfg {
+
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher";
+    prefix "cfg-net-client";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
+    import netty {prefix netty; }
+
+    description
+        "This module contains the base YANG definitions for
+        netconf-client-dispatcher implementation.
+
+        Copyright (c)2013 Cisco Systems, Inc. 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";
+
+    revision "2014-04-08" {
+        description
+            "Initial revision.";
+    }
+
+    identity netconf-client-dispatcher {
+            base config:module-type;
+            config:provided-service cfg-net:netconf-client-dispatcher;
+            config:java-name-prefix NetconfClientDispatcher;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case netconf-client-dispatcher {
+            when "/config:modules/config:module/config:type = 'netconf-client-dispatcher'";
+
+            container boss-thread-group {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-threadgroup;
+                    }
+                }
+            }
+
+            container worker-thread-group {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-threadgroup;
+                    }
+                }
+            }
+
+            container timer {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-timer;
+                    }
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file
index bd2924a..8bf9a0f 100644 (file)
@@ -38,6 +38,7 @@
     <module>yang-test-plugin</module>
     <module>shutdown-api</module>
     <module>shutdown-impl</module>
+    <module>netconf-config-dispatcher</module>
     <module>config-module-archetype</module>
   </modules>
 
index f9985cb..648c59e 100644 (file)
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-client</artifactId>
         </dependency>
+
+        <!--Netconf config-->
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>netconf-config-dispatcher</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-impl</artifactId>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf-connector.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf-connector.xml
new file mode 100644 (file)
index 0000000..fcbec19
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2013 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
+-->
+<snapshot>
+  <configuration>
+    <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+      <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+        <!-- Netconf dispatcher to be used by all netconf-connectors --> 
+        <module>
+          <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">prefix:netconf-client-dispatcher</type>
+          <name>global-netconf-dispatcher</name>
+          <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
+            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
+            <name>global-boss-group</name>
+          </boss-thread-group>
+          <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
+            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
+            <name>global-worker-group</name>
+          </worker-thread-group>
+          <timer xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
+            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
+            <name>global-timer</name>
+          </timer>
+        </module>  
+
+        <!-- Loopback connection to netconf server in controller using netconf-connector -->
+        <module>
+          <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
+          <name>controller-config</name>
+          <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
+          <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1830</port>
+          <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
+          <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
+          <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
+          <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
+            <name>global-event-executor</name>
+          </event-executor>
+          <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
+            <name>dom-broker</name>
+          </dom-registry>
+          <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
+            <name>global-netconf-dispatcher</name>
+          </client-dispatcher>
+        </module>
+      </modules>
+
+      <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+        <service>
+          <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
+          <instance>
+            <name>global-netconf-dispatcher</name>
+            <provider>/modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher']</provider>
+          </instance>
+        </service>
+      </services>
+
+    </data>
+  </configuration>
+  <required-capabilities>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&amp;revision=2013-10-28</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher?module=odl-netconfig-client-cfg&amp;revision=2014-04-08</capability>
+  </required-capabilities>
+</snapshot>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/04-netconf-connector.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/04-netconf-connector.xml
deleted file mode 100644 (file)
index 8143a38..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 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
--->
-<snapshot>
-  <configuration>
-    <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-      <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-    <module>
-      <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
-      <name>controller-config</name>
-      <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1830</port>
-      <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
-      <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
-        <name>global-worker-group</name>
-      </worker-thread-group>
-      <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
-      <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
-      <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
-        <name>global-event-executor</name>
-      </event-executor>
-      <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
-      <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
-        <name>global-boss-group</name>
-      </boss-thread-group>
-      <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
-        <name>dom-broker</name>
-      </dom-registry>
-    </module>
-      </modules>
-    </data>
-  </configuration>
-  <required-capabilities>
-      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&amp;revision=2013-10-28</capability>
-  </required-capabilities>
-</snapshot>
index 27d320f..ef485bb 100644 (file)
       <artifactId>netconf-client</artifactId>
       <version>${netconf.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-config-dispatcher</artifactId>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>sal-common-util</artifactId>
index ddaf6ea..6e92422 100644 (file)
@@ -9,7 +9,8 @@ package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
 
 import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkCondition;
 import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkNotNull;
-import io.netty.channel.EventLoopGroup;
+
+import io.netty.util.HashedWheelTimer;
 import io.netty.util.concurrent.GlobalEventExecutor;
 
 import java.io.File;
@@ -20,10 +21,12 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.NetconfSshClientDispatcher;
-import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
 import org.opendaylight.controller.netconf.util.handler.ssh.authentication.LoginPassword;
 import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceListener;
 import org.opendaylight.protocol.framework.ReconnectStrategy;
 import org.opendaylight.protocol.framework.TimedReconnectStrategy;
 import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider;
@@ -69,6 +72,18 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         checkNotNull(getBetweenAttemptsTimeoutMillis(), betweenAttemptsTimeoutMillisJmxAttribute);
         checkCondition(getBetweenAttemptsTimeoutMillis() > 0, "must be > 0", betweenAttemptsTimeoutMillisJmxAttribute);
 
+        // FIXME BUG-944 remove backwards compatibility
+        if(getClientDispatcher() == null) {
+            checkCondition(getBossThreadGroup() != null, "Client dispatcher was not set, thread groups have to be set instead", bossThreadGroupJmxAttribute);
+            checkCondition(getWorkerThreadGroup() != null, "Client dispatcher was not set, thread groups have to be set instead", workerThreadGroupJmxAttribute);
+        }
+
+        // Check username + password in case of ssh
+        if(getTcpOnly() == false) {
+            checkNotNull(getUsername(), usernameJmxAttribute);
+            checkNotNull(getPassword(), passwordJmxAttribute);
+        }
+
     }
 
     @Override
@@ -76,42 +91,13 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
 
         getDomRegistryDependency();
         NetconfDevice device = new NetconfDevice(getIdentifier().getInstanceName());
-        String addressValue = getAddress();
-
-        Long connectionAttempts;
-        if (getMaxConnectionAttempts() != null && getMaxConnectionAttempts() > 0) {
-            connectionAttempts = getMaxConnectionAttempts();
-        } else {
-            logger.trace("Setting {} on {} to infinity", maxConnectionAttemptsJmxAttribute, this);
-            connectionAttempts = null;
-        }
-        long clientConnectionTimeoutMillis = getConnectionTimeoutMillis();
-        /*
-         * Uncomment after Switch to IP Address
-        if(getAddress().getIpv4Address() != null) {
-            addressValue = getAddress().getIpv4Address().getValue();
-        } else {
-            addressValue = getAddress().getIpv6Address().getValue();
-        }
-         */
-        double sleepFactor = 1.0;
-        int minSleep = 1000;
-        Long maxSleep = null;
-        Long deadline = null;
-        ReconnectStrategy strategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, getBetweenAttemptsTimeoutMillis(),
-                minSleep, sleepFactor, maxSleep, connectionAttempts, deadline);
-
-        device.setReconnectStrategy(strategy);
-
-        InetAddress addr = InetAddresses.forString(addressValue);
-        InetSocketAddress socketAddress = new InetSocketAddress(addr , getPort().intValue());
 
+        device.setClientConfig(getClientConfig(device));
 
         device.setProcessingExecutor(getGlobalProcessingExecutor());
 
-        device.setSocketAddress(socketAddress);
         device.setEventExecutor(getEventExecutorDependency());
-        device.setDispatcher(createDispatcher(clientConnectionTimeoutMillis));
+        device.setDispatcher(getClientDispatcher() == null ? createDispatcher() : getClientDispatcherDependency());
         device.setSchemaSourceProvider(getGlobalNetconfSchemaProvider(bundleContext));
 
         getDomRegistryDependency().registerProvider(device, bundleContext);
@@ -120,12 +106,7 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
     }
 
     private ExecutorService getGlobalProcessingExecutor() {
-        if(GLOBAL_PROCESSING_EXECUTOR == null) {
-
-            GLOBAL_PROCESSING_EXECUTOR = Executors.newCachedThreadPool();
-
-        }
-        return GLOBAL_PROCESSING_EXECUTOR;
+        return GLOBAL_PROCESSING_EXECUTOR == null ? Executors.newCachedThreadPool() : GLOBAL_PROCESSING_EXECUTOR;
     }
 
     private synchronized AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider(BundleContext bundleContext) {
@@ -139,18 +120,64 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         return GLOBAL_NETCONF_SOURCE_PROVIDER;
     }
 
-    private NetconfClientDispatcher createDispatcher(long clientConnectionTimeoutMillis) {
-        EventLoopGroup bossGroup = getBossThreadGroupDependency();
-        EventLoopGroup workerGroup = getWorkerThreadGroupDependency();
-        if(getTcpOnly()) {
-            return new NetconfClientDispatcher( bossGroup, workerGroup, clientConnectionTimeoutMillis);
-        } else {
-            AuthenticationHandler authHandler = new LoginPassword(getUsername(),getPassword());
-            return new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup, clientConnectionTimeoutMillis);
-        }
+    // FIXME BUG-944 remove backwards compatibility
+    /**
+     * @deprecated Use getClientDispatcherDependency method instead to retrieve injected dispatcher.
+     * This one creates new instance of NetconfClientDispatcher and will be removed in near future.
+     */
+    @Deprecated
+    private NetconfClientDispatcher createDispatcher() {
+        return new NetconfClientDispatcherImpl(getBossThreadGroupDependency(), getWorkerThreadGroupDependency(), new HashedWheelTimer());
     }
 
     public void setBundleContext(BundleContext bundleContext) {
         this.bundleContext = bundleContext;
     }
+
+    public NetconfClientConfiguration getClientConfig(final NetconfDevice device) {
+        InetSocketAddress socketAddress = getSocketAddress();
+        ReconnectStrategy strategy = getReconnectStrategy();
+        long clientConnectionTimeoutMillis = getConnectionTimeoutMillis();
+
+        return NetconfClientConfigurationBuilder.create()
+        .withAddress(socketAddress)
+        .withConnectionTimeoutMillis(clientConnectionTimeoutMillis)
+        .withReconnectStrategy(strategy)
+        .withSessionListener(new NetconfDeviceListener(device))
+        .withAuthHandler(new LoginPassword(getUsername(),getPassword()))
+        .withProtocol(getTcpOnly() ?
+                NetconfClientConfiguration.NetconfClientProtocol.TCP :
+                NetconfClientConfiguration.NetconfClientProtocol.SSH)
+        .build();
+    }
+
+    private ReconnectStrategy getReconnectStrategy() {
+        Long connectionAttempts;
+        if (getMaxConnectionAttempts() != null && getMaxConnectionAttempts() > 0) {
+            connectionAttempts = getMaxConnectionAttempts();
+        } else {
+            logger.trace("Setting {} on {} to infinity", maxConnectionAttemptsJmxAttribute, this);
+            connectionAttempts = null;
+        }
+        double sleepFactor = 1.0;
+        int minSleep = 1000;
+        Long maxSleep = null;
+        Long deadline = null;
+
+        return new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, getBetweenAttemptsTimeoutMillis(),
+                minSleep, sleepFactor, maxSleep, connectionAttempts, deadline);
+    }
+
+    private InetSocketAddress getSocketAddress() {
+        /*
+         * Uncomment after Switch to IP Address
+        if(getAddress().getIpv4Address() != null) {
+            addressValue = getAddress().getIpv4Address().getValue();
+        } else {
+            addressValue = getAddress().getIpv6Address().getValue();
+        }
+         */
+        InetAddress inetAddress = InetAddresses.forString(getAddress());
+        return new InetSocketAddress(inetAddress, getPort().intValue());
+    }
 }
index aa5c6f4..e3f8649 100644 (file)
@@ -21,6 +21,7 @@ import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.toF
 import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.toRpcMessage;
 import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.wrap;
 
+import com.google.common.base.Preconditions;
 import java.io.InputStream;
 import java.net.InetSocketAddress;
 import java.net.URI;
@@ -38,6 +39,7 @@ import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
 import org.opendaylight.controller.sal.core.api.Provider;
@@ -121,6 +123,7 @@ public class NetconfDevice implements Provider, //
 
     private boolean rollbackSupported;
 
+    private NetconfClientConfiguration clientConfig;
 
     public NetconfDevice(String name) {
         this.name = name;
@@ -134,11 +137,12 @@ public class NetconfDevice implements Provider, //
         checkState(schemaSourceProvider != null, "Schema Source Provider must be set.");
         checkState(eventExecutor != null, "Event executor must be set.");
 
-        listener = new NetconfDeviceListener(this);
+        Preconditions.checkArgument(clientConfig.getSessionListener() instanceof NetconfDeviceListener);
+        listener = (NetconfDeviceListener) clientConfig.getSessionListener();
 
         logger.info("Starting NETCONF Client {} for address {}", name, socketAddress);
 
-        dispatcher.createClient(socketAddress, listener, reconnectStrategy);
+        dispatcher.createClient(clientConfig);
     }
 
     Optional<SchemaContext> getSchemaContext() {
@@ -464,6 +468,11 @@ public class NetconfDevice implements Provider, //
     public void setDispatcher(final NetconfClientDispatcher dispatcher) {
         this.dispatcher = dispatcher;
     }
+
+    public void setClientConfig(final NetconfClientConfiguration clientConfig) {
+        this.clientConfig = clientConfig;
+    }
+
 }
 
 class NetconfDeviceSchemaContextProvider {
index 1dfc3b4..68667f0 100644 (file)
@@ -41,8 +41,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 
-class NetconfDeviceListener implements NetconfClientSessionListener {
-
+public class NetconfDeviceListener implements NetconfClientSessionListener {
     private static final class Request {
         final UncancellableFuture<RpcResult<CompositeNode>> future;
         final NetconfMessage request;
index abd935d..31c6bd0 100644 (file)
@@ -59,7 +59,7 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String>
                     return Optional.of(schemaBody);
                 }
             }
-            logger.warn("YANG shcema was not successfully retrieved.");
+            logger.warn("YANG shcema was not successfully retrieved. Errors: {}", schemaReply.getErrors());
         } catch (InterruptedException | ExecutionException e) {
             logger.warn("YANG shcema was not successfully retrieved.", e);
         }
index f0fa452..d4dad11 100644 (file)
@@ -7,10 +7,11 @@ module odl-sal-netconf-connector-cfg {
        import threadpool {prefix th;}
        import netty {prefix netty;}
        import opendaylight-md-sal-dom {prefix dom;}
+    import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
 
     description
         "Service definition for Binding Aware MD-SAL.";
+
     revision "2013-10-28" {
         description
             "Initial revision";
@@ -26,7 +27,7 @@ module odl-sal-netconf-connector-cfg {
         leaf address {
             type string;
         }
-    
+
         leaf port {
             type uint32;
         }
@@ -36,7 +37,7 @@ module odl-sal-netconf-connector-cfg {
     augment "/config:modules/config:module/config:configuration" {
         case sal-netconf-connector {
             when "/config:modules/config:module/config:type = 'sal-netconf-connector'";
-            
+
             leaf address {
                 type string;
             }
@@ -44,7 +45,7 @@ module odl-sal-netconf-connector-cfg {
             leaf port {
                 type uint32;
             }
-            
+
             leaf tcp-only {
                 type boolean;
             }
@@ -52,10 +53,11 @@ module odl-sal-netconf-connector-cfg {
             leaf username {
                 type string;
             }
-            
+
             leaf password {
                 type string;
             }
+
             container dom-registry {
                 uses config:service-ref {
                     refine type {
@@ -65,17 +67,25 @@ module odl-sal-netconf-connector-cfg {
                 }
             }
 
+            // FIXME BUG-944 remove backwards compatibility
+            // Deprecated, replaced by client dispatcher.
+            // This dependency will be removed in near future and all configurations of netconf-connector need to be changed to use dispatcher dependency.
             container boss-thread-group {
                 uses config:service-ref {
                     refine type {
+                        mandatory false;
                         config:required-identity netty:netty-threadgroup;
                     }
                 }
             }
 
+            // FIXME BUG-944 remove backwards compatibility
+            // Deprecated, replaced by client dispatcher.
+            // This dependency will be removed in near future and all configurations of netconf-connector need to be changed to use dispatcher dependency.
             container worker-thread-group {
                 uses config:service-ref {
                     refine type {
+                        mandatory false;
                         config:required-identity netty:netty-threadgroup;
                     }
                 }
@@ -89,6 +99,16 @@ module odl-sal-netconf-connector-cfg {
                 }
             }
 
+            // Replaces thread group dependencies
+            container client-dispatcher {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity cfg-net:netconf-client-dispatcher;
+                    }
+                }
+            }
+
             leaf connection-timeout-millis {
                 description "Specifies timeout in milliseconds after which connection must be established.";
                 type uint32;
@@ -101,7 +121,6 @@ module odl-sal-netconf-connector-cfg {
                 default 0; // retry forever
             }
 
-
             leaf between-attempts-timeout-millis {
                 description "Timeout in milliseconds to wait between connection attempts.";
                 type uint16;
index fd44315..ce77fdc 100644 (file)
@@ -41,7 +41,7 @@
         <artifactId>maven-bundle-plugin</artifactId>
         <configuration>
           <instructions>
-            <Export-Package>org.opendaylight.controller.netconf.client,</Export-Package>
+            <Export-Package>org.opendaylight.controller.netconf.client.*,</Export-Package>
             <Import-Package>com.google.common.base,
                             com.google.common.collect,
                             io.netty.channel,
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java
deleted file mode 100644 (file)
index d98211d..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2013 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.controller.netconf.client;
-
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GlobalEventExecutor;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.TimedReconnectStrategy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.Sets;
-
-/**
- * @deprecated Use {@link NetconfClientDispatcher.createClient()} or {@link NetconfClientDispatcher.createReconnectingClient()} instead.
- */
-@Deprecated
-public class NetconfClient implements Closeable {
-
-    private static final Logger logger = LoggerFactory.getLogger(NetconfClient.class);
-
-    public static final int DEFAULT_CONNECT_TIMEOUT = 5000;
-    private final NetconfClientDispatcher dispatch;
-    private final String label;
-    private final NetconfClientSession clientSession;
-    private final NetconfClientSessionListener sessionListener;
-    private final long sessionId;
-    private final InetSocketAddress address;
-
-    // TODO test reconnecting constructor
-    public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectionAttempts,
-            int attemptMsTimeout, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
-        this(clientLabelForLogging, address, getReconnectStrategy(connectionAttempts, attemptMsTimeout),
-                netconfClientDispatcher);
-    }
-
-    private NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
-        this.label = clientLabelForLogging;
-        dispatch = netconfClientDispatcher;
-        sessionListener = new SimpleNetconfClientSessionListener();
-        Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strat);
-        this.address = address;
-        clientSession = get(clientFuture);
-        this.sessionId = clientSession.getSessionId();
-    }
-
-    private NetconfClientSession get(Future<NetconfClientSession> clientFuture) throws InterruptedException {
-        try {
-            return clientFuture.get();
-        } catch (CancellationException e) {
-            throw new RuntimeException("Cancelling " + this, e);
-        } catch (ExecutionException e) {
-            throw new IllegalStateException("Unable to create " + this, e);
-        }
-    }
-
-    public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
-        return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher);
-    }
-
-    public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address,
-            ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException {
-        return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher,listener);
-    }
-
-    public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs,
-            NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
-        this(clientLabelForLogging, address,
-                new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, connectTimeoutMs), netconfClientDispatcher);
-    }
-
-    public NetconfClient(String clientLabelForLogging, InetSocketAddress address,
-            NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
-        this(clientLabelForLogging, address, new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
-                DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher);
-    }
-
-    public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy,
-            NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{
-        this.label = clientLabelForLogging;
-        dispatch = netconfClientDispatcher;
-        sessionListener = listener;
-        Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strategy);
-        this.address = address;
-        clientSession = get(clientFuture);
-        this.sessionId = clientSession.getSessionId();
-    }
-
-    public Future<NetconfMessage> sendRequest(NetconfMessage message) {
-        return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message);
-    }
-
-    /**
-     * @deprecated Use {@link sendRequest} instead
-     */
-    @Deprecated
-    public NetconfMessage sendMessage(NetconfMessage message) throws ExecutionException, InterruptedException, TimeoutException {
-        return sendMessage(message, 5, 1000);
-    }
-
-    /**
-     * @deprecated Use {@link sendRequest} instead
-     */
-    @Deprecated
-    public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) throws ExecutionException, InterruptedException, TimeoutException {
-        final Stopwatch stopwatch = new Stopwatch().start();
-
-        try {
-            return sendRequest(message).get(attempts * attemptMsDelay, TimeUnit.MILLISECONDS);
-        } finally {
-            stopwatch.stop();
-            logger.debug("Total time spent waiting for response from {}: {} ms", address, stopwatch.elapsed(TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        clientSession.close();
-    }
-
-    public NetconfClientDispatcher getNetconfClientDispatcher() {
-        return dispatch;
-    }
-
-    private static ReconnectStrategy getReconnectStrategy(int connectionAttempts, int attemptMsTimeout) {
-        return new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null,
-                Long.valueOf(connectionAttempts), null);
-    }
-
-    @Override
-    public String toString() {
-        final StringBuffer sb = new StringBuffer("NetconfClient{");
-        sb.append("label=").append(label);
-        sb.append(", sessionId=").append(sessionId);
-        sb.append('}');
-        return sb.toString();
-    }
-
-    public long getSessionId() {
-        return sessionId;
-    }
-
-    public Set<String> getCapabilities() {
-        Preconditions.checkState(clientSession != null, "Client was not initialized successfully");
-        return Sets.newHashSet(clientSession.getServerCapabilities());
-    }
-
-    public NetconfClientSession getClientSession() {
-        return clientSession;
-    }
-}
index c7c723c..37e2987 100644 (file)
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014 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.controller.netconf.client;
 
-import com.google.common.base.Optional;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.util.HashedWheelTimer;
 import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.Promise;
-import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.AbstractDispatcher;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Closeable;
-import java.net.InetSocketAddress;
-
-public class NetconfClientDispatcher extends AbstractDispatcher<NetconfClientSession, NetconfClientSessionListener> implements Closeable {
-
-    private static final Logger logger = LoggerFactory.getLogger(NetconfClientDispatcher.class);
-
-    private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
-    private final HashedWheelTimer timer;
-
-    public NetconfClientDispatcher(EventLoopGroup bossGroup, EventLoopGroup workerGroup,
-            long clientConnectionTimeoutMillis) {
-        super(bossGroup, workerGroup);
-        timer = new HashedWheelTimer();
-        this.negotiatorFactory = new NetconfClientSessionNegotiatorFactory(timer,
-                Optional.<NetconfHelloMessageAdditionalHeader> absent(), clientConnectionTimeoutMillis);
-    }
-
-    public NetconfClientDispatcher(EventLoopGroup bossGroup, EventLoopGroup workerGroup,
-            NetconfHelloMessageAdditionalHeader additionalHeader, long connectionTimeoutMillis) {
-        super(bossGroup, workerGroup);
-        timer = new HashedWheelTimer();
-        this.negotiatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.of(additionalHeader),
-                connectionTimeoutMillis);
-    }
-
-    public Future<NetconfClientSession> createClient(InetSocketAddress address,
-            final NetconfClientSessionListener sessionListener, ReconnectStrategy strat) {
-
-        return super.createClient(address, strat, new PipelineInitializer<NetconfClientSession>() {
-
-            @Override
-            public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
-                initialize(ch, promise);
-            }
-
-            private void initialize(SocketChannel ch, Promise<NetconfClientSession> promise) {
-                new ClientChannelInitializer(negotiatorFactory, sessionListener).initialize(ch, promise);
-            }
-        });
-    }
-
-    public Future<Void> createReconnectingClient(final InetSocketAddress address,
-            final NetconfClientSessionListener listener,
-            final ReconnectStrategyFactory connectStrategyFactory, final ReconnectStrategy reestablishStrategy) {
-        final ClientChannelInitializer init = new ClientChannelInitializer(negotiatorFactory, listener);
-
-        return super.createReconnectingClient(address, connectStrategyFactory, reestablishStrategy,
-                new PipelineInitializer<NetconfClientSession>() {
-            @Override
-            public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
-                init.initialize(ch, promise);
-            }
-        });
-    }
-
-    private static final class ClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
-
-        private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
-        private final NetconfClientSessionListener sessionListener;
-
-        private ClientChannelInitializer(NetconfClientSessionNegotiatorFactory negotiatorFactory,
-                NetconfClientSessionListener sessionListener) {
-            this.negotiatorFactory = negotiatorFactory;
-            this.sessionListener = sessionListener;
-        }
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
 
-        @Override
-        public void initialize(SocketChannel ch, Promise<NetconfClientSession> promise) {
-                super.initialize(ch,promise);
-        }
+public interface NetconfClientDispatcher {
 
-        @Override
-        protected void initializeSessionNegotiator(SocketChannel ch, Promise<NetconfClientSession> promise) {
-            ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER,  AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
-                    negotiatorFactory.getSessionNegotiator(
-                            new SessionListenerFactory<NetconfClientSessionListener>() {
-                                @Override
-                                public NetconfClientSessionListener getSessionListener() {
-                                    return sessionListener;
-                                }
-                            }, ch, promise));
-        }
-    }
+    /**
+     *
+     * Create netconf client. Network communication has to be set up based on network protocol specified in clientConfiguration
+     *
+     * @param clientConfiguration
+     * @return netconf client based on provided configuration
+     */
+    Future<NetconfClientSession> createClient(NetconfClientConfiguration clientConfiguration);
 
-    @Override
-    public void close() {
-        try {
-            timer.stop();
-        } catch (Exception e) {
-            logger.debug("Ignoring exception while closing {}", timer, e);
-        }
-    }
+    Future<Void> createReconnectingClient(NetconfReconnectingClientConfiguration clientConfiguration);
 }
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcherImpl.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcherImpl.java
new file mode 100644 (file)
index 0000000..bdebfa2
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013 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.controller.netconf.client;
+
+import java.io.Closeable;
+
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.protocol.framework.AbstractDispatcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.Promise;
+
+public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClientSession, NetconfClientSessionListener>
+        implements NetconfClientDispatcher, Closeable {
+
+    private static final Logger logger = LoggerFactory.getLogger(NetconfClientDispatcherImpl.class);
+
+    private final Timer timer;
+
+    public NetconfClientDispatcherImpl(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup, final Timer timer) {
+        super(bossGroup, workerGroup);
+        this.timer = timer;
+    }
+
+    @Override
+    public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
+        switch (clientConfiguration.getProtocol()) {
+        case TCP:
+            return createTcpClient(clientConfiguration);
+        case SSH:
+            return createSshClient(clientConfiguration);
+        }
+        throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
+    }
+
+    @Override
+    public Future<Void> createReconnectingClient(final NetconfReconnectingClientConfiguration clientConfiguration) {
+        switch (clientConfiguration.getProtocol()) {
+            case TCP: return createReconnectingTcpClient(clientConfiguration);
+            case SSH: return createReconnectingSshClient(clientConfiguration);
+            default: throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
+        }
+    }
+
+    private Future<NetconfClientSession> createTcpClient(final NetconfClientConfiguration currentConfiguration) {
+        logger.debug("Creating TCP client with configuration: {}", currentConfiguration);
+        return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
+                new PipelineInitializer<NetconfClientSession>() {
+
+                    @Override
+                    public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
+                        initialize(ch, promise);
+                    }
+
+                    private void initialize(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
+                        new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration), currentConfiguration
+                                .getSessionListener()).initialize(ch, promise);
+                    }
+                });
+    }
+
+    private Future<Void> createReconnectingTcpClient(final NetconfReconnectingClientConfiguration currentConfiguration) {
+        logger.debug("Creating reconnecting TCP client with configuration: {}", currentConfiguration);
+        final TcpClientChannelInitializer init = new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
+                currentConfiguration.getSessionListener());
+
+        return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration.getConnectStrategyFactory(),
+                currentConfiguration.getReconnectStrategy(), new PipelineInitializer<NetconfClientSession>() {
+                    @Override
+                    public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
+                        init.initialize(ch, promise);
+                    }
+                });
+    }
+
+    private Future<NetconfClientSession> createSshClient(final NetconfClientConfiguration currentConfiguration) {
+        logger.debug("Creating SSH client with configuration: {}", currentConfiguration);
+        return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
+                new PipelineInitializer<NetconfClientSession>() {
+
+                    @Override
+                    public void initializeChannel(final SocketChannel ch,
+                                                  final Promise<NetconfClientSession> sessionPromise) {
+                        new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
+                                getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener())
+                                .initialize(ch, sessionPromise);
+                    }
+
+                });
+    }
+
+    private Future<Void> createReconnectingSshClient(final NetconfReconnectingClientConfiguration currentConfiguration) {
+        logger.debug("Creating reconnecting SSH client with configuration: {}", currentConfiguration);
+        final SshClientChannelInitializer init = new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
+                getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener());
+
+        return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration.getConnectStrategyFactory(), currentConfiguration.getReconnectStrategy(),
+                new PipelineInitializer<NetconfClientSession>() {
+                    @Override
+                    public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
+                        init.initialize(ch, promise);
+                    }
+                });
+    }
+
+    protected NetconfClientSessionNegotiatorFactory getNegotiatorFactory(final NetconfClientConfiguration cfg) {
+        return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
+                cfg.getConnectionTimeoutMillis());
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfSshClientDispatcher.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfSshClientDispatcher.java
deleted file mode 100644 (file)
index 5b82ff2..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2013 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.controller.netconf.client;
-
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.Promise;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
-import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
-import org.opendaylight.controller.netconf.util.handler.ssh.SshHandler;
-import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.util.handler.ssh.client.Invoker;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-
-import com.google.common.base.Optional;
-
-public class NetconfSshClientDispatcher extends NetconfClientDispatcher {
-
-    private final AuthenticationHandler authHandler;
-    private final HashedWheelTimer timer;
-    private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
-
-    public NetconfSshClientDispatcher(AuthenticationHandler authHandler, EventLoopGroup bossGroup,
-            EventLoopGroup workerGroup, long connectionTimeoutMillis) {
-        super(bossGroup, workerGroup, connectionTimeoutMillis);
-        this.authHandler = authHandler;
-        this.timer = new HashedWheelTimer();
-        this.negotiatorFactory = new NetconfClientSessionNegotiatorFactory(timer,
-                Optional.<NetconfHelloMessageAdditionalHeader> absent(), connectionTimeoutMillis);
-    }
-
-    public NetconfSshClientDispatcher(AuthenticationHandler authHandler, EventLoopGroup bossGroup,
-            EventLoopGroup workerGroup, NetconfHelloMessageAdditionalHeader additionalHeader, long socketTimeoutMillis) {
-        super(bossGroup, workerGroup, additionalHeader, socketTimeoutMillis);
-        this.authHandler = authHandler;
-        this.timer = new HashedWheelTimer();
-        this.negotiatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.of(additionalHeader),
-                socketTimeoutMillis);
-    }
-
-    @Override
-    public Future<NetconfClientSession> createClient(InetSocketAddress address,
-            final NetconfClientSessionListener sessionListener, ReconnectStrategy strat) {
-        return super.createClient(address, strat, new PipelineInitializer<NetconfClientSession>() {
-
-            @Override
-            public void initializeChannel(SocketChannel arg0, Promise<NetconfClientSession> arg1) {
-                new NetconfSshClientInitializer(authHandler, negotiatorFactory, sessionListener).initialize(arg0, arg1);
-            }
-
-        });
-    }
-
-    @Override
-    public Future<Void> createReconnectingClient(final InetSocketAddress address,
-            final NetconfClientSessionListener listener,
-            final ReconnectStrategyFactory connectStrategyFactory, final ReconnectStrategy reestablishStrategy) {
-        final NetconfSshClientInitializer init = new NetconfSshClientInitializer(authHandler, negotiatorFactory, listener);
-
-        return super.createReconnectingClient(address, connectStrategyFactory, reestablishStrategy,
-                new PipelineInitializer<NetconfClientSession>() {
-            @Override
-            public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
-                init.initialize(ch, promise);
-            }
-        });
-    }
-
-    private static final class NetconfSshClientInitializer extends AbstractChannelInitializer<NetconfClientSession> {
-
-        private final AuthenticationHandler authenticationHandler;
-        private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
-        private final NetconfClientSessionListener sessionListener;
-
-        public NetconfSshClientInitializer(AuthenticationHandler authHandler,
-                NetconfClientSessionNegotiatorFactory negotiatorFactory,
-                final NetconfClientSessionListener sessionListener) {
-            this.authenticationHandler = authHandler;
-            this.negotiatorFactory = negotiatorFactory;
-            this.sessionListener = sessionListener;
-        }
-
-        @Override
-        public void initialize(SocketChannel ch, Promise<NetconfClientSession> promise) {
-            try {
-                Invoker invoker = Invoker.subsystem("netconf");
-                ch.pipeline().addFirst(new SshHandler(authenticationHandler, invoker));
-                super.initialize(ch,promise);
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        @Override
-        protected void initializeSessionNegotiator(SocketChannel ch,
-                Promise<NetconfClientSession> promise) {
-            ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER,  AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
-                    negotiatorFactory.getSessionNegotiator(new SessionListenerFactory<NetconfClientSessionListener>() {
-                @Override
-                public NetconfClientSessionListener getSessionListener() {
-                    return sessionListener;
-                }
-            }, ch, promise));
-        }
-    }
-}
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SshClientChannelInitializer.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SshClientChannelInitializer.java
new file mode 100644 (file)
index 0000000..b86349d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 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.controller.netconf.client;
+
+import io.netty.channel.socket.SocketChannel;
+import io.netty.util.concurrent.Promise;
+import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
+import org.opendaylight.controller.netconf.util.handler.ssh.SshHandler;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.Invoker;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+
+import java.io.IOException;
+
+final class SshClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
+
+    private final AuthenticationHandler authenticationHandler;
+    private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
+    private final NetconfClientSessionListener sessionListener;
+
+    public SshClientChannelInitializer(final AuthenticationHandler authHandler,
+                                       final NetconfClientSessionNegotiatorFactory negotiatorFactory,
+                                       final NetconfClientSessionListener sessionListener) {
+        this.authenticationHandler = authHandler;
+        this.negotiatorFactory = negotiatorFactory;
+        this.sessionListener = sessionListener;
+    }
+
+    @Override
+    public void initialize(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
+        try {
+            final Invoker invoker = Invoker.subsystem("netconf");
+            ch.pipeline().addFirst(new SshHandler(authenticationHandler, invoker));
+            super.initialize(ch,promise);
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    protected void initializeSessionNegotiator(final SocketChannel ch,
+                                               final Promise<NetconfClientSession> promise) {
+        ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER,  AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
+                negotiatorFactory.getSessionNegotiator(new SessionListenerFactory<NetconfClientSessionListener>() {
+                    @Override
+                    public NetconfClientSessionListener getSessionListener() {
+                        return sessionListener;
+                    }
+                }, ch, promise));
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/TcpClientChannelInitializer.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/TcpClientChannelInitializer.java
new file mode 100644 (file)
index 0000000..967d3c6
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 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.controller.netconf.client;
+
+import io.netty.channel.socket.SocketChannel;
+import io.netty.util.concurrent.Promise;
+import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+
+class TcpClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
+
+    private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
+    private final NetconfClientSessionListener sessionListener;
+
+    TcpClientChannelInitializer(final NetconfClientSessionNegotiatorFactory negotiatorFactory,
+                                final NetconfClientSessionListener sessionListener) {
+        this.negotiatorFactory = negotiatorFactory;
+        this.sessionListener = sessionListener;
+    }
+
+    @Override
+    public void initialize(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
+        super.initialize(ch, promise);
+    }
+
+    @Override
+    protected void initializeSessionNegotiator(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
+        ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
+                negotiatorFactory.getSessionNegotiator(new SessionListenerFactory<NetconfClientSessionListener>() {
+                    @Override
+                    public NetconfClientSessionListener getSessionListener() {
+                        return sessionListener;
+                    }
+                }, ch, promise));
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfClientConfiguration.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfClientConfiguration.java
new file mode 100644 (file)
index 0000000..5a3ec3a
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014 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.controller.netconf.client.conf;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+
+import java.net.InetSocketAddress;
+
+public class NetconfClientConfiguration {
+
+    private final NetconfClientProtocol clientProtocol;
+    private final InetSocketAddress address;
+    private final Long connectionTimeoutMillis;
+
+    private final NetconfHelloMessageAdditionalHeader additionalHeader;
+    private final NetconfClientSessionListener sessionListener;
+
+    private final ReconnectStrategy reconnectStrategy;
+
+    private final AuthenticationHandler authHandler;
+
+    NetconfClientConfiguration(final NetconfClientProtocol protocol, final InetSocketAddress address, final Long connectionTimeoutMillis, final NetconfHelloMessageAdditionalHeader additionalHeader, final NetconfClientSessionListener sessionListener, final ReconnectStrategy reconnectStrategy, final AuthenticationHandler authHandler) {
+        this.address = address;
+        this.connectionTimeoutMillis = connectionTimeoutMillis;
+        this.additionalHeader = additionalHeader;
+        this.sessionListener = sessionListener;
+        this.clientProtocol = protocol;
+        this.reconnectStrategy = reconnectStrategy;
+        this.authHandler = authHandler;
+        validateConfiguration();
+    }
+
+    public final InetSocketAddress getAddress() {
+        return address;
+    }
+
+    public final Long getConnectionTimeoutMillis() {
+        return connectionTimeoutMillis;
+    }
+
+    public final Optional<NetconfHelloMessageAdditionalHeader> getAdditionalHeader() {
+        return Optional.fromNullable(additionalHeader);
+    }
+
+    public final NetconfClientSessionListener getSessionListener() {
+        return sessionListener;
+    }
+
+    public final ReconnectStrategy getReconnectStrategy() {
+        return reconnectStrategy;
+    }
+
+    public final AuthenticationHandler getAuthHandler() {
+        return authHandler;
+    }
+
+    public NetconfClientProtocol getProtocol() {
+        return clientProtocol;
+    }
+
+    private void validateConfiguration() {
+        Preconditions.checkNotNull(clientProtocol, " ");
+        switch (clientProtocol) {
+        case SSH:
+            validateSshConfiguration();
+            // Fall through intentional (ssh validation is a superset of tcp validation)
+        case TCP:
+            validateTcpConfiguration();
+        }
+    }
+
+    protected void validateSshConfiguration() {
+        Preconditions.checkNotNull(authHandler, "authHandler");
+    }
+
+    protected void validateTcpConfiguration() {
+        Preconditions.checkNotNull(address, "address");
+        Preconditions.checkNotNull(clientProtocol, "clientProtocol");
+        Preconditions.checkNotNull(connectionTimeoutMillis, "connectionTimeoutMillis");
+        Preconditions.checkNotNull(sessionListener, "sessionListener");
+        Preconditions.checkNotNull(reconnectStrategy, "reconnectStrategy");
+    }
+
+    @Override
+    public final String toString() {
+        return buildToStringHelper().toString();
+    }
+
+    protected Objects.ToStringHelper buildToStringHelper() {
+        return Objects.toStringHelper(this)
+                .add("address", address)
+                .add("connectionTimeoutMillis", connectionTimeoutMillis)
+                .add("additionalHeader", additionalHeader)
+                .add("sessionListener", sessionListener)
+                .add("reconnectStrategy", reconnectStrategy)
+                .add("clientProtocol", clientProtocol)
+                .add("authHandler", authHandler);
+    }
+
+    public static enum NetconfClientProtocol {
+        TCP, SSH
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfClientConfigurationBuilder.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfClientConfigurationBuilder.java
new file mode 100644 (file)
index 0000000..a3e57bd
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 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.controller.netconf.client.conf;
+
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+
+import java.net.InetSocketAddress;
+
+public class NetconfClientConfigurationBuilder {
+
+    public static final int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 5000;
+    public static final NetconfClientConfiguration.NetconfClientProtocol DEFAULT_CLIENT_PROTOCOL = NetconfClientConfiguration.NetconfClientProtocol.TCP;
+
+    private InetSocketAddress address;
+    private long connectionTimeoutMillis = DEFAULT_CONNECTION_TIMEOUT_MILLIS;
+    private NetconfHelloMessageAdditionalHeader additionalHeader;
+    private NetconfClientSessionListener sessionListener;
+    private ReconnectStrategy reconnectStrategy;
+    private AuthenticationHandler authHandler;
+    private NetconfClientConfiguration.NetconfClientProtocol clientProtocol = DEFAULT_CLIENT_PROTOCOL;
+
+    protected NetconfClientConfigurationBuilder() {
+    }
+
+    public static NetconfClientConfigurationBuilder create() {
+        return new NetconfClientConfigurationBuilder();
+    }
+
+    public NetconfClientConfigurationBuilder withAddress(final InetSocketAddress address) {
+        this.address = address;
+        return this;
+    }
+
+    public NetconfClientConfigurationBuilder withConnectionTimeoutMillis(final long connectionTimeoutMillis) {
+        this.connectionTimeoutMillis = connectionTimeoutMillis;
+        return this;
+    }
+
+    public NetconfClientConfigurationBuilder withProtocol(final NetconfClientConfiguration.NetconfClientProtocol clientProtocol) {
+        this.clientProtocol = clientProtocol;
+        return this;
+    }
+
+    public NetconfClientConfigurationBuilder withAdditionalHeader(final NetconfHelloMessageAdditionalHeader additionalHeader) {
+        this.additionalHeader = additionalHeader;
+        return this;
+    }
+
+    public NetconfClientConfigurationBuilder withSessionListener(final NetconfClientSessionListener sessionListener) {
+        this.sessionListener = sessionListener;
+        return this;
+    }
+
+    public NetconfClientConfigurationBuilder withReconnectStrategy(final ReconnectStrategy reconnectStrategy) {
+        this.reconnectStrategy = reconnectStrategy;
+        return this;
+    }
+
+    public NetconfClientConfigurationBuilder withAuthHandler(final AuthenticationHandler authHandler) {
+        this.authHandler = authHandler;
+        return this;
+    }
+
+    final InetSocketAddress getAddress() {
+        return address;
+    }
+
+    final long getConnectionTimeoutMillis() {
+        return connectionTimeoutMillis;
+    }
+
+    final NetconfHelloMessageAdditionalHeader getAdditionalHeader() {
+        return additionalHeader;
+    }
+
+    final NetconfClientSessionListener getSessionListener() {
+        return sessionListener;
+    }
+
+    final ReconnectStrategy getReconnectStrategy() {
+        return reconnectStrategy;
+    }
+
+    final AuthenticationHandler getAuthHandler() {
+        return authHandler;
+    }
+
+    final NetconfClientConfiguration.NetconfClientProtocol getProtocol() {
+        return clientProtocol;
+    }
+
+    public NetconfClientConfiguration build() {
+        return new NetconfClientConfiguration(clientProtocol, address, connectionTimeoutMillis, additionalHeader, sessionListener, reconnectStrategy, authHandler);
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfReconnectingClientConfiguration.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfReconnectingClientConfiguration.java
new file mode 100644 (file)
index 0000000..64fcc48
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 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.controller.netconf.client.conf;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+
+import java.net.InetSocketAddress;
+
+public final class NetconfReconnectingClientConfiguration extends NetconfClientConfiguration {
+
+    private final ReconnectStrategyFactory connectStrategyFactory;
+
+    NetconfReconnectingClientConfiguration(final NetconfClientProtocol clientProtocol, final InetSocketAddress address,
+            final Long connectionTimeoutMillis, final NetconfHelloMessageAdditionalHeader additionalHeader,
+            final NetconfClientSessionListener sessionListener, final ReconnectStrategy reconnectStrategy,
+            final ReconnectStrategyFactory connectStrategyFactory, final AuthenticationHandler authHandler) {
+        super(clientProtocol, address, connectionTimeoutMillis, additionalHeader, sessionListener, reconnectStrategy,
+                authHandler);
+        this.connectStrategyFactory = connectStrategyFactory;
+        validateReconnectConfiguration();
+    }
+
+    public ReconnectStrategyFactory getConnectStrategyFactory() {
+        return connectStrategyFactory;
+    }
+
+    private void validateReconnectConfiguration() {
+        Preconditions.checkNotNull(connectStrategyFactory);
+    }
+
+    @Override
+    protected Objects.ToStringHelper buildToStringHelper() {
+        return super.buildToStringHelper().add("connectStrategyFactory", connectStrategyFactory);
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfReconnectingClientConfigurationBuilder.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/conf/NetconfReconnectingClientConfigurationBuilder.java
new file mode 100644 (file)
index 0000000..411ac3c
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014 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.controller.netconf.client.conf;
+
+import java.net.InetSocketAddress;
+
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+
+public class NetconfReconnectingClientConfigurationBuilder extends NetconfClientConfigurationBuilder {
+
+    private ReconnectStrategyFactory connectStrategyFactory;
+
+    private NetconfReconnectingClientConfigurationBuilder() {
+    }
+
+    public static NetconfReconnectingClientConfigurationBuilder create() {
+        return new NetconfReconnectingClientConfigurationBuilder();
+    }
+
+
+    public NetconfReconnectingClientConfigurationBuilder withConnectStrategyFactory(final ReconnectStrategyFactory connectStrategyFactory) {
+        this.connectStrategyFactory = connectStrategyFactory;
+        return this;
+    }
+
+    @Override
+    public NetconfReconnectingClientConfiguration build() {
+        return new NetconfReconnectingClientConfiguration(getProtocol(), getAddress(), getConnectionTimeoutMillis(), getAdditionalHeader(), getSessionListener(), getReconnectStrategy(), connectStrategyFactory, getAuthHandler());
+    }
+
+    // Override setter methods to return subtype
+
+    @Override
+    public NetconfReconnectingClientConfigurationBuilder withAddress(final InetSocketAddress address) {
+        return (NetconfReconnectingClientConfigurationBuilder) super.withAddress(address);
+    }
+
+    @Override
+    public NetconfReconnectingClientConfigurationBuilder withConnectionTimeoutMillis(final long connectionTimeoutMillis) {
+        return (NetconfReconnectingClientConfigurationBuilder) super.withConnectionTimeoutMillis(connectionTimeoutMillis);
+    }
+
+    @Override
+    public NetconfReconnectingClientConfigurationBuilder withAdditionalHeader(final NetconfHelloMessageAdditionalHeader additionalHeader) {
+        return (NetconfReconnectingClientConfigurationBuilder) super.withAdditionalHeader(additionalHeader);
+    }
+
+    @Override
+    public NetconfReconnectingClientConfigurationBuilder withSessionListener(final NetconfClientSessionListener sessionListener) {
+        return (NetconfReconnectingClientConfigurationBuilder) super.withSessionListener(sessionListener);
+    }
+
+    @Override
+    public NetconfReconnectingClientConfigurationBuilder withReconnectStrategy(final ReconnectStrategy reconnectStrategy) {
+        return (NetconfReconnectingClientConfigurationBuilder) super.withReconnectStrategy(reconnectStrategy);
+    }
+
+    @Override
+    public NetconfReconnectingClientConfigurationBuilder withAuthHandler(final AuthenticationHandler authHandler) {
+        return (NetconfReconnectingClientConfigurationBuilder) super.withAuthHandler(authHandler);
+    }
+
+    @Override
+    public NetconfReconnectingClientConfigurationBuilder withProtocol(NetconfClientConfiguration.NetconfClientProtocol clientProtocol) {
+        return (NetconfReconnectingClientConfigurationBuilder) super.withProtocol(clientProtocol);
+    }
+}
index 32c6ea8..60d8f30 100644 (file)
@@ -8,12 +8,8 @@
 
 package org.opendaylight.controller.netconf.client.test;
 
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GlobalEventExecutor;
-
 import java.io.Closeable;
 import java.io.IOException;
-import java.net.InetSocketAddress;
 import java.util.Set;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutionException;
@@ -25,11 +21,11 @@ import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.controller.netconf.client.NetconfClientSession;
 import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
 import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Sets;
+import io.netty.util.concurrent.Future;
 
 
 /**
@@ -44,11 +40,11 @@ public class TestingNetconfClient implements Closeable {
     private final NetconfClientSessionListener sessionListener;
     private final long sessionId;
 
-    private TestingNetconfClient(String clientLabel, InetSocketAddress address, ReconnectStrategy strat,
-            NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+    public TestingNetconfClient(String clientLabel,
+                                 NetconfClientDispatcher netconfClientDispatcher, final NetconfClientConfiguration config) throws InterruptedException {
         this.label = clientLabel;
-        sessionListener = new SimpleNetconfClientSessionListener();
-        Future<NetconfClientSession> clientFuture = netconfClientDispatcher.createClient(address, sessionListener, strat);
+        sessionListener = config.getSessionListener();
+        Future<NetconfClientSession> clientFuture = netconfClientDispatcher.createClient(config);
         clientSession = get(clientFuture);
         this.sessionId = clientSession.getSessionId();
     }
@@ -63,18 +59,6 @@ public class TestingNetconfClient implements Closeable {
         }
     }
 
-    public TestingNetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs,
-                                NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
-        this(clientLabelForLogging, address,
-                new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, connectTimeoutMs), netconfClientDispatcher);
-    }
-
-    public TestingNetconfClient(String clientLabelForLogging, InetSocketAddress address,
-                                NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
-        this(clientLabelForLogging, address, new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
-                DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher);
-    }
-
     public Future<NetconfMessage> sendRequest(NetconfMessage message) {
         return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message);
     }
@@ -111,4 +95,4 @@ public class TestingNetconfClient implements Closeable {
         Preconditions.checkState(clientSession != null, "Client was not initialized successfully");
         return Sets.newHashSet(clientSession.getServerCapabilities());
     }
-}
\ No newline at end of file
+}
index 0a0cd22..b8622d1 100644 (file)
@@ -15,10 +15,6 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import io.netty.channel.EventLoopGroup;
-import io.netty.util.HashedWheelTimer;
 import java.io.DataOutputStream;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -30,13 +26,13 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
-
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicLong;
+
 import org.apache.commons.io.IOUtils;
 import org.junit.After;
 import org.junit.AfterClass;
@@ -48,6 +44,10 @@ import org.junit.runners.Parameterized;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
 import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
@@ -63,14 +63,20 @@ import org.opendaylight.controller.netconf.util.messages.NetconfStartExiMessage;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
 import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.concurrent.GlobalEventExecutor;
 
 @RunWith(Parameterized.class)
 public class ConcurrentClientsTest {
@@ -138,10 +144,9 @@ public class ConcurrentClientsTest {
 
     @Before
     public void setUp() throws Exception {
-
+        hashedWheelTimer = new HashedWheelTimer();
         nettyGroup = new NioEventLoopGroup(nettyThreads);
-        NetconfHelloMessageAdditionalHeader additionalHeader = new NetconfHelloMessageAdditionalHeader("uname", "10.10.10.1", "830", "tcp", "client");
-        netconfClientDispatcher = new NetconfClientDispatcher( nettyGroup, nettyGroup, additionalHeader, 5000);
+        netconfClientDispatcher = new NetconfClientDispatcherImpl(nettyGroup, nettyGroup, hashedWheelTimer);
 
         NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
 
@@ -149,7 +154,6 @@ public class ConcurrentClientsTest {
         factoriesListener.onAddNetconfOperationServiceFactory(new TestingOperationServiceFactory(testingNetconfOperation));
 
         SessionIdProvider idProvider = new SessionIdProvider();
-        hashedWheelTimer = new HashedWheelTimer();
 
         NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
                 hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService(), serverCaps);
@@ -333,8 +337,8 @@ public class ConcurrentClientsTest {
         @Override
         public void run() {
             try {
-                final TestingNetconfClient netconfClient = new TestingNetconfClient(Thread.currentThread().getName(),
-                        netconfAddress, netconfClientDispatcher);
+                final TestingNetconfClient netconfClient =
+                        new TestingNetconfClient(Thread.currentThread().getName(), netconfClientDispatcher, getClientConfig());
                 long sessionId = netconfClient.getSessionId();
                 logger.info("Client with session id {}: hello exchanged", sessionId);
 
@@ -353,5 +357,16 @@ public class ConcurrentClientsTest {
                 throw new IllegalStateException(Thread.currentThread().getName(), e);
             }
         }
+
+        private NetconfClientConfiguration getClientConfig() {
+            final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
+            b.withAddress(netconfAddress);
+            b.withAdditionalHeader(new NetconfHelloMessageAdditionalHeader("uname", "10.10.10.1", "830", "tcp",
+                    "client"));
+            b.withSessionListener(new SimpleNetconfClientSessionListener());
+            b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
+                    NetconfClientConfigurationBuilder.DEFAULT_CONNECTION_TIMEOUT_MILLIS));
+            return b.build();
+        }
     }
 }
index b81f950..d4073e5 100644 (file)
@@ -7,22 +7,30 @@
  */
 package org.opendaylight.controller.netconf.it;
 
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
+import java.net.InetSocketAddress;
+
 import org.junit.After;
 import org.junit.Before;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
 import org.opendaylight.controller.netconf.impl.SessionIdProvider;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
+
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.concurrent.GlobalEventExecutor;
 
 public class AbstractNetconfConfigTest extends AbstractConfigTest {
 
-    protected EventLoopGroup nettyThreadgroup;
+    private EventLoopGroup nettyThreadgroup;
     private HashedWheelTimer hashedWheelTimer;
 
     @Before
@@ -31,7 +39,6 @@ public class AbstractNetconfConfigTest extends AbstractConfigTest {
         hashedWheelTimer = new HashedWheelTimer();
     }
 
-
     protected NetconfServerDispatcher createDispatcher(
             NetconfOperationServiceFactoryListenerImpl factoriesListener, SessionMonitoringService sessionMonitoringService,
             DefaultCommitNotificationProducer commitNotifier) {
@@ -45,6 +52,13 @@ public class AbstractNetconfConfigTest extends AbstractConfigTest {
         return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
     }
 
+    protected HashedWheelTimer getHashedWheelTimer() {
+        return hashedWheelTimer;
+    }
+
+    protected EventLoopGroup getNettyThreadgroup() {
+        return nettyThreadgroup;
+    }
 
     @After
     public void cleanUpTimer() {
@@ -52,4 +66,13 @@ public class AbstractNetconfConfigTest extends AbstractConfigTest {
         nettyThreadgroup.shutdownGracefully();
     }
 
+    public NetconfClientConfiguration getClientConfiguration(final InetSocketAddress tcpAddress, final int timeout) {
+        final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
+        b.withAddress(tcpAddress);
+        b.withSessionListener(new SimpleNetconfClientSessionListener());
+        b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
+                timeout));
+        b.withConnectionTimeoutMillis(timeout);
+        return b.build();
+    }
 }
index d7f7714..3fa1b01 100644 (file)
@@ -7,14 +7,7 @@
  */
 package org.opendaylight.controller.netconf.it;
 
-import org.apache.commons.io.IOUtils;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreServiceImpl;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import static org.junit.Assert.assertNotNull;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -24,7 +17,14 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 
-import static org.junit.Assert.assertNotNull;
+import org.apache.commons.io.IOUtils;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreServiceImpl;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 
 public class HardcodedYangStoreService implements YangStoreService {
 
index af83fe4..29afa93 100644 (file)
@@ -17,7 +17,6 @@ import static org.mockito.Mockito.mock;
 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithName;
 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertElementsCount;
 import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToDocument;
-import io.netty.channel.ChannelFuture;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -43,6 +42,7 @@ import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
@@ -65,16 +65,14 @@ import org.xml.sax.SAXException;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
 
 public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
 
     private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
 
-
-
     private NetconfClientDispatcher clientDispatcher;
-
-    DefaultCommitNotificationProducer commitNotifier;
+    private DefaultCommitNotificationProducer commitNotifier;
 
     @Before
     public void setUp() throws Exception {
@@ -95,7 +93,7 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
         ChannelFuture s = dispatch.createServer(tcpAddress);
         s.await();
 
-        clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, 5000);
+        clientDispatcher = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
     }
 
     @After
@@ -124,12 +122,12 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
         VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
         VerifyingPersister mockedAggregator = mockAggregator();
 
-        try (TestingNetconfClient persisterClient = new TestingNetconfClient("persister", tcpAddress, 4000, clientDispatcher)) {
+        try (TestingNetconfClient persisterClient = new TestingNetconfClient("persister", clientDispatcher, getClientConfiguration(tcpAddress, 4000))) {
             try (ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
                     platformMBeanServer, mockedAggregator)) {
 
 
-                try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", tcpAddress, 4000, clientDispatcher)) {
+                try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(tcpAddress, 4000))) {
                     NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage());
                     assertContainsElementWithName(response.getDocument(), "modules");
                     assertContainsElementWithName(response.getDocument(), "services");
index 44d8420..4dc4b70 100644 (file)
@@ -34,7 +34,10 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.NetconfSshClientDispatcher;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
 import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
@@ -50,9 +53,11 @@ import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
 import org.opendaylight.controller.usermanager.IUserManager;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 
 import ch.ethz.ssh2.Connection;
 import io.netty.channel.ChannelFuture;
+import io.netty.util.concurrent.GlobalEventExecutor;
 
 public class NetconfITSecureTest extends AbstractNetconfConfigTest {
 
@@ -60,7 +65,6 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
     private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
 
     private DefaultCommitNotificationProducer commitNot;
-    private NetconfServerDispatcher dispatchS;
     private NetconfSSHServer sshServer;
     private NetconfMessage getConfig;
 
@@ -77,7 +81,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
         commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
 
 
-        dispatchS = createDispatcher(factoriesListener);
+        final NetconfServerDispatcher dispatchS = createDispatcher(factoriesListener);
         ChannelFuture s = dispatchS.createServer(tcpAddress);
         s.await();
 
@@ -108,14 +112,34 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
 
     @Test
     public void testSecure() throws Exception {
-        NetconfClientDispatcher dispatch = new NetconfSshClientDispatcher(getAuthHandler(), nettyThreadgroup, nettyThreadgroup, 5000);
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("tls-client", tlsAddress, 4000, dispatch)) {
+        NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration())) {
             NetconfMessage response = netconfClient.sendMessage(getConfig);
             Assert.assertFalse("Unexpected error message " + XmlUtil.toString(response.getDocument()),
                     NetconfMessageUtil.isErrorMessage(response));
+
+            NetconfMessage gs = new NetconfMessage(XmlUtil.readXmlToDocument("<rpc message-id=\"2\"\n" +
+                    "     xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
+                    "    <get-schema xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
+                    "        <identifier>config</identifier>\n" +
+                    "    </get-schema>\n" +
+                    "</rpc>\n"));
+
+            response = netconfClient.sendMessage(gs);
+            Assert.assertFalse("Unexpected error message " + XmlUtil.toString(response.getDocument()),
+                    NetconfMessageUtil.isErrorMessage(response));
         }
+    }
 
-        dispatch.close();
+    public NetconfClientConfiguration getClientConfiguration() throws IOException {
+        final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
+        b.withAddress(tlsAddress);
+        b.withSessionListener(new SimpleNetconfClientSessionListener());
+        b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
+        b.withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH);
+        b.withConnectionTimeoutMillis(5000);
+        b.withAuthHandler(getAuthHandler());
+        return b.build();
     }
 
     public AuthProvider getAuthProvider() throws Exception {
@@ -138,6 +162,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
                 return null;
             }
         }).when(authHandler).authenticate(any(Connection.class));
+        doReturn("auth handler").when(authHandler).toString();
         return authHandler;
     }
 }
index b77d92e..e99e51e 100644 (file)
@@ -8,11 +8,14 @@
 
 package org.opendaylight.controller.netconf.it;
 
-import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.Session;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import io.netty.channel.ChannelFuture;
+import static java.util.Collections.emptyList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.management.ManagementFactory;
@@ -25,9 +28,12 @@ import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
+
 import javax.management.ObjectName;
 import javax.xml.parsers.ParserConfigurationException;
+
 import junit.framework.Assert;
+
 import org.apache.commons.io.IOUtils;
 import org.junit.After;
 import org.junit.Before;
@@ -43,7 +49,7 @@ import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
 import org.opendaylight.controller.netconf.StubUserManager;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
@@ -66,13 +72,13 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
-import static java.util.Collections.emptyList;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+
+import ch.ethz.ssh2.Connection;
+import ch.ethz.ssh2.Session;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
 
 public class NetconfITTest extends AbstractNetconfConfigTest {
 
@@ -90,7 +96,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
     private DefaultCommitNotificationProducer commitNot;
     private NetconfServerDispatcher dispatch;
 
-    private NetconfClientDispatcher clientDispatcher;
+    private NetconfClientDispatcherImpl clientDispatcher;
 
     @Before
     public void setUp() throws Exception {
@@ -109,7 +115,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
         ChannelFuture s = dispatch.createServer(tcpAddress);
         s.await();
 
-        clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, 5000);
+        clientDispatcher = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
     }
 
     private NetconfServerDispatcher createDispatcher(NetconfOperationServiceFactoryListenerImpl factoriesListener) {
@@ -176,7 +182,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
 
     @Test
     public void testNetconfClientDemonstration() throws Exception {
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", tcpAddress, 4000, clientDispatcher)) {
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(tcpAddress, 4000))) {
 
             Set<String> capabilitiesFromNetconfServer = netconfClient.getCapabilities();
             long sessionId = netconfClient.getSessionId();
@@ -191,8 +197,8 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
 
     @Test
     public void testTwoSessions() throws Exception {
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("1", tcpAddress, 10000, clientDispatcher))  {
-            try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("2", tcpAddress, 10000, clientDispatcher)) {
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("1", clientDispatcher, getClientConfiguration(tcpAddress, 10000)))  {
+            try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("2", clientDispatcher, getClientConfiguration(tcpAddress, 10000))) {
             }
         }
     }
@@ -365,7 +371,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
     }
 
     private TestingNetconfClient createSession(final InetSocketAddress address, final String expected) throws Exception {
-        final TestingNetconfClient netconfClient = new TestingNetconfClient("test " + address.toString(), address, 5000, clientDispatcher);
+        final TestingNetconfClient netconfClient = new TestingNetconfClient("test " + address.toString(), clientDispatcher, getClientConfiguration(address, 5000));
         assertEquals(expected, Long.toString(netconfClient.getSessionId()));
         return netconfClient;
     }
index 8e98ab6..3b263f7 100644 (file)
@@ -7,11 +7,24 @@
  */
 package org.opendaylight.controller.netconf.it;
 
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import io.netty.channel.ChannelFuture;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
 import junit.framework.Assert;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -19,7 +32,7 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
@@ -40,21 +53,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText;
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
 
 public class NetconfMonitoringITTest extends AbstractNetconfConfigTest {
 
@@ -66,7 +68,7 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest {
     private DefaultCommitNotificationProducer commitNot;
     private NetconfServerDispatcher dispatch;
 
-    private NetconfClientDispatcher clientDispatcher;
+    private NetconfClientDispatcherImpl clientDispatcher;
 
     private NetconfMonitoringServiceImpl monitoringService;
 
@@ -88,7 +90,7 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest {
         ChannelFuture s = dispatch.createServer(tcpAddress);
         s.await();
 
-        clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, 5000);
+        clientDispatcher = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
     }
 
     private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
@@ -120,8 +122,8 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest {
 
     @Test
     public void testGetResponseFromMonitoring() throws Exception {
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("client-monitoring", tcpAddress, 4000, clientDispatcher)) {
-        try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("client-monitoring2", tcpAddress, 4000, clientDispatcher)) {
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("client-monitoring", clientDispatcher, getClientConfiguration(tcpAddress, 4000))) {
+        try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("client-monitoring2", clientDispatcher, getClientConfiguration(tcpAddress, 4000))) {
             NetconfMessage response = netconfClient.sendMessage(loadGetMessage());
             assertSessionElementsInResponse(response.getDocument(), 2);
         }
index c54285b..ebfcff3 100644 (file)
@@ -19,8 +19,9 @@ import static org.ops4j.pax.exam.CoreOptions.options;
 import static org.ops4j.pax.exam.CoreOptions.streamBundle;
 import static org.ops4j.pax.exam.CoreOptions.systemPackages;
 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-import io.netty.channel.nio.NioEventLoopGroup;
 
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timer;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
@@ -34,11 +35,15 @@ import org.junit.Test;
 import org.junit.matchers.JUnitMatchers;
 import org.junit.runner.RunWith;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
 import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
@@ -51,6 +56,9 @@ import org.xml.sax.SAXException;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Throwables;
 
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.concurrent.GlobalEventExecutor;
+
 @Ignore
 @RunWith(PaxExam.class)
 public class IdentityRefNetconfTest {
@@ -121,15 +129,15 @@ public class IdentityRefNetconfTest {
     public void testIdRef() throws Exception {
         Preconditions.checkNotNull(broker, "Controller not initialized");
 
-        NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup();
-        NetconfClientDispatcher clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup,
-                CLIENT_CONNECTION_TIMEOUT_MILLIS);
 
         NetconfMessage edit = xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
         NetconfMessage commit = xmlFileToNetconfMessage("netconfMessages/commit.xml");
         NetconfMessage getConfig = xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
 
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", tcpAddress, CLIENT_CONNECTION_TIMEOUT_MILLIS, clientDispatcher)) {
+        NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup();
+        Timer timer = new HashedWheelTimer();
+        NetconfClientDispatcherImpl clientDispatcher = new NetconfClientDispatcherImpl(nettyThreadgroup, nettyThreadgroup, timer);
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(tcpAddress))) {
             sendMessage(edit, netconfClient);
             sendMessage(commit, netconfClient);
             sendMessage(getConfig, netconfClient, "id-test",
@@ -141,6 +149,9 @@ public class IdentityRefNetconfTest {
             clientDispatcher.close();
         } catch (Exception e) {
             fail(Throwables.getStackTraceAsString(e));
+        } finally {
+            nettyThreadgroup.shutdownGracefully().get();
+            timer.stop();
         }
     }
 
@@ -160,4 +171,14 @@ public class IdentityRefNetconfTest {
             ParserConfigurationException {
         return XmlFileLoader.xmlFileToNetconfMessage(fileName);
     }
+
+    public NetconfClientConfiguration getClientConfiguration(final InetSocketAddress tcpAddress) {
+        final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
+        b.withAddress(tcpAddress);
+        b.withSessionListener(new SimpleNetconfClientSessionListener());
+        b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
+                CLIENT_CONNECTION_TIMEOUT_MILLIS));
+        b.withConnectionTimeoutMillis(CLIENT_CONNECTION_TIMEOUT_MILLIS);
+        return b.build();
+    }
 }
index c08db90..1f7eed2 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.netconf.mapping.api;
 
+import com.google.common.base.Objects;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
@@ -51,13 +52,13 @@ public final class HandlingPriority implements Comparable<HandlingPriority> {
 
     @Override
     public int compareTo(HandlingPriority o) {
-        if (this == o){
+        if (this == o) {
             return 0;
         }
-        if (this.equals(CANNOT_HANDLE)){
+        if (isCannotHandle()) {
             return -1;
         }
-        if (o.equals(CANNOT_HANDLE)){
+        if (o.isCannotHandle()) {
             return 1;
         }
 
@@ -70,7 +71,8 @@ public final class HandlingPriority implements Comparable<HandlingPriority> {
         if (priority < o.priority){
             return -1;
         }
-        throw new IllegalStateException("Unexpected state");
+
+        throw new IllegalStateException("Unexpected state comparing " + this + " with " + o);
     }
 
     @Override
@@ -95,4 +97,11 @@ public final class HandlingPriority implements Comparable<HandlingPriority> {
     public int hashCode() {
         return priority != null ? priority.hashCode() : 0;
     }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(this)
+                .add("priority", priority)
+                .toString();
+    }
 }
index adba548..ff950e9 100644 (file)
@@ -68,7 +68,7 @@ public final class NetconfSSHServer implements Runnable {
         while (up) {
             logger.trace("Starting new socket thread.");
             try {
-               SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(),authProvider);
+               SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(), authProvider);
             } catch (IOException e) {
                 logger.error("Exception occurred during socket thread initialization {}", e);
             }