Merge "Bug 1234: Force to use legacy OF plugin if it is installed."
authorGiovanni Meo <gmeo@cisco.com>
Mon, 25 Aug 2014 14:49:37 +0000 (14:49 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 25 Aug 2014 14:49:37 +0000 (14:49 +0000)
37 files changed:
features/netconf/pom.xml
features/netconf/src/main/resources/features.xml
opendaylight/archetypes/opendaylight-configfile-archetype/pom.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/archetype-resources/pom.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/archetype-resources/src/main/resources/80-configfile.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-configfile-archetype/src/test/resources/projects/basic/archetype.properties [new file with mode: 0644]
opendaylight/archetypes/opendaylight-configfile-archetype/src/test/resources/projects/basic/goal.txt [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-distro-archetype/pom.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/main/resources/archetype-resources/pom.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/test/resources/projects/basic/archetype.properties [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/test/resources/projects/basic/goal.txt [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-features/pom.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/META-INF/maven/archetype-metadata.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/archetype-resources/pom.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/archetype-resources/src/main/resources/features.xml [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-features/src/test/resources/projects/basic/archetype.properties [new file with mode: 0644]
opendaylight/archetypes/opendaylight-karaf-features/src/test/resources/projects/basic/goal.txt [new file with mode: 0644]
opendaylight/archetypes/pom.xml
opendaylight/commons/opendaylight/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SshClientChannelInitializer.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-netty-util/pom.xml
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/authentication/AuthenticationHandler.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/authentication/LoginPassword.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java [new file with mode: 0644]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/Invoker.java [deleted file]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshClient.java [deleted file]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshClientAdapter.java [deleted file]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshHandler.java [deleted file]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshSession.java [deleted file]
opendaylight/netconf/netconf-ssh/pom.xml
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java
pom.xml

index 106e54a338203453fca414f06b89bce81232a3bc..51d6f6291b08adb86157c75523bc93067401b906 100644 (file)
       <groupId>org.opendaylight.controller.thirdparty</groupId>
       <artifactId>ganymed</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.sshd</groupId>
+      <artifactId>sshd-core</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.openexi</groupId>
       <artifactId>nagasena</artifactId>
index f1631a53400c2d60a1e0c922cccad5b9d3f05051..1453a5fb969a9d1e3f6b9f6bec88cebb59182d3f 100644 (file)
@@ -52,6 +52,7 @@
     <feature version='${project.version}'>odl-netconf-util</feature>
     <bundle>mvn:org.opendaylight.controller/netconf-netty-util/${project.version}</bundle>
     <bundle>mvn:org.opendaylight.controller.thirdparty/ganymed/${ganymed.version}</bundle>
+    <bundle>mvn:org.apache.sshd/sshd-core/${sshd-core.version}</bundle>
     <bundle>mvn:org.openexi/nagasena/${exi.nagasena.version}</bundle>
     <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
     <bundle>mvn:io.netty/netty-handler/${netty.version}</bundle>
@@ -69,4 +70,4 @@
     <bundle>mvn:org.opendaylight.controller/netconf-monitoring/${project.version}</bundle>
   </feature>
 
-</features>
\ No newline at end of file
+</features>
diff --git a/opendaylight/archetypes/opendaylight-configfile-archetype/pom.xml b/opendaylight/archetypes/opendaylight-configfile-archetype/pom.xml
new file mode 100644 (file)
index 0000000..38c8616
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>opendaylight-configfile-archetype</artifactId>
+  <version>1.1-SNAPSHOT</version>
+  <packaging>maven-archetype</packaging>
+
+
+  <build>
+    <extensions>
+      <extension>
+        <groupId>org.apache.maven.archetype</groupId>
+        <artifactId>archetype-packaging</artifactId>
+        <version>2.2</version>
+      </extension>
+    </extensions>
+
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-archetype-plugin</artifactId>
+          <version>2.2</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <description>Configuration files for md-sal</description>
+
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git/md-sal-config</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git/md-sal-config</developerConnection>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL/md-sal-config</url>
+  </scm>
+
+  <distributionManagement>
+    <repository>
+      <id>opendaylight-release</id>
+      <url>http://nexus.opendaylight.org/content/repositories/opendaylight.release/</url>
+    </repository>
+    <snapshotRepository>
+      <id>opendaylight-snapshot</id>
+      <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+    </snapshotRepository>
+    <site>
+      <id>website</id>
+      <url>dav:http://nexus.opendaylight.org/content/sites/site/sal-parent</url>
+    </site>
+  </distributionManagement>
+</project>
diff --git a/opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml b/opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml
new file mode 100644 (file)
index 0000000..d404f99
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="md-sal-config"
+    xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <requiredProperties>
+    <requiredProperty key="repoName"/>
+  </requiredProperties>
+  <fileSets>
+    <fileSet filtered="true" encoding="UTF-8">
+      <directory>src/main/resources</directory>
+      <includes>
+        <include>**/*.xml</include>
+      </includes>
+    </fileSet>
+  </fileSets>
+</archetype-descriptor>
diff --git a/opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/archetype-resources/pom.xml b/opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/archetype-resources/pom.xml
new file mode 100644 (file)
index 0000000..e217b9a
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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
+--><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/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <!--
+    Necessary TODO: Hookup your parent pom here, else you will not get necessary versions,
+    maven repos etc.  If you run this archetype in a subdirectory of your project, it
+    will pick the pom.xml from the parent directory as the parent pom, which may or may
+    not be correct.
+  -->
+  <artifactId>${artifactId}</artifactId>
+  <groupId>${groupId}</groupId>
+  <description>Configuration files for md-sal</description>
+  <!-- Optional TODO: Uncomment version if you are not using a parent pom.xml
+   <version>${version}</version>
+   -->
+  <packaging>jar</packaging>
+  <properties>
+      <!-- Optional TODO: Rename your configfile to taste -->
+      <configfile>80-configfile.xml</configfile>
+  </properties>
+  <build>
+    <plugins>
+        <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/${configfile}</file>
+                  <type>xml</type>
+                  <classifier>config</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+      <connection>scm:git:ssh://git.opendaylight.org:29418/${repoName}.git</connection>
+      <developerConnection>scm:git:ssh://git.opendaylight.org:29418/${repoName}.git</developerConnection>
+      <tag>HEAD</tag>
+      <url>https://git.opendaylight.org/gerrit/gitweb?p=${repoName}.git;a=summary</url>
+   </scm>
+</project>
diff --git a/opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/archetype-resources/src/main/resources/80-configfile.xml b/opendaylight/archetypes/opendaylight-configfile-archetype/src/main/resources/archetype-resources/src/main/resources/80-configfile.xml
new file mode 100644 (file)
index 0000000..432b947
--- /dev/null
@@ -0,0 +1,78 @@
+<?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
+-->
+<snapshot>
+    <required-capabilities>
+        <!-- Necessary TODO put your required capabilities here
+
+        Examples:
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&amp;revision=2013-11-07</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&amp;revision=2013-11-19</capability>
+        -->
+    </required-capabilities>
+    <configuration>
+
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <!-- Optional TODO: Add your modules definitions here
+                Examples:
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
+                    <name>global-boss-group</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
+                    <name>global-worker-group</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">netty:netty-hashed-wheel-timer</type>
+                    <name>global-timer</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">netty:netty-global-event-executor</type>
+                    <name>singleton</name>
+                </module>
+                -->
+            </modules>
+
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <!-- Optional TODO: Put your service instance definitions here
+                Examples:
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
+                    <instance>
+                        <name>global-boss-group</name>
+                        <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
+                    </instance>
+                    <instance>
+                        <name>global-worker-group</name>
+                        <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
+                    </instance>
+                </service>
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
+                    <instance>
+                        <name>global-event-executor</name>
+                        <provider>/modules/module[type='netty-global-event-executor'][name='singleton']</provider>
+                    </instance>
+                </service>
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
+                    <instance>
+                        <name>global-timer</name>
+                        <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
+                    </instance>
+                </service>
+                -->
+            </services>
+        </data>
+
+    </configuration>
+</snapshot>
diff --git a/opendaylight/archetypes/opendaylight-configfile-archetype/src/test/resources/projects/basic/archetype.properties b/opendaylight/archetypes/opendaylight-configfile-archetype/src/test/resources/projects/basic/archetype.properties
new file mode 100644 (file)
index 0000000..7a940e7
--- /dev/null
@@ -0,0 +1,6 @@
+#Mon Aug 25 05:45:18 CDT 2014
+package=it.pkg
+version=0.1-SNAPSHOT
+groupId=archetype.it
+artifactId=basic
+repoName=foo
diff --git a/opendaylight/archetypes/opendaylight-configfile-archetype/src/test/resources/projects/basic/goal.txt b/opendaylight/archetypes/opendaylight-configfile-archetype/src/test/resources/projects/basic/goal.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/opendaylight/archetypes/opendaylight-karaf-distro-archetype/pom.xml b/opendaylight/archetypes/opendaylight-karaf-distro-archetype/pom.xml
new file mode 100644 (file)
index 0000000..8883c64
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>opendaylight-karaf-distro-archetype</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>maven-archetype</packaging>
+
+  <name>distribution-karaf-archetype</name>
+
+  <build>
+    <extensions>
+      <extension>
+        <groupId>org.apache.maven.archetype</groupId>
+        <artifactId>archetype-packaging</artifactId>
+        <version>2.2</version>
+      </extension>
+    </extensions>
+
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-archetype-plugin</artifactId>
+          <version>2.2</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <url>https://wiki.opendaylight.org/view/CrossProject:Integration_Group/distribution-karaf</url>
+
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
+  </scm>
+</project>
diff --git a/opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml b/opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml
new file mode 100644 (file)
index 0000000..4c4f510
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
+    xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <requiredProperties>
+    <requiredProperty key="repoName"/>
+  </requiredProperties>
+</archetype-descriptor>
diff --git a/opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/main/resources/archetype-resources/pom.xml b/opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/main/resources/archetype-resources/pom.xml
new file mode 100644 (file)
index 0000000..965c619
--- /dev/null
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <!--
+    Necessary TODO: Hookup your parent pom here, else you will not get necessary versions,
+    maven repos etc.  If you run this archetype in a subdirectory of your project, it
+    will pick the pom.xml from the parent directory as the parent pom, which may or may
+    not be correct.
+  -->
+  <artifactId>${artifactId}</artifactId>
+  <groupId>${groupId}</groupId>
+  <!-- Optional TODO: Uncomment version if you are not using a parent pom.xml
+  <version>${version}</version>
+  -->
+  <packaging>pom</packaging>
+  <prerequisites>
+    <maven>3.0</maven>
+  </prerequisites>
+  <properties>
+    <!-- Optional TODO: Move these properties to your parent pom and possibly
+            DependencyManagement section of your parent pom -->
+    <branding.version>1.0.0-SNAPSHOT</branding.version>
+    <karaf.resources.version>1.4.2-SNAPSHOT</karaf.resources.version>
+    <karaf.version>3.0.1</karaf.version>
+  </properties>
+
+  <dependencies>
+    <!-- Basic Karaf dependencies -->
+    <dependency>
+      <groupId>org.apache.karaf.features</groupId>
+      <artifactId>framework</artifactId>
+      <version>${karaf.version}</version>
+      <type>kar</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.karaf.features</groupId>
+      <artifactId>standard</artifactId>
+      <version>${karaf.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+
+    <!-- ODL Branding -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>karaf.branding</artifactId>
+      <version>${branding.version}</version>
+      <scope>compile</scope>
+    </dependency>
+
+    <!-- ODL Resources needed for karaf -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>opendaylight-karaf-resources</artifactId>
+      <version>${karaf.resources.version}</version>
+    </dependency>
+
+    <!-- Project local feautures -->
+    <!--
+      Necessary TODO put your features here.
+
+      Note: they will need to be <type>xml</xml>
+      and <classifier>features</classifier>.
+
+      Note: they must be <scope>runtime</scope>
+
+      Note: usually you would only need to depend
+      on your own feature file here for your local distro,
+      and possible the features-mdsal for odl-restconf
+      (although, strange situations do exist :) )
+
+      Example:
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>features-mdsal</artifactId>
+        <classifier>features</classifier>
+        <type>xml</type>
+        <scope>runtime</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.openflowplugin</groupId>
+        <artifactId>features-openflowplugin</artifactId>
+        <version>0.0.3-SNAPSHOT</version>
+        <classifier>features</classifier>
+        <type>xml</type>
+        <scope>runtime</scope>
+      </dependency>
+    -->
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>maven-bundle-plugin</artifactId>
+                    <versionRange>[0,)</versionRange>
+                    <goals>
+                      <goal>cleanVersions</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[0,)</versionRange>
+                    <goals>
+                      <goal>copy</goal>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.karaf.tooling</groupId>
+                    <artifactId>karaf-maven-plugin</artifactId>
+                    <versionRange>[0,)</versionRange>
+                    <goals>
+                      <goal>commands-generate-help</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.fusesource.scalate</groupId>
+                    <artifactId>maven-scalate-plugin</artifactId>
+                    <versionRange>[0,)</versionRange>
+                    <goals>
+                      <goal>sitegen</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.servicemix.tooling</groupId>
+                    <artifactId>depends-maven-plugin</artifactId>
+                    <versionRange>[0,)</versionRange>
+                    <goals>
+                      <goal>generate-depends-file</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.karaf.tooling</groupId>
+        <artifactId>karaf-maven-plugin</artifactId>
+        <version>${karaf.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <bootFeatures>
+            <feature>standard</feature>
+            <!--
+              Optional TODO: Add entries here for the features you want in your local distro
+              Note: odl-restconf is a separate feature from odl-mdsal-broker.  If you want
+              restconf, you need to list it here explicitely.
+              Examples:
+              <feature>odl-openflowplugin-flow-services</feature>
+              <feature>odl-restconf</feature>
+            -->
+            <!-- Final TODO: Remove TODO Comments ;) -->
+          </bootFeatures>
+        </configuration>
+        <executions>
+          <execution>
+            <id>process-resources</id>
+            <goals>
+              <goal>install-kars</goal>
+            </goals>
+            <phase>process-resources</phase>
+          </execution>
+          <execution>
+            <id>package</id>
+            <goals>
+              <goal>instance-create-archive</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.6</version>
+        <executions>
+          <execution>
+            <id>copy</id>
+            <goals>
+              <goal>copy</goal>
+            </goals>
+            <phase>generate-resources</phase>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.opendaylight.controller</groupId>
+                  <artifactId>karaf.branding</artifactId>
+                  <version>${karaf.branding.version}</version>
+                  <outputDirectory>target/assembly/lib</outputDirectory>
+                  <destFileName>karaf.branding-${branding.version}.jar</destFileName>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+          <execution>
+            <id>unpack-karaf-resources</id>
+            <goals>
+              <goal>unpack-dependencies</goal>
+            </goals>
+            <phase>prepare-package</phase>
+            <configuration>
+             <outputDirectory>${project.build.directory}/assembly</outputDirectory>
+             <groupId>org.opendaylight.controller</groupId>
+             <includeArtifactIds>opendaylight-karaf-resources</includeArtifactIds>
+             <excludes>META-INF\/**</excludes>
+             <excludeTransitive>true</excludeTransitive>
+             <ignorePermissions>false</ignorePermissions>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+            <execution>
+                <phase>prepare-package</phase>
+                <goals>
+                    <goal>run</goal>
+                </goals>
+                <configuration>
+                  <tasks>
+                    <chmod perm="755">
+                        <fileset dir="${project.build.directory}/assembly/bin">
+                          <include name="karaf" />
+                          <include name="instance" />
+                          <include name="start"/>
+                          <include name="stop"/>
+                          <include name="status"/>
+                          <include name="client"/>
+                          <include name="shell"/>
+                        </fileset>
+                    </chmod>
+                  </tasks>
+                </configuration>
+            </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/${repoName}.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/${repoName}.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://git.opendaylight.org/gerrit/gitweb?p=${repoName}.git;a=summary</url>
+  </scm>
+</project>
diff --git a/opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/test/resources/projects/basic/archetype.properties b/opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/test/resources/projects/basic/archetype.properties
new file mode 100644 (file)
index 0000000..dd29db6
--- /dev/null
@@ -0,0 +1,6 @@
+#Thu Aug 21 14:44:29 CDT 2014
+package=it.pkg
+version=0.1-SNAPSHOT
+groupId=archetype.it
+artifactId=basic
+repoName=foo
diff --git a/opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/test/resources/projects/basic/goal.txt b/opendaylight/archetypes/opendaylight-karaf-distro-archetype/src/test/resources/projects/basic/goal.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/opendaylight/archetypes/opendaylight-karaf-features/pom.xml b/opendaylight/archetypes/opendaylight-karaf-features/pom.xml
new file mode 100644 (file)
index 0000000..4973a69
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>opendaylight-karaf-features-archetype</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>maven-archetype</packaging>
+
+  <name>opendaylight-karaf-features-archetype</name>
+
+  <build>
+    <extensions>
+      <extension>
+        <groupId>org.apache.maven.archetype</groupId>
+        <artifactId>archetype-packaging</artifactId>
+        <version>2.2</version>
+      </extension>
+    </extensions>
+
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-archetype-plugin</artifactId>
+          <version>2.2</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git/</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git/</developerConnection>
+    <url>https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=summary</url>
+  </scm>
+</project>
diff --git a/opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/META-INF/maven/archetype-metadata.xml b/opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/META-INF/maven/archetype-metadata.xml
new file mode 100644 (file)
index 0000000..158e448
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="features-integration"
+    xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <requiredProperties>
+    <requiredProperty key="repoName"/>
+  </requiredProperties>
+  <fileSets>
+    <fileSet filtered="true" encoding="UTF-8">
+    <directory>src/main/resources</directory>
+    <include>**/*.xml</include>
+    </fileSet>
+  </fileSets>
+</archetype-descriptor>
diff --git a/opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/archetype-resources/pom.xml b/opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/archetype-resources/pom.xml
new file mode 100644 (file)
index 0000000..e135e6b
--- /dev/null
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Necessary TODO: Put your copyright here.
+
+ 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/xsd/maven-4.0.0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+   <!--
+    Necessary TODO: Hookup your parent pom here, else you will not get necessary versions,
+    maven repos etc.  If you run this archetype in a subdirectory of your project, it
+    will pick the pom.xml from the parent directory as the parent pom, which may or may
+    not be correct.
+  -->
+   <artifactId>features-${repoName}</artifactId>
+   <groupId>${groupId}</groupId>
+   <!-- Optional TODO: Uncomment version if you are not using a parent pom.xml
+   <version>${version}</version>
+   -->
+   <packaging>jar</packaging>
+   <properties>
+      <features.file>features.xml</features.file>
+      <!-- Optional TODO: Move these properties to your parent pom and possibly
+            DependencyManagement section of your parent pom -->
+      <branding.version>1.0.0-SNAPSHOT</branding.version>
+      <karaf.resources.version>1.4.2-SNAPSHOT</karaf.resources.version>
+      <karaf.version>3.0.1</karaf.version>
+      <feature.test.version>0.6.2-SNAPSHOT</feature.test.version>
+      <karaf.empty.version>1.4.2-SNAPSHOT</karaf.empty.version>
+      <surefire.version>2.16</surefire.version>
+   </properties>
+   <dependencies>
+    <!--
+      Necessary TODO: Put dependencies on any feature repos
+      you use in your features.xml file.
+
+      Note: they will need to be <type>xml</xml>
+      and <classifier>features</classifier>.
+      One other thing to watch for is to make sure they are
+      <scope>compile</compile>, which they should be by default,
+      but be cautious lest they be at a different scope in a parent pom.
+
+      Examples:
+        <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>features-yangtools</artifactId>
+          <version>0.6.2-SNAPSHOT</version>
+          <classifier>features</classifier>
+          <type>xml</type>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>features-mdsal</artifactId>
+          <version>1.1-SNAPSHOT</version>
+          <classifier>features</classifier>
+          <type>xml</type>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.openflowplugin</groupId>
+          <artifactId>features-openflowplugin</artifactId>
+          <version>0.0.3-SNAPSHOT</version>
+          <classifier>features</classifier>
+          <type>xml</type>
+        </dependency>
+    -->
+
+    <!--
+      Necessary TODO: Put dependencies for bundles directly referenced
+      in your features.xml file.  For every <bundle> reference in your
+      features.xml file, you need a corresponding dependency here.
+
+      Examples:
+      <dependency>
+        <groupId>${groupId}</groupId>
+        <artifactId>${repoName}-provider</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>${groupId}</groupId>
+        <artifactId>${repoName}-model</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+    -->
+
+    <!--
+      Necessary TODO: Put dependencies for configfiles directly referenced
+      in your features.xml file.  For every <configfile> reference in your
+      features.xml file, you need a corresponding dependency here.
+
+      Example (presuming here version is coming from the parent pom):
+      <dependency>
+        <groupId>${groupId}</groupId>
+        <artifactId>${repoName}-config</artifactId>
+        <version>${project.version}</version>
+        <type>xml</type>
+        <classifier>config</classifier>
+      </dependency>
+    -->
+
+    <!--
+      Optional TODO: Remove TODO comments.
+    -->
+    <!-- test to validate features.xml -->
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>features-test</artifactId>
+      <version>${feature.test.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <!-- dependency for opendaylight-karaf-empty for use by testing -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>opendaylight-karaf-empty</artifactId>
+      <version>${karaf.empty.version}</version>
+      <type>zip</type>
+    </dependency>
+    <!-- Uncomment this if you get an error : java.lang.NoSuchMethodError: org.slf4j.helpers.MessageFormatter.format(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Lorg/slf4j/helpers/FormattingTuple;
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>1.7.2</version>
+    </dependency>
+    -->
+
+   </dependencies>
+   <build>
+      <resources>
+         <resource>
+            <directory>src/main/resources</directory>
+            <filtering>true</filtering>
+         </resource>
+      </resources>
+      <plugins>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-resources-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>filter</id>
+                  <phase>generate-resources</phase>
+                  <goals>
+                     <goal>resources</goal>
+                  </goals>
+               </execution>
+            </executions>
+         </plugin>
+         <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>build-helper-maven-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>attach-artifacts</id>
+                  <phase>package</phase>
+                  <goals>
+                     <goal>attach-artifact</goal>
+                  </goals>
+                  <configuration>
+                     <artifacts>
+                        <artifact>
+                           <file>${project.build.directory}/classes/${features.file}</file>
+                           <type>xml</type>
+                           <classifier>features</classifier>
+                        </artifact>
+                     </artifacts>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <version>${surefire.version}</version>
+            <configuration>
+              <systemPropertyVariables>
+                <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+                <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+                <karaf.distro.version>${karaf.empty.version}</karaf.distro.version>
+              </systemPropertyVariables>
+              <dependenciesToScan>
+               <dependency>org.opendaylight.yangtools:features-test</dependency>
+              </dependenciesToScan>
+            </configuration>
+          </plugin>
+      </plugins>
+   </build>
+   <scm>
+      <connection>scm:git:ssh://git.opendaylight.org:29418/${repoName}.git</connection>
+      <developerConnection>scm:git:ssh://git.opendaylight.org:29418/${repoName}.git</developerConnection>
+      <tag>HEAD</tag>
+      <url>https://git.opendaylight.org/gerrit/gitweb?p=${repoName}.git;a=summary</url>
+   </scm>
+</project>
diff --git a/opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/archetype-resources/src/main/resources/features.xml b/opendaylight/archetypes/opendaylight-karaf-features/src/main/resources/archetype-resources/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..4a59657
--- /dev/null
@@ -0,0 +1,86 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Necessary TODO: Put your copyright statement here
+
+ 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
+-->
+<features name="odl-${repoName}-${symbol_dollar}{project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+    <!--
+        Necessary TODO: Please read the features guidelines:
+        https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Feature_Best_Practices
+    -->
+    <!--
+    Necessary TODO: Add repo entries for the repositories of features you refer to
+        in this feature file but do not define here.
+        Examples:
+            <repository>mvn:org.opendaylight.yangtools/features-yangtools/0.6.2-SNAPSHOT/xml/features</repository>
+            <repository>mvn:org.opendaylight.controller/features-mdsal/1.1-SNAPSHOT/xml/features</repository>
+            <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.0.3-SNAPSHOT/xml/features</repository>
+    -->
+    <feature name='odl-${repoName}-all' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${repoName} :: All'>
+        <!--
+            Necessary TODO:
+            List all of the user consumable features you define in this feature file here.
+            Generally you would *not* list individual bundles here, but only features defined in *this* file.
+            It is useful to list them in the same order they occur in the file.
+
+            Examples:
+            <feature version='${symbol_dollar}{project.version}'>odl-${repoName}-provider</feature>
+            <feature version='${symbol_dollar}{project.version}'>odl-${repoName}-model</feature>
+        -->
+    </feature>
+    <!--
+        Necessary TODO: Define your features.  It is useful to list then in order of dependency.  So if A depends on B, list A first.
+        When naming your features please be mindful of the guidelines:
+            https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines
+        Particularly:
+            a) Prefixing names with 'odl-': https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Feature_Naming
+            b) Descriptions: https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Description
+            c) Avoid start-levels: https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Avoid_start-levels
+
+        It's also nice to list inside a feature, first the features it needs, then the bundles it needs, then the configfiles.
+        Examples:
+
+        * Basic MD-SAL Provider
+        <feature name='odl-${repoName}-provider' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${repoName} :: Provider '>
+            <feature version='1.1-SNAPSHOT'>odl-mdsal-broker</feature>
+            <feature version='${symbol_dollar}{project.version}'>odl-${repoName}-model</feature>
+            <bundle>mvn:${groupId}/${repoName}-provider/${symbol_dollar}{project.version}</bundle>
+            ... whatever other bundles you need
+        </feature>
+
+        * Basic MD-SAL Model feature
+        <feature name='odl-${repoName}-model' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${repoName} :: Model'>
+            <feature version='0.6.2-SNAPSHOT'>odl-yangtools-binding</feature>
+            <feature version='0.6.2-SNAPSHOT'>odl-yangtools-models</feature>
+            <bundle>mvn:${groupId}/${repoName}-model/${symbol_dollar}{project.version}</bundle>
+            ... whatever other bundles you need
+        </feature>
+
+        * Config Subsystem example - the config file is your config subsystem configuration
+        <feature name='odl-${repoName}-provider' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${repoName} :: Provider'>
+            <feature version='1.1-SNAPSHOT'>odl-mdsal-broker</feature>
+            <bundle>mvn:${groupId}/${repoName}-provider/${symbol_dollar}{project.version}</bundle>
+            <configfile finalname="etc/opendaylight/karaf/80-${repoName}.xml">mvn:${groupId}/${repoName}-config/${symbol_dollar}{project.version}/xml/config</configfile>
+            ... whatever other bundles you need
+        </feature>
+
+        * Basic MD-SAL Provider that uses openflowplugin-flow-services (which brings along odl-mdsal-broker)
+        <feature name='odl-${repoName}-provider' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${repoName} :: Provider'>
+            <feature version='0.0.3-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
+            <bundle>mvn:${groupId}/${repoName}-provider/${symbol_dollar}{project.version}</bundle>
+            ... whatever other bundles you need
+        </feature>
+
+    -->
+    <!-- Optional TODO: Remove TODO Comments -->
+
+</features>
diff --git a/opendaylight/archetypes/opendaylight-karaf-features/src/test/resources/projects/basic/archetype.properties b/opendaylight/archetypes/opendaylight-karaf-features/src/test/resources/projects/basic/archetype.properties
new file mode 100644 (file)
index 0000000..bab8cd2
--- /dev/null
@@ -0,0 +1,6 @@
+#Thu Aug 21 23:46:25 CDT 2014
+package=it.pkg
+version=0.1-SNAPSHOT
+groupId=archetype.it
+artifactId=basic
+repoName=foo
diff --git a/opendaylight/archetypes/opendaylight-karaf-features/src/test/resources/projects/basic/goal.txt b/opendaylight/archetypes/opendaylight-karaf-features/src/test/resources/projects/basic/goal.txt
new file mode 100644 (file)
index 0000000..e69de29
index 36af861e84826e109ed53e97fadee123b6056c18..cb597c10bd09fe4375053ced97449e25a3b68dc0 100644 (file)
@@ -6,9 +6,9 @@
   </prerequisites>
   <parent>
     <groupId>org.opendaylight.controller</groupId>
-    <artifactId>commons.parent</artifactId>
-    <version>1.0.1-SNAPSHOT</version>
-    <relativePath>../commons/parent</relativePath>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.2-SNAPSHOT</version>
+    <relativePath>../commons/opendaylight</relativePath>
   </parent>
   <scm>
     <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
@@ -39,5 +39,8 @@
   </distributionManagement>
   <modules>
     <module>odl-model-project</module>
+    <module>opendaylight-configfile-archetype</module>
+    <module>opendaylight-karaf-distro-archetype</module>
+    <module>opendaylight-karaf-features</module>
   </modules>
 </project>
index 2f1cd8b925ce38719702cc707906cb05df042fd4..873ad7a9b7e3f4572ca3b7809a901ac716cc391f 100644 (file)
     <yang-ext.version>2013.09.07.4-SNAPSHOT</yang-ext.version>
     <yang-jmx-generator.version>1.0.0-SNAPSHOT</yang-jmx-generator.version>
     <yangtools.version>0.6.2-SNAPSHOT</yangtools.version>
+      <sshd-core.version>0.12.0</sshd-core.version>
   </properties>
 
   <dependencyManagement>
         <artifactId>netconf-netty-util</artifactId>
         <version>${netconf.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.sshd</groupId>
+        <artifactId>sshd-core</artifactId>
+        <version>${sshd-core.version}</version>
+      </dependency>
       <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-classic</artifactId>
index d70bf4641192c488d043e2ba7ff4bc41279b1375..9a7677099dd8be04b4357b707c135a8279153a64 100644 (file)
           <groupId>org.opendaylight.controller.thirdparty</groupId>
           <artifactId>ganymed</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.apache.sshd</groupId>
+          <artifactId>sshd-core</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>binding-generator-api</artifactId>
index 344694381a222850fb23ccac0cc8415b3296f472..dba2908e9c4a9309bf3a1acba4e4fcc5974f7a03 100644 (file)
@@ -73,6 +73,7 @@ public class TestHelper {
                 mavenBundle(CONTROLLER, "netconf-client").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "netconf-util").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "netconf-netty-util").versionAsInProject(), //
+                mavenBundle("org.apache.sshd", "sshd-core").versionAsInProject(), //
                 mavenBundle("org.openexi", "nagasena").versionAsInProject(), //
                 mavenBundle("org.openexi", "nagasena-rta").versionAsInProject(), //
                 mavenBundle(CONTROLLER + ".thirdparty", "ganymed").versionAsInProject(), //
index 87b3f837e8c43a25f74f78cfbdd0b425bd8d94e9..2aa5d15224be5efa4c4f6f56a2498eab9df5b4f7 100644 (file)
@@ -12,7 +12,7 @@ import io.netty.util.concurrent.Promise;
 import java.io.IOException;
 import org.opendaylight.controller.netconf.nettyutil.AbstractChannelInitializer;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshHandler;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
 import org.opendaylight.protocol.framework.SessionListenerFactory;
 
 final class SshClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
@@ -32,7 +32,7 @@ final class SshClientChannelInitializer extends AbstractChannelInitializer<Netco
     @Override
     public void initialize(final Channel ch, final Promise<NetconfClientSession> promise) {
         try {
-            ch.pipeline().addFirst(SshHandler.createForNetconfSubsystem(authenticationHandler));
+            ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(authenticationHandler));
             super.initialize(ch,promise);
         } catch (final IOException e) {
             throw new RuntimeException(e);
index 6826b4a09ca6013f57c192ef07fcef3bdd7e7387..56f674bc34f287d74224ad269a1274c657109e68 100644 (file)
@@ -9,13 +9,10 @@
 package org.opendaylight.controller.netconf.it;
 
 import static java.util.Arrays.asList;
-import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
-import ch.ethz.ssh2.Connection;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
@@ -30,8 +27,6 @@ import junit.framework.Assert;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
@@ -47,6 +42,7 @@ import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProduce
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProviderImpl;
@@ -144,16 +140,6 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
     }
 
     public AuthenticationHandler getAuthHandler() throws IOException {
-        final AuthenticationHandler authHandler = mock(AuthenticationHandler.class);
-        doAnswer(new Answer() {
-            @Override
-            public Object answer(final InvocationOnMock invocation) throws Throwable {
-                Connection conn = (Connection) invocation.getArguments()[0];
-                conn.authenticateWithPassword("user", "pwd");
-                return null;
-            }
-        }).when(authHandler).authenticate(any(Connection.class));
-        doReturn("auth handler").when(authHandler).toString();
-        return authHandler;
+        return new LoginPassword("user", "pwd");
     }
 }
index 13041598d1a149932aa37e6efa8cb6e414decd87..80dc1ae0fd352fd6827701059eeb10fa5050f5f2 100644 (file)
       <groupId>org.opendaylight.controller.thirdparty</groupId>
       <artifactId>ganymed</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.sshd</groupId>
+      <artifactId>sshd-core</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.openexi</groupId>
       <artifactId>nagasena</artifactId>
@@ -73,6 +77,7 @@
       <groupId>xmlunit</groupId>
       <artifactId>xmlunit</artifactId>
     </dependency>
+
   </dependencies>
 
   <build>
@@ -82,7 +87,7 @@
         <artifactId>maven-bundle-plugin</artifactId>
         <configuration>
           <instructions>
-            <Import-Package>ch.ethz.ssh2, com.google.common.base, com.google.common.collect, io.netty.buffer,
+            <Import-Package>org.apache.sshd.*, ch.ethz.ssh2, com.google.common.base, com.google.common.collect, io.netty.buffer,
               io.netty.channel, io.netty.channel.socket, io.netty.handler.codec, io.netty.handler.ssl, io.netty.util,
               io.netty.util.concurrent, javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax,
               javax.xml.transform.stream, org.opendaylight.controller.netconf.api,
index b22b792d52980227d2aa85da39436535a19097b2..eea2b8693a26449a5f96b8d791f4b07082273bf8 100644 (file)
@@ -9,12 +9,17 @@
 package org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication;
 
 import ch.ethz.ssh2.Connection;
-
 import java.io.IOException;
+import org.apache.sshd.ClientSession;
 
 /**
  * Class providing authentication facility to SSH handler.
  */
 public abstract class AuthenticationHandler {
     public abstract void authenticate(Connection connection) throws IOException;
+
+
+    public abstract String getUsername();
+
+    public abstract org.apache.sshd.client.future.AuthFuture authenticate(final ClientSession session) throws IOException;
 }
index b67aa0f96dcd53a084965fc3766399a26f2a5869..553e5359ffed1cd8b5728734bb5546e3abb0f72e 100644 (file)
@@ -8,10 +8,13 @@
 
 package org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication;
 
-import ch.ethz.ssh2.Connection;
-
 import java.io.IOException;
 
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.client.future.AuthFuture;
+
+import ch.ethz.ssh2.Connection;
+
 /**
  * Class Providing username/password authentication option to
  * {@link org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshHandler}
@@ -27,10 +30,21 @@ public class LoginPassword extends AuthenticationHandler {
 
     @Override
     public void authenticate(Connection connection) throws IOException {
-        boolean isAuthenticated = connection.authenticateWithPassword(username, password);
+        final boolean isAuthenticated = connection.authenticateWithPassword(username, password);
 
         if (!isAuthenticated) {
             throw new IOException("Authentication failed.");
         }
     }
+
+    @Override
+    public String getUsername() {
+        return username;
+    }
+
+    @Override
+    public AuthFuture authenticate(final ClientSession session) throws IOException {
+        session.addPasswordIdentity(password);
+        return session.auth();
+    }
 }
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java
new file mode 100644 (file)
index 0000000..2761a45
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * 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.nettyutil.handler.ssh.client;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import java.io.IOException;
+import java.net.SocketAddress;
+import org.apache.sshd.ClientChannel;
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.SshClient;
+import org.apache.sshd.client.future.AuthFuture;
+import org.apache.sshd.client.future.ConnectFuture;
+import org.apache.sshd.client.future.OpenFuture;
+import org.apache.sshd.common.future.CloseFuture;
+import org.apache.sshd.common.future.SshFutureListener;
+import org.apache.sshd.common.io.IoInputStream;
+import org.apache.sshd.common.io.IoReadFuture;
+import org.apache.sshd.common.util.Buffer;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Netty SSH handler class. Acts as interface between Netty and SSH library.
+ */
+public class AsyncSshHandler extends ChannelOutboundHandlerAdapter {
+
+    private static final Logger logger = LoggerFactory.getLogger(AsyncSshHandler.class);
+    public static final String SUBSYSTEM = "netconf";
+
+    public static final SshClient DEFAULT_CLIENT = SshClient.setUpDefaultClient();
+
+    public static final int SSH_DEFAULT_NIO_WORKERS = 8;
+
+    static {
+        // TODO make configurable, or somehow reuse netty threadpool
+        DEFAULT_CLIENT.setNioWorkers(SSH_DEFAULT_NIO_WORKERS);
+        DEFAULT_CLIENT.start();
+    }
+
+    private final AuthenticationHandler authenticationHandler;
+    private final SshClient sshClient;
+
+    private SshReadAsyncListener sshReadAsyncListener;
+    private ClientChannel channel;
+    private ClientSession session;
+    private ChannelPromise connectPromise;
+
+    public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler) throws IOException {
+        return new AsyncSshHandler(authenticationHandler, DEFAULT_CLIENT);
+    }
+
+    /**
+     *
+     * @param authenticationHandler
+     * @param sshClient started SshClient
+     * @throws IOException
+     */
+    public AsyncSshHandler(final AuthenticationHandler authenticationHandler, final SshClient sshClient) throws IOException {
+        this.authenticationHandler = Preconditions.checkNotNull(authenticationHandler);
+        this.sshClient = Preconditions.checkNotNull(sshClient);
+        // Start just in case
+        sshClient.start();
+    }
+
+    private void startSsh(final ChannelHandlerContext ctx, final SocketAddress address) {
+        logger.debug("Starting SSH to {} on channel: {}", address, ctx.channel());
+
+        final ConnectFuture sshConnectionFuture = sshClient.connect(authenticationHandler.getUsername(), address);
+        sshConnectionFuture.addListener(new SshFutureListener<ConnectFuture>() {
+            @Override
+            public void operationComplete(final ConnectFuture future) {
+                if (future.isConnected()) {
+                    handleSshSessionCreated(future, ctx);
+                } else {
+                    handleSshSetupFailure(ctx, future.getException());
+                }
+            }
+        });
+    }
+
+    private synchronized void handleSshSessionCreated(final ConnectFuture future, final ChannelHandlerContext ctx) {
+        try {
+            logger.trace("SSH session created on channel: {}", ctx.channel());
+
+            session = future.getSession();
+            final AuthFuture authenticateFuture = authenticationHandler.authenticate(session);
+            authenticateFuture.addListener(new SshFutureListener<AuthFuture>() {
+                @Override
+                public void operationComplete(final AuthFuture future) {
+                    if (future.isSuccess()) {
+                        handleSshAuthenticated(session, ctx);
+                    } else {
+                        handleSshSetupFailure(ctx, future.getException());
+                    }
+                }
+            });
+        } catch (final IOException e) {
+            handleSshSetupFailure(ctx, e);
+        }
+    }
+
+    private synchronized void handleSshAuthenticated(final ClientSession session, final ChannelHandlerContext ctx) {
+        try {
+            logger.debug("SSH session authenticated on channel: {}, server version: {}", ctx.channel(), session.getServerVersion());
+
+            channel = session.createSubsystemChannel(SUBSYSTEM);
+            channel.setStreaming(ClientChannel.Streaming.Async);
+            channel.open().addListener(new SshFutureListener<OpenFuture>() {
+                @Override
+                public void operationComplete(final OpenFuture future) {
+                    if(future.isOpened()) {
+                        handleSshChanelOpened(ctx);
+                    } else {
+                        handleSshSetupFailure(ctx, future.getException());
+                    }
+                }
+            });
+
+
+        } catch (final IOException e) {
+            handleSshSetupFailure(ctx, e);
+        }
+    }
+
+    private synchronized void handleSshChanelOpened(final ChannelHandlerContext ctx) {
+        logger.trace("SSH subsystem channel opened successfully on channel: {}", ctx.channel());
+
+        connectPromise.setSuccess();
+        connectPromise = null;
+        ctx.fireChannelActive();
+
+        final IoInputStream asyncOut = channel.getAsyncOut();
+        sshReadAsyncListener = new SshReadAsyncListener(ctx, asyncOut);
+    }
+
+    private synchronized void handleSshSetupFailure(final ChannelHandlerContext ctx, final Throwable e) {
+        logger.warn("Unable to setup SSH connection on channel: {}", ctx.channel(), e);
+        connectPromise.setFailure(e);
+        connectPromise = null;
+        throw new IllegalStateException("Unable to setup SSH connection on channel: " + ctx.channel(), e);
+    }
+
+    @Override
+    public synchronized void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) {
+        try {
+            if(channel.getAsyncIn().isClosed() || channel.getAsyncIn().isClosing()) {
+                handleSshSessionClosed(ctx);
+            } else {
+                channel.getAsyncIn().write(toBuffer(msg));
+                ((ByteBuf) msg).release();
+            }
+        } catch (final Exception e) {
+            logger.warn("Exception while writing to SSH remote on channel {}", ctx.channel(), e);
+            throw new IllegalStateException("Exception while writing to SSH remote on channel " + ctx.channel(),e);
+        }
+    }
+
+    private static void handleSshSessionClosed(final ChannelHandlerContext ctx) {
+        logger.debug("SSH session closed on channel: {}", ctx.channel());
+        ctx.fireChannelInactive();
+    }
+
+    private Buffer toBuffer(final Object msg) {
+        // TODO Buffer vs ByteBuf translate, Can we handle that better ?
+        Preconditions.checkState(msg instanceof ByteBuf);
+        final ByteBuf byteBuf = (ByteBuf) msg;
+        final byte[] temp = new byte[byteBuf.readableBytes()];
+        byteBuf.readBytes(temp, 0, byteBuf.readableBytes());
+        return new Buffer(temp);
+    }
+
+    @Override
+    public synchronized void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) throws Exception {
+        this.connectPromise = promise;
+        startSsh(ctx, remoteAddress);
+    }
+
+    @Override
+    public void close(final ChannelHandlerContext ctx, final ChannelPromise promise) throws Exception {
+        disconnect(ctx, promise);
+    }
+
+    @Override
+    public synchronized void disconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) throws Exception {
+        if(sshReadAsyncListener != null) {
+            sshReadAsyncListener.close();
+        }
+
+        session.close(false).addListener(new SshFutureListener<CloseFuture>() {
+            @Override
+            public void operationComplete(final CloseFuture future) {
+                if(future.isClosed() == false) {
+                    session.close(true);
+                }
+                session = null;
+            }
+        });
+
+        channel = null;
+    }
+
+    /**
+     * Listener over async input stream from SSH session.
+     * This listeners schedules reads in a loop until the session is closed or read fails.
+     */
+    private static class SshReadAsyncListener implements SshFutureListener<IoReadFuture>, AutoCloseable {
+        private static final int BUFFER_SIZE = 8192;
+
+        private final ChannelHandlerContext ctx;
+
+        private IoInputStream asyncOut;
+        private Buffer buf;
+        private IoReadFuture currentReadFuture;
+
+        public SshReadAsyncListener(final ChannelHandlerContext ctx, final IoInputStream asyncOut) {
+            this.ctx = ctx;
+            this.asyncOut = asyncOut;
+            buf = new Buffer(BUFFER_SIZE);
+            asyncOut.read(buf).addListener(this);
+        }
+
+        @Override
+        public synchronized void operationComplete(final IoReadFuture future) {
+            if(future.getException() != null) {
+
+                if(asyncOut.isClosed() || asyncOut.isClosing()) {
+                    // We are closing
+                    handleSshSessionClosed(ctx);
+                } else {
+                    logger.warn("Exception while reading from SSH remote on channel {}", ctx.channel(), future.getException());
+                    throw new IllegalStateException("Exception while reading from SSH remote on channel " + ctx.channel(), future.getException());
+                }
+            }
+
+            if (future.getRead() > 0) {
+                ctx.fireChannelRead(Unpooled.wrappedBuffer(buf.array(), 0, future.getRead()));
+
+                // Schedule next read
+                buf = new Buffer(BUFFER_SIZE);
+                currentReadFuture = asyncOut.read(buf);
+                currentReadFuture.addListener(this);
+            }
+        }
+
+        @Override
+        public synchronized void close() throws Exception {
+            // Remove self as listener on close to prevent reading from closed input
+            if(currentReadFuture != null) {
+                currentReadFuture.removeListener(this);
+            }
+
+            asyncOut = null;
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/Invoker.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/Invoker.java
deleted file mode 100644 (file)
index eab2546..0000000
+++ /dev/null
@@ -1,51 +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.nettyutil.handler.ssh.client;
-
-import java.io.IOException;
-
-/**
- * Abstract class providing mechanism of invoking various SSH level services.
- * Class is not allowed to be extended, as it provides its own implementations via instance initiators.
- */
-abstract class Invoker {
-    private boolean invoked = false;
-
-    private Invoker() {
-    }
-
-    protected boolean isInvoked() {
-        return invoked;
-    }
-
-    public void setInvoked() {
-        this.invoked = true;
-    }
-
-    abstract void invoke(SshSession session) throws IOException;
-
-    public static Invoker netconfSubsystem(){
-        return subsystem("netconf");
-    }
-
-    public static Invoker subsystem(final String subsystem) {
-        return new Invoker() {
-            @Override
-            synchronized void invoke(SshSession session) throws IOException {
-                if (isInvoked()) {
-                    throw new IllegalStateException("Already invoked.");
-                }
-                try {
-                    session.startSubSystem(subsystem);
-                } finally {
-                    setInvoked();
-                }
-            }
-        };
-    }
-}
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshClient.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshClient.java
deleted file mode 100644 (file)
index 271b781..0000000
+++ /dev/null
@@ -1,71 +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.nettyutil.handler.ssh.client;
-
-import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.Session;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.virtualsocket.VirtualSocket;
-
-/**
- * Wrapper class around GANYMED SSH java library.
- */
-class SshClient {
-    private final VirtualSocket socket;
-    private final Map<Integer, SshSession> openSessions = new HashMap<>();
-    private final AuthenticationHandler authenticationHandler;
-    private Connection connection;
-
-    public SshClient(VirtualSocket socket, AuthenticationHandler authenticationHandler) throws IOException {
-        this.socket = socket;
-        this.authenticationHandler = authenticationHandler;
-    }
-
-    public SshSession openSession() throws IOException {
-        if (connection == null) {
-            connect();
-        }
-
-        Session session = connection.openSession();
-        SshSession sshSession = new SshSession(session);
-        openSessions.put(openSessions.size(), sshSession);
-
-        return sshSession;
-    }
-
-    private void connect() throws IOException {
-        connection = new Connection(socket);
-
-        connection.connect();
-        authenticationHandler.authenticate(connection);
-    }
-
-
-    public void close() {
-        for (SshSession session : openSessions.values()){
-            session.close();
-        }
-
-        openSessions.clear();
-
-        if (connection != null) {
-            connection.close();
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "SshClient{" +
-                "socket=" + socket +
-                '}';
-    }
-}
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshClientAdapter.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshClientAdapter.java
deleted file mode 100644 (file)
index 4ca7bdf..0000000
+++ /dev/null
@@ -1,138 +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.nettyutil.handler.ssh.client;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelPromise;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.concurrent.atomic.AtomicBoolean;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * Worker thread class. Handles all downstream and upstream events in SSH Netty
- * pipeline.
- */
-class SshClientAdapter implements Runnable {
-    private static final Logger logger = LoggerFactory.getLogger(SshClientAdapter.class);
-
-    private static final int BUFFER_SIZE = 1024;
-
-    private final SshClient sshClient;
-    private final Invoker invoker;
-
-    private OutputStream stdIn;
-
-    private final Queue<ByteBuf> postponed = new LinkedList<>();
-
-    private ChannelHandlerContext ctx;
-    private ChannelPromise disconnectPromise;
-
-    private final AtomicBoolean stopRequested = new AtomicBoolean(false);
-
-    private final Object lock = new Object();
-
-    public SshClientAdapter(final SshClient sshClient, final Invoker invoker) {
-        this.sshClient = sshClient;
-        this.invoker = invoker;
-    }
-
-    // TODO ganymed spawns a Thread that receives the data from remote inside TransportManager
-    // Get rid of this thread and reuse Ganymed internal thread (not sure if its possible without modifications in ganymed)
-    public void run() {
-        try {
-            final SshSession session = sshClient.openSession();
-            invoker.invoke(session);
-            final InputStream stdOut = session.getStdout();
-
-            synchronized (lock) {
-                stdIn = session.getStdin();
-                while (postponed.peek() != null) {
-                    writeImpl(postponed.poll());
-                }
-            }
-
-            while (!stopRequested.get()) {
-                final byte[] readBuff = new byte[BUFFER_SIZE];
-                final int c = stdOut.read(readBuff);
-                if (c == -1) {
-                    continue;
-                }
-
-                ctx.fireChannelRead(Unpooled.copiedBuffer(readBuff, 0, c));
-            }
-        } catch (final Exception e) {
-            logger.error("Unexpected exception", e);
-        } finally {
-            sshClient.close();
-
-            synchronized (lock) {
-                if (disconnectPromise != null) {
-                    ctx.disconnect(disconnectPromise);
-                }
-            }
-        }
-    }
-
-    // TODO: needs rework to match netconf framer API.
-    public void write(final ByteBuf message) throws IOException {
-        synchronized (lock) {
-            if (stdIn == null) {
-                postponed.add(message);
-                return;
-            }
-            writeImpl(message);
-        }
-    }
-
-    private void writeImpl(final ByteBuf message) throws IOException {
-        message.getBytes(0, stdIn, message.readableBytes());
-        message.release();
-        stdIn.flush();
-    }
-
-    public void stop(final ChannelPromise promise) {
-        synchronized (lock) {
-            stopRequested.set(true);
-            disconnectPromise = promise;
-        }
-    }
-
-    public Thread start(final ChannelHandlerContext ctx, final ChannelFuture channelFuture) {
-        checkArgument(channelFuture.isSuccess());
-        checkNotNull(ctx.channel().remoteAddress());
-        synchronized (this) {
-            checkState(this.ctx == null);
-            this.ctx = ctx;
-        }
-        final String threadName = toString();
-        final Thread thread = new Thread(this, threadName);
-        thread.start();
-        return thread;
-    }
-
-    @Override
-    public String toString() {
-        return "SshClientAdapter{" +
-                "sshClient=" + sshClient +
-                '}';
-    }
-}
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshHandler.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshHandler.java
deleted file mode 100644 (file)
index c710a01..0000000
+++ /dev/null
@@ -1,87 +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.nettyutil.handler.ssh.client;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelOutboundHandlerAdapter;
-import io.netty.channel.ChannelPromise;
-import java.io.IOException;
-import java.net.SocketAddress;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.virtualsocket.VirtualSocket;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Netty SSH handler class. Acts as interface between Netty and SSH library. All standard Netty message handling
- * stops at instance of this class. All downstream events are handed of to wrapped {@link org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshClientAdapter};
- */
-public class SshHandler extends ChannelOutboundHandlerAdapter {
-    private static final Logger logger = LoggerFactory.getLogger(SshHandler.class);
-    private static final String SOCKET = "socket";
-
-    private final VirtualSocket virtualSocket = new VirtualSocket();
-    private final SshClientAdapter sshClientAdapter;
-
-
-    public static SshHandler createForNetconfSubsystem(AuthenticationHandler authenticationHandler) throws IOException {
-        return new SshHandler(authenticationHandler, Invoker.netconfSubsystem());
-    }
-
-
-    public SshHandler(AuthenticationHandler authenticationHandler, Invoker invoker) throws IOException {
-        SshClient sshClient = new SshClient(virtualSocket, authenticationHandler);
-        this.sshClientAdapter = new SshClientAdapter(sshClient, invoker);
-    }
-
-    @Override
-    public void handlerAdded(ChannelHandlerContext ctx){
-        if (ctx.channel().pipeline().get(SOCKET) == null) {
-            ctx.channel().pipeline().addFirst(SOCKET, virtualSocket);
-        }
-    }
-
-    @Override
-    public void handlerRemoved(ChannelHandlerContext ctx) {
-        if (ctx.channel().pipeline().get(SOCKET) != null) {
-            ctx.channel().pipeline().remove(SOCKET);
-        }
-    }
-
-    @Override
-    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws IOException {
-        this.sshClientAdapter.write((ByteBuf) msg);
-    }
-
-    @Override
-    public void connect(final ChannelHandlerContext ctx,
-                        SocketAddress remoteAddress,
-                        SocketAddress localAddress,
-                        ChannelPromise promise) {
-        ctx.connect(remoteAddress, localAddress, promise);
-
-        promise.addListener(new ChannelFutureListener() {
-            public void operationComplete(ChannelFuture channelFuture) {
-                if (channelFuture.isSuccess()) {
-                    sshClientAdapter.start(ctx, channelFuture);
-                } else {
-                    logger.debug("Failed to connect to remote host");
-                }
-            }}
-        );
-    }
-
-    @Override
-    public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) {
-        sshClientAdapter.stop(promise);
-    }
-}
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshSession.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshSession.java
deleted file mode 100644 (file)
index 9cdc592..0000000
+++ /dev/null
@@ -1,52 +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.nettyutil.handler.ssh.client;
-
-import ch.ethz.ssh2.Session;
-import ch.ethz.ssh2.channel.Channel;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Wrapper class for proprietary SSH sessions implementations
- */
-class SshSession implements Closeable {
-    private final Session session;
-
-    public SshSession(final Session session) {
-        this.session = session;
-    }
-
-    public void startSubSystem(final String name) throws IOException {
-        session.startSubSystem(name);
-    }
-
-    public InputStream getStdout() {
-        return session.getStdout();
-    }
-
-    // FIXME according to http://www.ganymed.ethz.ch/ssh2/FAQ.html#blocking you should read data from both stdout and stderr to prevent window filling up (since stdout and stderr share a window)
-    // FIXME stdErr is not used anywhere
-    public InputStream getStderr() {
-        return session.getStderr();
-    }
-
-    public OutputStream getStdin() {
-        return session.getStdin();
-    }
-
-    @Override
-    public void close() {
-        if (session.getState() == Channel.STATE_OPEN || session.getState() == Channel.STATE_OPENING) {
-            session.close();
-        }
-    }
-}
index febf3abf8e6fcbb6b035dfafffebb784e6392f44..8d48077f93174dbf211d4ac5be0568a9b6cfab9b 100644 (file)
       <groupId>org.opendaylight.controller.thirdparty</groupId>
       <artifactId>ganymed</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.sshd</groupId>
+      <artifactId>sshd-core</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
index 61297835a07b684dd009176c6c0e16c0971c2b5e..1b2201170a2426dabce3174515bfe3784e374ced 100644 (file)
@@ -29,7 +29,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.netconf.netty.EchoClientHandler.State;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshHandler;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProviderImpl;
@@ -94,7 +94,7 @@ public class SSHTest {
         ChannelInitializer<NioSocketChannel> channelInitializer = new ChannelInitializer<NioSocketChannel>() {
             @Override
             public void initChannel(NioSocketChannel ch) throws Exception {
-                ch.pipeline().addFirst(SshHandler.createForNetconfSubsystem(new LoginPassword("a", "a")));
+                ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(new LoginPassword("a", "a")));
                 ch.pipeline().addLast(echoClientHandler);
             }
         };
diff --git a/pom.xml b/pom.xml
index 22c03ac7acedc509d68f7f3edbcee5171eb76e1a..10c05e254f84d88d25f1e3e9b5ef3da3af84b7a1 100644 (file)
--- a/pom.xml
+++ b/pom.xml
     <module>opendaylight/distribution/opendaylight-karaf</module>
     <module>opendaylight/distribution/opendaylight-karaf-resources</module>
     <module>features</module>
+
+    <!-- archetypes -->
+    <module>opendaylight/archetypes</module>
   </modules>
   <scm>
     <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>