Merge "Added IP address of the OF switch to flow-node"
authorEd Warnicke <eaw@cisco.com>
Tue, 26 Aug 2014 10:18:41 +0000 (10:18 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 26 Aug 2014 10:18:41 +0000 (10:18 +0000)
133 files changed:
features/adsal/pom.xml
features/adsal/src/main/resources/features.xml
features/base/pom.xml
features/base/src/main/resources/features.xml
features/config-netty/src/main/resources/features.xml
features/config-persister/src/main/resources/features.xml
features/config/src/main/resources/features.xml
features/flow/src/main/resources/features.xml
features/mdsal/pom.xml
features/mdsal/src/main/resources/features.xml
features/netconf/pom.xml
features/netconf/src/main/resources/features.xml
features/nsf/pom.xml
features/nsf/src/main/resources/features.xml
features/protocol-framework/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/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/ConfigurationService.java
opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/ContainerConfigurationService.java
opendaylight/distribution/opendaylight-karaf-resources/src/main/resources/configuration/tomcat-server.xml
opendaylight/distribution/opendaylight-karaf-resources/src/main/resources/etc/custom.properties
opendaylight/distribution/opendaylight-karaf/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/karaf-tomcat-security/pom.xml [new file with mode: 0644]
opendaylight/karaf-tomcat-security/src/main/java/org/opendaylight/controller/karafsecurity/ControllerCustomRealm.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/pom.xml
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/FindLeader.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/FindLeaderReply.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/AbstractActorTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/resources/application.conf
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/BindingTransactionChain.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/BindingNormalizedCodecTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodec.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeGetter.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/PathUtils.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/QNameFactory.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/util/InstanceIdentifierUtils.java
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodecTest.java
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/PathUtilsTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/QNameFactoryTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/akka.conf
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/TransactionChain.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/TransactionChainFactory.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxy.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionProxy.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/FindPrimary.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PrimaryFound.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PrimaryNotFound.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxyTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreTransactionChain.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadTransaction.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/BucketStore.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/Gossiper.java
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/gossip/BucketStoreTest.java
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/gossip/GossiperTest.java
opendaylight/md-sal/sal-remoterpc-connector/src/test/resources/application.conf
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowComparator.java
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.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-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringServiceTracker.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializer.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/NetconfState.java
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java
opendaylight/netconf/netconf-netty-util/pom.xml
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoder.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java
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-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/ChannelInputStream.java [deleted file]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/ChannelOutputStream.java [deleted file]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/VirtualSocket.java [deleted file]
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/ChunkedFramingMechanismEncoderTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/EOMFramingMechanismEncoderTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/FramingMechanismHandlerFactoryTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfChunkAggregatorTest.java
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoderTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoderTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/authentication/LoginPasswordTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-ssh/pom.xml
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerPoolMemberAware.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/Activator.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/GlobalConstants.java
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/action/ActionTest.java
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/DataPacketService.java
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/FlowProgrammerService.java
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/ProtocolService.java [new file with mode: 0644]
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/ReadService.java
opendaylight/sal/implementation/src/test/java/org/opendaylight/controller/sal/implementation/ProtocolServiceTest.java [new file with mode: 0644]
opendaylight/web/flows/src/main/resources/js/page.js
pom.xml

index 0ccb17a664ef203a88aa01e263811d998f09222f..0ce976e2ef3beed38a8019cfc63074d04989a674 100644 (file)
@@ -9,7 +9,7 @@
   </parent>
   <artifactId>features-adsal</artifactId>
   <version>${sal.version}</version>
-  <packaging>pom</packaging>
+  <packaging>jar</packaging>
   <name>Features :: AD-SAL Features</name>
   <description>AD-SAL Features POM</description>
   <properties>
   <dependencies>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
-      <artifactId>base-features</artifactId>
-      <version>${project.parent.version}</version>
+      <artifactId>features-base</artifactId>
       <classifier>features</classifier>
       <type>xml</type>
-      <scope>runtime</scope>
+    </dependency>
+    <!-- test to validate features.xml -->
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>features-test</artifactId>
+    </dependency>
+    <!-- dependency for opendaylight-karaf-empty for use by testing -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>opendaylight-karaf-empty</artifactId>
+      <version>1.4.2-SNAPSHOT</version>
+      <type>zip</type>
+    </dependency>
+    <!-- Bundle dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>dummy-console</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal.connection</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal.connection.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal.networkconfiguration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal.networkconfiguration.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services-implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.stub</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>configuration.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>logging.bridge</artifactId>
     </dependency>
   </dependencies>
   <build>
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemPropertyVariables>
+            <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+            <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+            <karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>
+          </systemPropertyVariables>
+          <dependenciesToScan>
+           <dependency>org.opendaylight.yangtools:features-test</dependency>
+          </dependenciesToScan>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 </project>
index f955315164ced774198c742c5c8f55171abe58b3..e12ca8e5e990acc860dc9e56e4eed57ed9c2a0e0 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <features name="adsal-${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">
+   <repository>mvn:org.opendaylight.controller/features-base/${commons.opendaylight.version}/xml/features</repository>
    <feature name="odl-adsal-all" description="OpenDaylight AD-SAL All Features" version="${sal.version}">
       <feature version="${sal.version}">odl-adsal-core</feature>
       <feature version="${sal.networkconfiguration.version}">odl-adsal-networkconfiguration</feature>
       <feature version="${configuration.version}">odl-adsal-configuration</feature>
    </feature>
    <feature name="odl-adsal-core" description="OpenDaylight :: AD-SAL :: Core" version="${sal.version}">
-      <feature>base-felix-dm</feature>
-      <feature>base-dummy-console</feature>
+      <feature>odl-base-felix-dm</feature>
+      <feature>odl-base-dummy-console</feature>
       <feature version="${project.version}">odl-adsal-thirdparty</feature>
-      <bundle start="true" start-level="35">mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
+      <bundle start="true">mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
   <!--    <bundle>mvn:org.osgi/org.osgi.compendium/${osgi.compendium.version}</bundle> -->
       <bundle>mvn:org.opendaylight.controller/sal/${sal.version}</bundle>
       <bundle>mvn:org.opendaylight.controller/sal.implementation/${sal.implementation.version}</bundle>
    </feature>
    <feature name="odl-adsal-networkconfiguration" description="OpenDaylight :: AD-SAL :: Network Configuration" version="${sal.networkconfiguration.version}">
+      <feature>odl-adsal-core</feature>
       <bundle>mvn:org.opendaylight.controller/sal.networkconfiguration/${sal.networkconfiguration.version}</bundle>
       <bundle>mvn:org.opendaylight.controller/sal.networkconfiguration.implementation/${sal.networkconfiguration.version}</bundle>
    </feature>
@@ -28,8 +30,8 @@
    </feature>
    <feature name="odl-adsal-clustering" description="OpenDaylight :: AD-SAL :: Clustering" version="${clustering.services.version}">
       <feature>transaction</feature>
-      <feature>base-felix-dm</feature>
-      <feature>base-eclipselink-persistence</feature>
+      <feature>odl-base-felix-dm</feature>
+      <feature>odl-base-eclipselink-persistence</feature>
       <feature version="${sal.version}">odl-adsal-core</feature>
       <bundle>mvn:org.opendaylight.controller/clustering.services/${clustering.services.version}</bundle>
       <bundle>mvn:org.opendaylight.controller/clustering.services-implementation/${clustering.services_implementation.version}</bundle>
index d925f51b948cfe444a77a5875546e6986ec5ca26..ed8e2a8c20d2765ade8cbe42856f8b94460eeb40 100644 (file)
     <version>1.4.2-SNAPSHOT</version>
     <relativePath>../../opendaylight/commons/opendaylight</relativePath>
   </parent>
-  <artifactId>base-features</artifactId>
-  <packaging>pom</packaging>
+  <artifactId>features-base</artifactId>
+  <packaging>jar</packaging>
   <name>${project.artifactId}</name>
   <description>Base Features POM</description>
   <properties>
     <features.file>features.xml</features.file>
   </properties>
+  <dependencies>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>dummy-console</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>karaf-tomcat-security</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.thirdparty</groupId>
+      <artifactId>ganymed</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.datatype</groupId>
+      <artifactId>jackson-datatype-json-org</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.jaxrs</groupId>
+      <artifactId>jackson-jaxrs-base</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.jaxrs</groupId>
+      <artifactId>jackson-jaxrs-json-provider</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.module</groupId>
+      <artifactId>jackson-module-jaxb-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-client</artifactId>
+    </dependency>
+    <!-- Jersey for JAXRS -->
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-server</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-fileupload</groupId>
+      <artifactId>commons-fileupload</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-net</groupId>
+      <artifactId>commons-net</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>eclipselink</groupId>
+      <artifactId>javax.persistence</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>eclipselink</groupId>
+      <artifactId>javax.resource</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>javax.servlet</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>javax.servlet.jsp</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.command</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.runtime</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.cm</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.console</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.ds</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.launcher</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.osgi</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.osgi.services</artifactId>
+    </dependency>
+    <!-- Gemini Web -->
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.gemini.web.core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.gemini.web.extender</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.gemini.web.tomcat</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.kernel.equinox.extensions</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.io</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.math</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.osgi</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.osgi.manifest</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>geminiweb</groupId>
+      <artifactId>org.eclipse.virgo.util.parser.manifest</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-buffer</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-codec-http</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-common</artifactId>
+    </dependency>
+
+    <!--Netty-->
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-handler</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-transport</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.activation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.annotation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.ejb</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.el</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.mail.glassfish</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.servlet.jsp.jstl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.servlet.jsp.jstl.impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>javax.xml.rpc</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.catalina</artifactId>
+      <version>7.0.53.v201406061610</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.catalina.ha</artifactId>
+      <version>7.0.53.v201406070630</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.catalina.tribes</artifactId>
+      <version>7.0.53.v201406070630</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.coyote</artifactId>
+      <version>7.0.53.v201406070630</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.el</artifactId>
+      <version>7.0.53.v201406060720</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.jasper</artifactId>
+      <version>7.0.53.v201406070630</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.juli.extras</artifactId>
+      <version>7.0.53.v201406060720</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.tomcat.api</artifactId>
+      <version>7.0.53.v201406060720</version>
+    </dependency>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.tomcat.util</artifactId>
+      <version>7.0.53.v201406070630</version>
+    </dependency>
+    <dependency>
+      <groupId>org.aopalliance</groupId>
+      <artifactId>com.springsource.org.aopalliance</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.dependencymanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.dependencymanager.shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.fileinstall</artifactId>
+    </dependency>
+    <!-- felix webconsole -->
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.webconsole</artifactId>
+      <classifier>all</classifier>
+    </dependency>
+
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.equinox.http</groupId>
+      <artifactId>servlet</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.persistence</groupId>
+      <artifactId>org.eclipse.persistence.antlr</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.persistence</groupId>
+      <artifactId>org.eclipse.persistence.core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.persistence</groupId>
+      <artifactId>org.eclipse.persistence.moxy</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.javassist</groupId>
+      <artifactId>javassist</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.spec.javax.transaction</groupId>
+      <artifactId>jboss-transaction-api_1.1_spec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jolokia</groupId>
+      <artifactId>jolokia-osgi</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.json</groupId>
+      <artifactId>json</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm-all</artifactId>
+    </dependency>
+    <!-- Visual VM hook -->
+    <dependency>
+      <groupId>org.ow2.chameleon.management</groupId>
+      <artifactId>chameleon-mbeans</artifactId>
+    </dependency>
+
+    <!-- Third party depedencies -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>log4j-over-slf4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.aop</artifactId>
+    </dependency>
+    <!-- Add Pax Exam -->
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.asm</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.beans</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.context</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.context.support</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.expression</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.transaction</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>org.springframework.web.servlet</artifactId>
+    </dependency>
+    <!-- Spring security -->
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-config</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-taglibs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>virgomirror</groupId>
+      <artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
+    </dependency>
+
+    <!-- test to validate features.xml -->
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>features-test</artifactId>
+      <version>0.6.2-SNAPSHOT</version>
+    </dependency>
+    <!-- dependency for opendaylight-karaf-empty for use by testing -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>opendaylight-karaf-empty</artifactId>
+      <version>1.4.2-SNAPSHOT</version>
+      <type>zip</type>
+    </dependency>
+  </dependencies>
   <build>
     <resources>
       <resource>
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemPropertyVariables>
+            <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+            <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+            <karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>
+          </systemPropertyVariables>
+          <dependenciesToScan>
+           <dependency>org.opendaylight.yangtools:features-test</dependency>
+          </dependenciesToScan>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 </project>
index b9107b9f62881d1fc2799ddbecc238559add943a..999cf704d2bedf212a283864e6d8e4d74f10fd68 100644 (file)
@@ -1,34 +1,35 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<features name="base-${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">
+<features name="odl-base-${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">
 
-   <feature name="base-all" description="OpenDaylight Controller" version="${project.version}">
+   <feature name="odl-base-all" description="OpenDaylight Controller" version="${project.version}">
       <feature>http</feature>
       <feature>transaction</feature>
-      <feature>base-felix-dm</feature>
-      <feature>base-aries-spi-fly</feature>
-      <feature>base-dummy-console</feature>
-      <feature>base-apache-commons</feature>
-      <feature>base-eclipselink-persistence</feature>
-      <feature>base-gemini-web</feature>
-      <feature>base-tomcat</feature>
-      <feature>base-netty</feature>
-      <feature>base-jersey</feature>
-      <feature>base-spring-security</feature>
+      <feature>odl-base-felix-dm</feature>
+      <feature>odl-base-aries-spi-fly</feature>
+      <feature>odl-base-dummy-console</feature>
+      <feature>odl-base-apache-commons</feature>
+      <feature>odl-base-eclipselink-persistence</feature>
+      <feature>odl-base-gemini-web</feature>
+      <feature>odl-base-tomcat</feature>
+      <feature>odl-base-netty</feature>
+      <feature>odl-base-jersey</feature>
+      <feature>odl-base-jackson</feature>
+      <feature>odl-base-spring-security</feature>
    </feature>
-   <feature name="base-dummy-console" description="Temporary Dummy Console" version="1.1.0-SNAPSHOT">
+   <feature name="odl-base-dummy-console" description="Temporary Dummy Console" version="1.1.0-SNAPSHOT">
       <bundle>mvn:org.opendaylight.controller/dummy-console/1.1.0-SNAPSHOT</bundle>
    </feature>
-   <feature name="base-felix-dm" description="Felix Dependency Manager" version="${felix.dependencymanager.version}">
-      <bundle start-level="35">mvn:org.osgi/org.osgi.compendium/${osgi.compendium.version}</bundle>
-      <bundle start-level="35">mvn:org.apache.felix/org.apache.felix.dependencymanager/${felix.dependencymanager.version}</bundle>
-      <bundle start-level="35">mvn:org.apache.felix/org.apache.felix.dependencymanager.shell/${felix.dependencymanager.shell.version}</bundle>
+   <feature name="odl-base-felix-dm" description="Felix Dependency Manager" version="${felix.dependencymanager.version}">
+      <bundle>mvn:org.osgi/org.osgi.compendium/${osgi.compendium.version}</bundle>
+      <bundle>mvn:org.apache.felix/org.apache.felix.dependencymanager/${felix.dependencymanager.version}</bundle>
+      <bundle>mvn:org.apache.felix/org.apache.felix.dependencymanager.shell/${felix.dependencymanager.shell.version}</bundle>
    </feature>
-   <feature name="base-aries-spi-fly" description="Aries SPI Fly" version="${spifly.version}">
-      <bundle start-level="35">mvn:org.apache.aries/org.apache.aries.util/1.1.0</bundle>
-      <bundle start-level="35">mvn:org.apache.aries.spifly/org.apache.aries.spifly.dynamic.bundle/${spifly.version}</bundle>
-      <bundle start-level="35">mvn:org.ow2.asm/asm-all/4.0</bundle>
+   <feature name="odl-base-aries-spi-fly" description="Aries SPI Fly" version="${spifly.version}">
+      <bundle>mvn:org.apache.aries/org.apache.aries.util/1.1.0</bundle>
+      <bundle>mvn:org.apache.aries.spifly/org.apache.aries.spifly.dynamic.bundle/${spifly.version}</bundle>
+      <bundle>mvn:org.ow2.asm/asm-all/4.0</bundle>
    </feature>
-   <feature name='base-netty' version='${netty.version}'>
+   <feature name='odl-base-netty' version='${netty.version}'>
       <bundle>wrap:mvn:io.netty/netty-buffer/${netty.version}</bundle>
       <bundle>wrap:mvn:io.netty/netty-codec/${netty.version}</bundle>
       <bundle>wrap:mvn:io.netty/netty-transport/${netty.version}</bundle>
       <bundle>wrap:mvn:io.netty/netty-codec-http/${netty.version}</bundle>
       <bundle>mvn:org.opendaylight.controller.thirdparty/ganymed/1.1-SNAPSHOT</bundle>
    </feature>
-   <feature name="base-jersey" description="Jersey" version="${jersey.version}">
-      <feature>base-gemini-web</feature>
-      <bundle>mvn:org.opendaylight.controller.thirdparty/com.sun.jersey.jersey-servlet/${jersey.version}</bundle>
+   <feature name="odl-base-jersey" description="Jersey" version="${jersey.version}">
+      <feature>odl-base-gemini-web</feature>
       <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
       <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
       <bundle>mvn:com.sun.jersey/jersey-client/${jersey.version}</bundle>
       <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
-      <bundle start="true" start-level="35">mvn:javax.ws.rs/javax.ws.rs-api/2.0</bundle>
    </feature>
-   <feature name="base-jersey2-osgi" description="OSGi friendly Jersey" version="${jersey2.publisher.version}">
+   <feature name="odl-base-jersey2-osgi" description="OSGi friendly Jersey" version="${jersey2.publisher.version}">
       <feature>http</feature>
       <bundle>mvn:com.eclipsesource.jaxrs/jersey-all/${jersey2.version}</bundle>
       <bundle>mvn:com.eclipsesource.jaxrs/publisher/${jersey2.publisher.version}</bundle>
-      <bundle start="true" start-level="35">mvn:javax.ws.rs/javax.ws.rs-api/${jsr311.v2.api.version}</bundle>
+      <bundle start="true">mvn:javax.ws.rs/javax.ws.rs-api/${jsr311.v2.api.version}</bundle>
       <bundle>mvn:javax.annotation/javax.annotation-api/${javax.annotation.version}</bundle>
     </feature>
-   <feature name="base-jackson" description="Jackson JAX-RS" version="${jackson.version}">
-      <bundle start="true" start-level="35">mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
-      <bundle start="true" start-level="35">mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
-      <bundle start="true" start-level="35">mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
-      <bundle start="true" start-level="35">mvn:org.codehaus.jettison/jettison/${jettison.version}</bundle>
-      <bundle start="true" start-level="35">mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${jackson.version}</bundle>
-      <bundle start="true" start-level="35">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
-      <bundle start="true" start-level="35">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
+   <feature name="odl-base-jackson" description="Jackson JAX-RS" version="${jackson.version}">
+      <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
+      <bundle>mvn:com.sun.jersey/jersey-client/${jersey.version}</bundle>
+      <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
+      <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
+      <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
+      <bundle start="true">mvn:org.codehaus.jettison/jettison/${jettison.version}</bundle>
+      <bundle start="true">mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${jackson.version}</bundle>
+      <bundle start="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
+      <bundle start="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
    </feature>
-   <feature name="base-slf4j" description="SLF4J Logging" version="${slf4j.version}">
-      <bundle start-level="35">mvn:org.slf4j/slf4j-jdk14/1.7.2</bundle>
-      <bundle start-level="35">mvn:org.slf4j/slf4j-nop/1.7.2</bundle>
-      <bundle start-level="35">mvn:org.slf4j/slf4j-simple/1.7.2</bundle>
-      <bundle start="true" start-level="35">mvn:org.slf4j/slf4j-api/1.7.2</bundle>
+   <feature name="odl-base-slf4j" description="SLF4J Logging" version="${slf4j.version}">
+      <bundle>mvn:org.slf4j/slf4j-jdk14/1.7.2</bundle>
+      <bundle>mvn:org.slf4j/slf4j-nop/1.7.2</bundle>
+      <bundle>mvn:org.slf4j/slf4j-simple/1.7.2</bundle>
+      <bundle start="true">mvn:org.slf4j/slf4j-api/1.7.2</bundle>
    </feature>
-   <feature name="base-apache-commons" description="Apache Commons Libraries" version="${project.version}">
-      <bundle start="true" start-level="35">mvn:com.google.guava/guava/${guava.version}</bundle>
-      <bundle start="true" start-level="35">mvn:org.javassist/javassist/${javassist.version}</bundle>
-      <bundle start="true" start-level="35">mvn:commons-io/commons-io/${commons.io.version}</bundle>
-      <bundle start="true" start-level="35">mvn:commons-codec/commons-codec/${commons.codec.version}</bundle>
-      <bundle start="true" start-level="35">mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
-      <bundle start="true" start-level="35">mvn:commons-net/commons-net/${commons.net.version}</bundle>
+   <feature name="odl-base-apache-commons" description="Apache Commons Libraries" version="${project.version}">
+      <bundle start="true">mvn:com.google.guava/guava/${guava.version}</bundle>
+      <bundle start="true">mvn:org.javassist/javassist/${javassist.version}</bundle>
+      <bundle start="true">mvn:commons-io/commons-io/${commons.io.version}</bundle>
+      <bundle start="true">mvn:commons-codec/commons-codec/${commons.codec.version}</bundle>
+      <bundle start="true">mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
+      <bundle start="true">mvn:commons-net/commons-net/${commons.net.version}</bundle>
    </feature>
-   <feature name="base-eclipselink-persistence" description="EclipseLink Persistence API" version="2.0.4.v201112161009">
-      <bundle start="true" start-level="35">mvn:eclipselink/javax.persistence/2.0.4.v201112161009</bundle>
-      <bundle start="true" start-level="35">mvn:eclipselink/javax.resource/1.5.0.v200906010428</bundle>
-      <bundle start="true" start-level="35">mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/2.5.0</bundle>
-      <bundle start="true" start-level="35">mvn:org.eclipse.persistence/org.eclipse.persistence.core/2.5.0</bundle>
+   <feature name="odl-base-eclipselink-persistence" description="EclipseLink Persistence API" version="2.0.4.v201112161009">
+      <bundle start="true">mvn:eclipselink/javax.persistence/2.0.4.v201112161009</bundle>
+      <bundle start="true">mvn:eclipselink/javax.resource/1.5.0.v200906010428</bundle>
+      <bundle start="true">mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/2.5.0</bundle>
+      <bundle start="true">mvn:org.eclipse.persistence/org.eclipse.persistence.core/2.5.0</bundle>
    </feature>
-   <feature name="base-gemini-web" description="Gemini Web" version="${geminiweb.version}">
+   <feature name="odl-base-gemini-web" description="Gemini Web" version="${geminiweb.version}">
       <feature>http</feature>
       <feature>transaction</feature>
-      <feature>base-slf4j</feature>
-      <feature>base-felix-dm</feature>
-      <feature>base-jackson</feature>
-      <feature>base-apache-commons</feature>
-      <bundle start="true" start-level="35">mvn:com.google.code.gson/gson/${gson.version}</bundle>
-      <bundle start="true" start-level="35">mvn:commons-fileupload/commons-fileupload/${commons.fileupload.version}</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.gemini.web.core/${geminiweb.version}</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.gemini.web.extender/${geminiweb.version}</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.virgo.util.common/${virgo.version}</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.virgo.util.io/${virgo.version}</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.virgo.util.math/${virgo.version}</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.virgo.util.osgi/${virgo.version}</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.virgo.util.osgi.manifest/${virgo.version}</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.virgo.util.parser.manifest/${virgo.version}</bundle>
-      <bundle start="true" start-level="35">mvn:org.apache.felix/org.apache.felix.fileinstall/3.1.6</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/javax.activation/1.1.0.v201211130549</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/javax.annotation/1.1.0.v201209060031</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/javax.ejb/3.1.1.v201204261316</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/javax.el/2.2.0.v201108011116</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/javax.mail.glassfish/1.4.1.v201108011116</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/javax.xml.rpc/1.1.0.v201005080400</bundle>
-      <bundle start="true" start-level="35">mvn:org.eclipse.jetty.orbit/javax.servlet.jsp/2.2.0.v201112011158</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/javax.servlet.jsp.jstl/1.2.0.v201105211821</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/javax.servlet.jsp.jstl.impl/1.2.0.v201210211230</bundle>
+      <feature>odl-base-slf4j</feature>
+      <feature>odl-base-felix-dm</feature>
+      <feature>odl-base-jackson</feature>
+      <feature>odl-base-apache-commons</feature>
+      <bundle start="true">mvn:com.google.code.gson/gson/${gson.version}</bundle>
+      <bundle start="true">mvn:commons-fileupload/commons-fileupload/${commons.fileupload.version}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.gemini.web.core/${geminiweb.version}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.gemini.web.extender/${geminiweb.version}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.virgo.util.common/${virgo.version}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.virgo.util.io/${virgo.version}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.virgo.util.math/${virgo.version}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.virgo.util.osgi/${virgo.version}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.virgo.util.osgi.manifest/${virgo.version}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.virgo.util.parser.manifest/${virgo.version}</bundle>
+      <bundle start="true">mvn:org.apache.felix/org.apache.felix.fileinstall/3.1.6</bundle>
+      <bundle start="true">mvn:orbit/javax.activation/1.1.0.v201211130549</bundle>
+      <bundle start="true">mvn:orbit/javax.annotation/1.1.0.v201209060031</bundle>
+      <bundle start="true">mvn:orbit/javax.ejb/3.1.1.v201204261316</bundle>
+      <bundle start="true">mvn:orbit/javax.el/2.2.0.v201108011116</bundle>
+      <bundle start="true">mvn:orbit/javax.mail.glassfish/1.4.1.v201108011116</bundle>
+      <bundle start="true">mvn:orbit/javax.xml.rpc/1.1.0.v201005080400</bundle>
+      <bundle start="true">mvn:org.eclipse.jetty.orbit/javax.servlet.jsp/2.2.0.v201112011158</bundle>
+      <bundle start="true">mvn:orbit/javax.servlet.jsp.jstl/1.2.0.v201105211821</bundle>
+      <bundle start="true">mvn:orbit/javax.servlet.jsp.jstl.impl/1.2.0.v201210211230</bundle>
    </feature>
-   <feature name="base-tomcat" description="OpenDaylight Tomcat" version="7.0.32">
-      <feature>base-gemini-web</feature>
-      <feature>base-eclipselink-persistence</feature>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.catalina/7.0.32.v201211201336</bundle>
-      <bundle start="true" start-level="35">mvn:geminiweb/org.eclipse.gemini.web.tomcat/${geminiweb.version}</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.catalina.ha/7.0.32.v201211201952</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.catalina.tribes/7.0.32.v201211201952</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.coyote/7.0.32.v201211201952</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.el/7.0.32.v201211081135</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.jasper/7.0.32.v201211201952</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.juli.extras/7.0.32.v201211081135</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.tomcat.api/7.0.32.v201211081135</bundle>
-      <bundle start="true" start-level="35">mvn:orbit/org.apache.tomcat.util/7.0.32.v201211201952</bundle>
-      <bundle start="true" start-level="35">wrap:mvn:virgomirror/org.eclipse.jdt.core.compiler.batch/3.8.0.I20120518-2145</bundle>
+   <feature name="odl-base-tomcat" description="OpenDaylight Tomcat" version="7.0.53">
+      <feature>odl-base-gemini-web</feature>
+      <feature>odl-base-eclipselink-persistence</feature>
+      <bundle start="true">mvn:orbit/org.apache.catalina/${commons.karaf.catalina}</bundle>
+      <bundle start="true">mvn:geminiweb/org.eclipse.gemini.web.tomcat/${geminiweb.version}</bundle>
+      <bundle start="true">mvn:orbit/org.apache.catalina.ha/${commons.karaf.catalina.ha}</bundle>
+      <bundle start="true">mvn:orbit/org.apache.catalina.tribes/${commons.karaf.catalina.tribes}</bundle>
+      <bundle start="true">mvn:orbit/org.apache.coyote/${commons.karaf.coyote}</bundle>
+      <bundle start="true">mvn:orbit/org.apache.el/${commons.karaf.el}</bundle>
+      <bundle start="true">mvn:orbit/org.apache.jasper/${commons.karaf.jasper}</bundle>
+      <bundle start="true">mvn:orbit/org.apache.juli.extras/${commons.karaf.juli.version}</bundle>
+      <bundle start="true">mvn:orbit/org.apache.tomcat.api/${commons.karaf.tomcat.api}</bundle>
+      <bundle start="true">mvn:orbit/org.apache.tomcat.util/${commons.karaf.tomcat.util}</bundle>
+      <bundle start="true" >mvn:org.opendaylight.controller/karaf-tomcat-security/${karaf.security.version}</bundle>
+      <bundle start="true">wrap:mvn:virgomirror/org.eclipse.jdt.core.compiler.batch/${eclipse.jdt.core.compiler.batch.version}</bundle>
    </feature>
-   <feature name="base-spring" description="Opendaylight Spring Support" version="${spring.version}">
+   <feature name="odl-base-spring" description="Opendaylight Spring Support" version="${spring.version}">
       <bundle>mvn:org.ow2.asm/asm-all/${asm.version}</bundle>
       <bundle>mvn:org.aopalliance/com.springsource.org.aopalliance/${aopalliance.version}</bundle>
       <bundle>mvn:org.springframework/org.springframework.aop/${spring.version}</bundle>
       <bundle>mvn:org.springframework/org.springframework.expression/${spring.version}</bundle>
       <bundle>mvn:org.springframework/org.springframework.transaction/${spring.version}</bundle>
    </feature>
-   <feature name="base-spring-web" description="OpenDaylight Spring Web" version="${spring.version}">
-      <feature>base-spring</feature>
-      <feature>base-gemini-web</feature>
+   <feature name="odl-base-spring-web" description="OpenDaylight Spring Web" version="${spring.version}">
+      <feature>odl-base-spring</feature>
+      <feature>odl-base-gemini-web</feature>
       <bundle>mvn:org.springframework/org.springframework.web/${spring.version}</bundle>
       <bundle>mvn:org.springframework/org.springframework.web.servlet/${spring.version}</bundle>
    </feature>
-   <feature name="base-spring-security" description="OpenDaylight Spring Security" version="${spring-security.version}">
-      <feature>base-spring-web</feature>
+   <feature name="odl-base-spring-security" description="OpenDaylight Spring Security" version="${spring-security.version}">
+      <feature>odl-base-spring-web</feature>
       <bundle>mvn:org.springframework.security/spring-security-config/${spring-security.version}</bundle>
       <bundle>mvn:org.springframework.security/spring-security-core/${spring-security.version}</bundle>
       <bundle>mvn:org.springframework.security/spring-security-taglibs/${spring-security.version}</bundle>
index 7f57d8cb84cbb3b5d103799646c8ea787f8e0d88..f8df1aa58c979d5f5b5b1cfb4cc7e8f928754852 100644 (file)
@@ -4,7 +4,7 @@
           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">
   <repository>mvn:org.opendaylight.controller/features-config-persister/${config.version}/xml/features</repository>
-  <feature name='odl-config-netty' version='${project.version}'>
+  <feature name='odl-config-netty' version='${project.version}' description="OpenDaylight :: Config-Netty">
     <feature version='${project.version}'>odl-config-netty-config-api</feature>
     <bundle>mvn:org.opendaylight.controller/netty-event-executor-config/${project.version}</bundle>
     <bundle>mvn:org.opendaylight.controller/netty-threadgroup-config/${project.version}</bundle>
index a3c005b3bd8937425420c1eff652e89262657225..20fb19f5ff6a1218975f9703f6ad5310be601cdf 100644 (file)
@@ -6,11 +6,11 @@
   <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-netconf/${netconf.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-config/${config.version}/xml/features</repository>
-  <feature name='odl-config-all' version='${project.version}'>
+  <feature name='odl-config-persister-all' version='${project.version}' description="OpenDaylight :: Config Persister:: All">
     <feature version='${project.version}'>odl-config-persister</feature>
     <feature version='${project.version}'>odl-config-startup</feature>
   </feature>
-  <feature name='odl-config-persister' version='${project.version}'>
+  <feature name='odl-config-persister' version='${project.version}' description="OpenDaylight :: Config Persister ">
     <feature version='${netconf.version}'>odl-netconf-api</feature>
     <feature version='${project.version}'>odl-config-api</feature>
     <feature version='${yangtools.version}'>odl-yangtools-binding-generator</feature>
@@ -27,7 +27,7 @@
     <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.core/${eclipse.persistence.version}</bundle>
     <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/${eclipse.persistence.version}</bundle>
   </feature>
-  <feature name='odl-config-startup' version='${project.version}'>
+  <feature name='odl-config-startup' version='${project.version}' description="OpenDaylight :: Config Persister:: Config Startup">
     <feature version='${project.version}'>odl-config-netconf-connector</feature>
     <feature version='${project.version}'>odl-config-persister</feature>
     <feature version='${project.version}'>odl-netconf-impl</feature>
index 5027588acb2e9fce758cffffff77388400c21c68..b4dd03f4910d6761e7415c7d657851e15de356f5 100644 (file)
@@ -5,7 +5,7 @@
           xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
   <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
 
-  <feature name='odl-config-all' version='${project.version}'>
+  <feature name='odl-config-all' version='${project.version}' description="OpenDaylight :: Config :: All">
       <feature version='${mdsal.version}'>odl-mdsal-common</feature>
       <feature version='${project.version}'>odl-config-api</feature>
       <feature version='${project.version}'>odl-config-netty-config-api</feature>
@@ -13,7 +13,7 @@
       <feature version='${project.version}'>odl-config-manager</feature>
   </feature>
 
-  <feature name='odl-mdsal-common' version='${mdsal.version}'>
+  <feature name='odl-mdsal-common' version='${mdsal.version}' description="OpenDaylight :: Config :: All">
       <feature version='${yangtools.version}'>odl-yangtools-data-binding</feature>
       <bundle>mvn:org.opendaylight.controller/sal-common/${mdsal.version}</bundle>
       <bundle>mvn:org.opendaylight.controller/sal-common-api/${mdsal.version}</bundle>
       <bundle>mvn:org.opendaylight.controller/sal-common-util/${mdsal.version}</bundle>
   </feature>
 
-  <feature name='odl-config-api' version='${project.version}'>
+  <feature name='odl-config-api' version='${project.version}' description="OpenDaylight :: Config :: API">
     <bundle>mvn:org.opendaylight.controller/config-api/${project.version}</bundle>
     <feature version='${yangtools.version}'>odl-yangtools-common</feature>
     <feature version='${yangtools.version}'>odl-yangtools-binding</feature>
   </feature>
 
-  <feature name='odl-config-netty-config-api' version='${project.version}'>
+  <feature name='odl-config-netty-config-api' version='${project.version}' description="OpenDaylight :: Config :: Netty Config API">
     <feature version='${project.version}'>odl-config-api</feature>
     <bundle>mvn:org.opendaylight.controller/netty-config-api/${project.version}</bundle>
     <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
@@ -35,7 +35,7 @@
     <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
   </feature>
 
-  <feature name='odl-config-core' version='${project.version}'>
+  <feature name='odl-config-core' version='${project.version}' description="OpenDaylight :: Config :: Core">
     <feature version='${yangtools.version}'>odl-yangtools-common</feature>
     <feature version='${yangtools.version}'>odl-yangtools-binding</feature>
     <feature version='${yangtools.version}'>odl-yangtools-binding-generator</feature>
@@ -49,7 +49,7 @@
     <bundle>mvn:com.google.guava/guava/${guava.version}</bundle>
     <bundle>mvn:org.javassist/javassist/${javassist.version}</bundle>
   </feature>
-  <feature name='odl-config-manager' version='${project.version}'>
+  <feature name='odl-config-manager' version='${project.version}' description="OpenDaylight :: Config :: Manager">
     <feature version='${project.version}'>odl-config-core</feature>
     <bundle>mvn:org.opendaylight.controller/config-manager/${project.version}</bundle>
   </feature>
index 3f914be4aeabacfef427189543a1a9f91fe7325f..05404586309e24af131236d14b83c4c2d6bcb1b0 100644 (file)
@@ -4,7 +4,7 @@
    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">
     <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
-    <feature name='odl-flow-model' version='${project.version}'>
+    <feature name='odl-flow-model' version='${project.version}' description="OpenDaylight :: Flow :: Model">
         <feature version='${yangtools.version}'>odl-yangtools-models</feature>
         <bundle>mvn:org.opendaylight.controller.model/model-flow-base/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller.model/model-flow-service/${project.version}</bundle>
@@ -12,7 +12,7 @@
         <bundle>mvn:org.opendaylight.controller.model/model-inventory/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller.model/model-topology/${project.version}</bundle>
     </feature>
-    <feature name='odl-flow-services' version='${project.version}'>
+    <feature name='odl-flow-services' version='${project.version}' description="OpenDaylight :: Flow :: Services">
         <feature version='${project.version}'>odl-mdsal-broker</feature>
         <feature version='${project.version}'>odl-flow-model</feature>
         <bundle>mvn:org.opendaylight.controller.md/topology-manager/${project.version}</bundle>
index ac6b82b26fb355036ba92f4b2f26bc49df21e0c9..5be0061698ab3947d63323cd3390ebdc8771dd7b 100644 (file)
       <artifactId>jersey-server</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.controller.thirdparty</groupId>
-      <artifactId>com.sun.jersey.jersey-servlet</artifactId>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-servlet</artifactId>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
index a3d7ed0f83df6455006a4c94dbb52283d1438461..754e97dee3ed064d54f72f900ebe925c21ae8c89 100644 (file)
@@ -7,13 +7,13 @@
     <repository>mvn:org.opendaylight.controller/features-config/${config.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.controller/features-config-persister/${config.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.controller/features-config-netty/${config.version}/xml/features</repository>
-    <feature name='odl-mdsal-all' version='${project.version}'>
+    <feature name='odl-mdsal-all' version='${project.version}' description="OpenDaylight :: MDSAL :: All">
         <feature version='${project.version}'>odl-mdsal-broker</feature>
         <feature version='${project.version}'>odl-mdsal-netconf-connector</feature>
         <feature version='${project.version}'>odl-restconf</feature>
         <feature version='${project.version}'>odl-toaster</feature>
     </feature>
-    <feature name='odl-mdsal-broker' version='${project.version}'>
+    <feature name='odl-mdsal-broker' version='${project.version}' description="OpenDaylight :: MDSAL :: Broker">
         <feature version='${yangtools.version}'>odl-yangtools-common</feature>
         <feature version='${yangtools.version}'>odl-yangtools-binding</feature>
         <feature version='${mdsal.version}'>odl-mdsal-common</feature>
@@ -30,7 +30,7 @@
         <bundle>mvn:org.opendaylight.controller/sal-inmemory-datastore/${project.version}</bundle>
         <configfile finalname="${config.configfile.directory}/${config.mdsal.configfile}">mvn:org.opendaylight.controller/md-sal-config/${mdsal.version}/xml/config</configfile>
     </feature>
-    <feature name='odl-mdsal-netconf-connector' version='${project.version}'>
+    <feature name='odl-mdsal-netconf-connector' version='${project.version}' description="OpenDaylight :: MDSAL :: Netconf Connector">
         <feature version='${project.version}'>odl-mdsal-broker</feature>
         <feature version='${netconf.version}'>odl-netconf-client</feature>
         <feature version='${yangtools.version}'>odl-yangtools-models</feature>
         <bundle>mvn:org.opendaylight.controller/netconf-config-dispatcher/${config.version}</bundle>
         <configfile finalname="${config.configfile.directory}/${config.netconf.connector.configfile}">mvn:org.opendaylight.controller/netconf-connector-config/${netconf.version}/xml/config</configfile>
     </feature>
-    <feature name='odl-restconf' version='${project.version}'>
+    <feature name='odl-restconf' version='${project.version}' description="OpenDaylight :: Restconf">
         <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
         <feature>war</feature>
         <bundle>mvn:org.opendaylight.controller/sal-rest-connector/${project.version}</bundle>
         <bundle>mvn:com.google.code.gson/gson/${gson.version}</bundle>
         <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
         <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
-        <bundle>mvn:org.opendaylight.controller.thirdparty/com.sun.jersey.jersey-servlet/${jersey.version}</bundle>
+        <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
         <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
         <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
         <bundle>mvn:io.netty/netty-codec-http/${netty.version}</bundle>
@@ -56,7 +56,7 @@
         <bundle>mvn:org.opendaylight.controller/sal-remote/${project.version}</bundle>
         <configfile finalname="${config.configfile.directory}/${config.restconf.configfile}">mvn:org.opendaylight.controller/sal-rest-connector-config/${mdsal.version}/xml/config</configfile>
     </feature>
-    <feature name='odl-toaster' version='${project.version}'>
+    <feature name='odl-toaster' version='${project.version}' description="OpenDaylight :: Toaster">
         <feature version='${yangtools.version}'>odl-yangtools-common</feature>
         <feature version='${yangtools.version}'>odl-yangtools-binding</feature>
         <feature version='${project.version}'>odl-mdsal-broker</feature>
index 956a67e28b3652d05ebb0547d5e3e456bc135dbd..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>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>netconf-config</artifactId>
+      <version>${config.version}</version>
+      <type>xml</type>
+      <classifier>config</classifier>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 0033b0d83c7e4bf02aea300b62cf0ee69be350ba..1453a5fb969a9d1e3f6b9f6bec88cebb59182d3f 100644 (file)
@@ -5,7 +5,7 @@
           xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
   <repository>mvn:org.opendaylight.controller/features-protocol-framework/${protocol-framework.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-config/${config.version}/xml/features</repository>
-  <feature name='odl-netconf-all' version='${project.version}'>
+  <feature name='odl-netconf-all' version='${project.version}' description="OpenDaylight :: Netconf :: All">
     <feature version='${project.version}'>odl-netconf-api</feature>
     <feature version='${project.version}'>odl-netconf-mapping-api</feature>
     <feature version='${project.version}'>odl-netconf-util</feature>
@@ -16,7 +16,7 @@
     <feature version='${project.version}'>odl-netconf-monitoring</feature>
   </feature>
 
-  <feature name='odl-netconf-api' version='${project.version}'>
+  <feature name='odl-netconf-api' version='${project.version}' description="OpenDaylight :: Netconf :: API">
     <feature version='${protocol-framework.version}'>odl-protocol-framework</feature>
     <bundle>mvn:org.opendaylight.controller/netconf-api/${project.version}</bundle>
     <bundle>mvn:org.opendaylight.controller/ietf-netconf-monitoring/${project.version}</bundle>
@@ -24,7 +24,7 @@
     <bundle>mvn:org.opendaylight.yangtools.model/ietf-inet-types/${ietf-inet-types.version}</bundle>
     <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types/${ietf-yang-types.version}</bundle>
   </feature>
-  <feature name='odl-netconf-mapping-api' version='${project.version}'>
+  <feature name='odl-netconf-mapping-api' version='${project.version}' description="OpenDaylight :: Netconf :: Mapping API">
     <feature version='${project.version}'>odl-netconf-api</feature>
     <bundle>mvn:org.opendaylight.controller/netconf-mapping-api/${project.version}</bundle>
   </feature>
     <feature version='${project.version}'>odl-netconf-mapping-api</feature>
     <bundle>mvn:org.opendaylight.controller/netconf-util/${project.version}</bundle>
   </feature>
-    <feature name='odl-netconf-impl' version='${project.version}'>
+    <feature name='odl-netconf-impl' version='${project.version}' description="OpenDaylight :: Netconf :: Impl">
     <feature version='${project.version}'>odl-netconf-api</feature>
     <feature version='${project.version}'>odl-netconf-mapping-api</feature>
     <feature version='${project.version}'>odl-netconf-util</feature>
     <feature version='${project.version}'>odl-netconf-netty-util</feature>
     <bundle>mvn:org.opendaylight.controller/netconf-impl/${project.version}</bundle>
   </feature>
-  <feature name='odl-config-netconf-connector' version='${project.version}'>
+  <feature name='odl-config-netconf-connector' version='${project.version}' description="OpenDaylight :: Netconf :: Connector">
     <feature version='${config.version}'>odl-config-manager</feature>
     <feature version='${project.version}'>odl-netconf-api</feature>
     <feature version='${project.version}'>odl-netconf-mapping-api</feature>
     <feature version='${project.version}'>odl-netconf-util</feature>
     <bundle>mvn:org.opendaylight.controller/config-netconf-connector/${project.version}</bundle>
   </feature>
-  <feature name='odl-netconf-netty-util' version='${project.version}'>
+  <feature name='odl-netconf-netty-util' version='${project.version}' description="OpenDaylight :: Netconf :: Netty Util">
     <feature version='${project.version}'>odl-netconf-api</feature>
     <feature version='${project.version}'>odl-netconf-mapping-api</feature>
     <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>
     <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
     <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
   </feature>
-  <feature name='odl-netconf-client' version="${project.version}">
+  <feature name='odl-netconf-client' version='${project.version}' description="OpenDaylight :: Netconf :: Client">
     <feature version='${project.version}'>odl-netconf-netty-util</feature>
     <bundle>mvn:org.opendaylight.controller/netconf-client/${project.version}</bundle>
-    <configfile finalname="${config.configfile.directory}/${config.netconf.client.configfile}">mvn:org.opendaylight.controller/netconf-config/${netconf.version}/xml/config</configfile>
+    <configfile finalname='${config.configfile.directory}/${config.netconf.client.configfile}'>mvn:org.opendaylight.controller/netconf-config/${netconf.version}/xml/config</configfile>
   </feature>
-  <feature name='odl-netconf-monitoring' version='${project.version}'>
+  <feature name='odl-netconf-monitoring' version='${project.version}' description="OpenDaylight :: Netconf :: Monitoring">
     <feature version='${project.version}'>odl-netconf-util</feature>
     <bundle>mvn:org.opendaylight.controller/netconf-monitoring/${project.version}</bundle>
   </feature>
 
-</features>
\ No newline at end of file
+</features>
index 224aef1dacb040b33f3ef88872d86384fb436b96..5be411caae22212330ad5ba1104f2a66067dbae1 100644 (file)
     <relativePath>../../opendaylight/commons/opendaylight</relativePath>
   </parent>
   <artifactId>features-nsf</artifactId>
-  <packaging>pom</packaging>
+  <version>${nsf.version}</version>
+  <packaging>jar</packaging>
   <name>OpenDaylight :: Features :: Network Service Functions</name>
   <description>Feature for Network Service Functions</description>
   <properties>
     <features.file>features.xml</features.file>
   </properties>
+  <dependencies>
+    <!-- test to validate features.xml -->
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>features-test</artifactId>
+    </dependency>
+    <!-- dependency for opendaylight-karaf-empty for use by testing -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>opendaylight-karaf-empty</artifactId>
+      <version>1.4.2-SNAPSHOT</version>
+      <type>zip</type>
+    </dependency>
+    <!-- Bundle Dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>appauth</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>arphandler</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>bundlescanner</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>bundlescanner.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>commons.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>configuration.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>connectionmanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>connectionmanager.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>connectionmanager.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager.shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>controllermanager.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>devices.web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>flowprogrammer.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>flows.web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>routing.dijkstra_implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>forwarding.staticrouting</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>forwarding.staticrouting.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>forwardingrulesmanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>forwardingrulesmanager.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>hosttracker</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>hosttracker.shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>hosttracker.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>hosttracker.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>httpservice-bridge</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>jolokia-bridge</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>logging.bridge</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>networkconfig.bridgedomain.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>networkconfig.neutron</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>networkconfig.neutron.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>networkconfig.neutron.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>osgi-brandfragment.web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>samples.loadbalancer</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>samples.loadbalancer.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>samples.simpleforwarding</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>security</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>statistics.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>statisticsmanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>statisticsmanager.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>subnets.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>switchmanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>switchmanager.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>switchmanager.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>topology.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>topology.web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>topologymanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>topologymanager.shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>troubleshoot.web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>usermanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>usermanager.implementation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>usermanager.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.thirdparty</groupId>
+      <artifactId>net.sf.jung2</artifactId>
+    </dependency>
+  </dependencies>
   <build>
     <resources>
       <resource>
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemPropertyVariables>
+            <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+            <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+            <karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>
+          </systemPropertyVariables>
+          <dependenciesToScan>
+           <dependency>org.opendaylight.yangtools:features-test</dependency>
+          </dependenciesToScan>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 </project>
index 130d72e01ae588780ccaa8d7840be0727874e2da..8dc51f1644c48dd31e9bf911681ea6819d7dc32b 100644 (file)
@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <features name="nsf-${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">
+    <repository>mvn:org.opendaylight.controller/features-base/${commons.opendaylight.version}/xml/features</repository>
+    <repository>mvn:org.opendaylight.controller/features-adsal/${sal.version}/xml/features</repository>
     <feature name="odl-nsf-all" description="OpenDaylight :: NSF :: All Network Service Functions" version="${project.version}">
         <feature version="${sal.version}">odl-adsal-all</feature>
         <feature version="${project.version}">odl-nsf-managers</feature>
@@ -11,7 +13,7 @@
     </feature>
 
     <feature name="odl-nsf-managers" description="OpenDaylight :: AD-SAL :: Network Service Functions" version="${project.version}">
-        <feature version="${project.version}">base-all</feature>
+        <feature version="${commons.opendaylight.version}">odl-base-all</feature>
         <feature version="${sal.version}">odl-adsal-all</feature>
         <bundle>mvn:org.opendaylight.controller/usermanager/${usermanager.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/usermanager.implementation/${usermanager.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/hosttracker.implementation/${hosttracker.implementation.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/hosttracker.shell/${hosttracker.shell.version}</bundle>
 
-        <bundle>mvn:org.opendaylight.controller/forwarding.staticrouting</bundle>
+        <bundle>mvn:org.opendaylight.controller/forwarding.staticrouting/${forwarding.staticrouting}</bundle>
 
         <bundle>mvn:org.opendaylight.controller.thirdparty/net.sf.jung2/2.0.1</bundle>
-        <bundle>mvn:org.opendaylight.controller/routing.dijkstra_implementation</bundle>
+        <bundle>mvn:org.opendaylight.controller/routing.dijkstra_implementation/${routing.dijkstra_implementation.version}</bundle>
     </feature>
 
     <feature name="odl-adsal-northbound" description="OpenDaylight :: AD-SAL :: Northbound APIs" version="${project.version}">
-        <feature version="${project.version}">base-all</feature>
+        <feature version="${commons.opendaylight.version}">odl-base-all</feature>
         <feature version="${project.version}">odl-nsf-managers</feature>
-        <bundle start-level="35">mvn:org.ow2.asm/asm-all/${asm.version}</bundle>
+        <bundle>mvn:org.ow2.asm/asm-all/${asm.version}</bundle>
         <!--
             TODO : Resolve these in a follow-up commit
             <bundle>mvn:org.opendaylight.controller/httpservice-bridge/${httpservice-bridge.northbound.version}</bundle>
@@ -61,6 +63,7 @@
         <bundle>mvn:org.opendaylight.controller/bundlescanner/${bundlescanner.api.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/bundlescanner.implementation/${bundlescanner.implementation.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/commons.northbound/${northbound.commons.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/connectionmanager.northbound/${connectionmanager.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/flowprogrammer.northbound/${flowprogrammer.northbound.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/hosttracker.northbound/${hosttracker.northbound.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/networkconfig.bridgedomain.northbound/${networkconfig.bridgedomain.northbound.version}</bundle>
index 6daa3432c14285d8746bcd7385b08e520213f330..46510bca469805cd190222787693fe50d9492e33 100644 (file)
@@ -4,7 +4,7 @@
           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">
   <repository>mvn:org.opendaylight.controller/features-config/${config.version}/xml/features</repository>
-  <feature name='odl-protocol-framework' version='${project.version}'>
+  <feature name='odl-protocol-framework' version='${project.version}' description="OpenDaylight :: Protocol Framework">
     <feature version='${config.version}'>odl-config-api</feature>
     <feature version='${config.version}'>odl-config-netty-config-api</feature>
     <bundle>mvn:org.opendaylight.controller/protocol-framework/${protocol-framework.version}</bundle>
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 1064afd82d53fcdcdf6714421b5702535a2d6180..b9a6f3841270b543e1190b92d3f8bcb15ed2d1f0 100644 (file)
     <commons.catalina>7.0.32.v201211201336</commons.catalina>
     <commons.catalina.ha>7.0.32.v201211201952</commons.catalina.ha>
     <commons.catalina.tribes>7.0.32.v201211201952</commons.catalina.tribes>
-    <commons.checkstyle.version>0.0.3-SNAPSHOT</commons.checkstyle.version>
     <commons.coyote>7.0.32.v201211201952</commons.coyote>
     <commons.el>7.0.32.v201211081135</commons.el>
+    <commons.jasper>7.0.32.v201211201952</commons.jasper>
+    <commons.juli.version>7.0.32.v201211081135</commons.juli.version>
+    <commons.tomcat.api>7.0.32.v201211081135</commons.tomcat.api>
+    <commons.tomcat.util>7.0.32.v201211201952</commons.tomcat.util>
+
+    <commons.karaf.catalina>7.0.53.v201406061610</commons.karaf.catalina>
+    <commons.karaf.catalina.ha>7.0.53.v201406070630</commons.karaf.catalina.ha>
+    <commons.karaf.catalina.tribes>7.0.53.v201406070630</commons.karaf.catalina.tribes>
+    <commons.karaf.coyote>7.0.53.v201406070630</commons.karaf.coyote>
+    <commons.karaf.el>7.0.53.v201406060720</commons.karaf.el>
+    <commons.karaf.jasper>7.0.53.v201406070630</commons.karaf.jasper>
+    <commons.karaf.juli.version>7.0.53.v201406060720</commons.karaf.juli.version>
+    <commons.karaf.tomcat.api>7.0.53.v201406060720</commons.karaf.tomcat.api>
+    <commons.karaf.tomcat.util>7.0.53.v201406070630</commons.karaf.tomcat.util>
+
+    <commons.checkstyle.version>0.0.3-SNAPSHOT</commons.checkstyle.version>
     <commons.fileupload.version>1.2.2</commons.fileupload.version>
     <commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
     <commons.io.version>2.4</commons.io.version>
-    <commons.jasper>7.0.32.v201211201952</commons.jasper>
-    <commons.juli.version>7.0.32.v201211081135</commons.juli.version>
     <commons.lang3.version>3.1</commons.lang3.version>
     <commons.logback_settings.version>0.0.2-SNAPSHOT</commons.logback_settings.version>
     <commons.net.version>3.0.1</commons.net.version>
@@ -57,8 +70,6 @@
     <commons.opendaylight.concepts.version>0.5.2-SNAPSHOT</commons.opendaylight.concepts.version>
     <commons.opendaylight.version>1.4.2-SNAPSHOT</commons.opendaylight.version>
     <commons.parent.version>1.0.2-SNAPSHOT</commons.parent.version>
-    <commons.tomcat.api>7.0.32.v201211081135</commons.tomcat.api>
-    <commons.tomcat.util>7.0.32.v201211201952</commons.tomcat.util>
     <compiler.version>2.3.2</compiler.version>
     <commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
     <concepts.version>0.5.2-SNAPSHOT</concepts.version>
@@ -82,6 +93,7 @@
     <devices.web.version>0.4.2-SNAPSHOT</devices.web.version>
     <dummy-console.version>1.1.0-SNAPSHOT</dummy-console.version>
     <eclipse.persistence.version>2.5.0</eclipse.persistence.version>
+    <eclipse.jdt.core.compiler.batch.version>3.8.0.I20120518-2145</eclipse.jdt.core.compiler.batch.version>
     <!-- enforcer version -->
     <enforcer.version>1.3.1</enforcer.version>
     <enunciate.version>1.28</enunciate.version>
     <scala.version>2.10</scala.version>
     <scala.micro.version>4</scala.micro.version>
     <security.version>0.4.2-SNAPSHOT</security.version>
+    <karaf.security.version>0.4.2-SNAPSHOT</karaf.security.version>
     <shapeless.version>1.2.4</shapeless.version>
     <sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
     <sonar.branch>${user.name}-private-view</sonar.branch>
     <usermanager.implementation.version>0.4.2-SNAPSHOT</usermanager.implementation.version>
     <usermanager.northbound.version>0.0.2-SNAPSHOT</usermanager.northbound.version>
     <usermanager.version>0.4.2-SNAPSHOT</usermanager.version>
+    <nsf.version>0.4.2-SNAPSHOT</nsf.version>
     <web.version>0.4.2-SNAPSHOT</web.version>
     <xtend.dstdir>src/main/xtend-gen</xtend.dstdir>
     <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>
         <artifactId>jersey-core</artifactId>
         <version>${jersey.version}</version>
       </dependency>
-
       <dependency>
         <groupId>com.sun.jersey</groupId>
         <artifactId>jersey-server</artifactId>
         <version>${jersey.version}</version>
       </dependency>
+      <dependency>
+        <groupId>com.sun.jersey</groupId>
+        <artifactId>jersey-servlet</artifactId>
+        <version>${jersey-servlet.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>com.typesafe.akka</groupId>
         <artifactId>hosttracker.northbound</artifactId>
         <version>${hosttracker.northbound.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>hosttracker.shell</artifactId>
+        <version>${hosttracker.shell.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>hosttracker_new</artifactId>
         <artifactId>logging.bridge</artifactId>
         <version>${logging.bridge.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>dummy-console</artifactId>
+        <version>${dummy-console.version}</version>
+      </dependency>
 
       <!-- Netconf -->
       <dependency>
         <artifactId>security</artifactId>
         <version>${security.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>karaf-tomcat-security</artifactId>
+        <version>${karaf.security.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>topologymanager</artifactId>
         <version>${topologymanager.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>topologymanager.shell</artifactId>
+        <version>${topologymanager.shell.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>troubleshoot.web</artifactId>
         <type>xml</type>
         <scope>runtime</scope>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>features-base</artifactId>
+        <version>${commons.opendaylight.version}</version>
+        <classifier>features</classifier>
+        <type>xml</type>
+        <scope>runtime</scope>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>features-adsal</artifactId>
         <type>xml</type>
         <scope>runtime</scope>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>features-nsf</artifactId>
+        <version>${nsf.version}</version>
+        <classifier>features</classifier>
+        <type>xml</type>
+        <scope>runtime</scope>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>features-mdsal</artifactId>
index dd73675070c95ce2bf3365bf8589843322ddf53d..de7621110e21637b93d1b3531fbe579470b2e6f1 100644 (file)
@@ -44,13 +44,13 @@ import org.slf4j.LoggerFactory;
  *
  */
 
-public class ConfigurationService implements IConfigurationService, ICacheUpdateAware<ConfigurationEvent, String> {
+public class ConfigurationService implements IConfigurationService, ICacheUpdateAware<String, String> {
     private static final Logger logger = LoggerFactory
             .getLogger(ConfigurationService.class);
     public static final String SAVE_EVENT_CACHE = "config.event.save";
     private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
     private IClusterGlobalServices clusterServices;
-    private ConcurrentMap <ConfigurationEvent, String> configEvent;
+    private ConcurrentMap<String, String> configEvent;
     private Set<IConfigurationAware> configurationAwareList = Collections
             .synchronizedSet(new HashSet<IConfigurationAware>());
     private ObjectReader objReader;
@@ -105,7 +105,7 @@ public class ConfigurationService implements IConfigurationService, ICacheUpdate
     @Override
     public Status saveConfigurations() {
         if (configEvent != null) {
-            configEvent.put(ConfigurationEvent.SAVE, "");
+            configEvent.put(ConfigurationEvent.SAVE.toString(), "");
         }
         return saveConfigurationsInternal();
     }
@@ -183,7 +183,7 @@ public class ConfigurationService implements IConfigurationService, ICacheUpdate
     }
 
     @Override
-    public void entryCreated(ConfigurationEvent key, String cacheName,
+    public void entryCreated(String key, String cacheName,
             boolean originLocal) {
         if (originLocal) {
             return;
@@ -191,18 +191,18 @@ public class ConfigurationService implements IConfigurationService, ICacheUpdate
     }
 
     @Override
-    public void entryUpdated(ConfigurationEvent key, String new_value,
+    public void entryUpdated(String key, String new_value,
             String cacheName, boolean originLocal) {
         if (originLocal) {
             return;
         }
-        if (key == ConfigurationEvent.SAVE) {
+        if (key.equals(ConfigurationEvent.SAVE.toString())) {
             saveConfigurationsInternal();
         }
     }
 
     @Override
-    public void entryDeleted(ConfigurationEvent key, String cacheName,
+    public void entryDeleted(String key, String cacheName,
             boolean originLocal) {
         if (originLocal) {
             return;
@@ -230,7 +230,7 @@ public class ConfigurationService implements IConfigurationService, ICacheUpdate
             logger.error("uninitialized clusterServices, can't retrieve cache");
             return;
         }
-        configEvent = (ConcurrentMap<ConfigurationEvent, String>) this.clusterServices.getCache(SAVE_EVENT_CACHE);
+        configEvent = (ConcurrentMap<String, String>) this.clusterServices.getCache(SAVE_EVENT_CACHE);
         if (configEvent == null) {
             logger.error("Failed to retrieve configuration Cache");
         }
index a36d4cc6d78588df5828b175de0facd9fe666f33..dcab1f63fbc1104e4225b0351455fb3de0db1d70 100644 (file)
@@ -47,11 +47,12 @@ import org.slf4j.LoggerFactory;
  */
 
 public class ContainerConfigurationService implements IConfigurationContainerService,
-        IConfigurationAware, ICacheUpdateAware<ConfigurationEvent, String> {
+        IConfigurationAware,
+        ICacheUpdateAware<String, String> {
     public static final String CONTAINER_SAVE_EVENT_CACHE = "config.container.event.save";
     private static final Logger logger = LoggerFactory.getLogger(ContainerConfigurationService.class);
     private IClusterContainerServices clusterServices;
-    private ConcurrentMap <ConfigurationEvent, String> containerConfigEvent;
+    private ConcurrentMap<String, String> containerConfigEvent;
     // Directory which contains the startup files for this container
     private String root;
     private Set<IConfigurationContainerAware> configurationAwareList = Collections
@@ -142,12 +143,12 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
 
     @Override
     public Status saveConfigurations() {
-        containerConfigEvent.put(ConfigurationEvent.SAVE, "");
+        containerConfigEvent.put(ConfigurationEvent.SAVE.toString(), "");
         return saveConfiguration();
     }
 
     @Override
-    public void entryCreated(ConfigurationEvent key, String cacheName,
+    public void entryCreated(String key, String cacheName,
             boolean originLocal) {
         if (originLocal) {
             return;
@@ -155,19 +156,19 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
     }
 
     @Override
-    public void entryUpdated(ConfigurationEvent key, String new_value,
+    public void entryUpdated(String key, String new_value,
             String cacheName, boolean originLocal) {
         if (originLocal) {
             return;
         }
         logger.debug("Processing {} event", key);
-        if (key == ConfigurationEvent.SAVE) {
+        if (key.equals(ConfigurationEvent.SAVE.toString())) {
             saveConfiguration();
         }
     }
 
     @Override
-    public void entryDeleted(ConfigurationEvent key, String cacheName,
+    public void entryDeleted(String key, String cacheName,
             boolean originLocal) {
         if (originLocal) {
             return;
@@ -195,7 +196,8 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
             logger.error("uninitialized clusterServices, can't retrieve cache");
             return;
         }
-        containerConfigEvent = (ConcurrentMap<ConfigurationEvent, String>) this.clusterServices.getCache(CONTAINER_SAVE_EVENT_CACHE);
+        containerConfigEvent =
+                (ConcurrentMap<String, String>) this.clusterServices.getCache(CONTAINER_SAVE_EVENT_CACHE);
         if (containerConfigEvent == null) {
             logger.error("Failed to retrieve configuration Cache");
         }
index f6f923e0d26720bda6960c0acf21954d0f6721f5..fbcd0a4c779ed4203a4f153f67604016f43085e6 100644 (file)
@@ -48,9 +48,8 @@
       <Host name="localhost" appBase=""
             unpackWARs="false" autoDeploy="false"
             deployOnStartup="false" createDirs="false">
-<!--         <Realm className="org.opendaylight.controller.security.ControllerCustomRealm" />
+            <Realm className="org.opendaylight.controller.karafsecurity.ControllerCustomRealm" />
             <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
- -->
             <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                         prefix="web_access_log_" suffix=".txt" resolveHosts="false"
                         rotatable="true" fileDateFormat="yyyy-MM"
index e9a6992521250d612c1924e4f0fa46548f63d741..c2ac77a5d6f57b3ba24a581a700dead2fcc8a377 100644 (file)
@@ -1,6 +1,20 @@
 # Extra packages to import from the boot class loader
 org.osgi.framework.system.packages.extra=org.apache.karaf.branding,sun.reflect,sun.reflect.misc,sun.misc,sun.nio.ch
 
+# Override the config.properties to remove
+# ${services-${karaf.framework}}
+# This is to work around:
+# https://issues.apache.org/jira/browse/KARAF-3092
+# Which should be fixed in karaf 3.0.2
+# Which is not as of today (2014-08-24) released.
+# Since it is biting folks, we need to fix it here
+# Please remove this when we shift to karaf 3.0.2
+org.osgi.framework.system.capabilities= \
+ ${eecap-${java.specification.version}}, \
+ service-reference;effective:=active;objectClass=org.osgi.service.packageadmin.PackageAdmin, \
+ service-reference;effective:=active;objectClass=org.osgi.service.startlevel.StartLevel, \
+ service-reference;effective:=active;objectClass=org.osgi.service.url.URLHandlers
+
 # https://bugs.eclipse.org/bugs/show_bug.cgi?id=325578
 # Extend the framework to avoid the resources to be presented with
 # a URL of type bundleresource: but to be presented as file:
@@ -105,3 +119,4 @@ java.util.logging.config.file=configuration/tomcat-logging.properties
 
 #Hosttracker hostsdb key scheme setting
 hosttracker.keyscheme=IP
+
index 5cbe412b2b0af28da537a95af2ace0766df8e120..cdc592428f9d685ab0e715a6e9f762e5a743cc83 100644 (file)
           down with testing... ie, no broken feature repos
     -->
 
+    <!-- AD-SAL Related Features -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-base</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-adsal</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-nsf</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
     <!-- MD-SAL Related Features -->
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
                         <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>
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>
diff --git a/opendaylight/karaf-tomcat-security/pom.xml b/opendaylight/karaf-tomcat-security/pom.xml
new file mode 100644 (file)
index 0000000..817e0fa
--- /dev/null
@@ -0,0 +1,49 @@
+<?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>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.2-SNAPSHOT</version>
+    <relativePath>../commons/opendaylight</relativePath>
+  </parent>
+
+  <artifactId>karaf-tomcat-security</artifactId>
+  <version>0.4.2-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+  <dependencies>
+    <dependency>
+      <groupId>orbit</groupId>
+      <artifactId>org.apache.catalina</artifactId>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Fragment-Host>org.apache.catalina</Fragment-Host>
+            <Import-Package>org.slf4j,
+              javax.servlet,
+              org.apache.catalina,
+              org.apache.catalina.connector,
+              org.apache.catalina.valves,
+              org.apache.catalina.realm
+            </Import-Package>
+            <Export-Package>org.opendaylight.controller.karafsecurity</Export-Package>
+          </instructions>
+          <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
+  </scm>
+</project>
diff --git a/opendaylight/karaf-tomcat-security/src/main/java/org/opendaylight/controller/karafsecurity/ControllerCustomRealm.java b/opendaylight/karaf-tomcat-security/src/main/java/org/opendaylight/controller/karafsecurity/ControllerCustomRealm.java
new file mode 100644 (file)
index 0000000..316067c
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.karafsecurity;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.catalina.realm.GenericPrincipal;
+import org.apache.catalina.realm.RealmBase;
+
+public class ControllerCustomRealm  extends RealmBase {
+
+    private static final String name = "ControllerCustomRealm";
+
+    @Override
+    protected String getName() {
+        return name;
+    }
+
+    @Override
+    protected String getPassword(String username) {
+        return "admin";
+    }
+
+    @Override
+    protected Principal getPrincipal(String username) {
+        List<String> controllerRoles = new ArrayList<String>();
+        controllerRoles.add("System-Admin");
+        return new GenericPrincipal(username, "", controllerRoles);
+    }
+
+    @Override
+    public Principal authenticate(String username, String credentials) {
+        return this.getPrincipal(username);
+    }
+}
index 3dcc546426165ac578486c5dd528b7b8cb4d0766..084ef16f575ce67c8725031e2742a86f1f7105d5 100644 (file)
       <artifactId>scala-library</artifactId>
     </dependency>
 
-    <!-- Test Dependencies -->
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-slf4j_${scala.version}</artifactId>
+    </dependency>
+
+
+      <!-- Test Dependencies -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
         <artifactId>jacoco-maven-plugin</artifactId>
         <configuration>
           <includes>
-            <include>org.opendaylight.controller.*</include>
+            <include>org/opendaylight/controller/cluster/**/*</include>
           </includes>
+          <excludes>
+              <exclude>org/opendaylight/controller/cluster/raft/protobuff/**/*</exclude>
+              <exclude>org/opendaylight/controller/cluster/example/**/*</exclude>
+          </excludes>
           <check>false</check>
         </configuration>
         <executions>
index ae8b6fe8e3aadc23a33cf57531a43ff9cefed8d4..988789b4011e4f3ba9e9e9abe6b0c3009704c810 100644 (file)
@@ -168,8 +168,7 @@ public abstract class RaftActor extends UntypedPersistentActor {
 
         } else if (message instanceof FindLeader) {
             getSender().tell(
-                new FindLeaderReply(
-                    context.getPeerAddress(currentBehavior.getLeaderId())),
+                new FindLeaderReply(getLeaderAddress()),
                 getSelf()
             );
 
@@ -183,12 +182,6 @@ public abstract class RaftActor extends UntypedPersistentActor {
 
             // TODO: Handle failure in saving the snapshot
 
-        } else if (message instanceof FindLeader){
-
-            getSender().tell(new FindLeaderReply(
-                context.getPeerAddress(currentBehavior.getLeaderId())),
-                getSelf());
-
         } else if (message instanceof AddRaftPeer){
 
             // FIXME : Do not add raft peers like this.
@@ -269,18 +262,9 @@ public abstract class RaftActor extends UntypedPersistentActor {
      * @return A reference to the leader if known, null otherwise
      */
     protected ActorSelection getLeader(){
-        String leaderId = currentBehavior.getLeaderId();
-        if (leaderId == null) {
-            return null;
-        }
-        String peerAddress = context.getPeerAddress(leaderId);
-        LOG.debug("getLeader leaderId = " + leaderId + " peerAddress = "
-            + peerAddress);
+        String leaderAddress = getLeaderAddress();
 
-        if(peerAddress == null){
-            return null;
-        }
-        return context.actorSelection(peerAddress);
+        return context.actorSelection(leaderAddress);
     }
 
     /**
@@ -424,6 +408,21 @@ public abstract class RaftActor extends UntypedPersistentActor {
         deleteMessages(sequenceNumber);
     }
 
+    private String getLeaderAddress(){
+        if(isLeader()){
+            return getSelf().path().toString();
+        }
+        String leaderId = currentBehavior.getLeaderId();
+        if (leaderId == null) {
+            return null;
+        }
+        String peerAddress = context.getPeerAddress(leaderId);
+        LOG.debug("getLeaderAddress leaderId = " + leaderId + " peerAddress = "
+            + peerAddress);
+
+        return peerAddress;
+    }
+
 
     private class ReplicatedLogImpl extends AbstractReplicatedLogImpl {
 
index a60aea46e82965d0ded03eb7464941bf1a62f4af..98dd0d46531cadef35f8832a89237a1a95ae44fd 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.controller.cluster.raft.client.messages;
 
-public class FindLeader {
+import java.io.Serializable;
+
+public class FindLeader implements Serializable{
 
 }
index b36ef112b364371d01d9e7f411fdf27761938606..64c73508960144ab3f0095ba3af34c897217c336 100644 (file)
@@ -8,7 +8,9 @@
 
 package org.opendaylight.controller.cluster.raft.client.messages;
 
-public class FindLeaderReply {
+import java.io.Serializable;
+
+public class FindLeaderReply implements Serializable {
     private final String leaderActor;
 
     public FindLeaderReply(String leaderActor) {
index 1971432fb9844f747d39e37c8546c7568632f7c0..ec5381546964d7c8846ed446e4947baebe48380f 100644 (file)
@@ -10,20 +10,26 @@ package org.opendaylight.controller.cluster.raft;
 
 import akka.actor.ActorSystem;
 import akka.testkit.JavaTestKit;
+import org.apache.commons.io.FileUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 
+import java.io.File;
+import java.io.IOException;
+
 public abstract class AbstractActorTest {
     private static ActorSystem system;
 
     @BeforeClass
-    public static void setUpClass() {
+    public static void setUpClass() throws Exception{
+        deleteJournal();
         System.setProperty("shard.persistent", "false");
         system = ActorSystem.create("test");
     }
 
     @AfterClass
-    public static void tearDownClass() {
+    public static void tearDownClass() throws Exception{
+        deleteJournal();
         JavaTestKit.shutdownActorSystem(system);
         system = null;
     }
@@ -32,4 +38,12 @@ public abstract class AbstractActorTest {
         return system;
     }
 
+    protected static void deleteJournal() throws IOException {
+        File journal = new File("journal");
+
+        if(journal.exists()) {
+            FileUtils.deleteDirectory(journal);
+        }
+    }
+
 }
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java
new file mode 100644 (file)
index 0000000..ff0ffeb
--- /dev/null
@@ -0,0 +1,137 @@
+package org.opendaylight.controller.cluster.raft;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.event.Logging;
+import akka.japi.Creator;
+import akka.testkit.JavaTestKit;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.raft.client.messages.FindLeader;
+import org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply;
+
+import java.util.Collections;
+import java.util.Map;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class RaftActorTest extends AbstractActorTest {
+
+
+    public static class MockRaftActor extends RaftActor {
+
+        public MockRaftActor(String id,
+            Map<String, String> peerAddresses) {
+            super(id, peerAddresses);
+        }
+
+        public static Props props(final String id, final Map<String, String> peerAddresses){
+            return Props.create(new Creator<MockRaftActor>(){
+
+                @Override public MockRaftActor create() throws Exception {
+                    return new MockRaftActor(id, peerAddresses);
+                }
+            });
+        }
+
+        @Override protected void applyState(ActorRef clientActor,
+            String identifier,
+            Object data) {
+        }
+
+        @Override protected Object createSnapshot() {
+            throw new UnsupportedOperationException("createSnapshot");
+        }
+
+        @Override protected void applySnapshot(Object snapshot) {
+            throw new UnsupportedOperationException("applySnapshot");
+        }
+
+        @Override protected void onStateChanged() {
+        }
+
+        @Override public String persistenceId() {
+            return this.getId();
+        }
+
+    }
+
+
+    private static class RaftActorTestKit extends JavaTestKit {
+        private final ActorRef raftActor;
+
+        public RaftActorTestKit(ActorSystem actorSystem, String actorName) {
+            super(actorSystem);
+
+            raftActor = this.getSystem()
+                .actorOf(MockRaftActor.props(actorName,
+                    Collections.EMPTY_MAP), actorName);
+
+        }
+
+
+        public boolean waitForStartup(){
+            // Wait for a specific log message to show up
+            return
+                new JavaTestKit.EventFilter<Boolean>(Logging.Info.class
+                ) {
+                    protected Boolean run() {
+                        return true;
+                    }
+                }.from(raftActor.path().toString())
+                    .message("Switching from state Candidate to Leader")
+                    .occurrences(1).exec();
+
+
+        }
+
+        public void findLeader(final String expectedLeader){
+
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    raftActor.tell(new FindLeader(), getRef());
+
+                    String s = new ExpectMsg<String>(duration("1 seconds"),
+                        "findLeader") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in instanceof FindLeaderReply) {
+                                return ((FindLeaderReply) in).getLeaderActor();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();// this extracts the received message
+
+                    assertEquals(expectedLeader, s);
+
+                }
+
+
+            };
+        }
+
+        public ActorRef getRaftActor() {
+            return raftActor;
+        }
+
+    }
+
+
+    @Test
+    public void testConstruction() {
+        boolean started = new RaftActorTestKit(getSystem(), "testConstruction").waitForStartup();
+        assertEquals(true, started);
+    }
+
+    @Test
+    public void testFindLeaderWhenLeaderIsSelf(){
+        RaftActorTestKit kit = new RaftActorTestKit(getSystem(), "testFindLeader");
+        kit.waitForStartup();
+        kit.findLeader(kit.getRaftActor().path().toString());
+    }
+
+
+}
index dbe7508cc8c185a33a35fcf072498041b589854c..2b753004c48265620628fdbc58a1e41a96a65c51 100644 (file)
@@ -1,6 +1,6 @@
 akka {
-
     loglevel = "DEBUG"
+    loggers = ["akka.testkit.TestEventListener", "akka.event.slf4j.Slf4jLogger"]
 
     actor {
         # enable to test serialization only.
@@ -12,6 +12,7 @@ akka {
         }
 
         serialization-bindings {
+            "org.opendaylight.controller.cluster.raft.client.messages.FindLeader" = java
             "org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry" = java
             "com.google.protobuf.Message" = proto
             "com.google.protobuf.GeneratedMessage" = proto
index 24ec89ebb27da82f92fa569216ee7db5fc07d6cc..c71aa049c0622397773d5547faa773aac45ad7fd 100644 (file)
@@ -1,18 +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.md.sal.binding.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
+/**
+ * A chain of transactions.
+ * <p>
+ * For more information about transaction chaining and transaction chains
+ * see {@link TransactionChain}.
+ *
+ * @see TransactionChain
+ *
+ */
 public interface BindingTransactionChain extends TransactionFactory, TransactionChain<InstanceIdentifier<?>, DataObject> {
-
+    /**
+     * {@inheritDoc}
+     */
     @Override
     ReadOnlyTransaction newReadOnlyTransaction();
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     ReadWriteTransaction newReadWriteTransaction();
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     WriteTransaction newWriteOnlyTransaction();
-
 }
index 619a08eac5f30a6f3a7ff7f5f154b1be4c74bdbc..cc8deb81b31777ee6dd4aa3b5bf19a97f3ababb5 100644 (file)
@@ -20,22 +20,39 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  * subscribe for changes to data under a given branch of the tree.
  * <p>
  * For more information on usage, please see the documentation in {@link AsyncDataBroker}.
+ *
+ * @see AsyncDataBroker
+ * @see TransactionChainFactory
  */
 public interface DataBroker extends TransactionFactory, AsyncDataBroker<InstanceIdentifier<?>, DataObject, DataChangeListener>, BindingService, TransactionChainFactory<InstanceIdentifier<?>, DataObject> {
-
+    /**
+     * {@inheritDoc}
+     */
     @Override
     ReadOnlyTransaction newReadOnlyTransaction();
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     ReadWriteTransaction newReadWriteTransaction();
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     WriteTransaction newWriteOnlyTransaction();
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     ListenerRegistration<DataChangeListener> registerDataChangeListener(LogicalDatastoreType store,
             InstanceIdentifier<?> path, DataChangeListener listener, DataChangeScope triggeringScope);
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     BindingTransactionChain createTransactionChain(TransactionChainListener listener);
 }
index f843b23f9b2cc9d15a55c2d9a4373cde3baffecc..53f96e44f4105b8ecd3f2125be2360bd54a0b0c4 100644 (file)
@@ -9,15 +9,14 @@ package org.opendaylight.controller.md.sal.binding.impl;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Optional;
-import java.util.ArrayList;
+
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
@@ -88,7 +87,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
             final Map<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized) {
         Map<InstanceIdentifier<?>, DataObject> newMap = new HashMap<>();
 
-        for (Map.Entry<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : sortedEntries(normalized)) {
+        for (Map.Entry<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : normalized.entrySet()) {
             try {
                 Optional<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> potential = getCodec().toBinding(entry);
                 if (potential.isPresent()) {
@@ -102,38 +101,6 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         return newMap;
     }
 
-    private static final Comparator<Entry<YangInstanceIdentifier, ?>> MAP_ENTRY_COMPARATOR = new Comparator<Entry<YangInstanceIdentifier, ?>>() {
-        @Override
-        public int compare(final Entry<YangInstanceIdentifier, ?> left, final Entry<YangInstanceIdentifier, ?> right) {
-            final Iterator<?> li = left.getKey().getPathArguments().iterator();
-            final Iterator<?> ri = right.getKey().getPathArguments().iterator();
-
-            // Iterate until left is exhausted...
-            while (li.hasNext()) {
-                if (!ri.hasNext()) {
-                    // Left is deeper
-                    return 1;
-                }
-
-                li.next();
-                ri.next();
-            }
-
-            // Check if right is exhausted
-            return ri.hasNext() ? -1 : 0;
-        }
-    };
-
-    private static <T> Iterable<Entry<YangInstanceIdentifier, T>> sortedEntries(final Map<YangInstanceIdentifier, T> map) {
-        if (!map.isEmpty()) {
-            ArrayList<Entry<YangInstanceIdentifier, T>> entries = new ArrayList<>(map.entrySet());
-            Collections.sort(entries, MAP_ENTRY_COMPARATOR);
-            return entries;
-        } else {
-            return Collections.emptySet();
-        }
-    }
-
     protected Set<InstanceIdentifier<?>> toBinding(final InstanceIdentifier<?> path,
             final Set<YangInstanceIdentifier> normalized) {
         Set<InstanceIdentifier<?>> hashSet = new HashSet<>();
index 1e2d2b17f0b1846ab9272f6683f2a0f00cd1c070..9ad35fcdda85347de6a7680c4f91dabbeed8e2a7 100644 (file)
@@ -9,9 +9,10 @@ package org.opendaylight.controller.md.sal.binding.impl;
 
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
-import java.util.AbstractMap.SimpleEntry;
+
 import java.util.Iterator;
 import java.util.Map.Entry;
+
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
@@ -26,13 +27,9 @@ import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMapping
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoCloseable {
 
-    private static final Logger LOG = LoggerFactory.getLogger(BindingToNormalizedNodeCodec.class);
-
     private final BindingIndependentMappingService bindingToLegacy;
     private final BindingNormalizedNodeCodecRegistry codecRegistry;
     private DataNormalizer legacyToNormalized;
@@ -82,14 +79,6 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoC
         }
     }
 
-
-    private static final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toBindingEntry(
-            final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> key,
-            final DataObject value) {
-        return new SimpleEntry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>(
-                key, value);
-    }
-
     public DataNormalizer getDataNormalizer() {
         return legacyToNormalized;
     }
index 815fc452594e837965b1bd7d66a1814cf87bf299..3e6c4c072d15738d6d2dd1faa897bd7bd231e101 100644 (file)
@@ -1,8 +1,8 @@
 package org.opendaylight.controller.md.sal.binding.impl.test;
 
 import static org.junit.Assert.assertTrue;
-
 import javassist.ClassPool;
+
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.md.sal.binding.test.AbstractSchemaAwareTest;
@@ -11,6 +11,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controll
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
 import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
 import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
@@ -38,7 +39,7 @@ public class BindingNormalizedCodecTest extends AbstractSchemaAwareTest {
     @Override
     protected void setupWithSchema(final SchemaContext context) {
         mappingService = new RuntimeGeneratedMappingServiceImpl(ClassPool.getDefault());
-        StreamWriterGenerator streamWriter = new StreamWriterGenerator(JavassistUtils.forClassPool(ClassPool.getDefault()));
+        DataObjectSerializerGenerator streamWriter = StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault()));
         BindingNormalizedNodeCodecRegistry registry = new BindingNormalizedNodeCodecRegistry(streamWriter);
         codec = new BindingToNormalizedNodeCodec(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), mappingService, registry);
         mappingService.onGlobalContextUpdated(context);
index 106fcea0e9f178470c26eab42fe1bf7c36eb4e08..ca04f99ba22361d8fcdc09794bcaa9193729483c 100644 (file)
@@ -30,7 +30,6 @@ import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeC
 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
 import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public class DataBrokerTestCustomizer {
@@ -93,10 +92,6 @@ public class DataBrokerTestCustomizer {
         return schemaService;
     }
 
-    private BindingIndependentMappingService getMappingService() {
-        return mappingService;
-    }
-
     private DOMDataBroker getDOMDataBroker() {
         if(domDataBroker == null) {
             domDataBroker = createDOMDataBroker();
@@ -104,8 +99,8 @@ public class DataBrokerTestCustomizer {
         return domDataBroker;
     }
 
-    private ImmutableMap<LogicalDatastoreType, DOMStore> getDatastores() {
-        if(datastores == null) {
+    private synchronized ImmutableMap<LogicalDatastoreType, DOMStore> getDatastores() {
+        if (datastores == null) {
             datastores = createDatastores();
         }
         return datastores;
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 17bdb36e569612ef513a787e010aeb8583167984..d1ae264c3b912839a4332fc74766076859b754db 100644 (file)
@@ -32,7 +32,7 @@ public class NormalizedNodeToNodeCodec {
         String parentPath = "";
 
         if(id != null){
-            parentPath = PathUtils.getParentPath(id.toString());
+            parentPath = PathUtils.getParentPath(PathUtils.toString(id));
         }
 
 
index 31e6521a2861e65f1412b99818d4d47684e04c7b..32f3be82fcd0648e35796c5e3c835332825a20e9 100644 (file)
@@ -25,7 +25,7 @@ public class NormalizedNodeGetter implements
 
     @Override
     public void visitNode(int level, String parentPath, NormalizedNode normalizedNode) {
-        String nodePath = parentPath + "/"+ normalizedNode.getIdentifier().toString();
+        String nodePath = parentPath + "/"+ PathUtils.toString(normalizedNode.getIdentifier());
 
         if(nodePath.toString().equals(path)){
             output = normalizedNode;
index 1dd0f3b8278407752b91afbb24548eb857385cbc..25b65f01681ac4b9dcaa6354ec001c85bc531981 100644 (file)
 
 package org.opendaylight.controller.cluster.datastore.node.utils;
 
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
 public class PathUtils {
+
     public static String getParentPath(String currentElementPath){
         StringBuilder parentPath = new StringBuilder();
 
@@ -27,4 +36,86 @@ public class PathUtils {
         }
         return parentPath.toString();
     }
+
+    /**
+     * Given a YangInstanceIdentifier return a serialized version of the same
+     * as a String
+     *
+     * @param path
+     * @return
+     */
+    public static String toString(YangInstanceIdentifier path){
+        StringBuilder sb = new StringBuilder();
+        Iterator<YangInstanceIdentifier.PathArgument> iterator =
+            path.getPathArguments().iterator();
+
+        while(iterator.hasNext()){
+            sb.append(toString(iterator.next()));
+            if(iterator.hasNext()){
+                sb.append("/");
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Given a YangInstanceIdentifier.PathArgument return a serialized version
+     * of the same as a String
+     *
+     * @param pathArgument
+     * @return
+     */
+    public static String toString(YangInstanceIdentifier.PathArgument pathArgument){
+        if(pathArgument instanceof YangInstanceIdentifier.NodeIdentifier){
+            return toString((YangInstanceIdentifier.NodeIdentifier) pathArgument);
+        } else if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier){
+            return toString((YangInstanceIdentifier.AugmentationIdentifier) pathArgument);
+        } else if(pathArgument instanceof YangInstanceIdentifier.NodeWithValue){
+            return toString((YangInstanceIdentifier.NodeWithValue) pathArgument);
+        } else if(pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates){
+            return toString((YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument);
+        }
+
+        return pathArgument.toString();
+    }
+
+    /**
+     * Given a serialized string version of a YangInstanceIdentifier convert
+     * to a YangInstanceIdentifier
+     *
+     * @param path
+     * @return
+     */
+    public static YangInstanceIdentifier toYangInstanceIdentifier(String path){
+        String[] segments = path.split("/");
+
+        List<YangInstanceIdentifier.PathArgument> pathArguments = new ArrayList<>();
+        for (String segment : segments) {
+            if (!"".equals(segment)) {
+                pathArguments.add(NodeIdentifierFactory.getArgument(segment));
+            }
+        }
+        return YangInstanceIdentifier.create(pathArguments);
+    }
+
+    private static String toString(YangInstanceIdentifier.NodeIdentifier pathArgument){
+        return pathArgument.getNodeType().toString();
+    }
+
+    private static String toString(YangInstanceIdentifier.AugmentationIdentifier pathArgument){
+        Set<QName> childNames = pathArgument.getPossibleChildNames();
+        final StringBuilder sb = new StringBuilder("AugmentationIdentifier{");
+        sb.append("childNames=").append(childNames).append('}');
+        return sb.toString();
+
+    }
+
+    private static String toString(YangInstanceIdentifier.NodeWithValue pathArgument){
+        return pathArgument.getNodeType().toString() + "[" + pathArgument.getValue() + "]";
+    }
+
+    private static String toString(YangInstanceIdentifier.NodeIdentifierWithPredicates pathArgument){
+        return pathArgument.getNodeType().toString() + '[' + pathArgument.getKeyValues() + ']';
+    }
+
 }
index 002b9ff82e53eea0b62fd98d97756926a2e21bea..5a8f5228619e9f80a091da123aa734fb59dcd85f 100644 (file)
 
 package org.opendaylight.controller.cluster.datastore.node.utils;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
 import org.opendaylight.yangtools.yang.common.QName;
 
-import java.util.HashMap;
-import java.util.Map;
-
 public class QNameFactory {
-    private static final Map<String, QName> cache = new HashMap<>();
 
-    public static QName create(String name){
-        QName value = cache.get(name);
-        if(value == null){
-            synchronized (cache){
-                value = cache.get(name);
-                if(value == null) {
-                    value = QName.create(name);
-                    cache.put(name, value);
+    private static final int MAX_QNAME_CACHE_SIZE = 10000;
+
+    private static LoadingCache<String, QName> cache = CacheBuilder.newBuilder()
+        .maximumSize(MAX_QNAME_CACHE_SIZE)
+        .softValues()
+        .build(
+            new CacheLoader<String, QName>() {
+                public QName load(String key) {
+                    return QName.create(key);
                 }
             }
-        }
-        return value;
+        );
+
+
+    public static QName create(String name){
+        return cache.getUnchecked(name);
     }
 }
index 55cb341086078b79406d574c11cec8961813e6b6..0bb0d4fe8798b8623dc433d659f6ea550096c41e 100644 (file)
@@ -11,6 +11,7 @@
 package org.opendaylight.controller.cluster.datastore.util;
 
 import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
+import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory;
 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -222,7 +223,7 @@ public class InstanceIdentifierUtils {
 
             YangInstanceIdentifier.NodeWithValue nodeWithValue =
                 new YangInstanceIdentifier.NodeWithValue(
-                    QName.create(pathArgument.getNodeType().getValue()),
+                    QNameFactory.create(pathArgument.getNodeType().getValue()),
                     parseAttribute(pathArgument.getAttributes(0)));
 
             return nodeWithValue;
@@ -232,7 +233,7 @@ public class InstanceIdentifierUtils {
             YangInstanceIdentifier.NodeIdentifierWithPredicates
                 nodeIdentifierWithPredicates =
                 new YangInstanceIdentifier.NodeIdentifierWithPredicates(
-                    QName.create(pathArgument.getNodeType().getValue()), toAttributesMap(pathArgument.getAttributesList()));
+                    QNameFactory.create(pathArgument.getNodeType().getValue()), toAttributesMap(pathArgument.getAttributesList()));
 
             return nodeIdentifierWithPredicates;
 
@@ -241,7 +242,7 @@ public class InstanceIdentifierUtils {
             Set<QName> qNameSet = new HashSet<>();
 
             for(NormalizedNodeMessages.Attribute attribute : pathArgument.getAttributesList()){
-                qNameSet.add(QName.create(attribute.getValue()));
+                qNameSet.add(QNameFactory.create(attribute.getValue()));
             }
 
             return new YangInstanceIdentifier.AugmentationIdentifier(qNameSet);
@@ -259,7 +260,7 @@ public class InstanceIdentifierUtils {
             String name = attribute.getName();
             Object value = parseAttribute(attribute);
 
-            map.put(QName.create(name), value);
+            map.put(QNameFactory.create(name), value);
         }
 
         return map;
index bdad86ddc1e8fb5521607fbb91a575a99e677d38..c42865c659192e0584ebe93a147fee655ab284c4 100644 (file)
@@ -13,9 +13,9 @@ package org.opendaylight.controller.cluster.datastore.node;
 import junit.framework.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
 import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeGetter;
 import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeNavigator;
+import org.opendaylight.controller.cluster.datastore.node.utils.PathUtils;
 import org.opendaylight.controller.cluster.datastore.util.TestModel;
 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container;
 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
@@ -24,7 +24,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import static junit.framework.Assert.assertEquals;
@@ -43,21 +42,9 @@ public class NormalizedNodeToNodeCodecTest {
   }
 
   private YangInstanceIdentifier instanceIdentifierFromString(String s) {
-
-    String[] ids = s.split("/");
-
-    List<YangInstanceIdentifier.PathArgument> pathArguments = new ArrayList<>();
-    for (String nodeId : ids) {
-      if (!"".equals(nodeId)) {
-        pathArguments.add(NodeIdentifierFactory.getArgument(nodeId));
-      }
-    }
-    final YangInstanceIdentifier instanceIdentifier =
-        YangInstanceIdentifier.create(pathArguments);
-    return instanceIdentifier;
+      return PathUtils.toYangInstanceIdentifier(s);
   }
 
-
   @Test
   public void testNormalizeNodeAttributesToProtoBuffNode() {
     final NormalizedNode<?, ?> documentOne = TestModel.createTestContainer();
@@ -69,7 +56,7 @@ public class NormalizedNodeToNodeCodecTest {
 
     NormalizedNodeGetter normalizedNodeGetter = new NormalizedNodeGetter(id);
     new NormalizedNodeNavigator(normalizedNodeGetter).navigate(
-        YangInstanceIdentifier.builder().build().toString(), documentOne);
+        PathUtils.toString(YangInstanceIdentifier.builder().build()), documentOne);
 
     // Validate the value of id can be retrieved from the normalized node
     NormalizedNode output = normalizedNodeGetter.getOutput();
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/PathUtilsTest.java b/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/PathUtilsTest.java
new file mode 100644 (file)
index 0000000..ffa8a10
--- /dev/null
@@ -0,0 +1,121 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.util.TestModel;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class PathUtilsTest {
+
+    @Test
+    public void getParentPath(){
+        assertEquals("", PathUtils.getParentPath("foobar"));
+        assertEquals("", PathUtils.getParentPath("/a"));
+        assertEquals("/a", PathUtils.getParentPath("/a/b"));
+        assertEquals("/a/b", PathUtils.getParentPath("/a/b/c"));
+        assertEquals("/a/b", PathUtils.getParentPath("a/b/c"));
+    }
+
+    @Test
+    public void toStringNodeIdentifier(){
+        YangInstanceIdentifier.PathArgument pathArgument = nodeIdentifier();
+
+        String expected = "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test";
+
+        assertEquals(expected , PathUtils.toString(pathArgument));
+    }
+
+    @Test
+    public void toStringAugmentationIdentifier(){
+        String expected = "AugmentationIdentifier{childNames=[(urn:opendaylight:flow:table:statistics?revision=2013-12-15)flow-table-statistics]}";
+
+        YangInstanceIdentifier.PathArgument pathArgument = augmentationIdentifier();
+
+        assertEquals(expected, PathUtils.toString(pathArgument));
+    }
+
+    @Test
+    public void toStringNodeWithValue(){
+
+        YangInstanceIdentifier.PathArgument pathArgument = nodeWithValue();
+
+        String expected = "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test[100]";
+
+        assertEquals(expected, PathUtils.toString(pathArgument));
+    }
+
+
+    @Test
+    public void toStringNodeIdentifierWithPredicates(){
+
+        YangInstanceIdentifier.PathArgument pathArgument = nodeIdentifierWithPredicates();
+
+        String expected = "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test[{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)id=100}]";
+
+        assertEquals(expected, PathUtils.toString(pathArgument));
+    }
+
+    @Test
+    public void toStringYangInstanceIdentifier(){
+
+        YangInstanceIdentifier path =
+            YangInstanceIdentifier.create(nodeIdentifier())
+                .node(nodeIdentifierWithPredicates())
+                .node(augmentationIdentifier()).node(nodeWithValue());
+
+
+        String expected = "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test/" +
+            "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test[{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)id=100}]/" +
+            "AugmentationIdentifier{childNames=[(urn:opendaylight:flow:table:statistics?revision=2013-12-15)flow-table-statistics]}/" +
+            "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test[100]";
+
+        assertEquals(expected, PathUtils.toString(path));
+
+    }
+
+    @Test
+    public void toYangInstanceIdentifier(){
+        String expected = "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test/" +
+            "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test[{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)id=100}]/" +
+            "AugmentationIdentifier{childNames=[(urn:opendaylight:flow:table:statistics?revision=2013-12-15)flow-table-statistics]}/" +
+            "(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test[100]";
+
+        YangInstanceIdentifier yangInstanceIdentifier =
+            PathUtils.toYangInstanceIdentifier(expected);
+
+        String actual = PathUtils.toString(yangInstanceIdentifier);
+
+        assertEquals(expected, actual);
+
+    }
+
+    private YangInstanceIdentifier.NodeIdentifier nodeIdentifier(){
+        return new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME);
+    }
+
+    private YangInstanceIdentifier.AugmentationIdentifier augmentationIdentifier(){
+        Set<QName> childNames = new HashSet();
+        childNames.add(QNameFactory.create("(urn:opendaylight:flow:table:statistics?revision=2013-12-15)flow-table-statistics"));
+
+        return new YangInstanceIdentifier.AugmentationIdentifier(childNames);
+    }
+
+    private YangInstanceIdentifier.NodeWithValue nodeWithValue(){
+        return new YangInstanceIdentifier.NodeWithValue(TestModel.TEST_QNAME, Integer.valueOf(100));
+    }
+
+    private YangInstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifierWithPredicates(){
+        Map<QName, Object> keys = new HashMap<>();
+
+        keys.put(TestModel.ID_QNAME, Integer.valueOf(100));
+
+        return new YangInstanceIdentifier.NodeIdentifierWithPredicates(TestModel.TEST_QNAME, keys);
+    }
+}
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/QNameFactoryTest.java b/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/QNameFactoryTest.java
new file mode 100644 (file)
index 0000000..76d4ceb
--- /dev/null
@@ -0,0 +1,29 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.util.TestModel;
+import org.opendaylight.yangtools.yang.common.QName;
+
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+public class QNameFactoryTest {
+
+    @Test
+    public void testBasic(){
+        QName expected = TestModel.AUG_NAME_QNAME;
+        QName created = QNameFactory.create(expected.toString());
+
+        assertFalse( expected == created);
+
+        assertEquals(expected, created);
+
+        QName cached = QNameFactory.create(expected.toString());
+
+        assertEquals(expected, cached);
+
+        assertTrue( cached == created );
+    }
+
+}
index 5bf231dbe1ca31040565bad6b82d90201a4c0df2..0535179aadf79c4196a8f606433c1cd8b4e89949 100644 (file)
@@ -25,7 +25,7 @@ odl-cluster-data {
     }
 
     cluster {
-      seed-nodes = ["akka.tcp://opendaylight-cluster-data@<CHANGE_ME>:2550"]
+      seed-nodes = ["akka.tcp://opendaylight-cluster-data@<CHANGE_SEED_IP>:2550"]
 
       auto-down-unreachable-after = 10s
     }
@@ -47,7 +47,7 @@ odl-cluster-rpc {
     }
 
     cluster {
-      seed-nodes = ["akka.tcp://opendaylight-cluster-rpc@<CHANGE_ME>:2551"]
+      seed-nodes = ["akka.tcp://opendaylight-cluster-rpc@<CHANGE_SEED_IP>:2551"]
 
       auto-down-unreachable-after = 10s
     }
index 940559ef895bf9cec406eee2fbe73a7617da581a..32e32f94eb34e59d5b956095235883a717d3f95b 100644 (file)
@@ -10,39 +10,114 @@ package org.opendaylight.controller.md.sal.common.api.data;
 import org.opendaylight.yangtools.concepts.Path;
 
 /**
- * A chain of transactions. Transactions in a chain need to be committed in sequence and each
- * transaction should see the effects of previous transactions as if they happened. A chain
- * makes no guarantees of atomicity, in fact transactions are committed as soon as possible.
+ * A chain of transactions. Transactions in a chain need to be committed in
+ * sequence and each transaction should see the effects of previous committed transactions
+ * as they occurred. A chain makes no guarantees of atomicity across the chained transactions -
+ * the transactions are committed as soon as possible in the order that they were submitted.
  *
+ * This behaviour is different from the default AsyncDataBroker, where a
+ * transaction is always created from the current global state, not taking into
+ * account any transactions previously committed by the calling thread. Due to
+ * the asynchronous nature of transaction submission this can lead to surprising
+ * results. If a thread executes the following sequence sufficiently quickly:
+ *
+ * AsyncWriteTransaction t1 = broker.newWriteOnlyTransaction();
+ * t1.put(id, data);
+ * t1.submit();
+ *
+ * AsyncReadTransaction t2 = broker.newReadOnlyTransaction();
+ * Optional<?> maybeData = t2.read(id).get();
+ *
+ * it may happen, that it sees maybeData.isPresent() == false, simply because
+ * t1 has not completed the processes of being applied and t2 is actually
+ * allocated from the previous state. This is obviously bad for users who create
+ * incremental state in the datastore and actually read what they write in
+ * subsequent transactions.
+ *
+ * Using a TransactionChain instead of a broker solves this particular problem,
+ * and leads to expected behavior: t2 will always see the data written in t1
+ * present.
  */
-public interface TransactionChain<P extends Path<P>, D> extends AutoCloseable, AsyncDataTransactionFactory<P, D> {
+public interface TransactionChain<P extends Path<P>, D> extends AutoCloseable,
+        AsyncDataTransactionFactory<P, D> {
 
     /**
      * Create a new read only transaction which will continue the chain.
-     * The previous read-write transaction has to be either COMMITED or CANCELLED.
+     *
+     * <p>
+     * The previous write transaction has to be either SUBMITTED
+     * ({@link AsyncWriteTransaction#submit submit} was invoked) or CANCELLED
+     * ({@link #close close} was invoked).
+     * <p>
+     * The returned read-only transaction presents an isolated view of the data if the previous
+     * write transaction was successful - in other words, this read-only transaction will see the
+     * state changes made by the previous write transaction in the chain. However, state which
+     * was introduced by other transactions outside this transaction chain after creation of
+     * the previous transaction is not visible.
      *
      * @return New transaction in the chain.
-     * @throws IllegalStateException if the previous transaction was not COMMITED
-     *    or CANCELLED.
-     * @throws TransactionChainClosedException if the chain has been closed.
+     * @throws IllegalStateException
+     *             if the previous transaction was not SUBMITTED or CANCELLED.
+     * @throws TransactionChainClosedException
+     *             if the chain has been closed.
      */
     @Override
     public AsyncReadOnlyTransaction<P, D> newReadOnlyTransaction();
 
-
     /**
-     * Create a new read write transaction which will continue the chain.
-     * The previous read-write transaction has to be either COMMITED or CANCELLED.
+     * Create a new read-write transaction which will continue the chain.
+     *
+     * <p>
+     * The previous write transaction has to be either SUBMITTED
+     * ({@link AsyncWriteTransaction#submit submit} was invoked) or CANCELLED
+     * ({@link #close close} was invoked).
+     * <p>
+     * The returned read-write transaction presents an isolated view of the data if the previous
+     * write transaction was successful - in other words, this read-write transaction will see the
+     * state changes made by the previous write transaction in the chain. However, state which
+     * was introduced by other transactions outside this transaction chain after creation of
+     * the previous transaction is not visible.
+     * <p>
+     * Committing this read-write transaction using {@link AsyncWriteTransaction#submit submit}
+     * will submit the state changes in this transaction to be visible to any subsequent
+     * transaction in this chain and also to any transaction outside this chain.
      *
      * @return New transaction in the chain.
-     * @throws IllegalStateException if the previous transaction was not COMMITTED
-     *    or CANCELLED.
-     * @throws TransactionChainClosedException if the chain has been closed.
+     * @throws IllegalStateException
+     *             if the previous transaction was not SUBMITTED or CANCELLED.
+     * @throws TransactionChainClosedException
+     *             if the chain has been closed.
      */
     @Override
     public AsyncReadWriteTransaction<P, D> newReadWriteTransaction();
 
+    /**
+     * Create a new write-only transaction which will continue the chain.
+     *
+     * <p>
+     * The previous write transaction has to be either SUBMITTED
+     * ({@link AsyncWriteTransaction#submit submit} was invoked) or CANCELLED
+     * ({@link #close close} was invoked).
+     * <p>
+     * The returned write-only transaction presents an isolated view of the data if the previous
+     * write transaction was successful - in other words, this write-only transaction will see the
+     * state changes made by the previous write transaction in the chain. However, state which
+     * was introduced by other transactions outside this transaction chain after creation of
+     * the previous transaction is not visible.
+     * <p>
+     * Committing this write-only transaction using {@link AsyncWriteTransaction#submit submit}
+     * will submit the state changes in this transaction to be visible to any subsequent
+     * transaction in this chain and also to any transaction outside this chain.
+     *
+     * @return New transaction in the chain.
+     * @throws IllegalStateException
+     *             if the previous transaction was not SUBMITTED or CANCELLED.
+     * @throws TransactionChainClosedException
+     *             if the chain has been closed.
+     */
+    @Override
+    public AsyncWriteTransaction<P, D> newWriteOnlyTransaction();
+
     @Override
     void close();
 }
-
index 94d21f5fd6bb02736a360592dc6826a3c70e4ae4..470e6110047adb93014455ae679dc8126b7e1dd3 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.yangtools.concepts.Path;
  * Interface for creating transaction chains.
  */
 public interface TransactionChainFactory<P extends Path<P>, D> {
+
     /**
      * Create a new transaction chain. The chain will be initialized to read
      * from its backing datastore, with no outstanding transaction. Listener
index c4ec760b40cd57d54579144f010b5e0f7425363e..76bbef713c350ad975c9dbb256bdef83bd1e4915 100644 (file)
@@ -36,13 +36,13 @@ public class TransactionChainProxy implements DOMStoreTransactionChain{
     @Override
     public DOMStoreReadWriteTransaction newReadWriteTransaction() {
         return new TransactionProxy(actorContext,
-            TransactionProxy.TransactionType.WRITE_ONLY, schemaContext);
+            TransactionProxy.TransactionType.READ_WRITE, schemaContext);
     }
 
     @Override
     public DOMStoreWriteTransaction newWriteOnlyTransaction() {
         return new TransactionProxy(actorContext,
-            TransactionProxy.TransactionType.READ_WRITE, schemaContext);
+            TransactionProxy.TransactionType.WRITE_ONLY, schemaContext);
     }
 
     @Override
index 5b5b1296af08e42c2278b6db80ac05cbf08329c6..6183c489c4cdbc56a1ba9ac0c3c3939963277edb 100644 (file)
@@ -99,7 +99,7 @@ public class TransactionProxy implements DOMStoreReadWriteTransaction {
         this.identifier = TransactionIdentifier.builder().memberName(memberName).counter(
                 counter.getAndIncrement()).build();
 
-        LOG.debug("Created txn {}", identifier);
+        LOG.debug("Created txn {} of type {}", identifier, transactionType);
 
     }
 
index f584467ee91b37f2b0866cb9a39556eba3c9ace8..f5a6a348415308377d755011b133796659d3f27d 100644 (file)
@@ -9,14 +9,13 @@
 package org.opendaylight.controller.cluster.datastore.messages;
 
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages;
 
 /**
  * The FindPrimary message is used to locate the primary of any given shard
  *
  */
 public class FindPrimary implements SerializableMessage{
-  public static final Class SERIALIZABLE_CLASS = ShardManagerMessages.FindPrimary.class;
+  public static final Class SERIALIZABLE_CLASS = FindPrimary.class;
     private final String shardName;
 
     public FindPrimary(String shardName){
@@ -32,10 +31,10 @@ public class FindPrimary implements SerializableMessage{
 
   @Override
   public Object toSerializable() {
-    return ShardManagerMessages.FindPrimary.newBuilder().setShardName(shardName).build();
+    return this;
   }
 
   public static FindPrimary fromSerializable(Object message){
-    return new FindPrimary(((ShardManagerMessages.FindPrimary)message).getShardName());
+    return (FindPrimary) message;
   }
 }
index 69502837bcc6c114a1daa98986006ed0bd206aab..a2f6701524a7f4d2f42a4ce93b4463d368414659 100644 (file)
@@ -8,10 +8,9 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-import org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages;
 
 public class PrimaryFound implements SerializableMessage {
-  public static final Class SERIALIZABLE_CLASS = ShardManagerMessages.PrimaryFound.class;
+  public static final Class SERIALIZABLE_CLASS = PrimaryFound.class;
   private final String primaryPath;
 
   public PrimaryFound(String primaryPath) {
@@ -49,10 +48,10 @@ public class PrimaryFound implements SerializableMessage {
 
   @Override
   public Object toSerializable() {
-    return  ShardManagerMessages.PrimaryFound.newBuilder().setPrimaryPath(primaryPath).build();
+    return  this;
   }
 
   public static PrimaryFound fromSerializable(Object message){
-    return new PrimaryFound(((ShardManagerMessages.PrimaryFound)message).getPrimaryPath());
+    return (PrimaryFound) message;
   }
 }
index 057028c469416df2767a067ef5e36e4256babd35..731a5364db247d52642e31da6e105ea655793196 100644 (file)
@@ -9,10 +9,9 @@
 package org.opendaylight.controller.cluster.datastore.messages;
 
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages;
 
 public class PrimaryNotFound implements SerializableMessage {
-  public static final Class SERIALIZABLE_CLASS = ShardManagerMessages.PrimaryNotFound.class;
+  public static final Class SERIALIZABLE_CLASS = PrimaryNotFound.class;
 
     private final String shardName;
 
@@ -42,10 +41,10 @@ public class PrimaryNotFound implements SerializableMessage {
 
   @Override
   public Object toSerializable() {
-    return ShardManagerMessages.PrimaryNotFound.newBuilder().setShardName(shardName).build();
+    return this;
   }
 
   public static PrimaryNotFound fromSerializable(Object message){
-    return new PrimaryNotFound(((ShardManagerMessages.PrimaryNotFound)message).getShardName());
+    return (PrimaryNotFound) message;
   }
 }
index 592bc49d9e40648a53e6d448666d34c58f2f4184..ce31c3ad5738edc81db36f8666c67dc309cbdfb7 100644 (file)
@@ -27,9 +27,9 @@ public class DistributedConfigDataStoreProviderModule extends
     @Override
     public java.lang.AutoCloseable createInstance() {
         return DistributedDataStoreFactory.createInstance("config", getConfigSchemaServiceDependency(),
-                InMemoryDOMDataStoreConfigProperties.create(getMaxShardDataChangeExecutorPoolSize(),
-                        getMaxShardDataChangeExecutorQueueSize(),
-                        getMaxShardDataChangeListenerQueueSize()));
+                InMemoryDOMDataStoreConfigProperties.create(getConfigMaxShardDataChangeExecutorPoolSize(),
+                        getConfigMaxShardDataChangeExecutorQueueSize(),
+                        getConfigMaxShardDataChangeListenerQueueSize()));
     }
 
 }
index 9eb72d64d0e90079b5fe1ae7a0405bc5a522b8d0..4d5b07420f7cda5d0a0c1d74740026cde5e74eab 100644 (file)
@@ -28,9 +28,9 @@ public class DistributedOperationalDataStoreProviderModule extends
     public java.lang.AutoCloseable createInstance() {
         return DistributedDataStoreFactory.createInstance("operational",
                 getOperationalSchemaServiceDependency(),
-                InMemoryDOMDataStoreConfigProperties.create(getMaxShardDataChangeExecutorPoolSize(),
-                        getMaxShardDataChangeExecutorQueueSize(),
-                        getMaxShardDataChangeListenerQueueSize()));
+                InMemoryDOMDataStoreConfigProperties.create(getOperationalMaxShardDataChangeExecutorPoolSize(),
+                        getOperationalMaxShardDataChangeExecutorQueueSize(),
+                        getOperationalMaxShardDataChangeListenerQueueSize()));
     }
 
 }
index ecb823e624709bc84f167e522efa09bba06e53f8..6bca5ce25cefe5dbcea73279fa5395f359bb8916 100644 (file)
@@ -49,19 +49,19 @@ module distributed-datastore-provider {
                 }
             }
 
-            leaf max-shard-data-change-executor-queue-size {
+            leaf config-max-shard-data-change-executor-queue-size {
                 default 1000;
                 type uint16;
                 description "The maximum queue size for each shard's data store data change notification executor.";
             }
 
-            leaf max-shard-data-change-executor-pool-size {
+            leaf config-max-shard-data-change-executor-pool-size {
                 default 20;
                 type uint16;
                 description "The maximum thread pool size for each shard's data store data change notification executor.";
             }
 
-            leaf max-shard-data-change-listener-queue-size {
+            leaf config-max-shard-data-change-listener-queue-size {
                 default 1000;
                 type uint16;
                 description "The maximum queue size for each shard's data store data change listeners.";
@@ -82,19 +82,19 @@ module distributed-datastore-provider {
                     }
                 }
 
-            leaf max-shard-data-change-executor-queue-size {
+            leaf operational-max-shard-data-change-executor-queue-size {
                 default 1000;
                 type uint16;
                 description "The maximum queue size for each shard's data store data change notification executor.";
             }
 
-            leaf max-shard-data-change-executor-pool-size {
+            leaf operational-max-shard-data-change-executor-pool-size {
                 default 20;
                 type uint16;
                 description "The maximum thread pool size for each shard's data store data change notification executor.";
             }
 
-            leaf max-shard-data-change-listener-queue-size {
+            leaf operational-max-shard-data-change-listener-queue-size {
                 default 1000;
                 type uint16;
                 description "The maximum queue size for each shard's data store data change listeners.";
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxyTest.java
new file mode 100644 (file)
index 0000000..9b70397
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *
+ *  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.cluster.datastore;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class TransactionChainProxyTest {
+    ActorContext actorContext = Mockito.mock(ActorContext.class);
+    SchemaContext schemaContext = Mockito.mock(SchemaContext.class);
+    @Test
+    public void testNewReadOnlyTransaction() throws Exception {
+
+     DOMStoreTransaction dst = new TransactionChainProxy(actorContext, schemaContext).newReadOnlyTransaction();
+         Assert.assertTrue(dst instanceof DOMStoreReadTransaction);
+
+    }
+
+    @Test
+    public void testNewReadWriteTransaction() throws Exception {
+        DOMStoreTransaction dst = new TransactionChainProxy(actorContext, schemaContext).newReadWriteTransaction();
+        Assert.assertTrue(dst instanceof DOMStoreReadWriteTransaction);
+
+    }
+
+    @Test
+    public void testNewWriteOnlyTransaction() throws Exception {
+        DOMStoreTransaction dst = new TransactionChainProxy(actorContext, schemaContext).newWriteOnlyTransaction();
+        Assert.assertTrue(dst instanceof DOMStoreWriteTransaction);
+
+    }
+
+    @Test(expected=UnsupportedOperationException.class)
+    public void testClose() throws Exception {
+        new TransactionChainProxy(actorContext, schemaContext).close();
+    }
+}
index 5876c50d51380a865afead594618627e7347bf3f..b916fddca7796e90dca402f1a8b4ac6a26fe2837 100644 (file)
@@ -12,8 +12,6 @@ package org.opendaylight.controller.sal.core.spi.data;
  * sequence and each transaction must see the effects of previous transactions
  * as if they happened. A chain makes no guarantees of atomicity, in fact
  * transactions are committed as soon as possible.
- *
- *
  */
 public interface DOMStoreTransactionChain extends DOMStoreTransactionFactory, AutoCloseable {
 
@@ -35,7 +33,7 @@ public interface DOMStoreTransactionChain extends DOMStoreTransactionFactory, Au
      *             if the chain has been closed.
      */
     @Override
-    public DOMStoreReadTransaction newReadOnlyTransaction();
+    DOMStoreReadTransaction newReadOnlyTransaction();
 
     /**
      * Create a new read write transaction which will continue the chain. The
@@ -55,10 +53,10 @@ public interface DOMStoreTransactionChain extends DOMStoreTransactionFactory, Au
      *             if the chain has been closed.
      */
     @Override
-    public DOMStoreReadWriteTransaction newReadWriteTransaction();
+    DOMStoreReadWriteTransaction newReadWriteTransaction();
 
     /**
-     * Create a new read write transaction which will continue the chain. The
+     * Create a new write-only transaction which will continue the chain. The
      * previous read-write transaction has to be either READY or CANCELLED.
      *
      *
@@ -68,8 +66,7 @@ public interface DOMStoreTransactionChain extends DOMStoreTransactionFactory, Au
      *             if the chain has been closed.
      */
     @Override
-    public DOMStoreWriteTransaction newWriteOnlyTransaction();
-
+    DOMStoreWriteTransaction newWriteOnlyTransaction();
 
     /**
      * Closes Transaction Chain.
@@ -80,6 +77,5 @@ public interface DOMStoreTransactionChain extends DOMStoreTransactionFactory, Au
      * @throws IllegalStateException If any of the outstanding created transactions was not canceled or ready.
      */
     @Override
-    public void close();
-
+    void close();
 }
index 129013378ea57c713304793248e1cdc2f2c0a6ce..7ad3b8201e182cff9b3820a9e029f697e4cdb950 100644 (file)
@@ -191,7 +191,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
     }
 
     @Override
-    public synchronized DOMStoreThreePhaseCommitCohort ready(final SnapshotBackedWriteTransaction writeTx) {
+    public DOMStoreThreePhaseCommitCohort ready(final SnapshotBackedWriteTransaction writeTx) {
         LOG.debug("Tx: {} is submitted. Modifications: {}", writeTx.getIdentifier(), writeTx.getMutatedView());
         return new ThreePhaseCommitImpl(writeTx);
     }
index 44ee61c116a9a4c5f8f336890827fcfceea68075..2caa76d49dff02a34ad98232ccdc7db139f07f2c 100644 (file)
@@ -33,7 +33,7 @@ final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction
                                           implements DOMStoreReadTransaction {
 
     private static final Logger LOG = LoggerFactory.getLogger(SnapshotBackedReadTransaction.class);
-    private DataTreeSnapshot stableSnapshot;
+    private volatile DataTreeSnapshot stableSnapshot;
 
     public SnapshotBackedReadTransaction(final Object identifier, final DataTreeSnapshot snapshot) {
         super(identifier);
@@ -52,19 +52,21 @@ final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction
         LOG.debug("Tx: {} Read: {}", getIdentifier(), path);
         checkNotNull(path, "Path must not be null.");
 
-        if(stableSnapshot == null) {
+        final DataTreeSnapshot snapshot = stableSnapshot;
+        if (snapshot == null) {
             return Futures.immediateFailedCheckedFuture(new ReadFailedException("Transaction is closed"));
         }
 
         try {
-            return Futures.immediateCheckedFuture(stableSnapshot.readNode(path));
+            return Futures.immediateCheckedFuture(snapshot.readNode(path));
         } catch (Exception e) {
             LOG.error("Tx: {} Failed Read of {}", getIdentifier(), path, e);
             return Futures.immediateFailedCheckedFuture(new ReadFailedException("Read failed",e));
         }
     }
 
-    @Override public CheckedFuture<Boolean, ReadFailedException> exists(YangInstanceIdentifier path) {
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(YangInstanceIdentifier path) {
         LOG.debug("Tx: {} Exists: {}", getIdentifier(), path);
         checkNotNull(path, "Path must not be null.");
 
index d6bfc0c3b69152fd560afd545f11ddfd0773862a..23b039c2542540fe39d7af70b8ea0b0129e11aa3 100644 (file)
@@ -115,6 +115,11 @@ public final class NetconfStateSchemas {
 
         final CompositeNode schemasNode =
                 (CompositeNode) NetconfMessageTransformUtil.findNode(schemasNodeResult.getResult(), DATA_STATE_SCHEMAS_IDENTIFIER);
+        if(schemasNode == null) {
+            logger.warn("{}: Unable to detect available schemas, get to {} was empty", id, STATE_SCHEMAS_IDENTIFIER);
+            return EMPTY;
+        }
+
         return create(id, schemasNode);
     }
 
index 23cbaca32f483f6af6ba8046e34d9233d326d6c5..3b078aa062fdf1fc3feaca7fa10147de8c3503cc 100644 (file)
@@ -9,10 +9,11 @@
 package org.opendaylight.controller.remote.rpc.registry.gossip;
 
 import akka.actor.ActorRef;
+import akka.actor.ActorRefProvider;
 import akka.actor.Address;
 import akka.actor.Props;
 import akka.actor.UntypedActor;
-import akka.cluster.Cluster;
+import akka.cluster.ClusterActorRefProvider;
 import akka.event.Logging;
 import akka.event.LoggingAdapter;
 import org.opendaylight.controller.utils.ConditionalProbe;
@@ -65,37 +66,25 @@ public class BucketStore extends UntypedActor {
     /**
      * Cluster address for this node
      */
-    private final Address selfAddress = Cluster.get(getContext().system()).selfAddress();
-
-    /**
-     * Our private gossiper
-     */
-    private ActorRef gossiper;
+    private Address selfAddress;
 
     private ConditionalProbe probe;
 
-    public BucketStore(){
-        gossiper = getContext().actorOf(Props.create(Gossiper.class), "gossiper");
-    }
+    @Override
+    public void preStart(){
+        ActorRefProvider provider = getContext().provider();
+        selfAddress = provider.getDefaultAddress();
 
-    /**
-     * This constructor is useful for testing.
-     * TODO: Pass Props instead of ActorRef
-     *
-     * @param gossiper
-     */
-    public BucketStore(ActorRef gossiper){
-        this.gossiper = gossiper;
+        if ( provider instanceof ClusterActorRefProvider)
+            getContext().actorOf(Props.create(Gossiper.class), "gossiper");
     }
 
     @Override
     public void onReceive(Object message) throws Exception {
 
-        log.debug("Received message: node[{}], message[{}]", selfAddress,
-            message);
+        log.debug("Received message: node[{}], message[{}]", selfAddress, message);
 
         if (probe != null) {
-
             probe.tell(message, getSelf());
         }
 
@@ -238,7 +227,7 @@ public class BucketStore extends UntypedActor {
             if (remoteVersion == null) remoteVersion = -1L;
 
             //update only if remote version is newer
-            if ( remoteVersion > localVersion ) {
+            if ( remoteVersion.longValue() > localVersion.longValue() ) {
                 remoteBuckets.put(entry.getKey(), receivedBucket);
                 versions.put(entry.getKey(), remoteVersion);
             }
@@ -278,5 +267,4 @@ public class BucketStore extends UntypedActor {
     Address getSelfAddress() {
         return selfAddress;
     }
-
 }
index 2320789d594aa56c8f7d4ff1ca4f99525b84ca95..a8bc25c40ba14b2ecf8c45926f7871f189dbdafa 100644 (file)
@@ -8,11 +8,13 @@
 package org.opendaylight.controller.remote.rpc.registry.gossip;
 
 import akka.actor.ActorRef;
+import akka.actor.ActorRefProvider;
 import akka.actor.ActorSelection;
 import akka.actor.Address;
 import akka.actor.Cancellable;
 import akka.actor.UntypedActor;
 import akka.cluster.Cluster;
+import akka.cluster.ClusterActorRefProvider;
 import akka.cluster.ClusterEvent;
 import akka.cluster.Member;
 import akka.dispatch.Mapper;
@@ -60,12 +62,12 @@ public class Gossiper extends UntypedActor {
 
     final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
 
-    Cluster cluster = Cluster.get(getContext().system());
+    private Cluster cluster;
 
     /**
      * ActorSystem's address for the current cluster node.
      */
-    private Address selfAddress = cluster.selfAddress();
+    private Address selfAddress;
 
     /**
      * All known cluster members
@@ -89,11 +91,16 @@ public class Gossiper extends UntypedActor {
 
     @Override
     public void preStart(){
-
-        cluster.subscribe(getSelf(),
-                          ClusterEvent.initialStateAsEvents(),
-                          ClusterEvent.MemberEvent.class,
-                          ClusterEvent.UnreachableMember.class);
+        ActorRefProvider provider = getContext().provider();
+        selfAddress = provider.getDefaultAddress();
+
+        if ( provider instanceof ClusterActorRefProvider ) {
+            cluster = Cluster.get(getContext().system());
+            cluster.subscribe(getSelf(),
+                    ClusterEvent.initialStateAsEvents(),
+                    ClusterEvent.MemberEvent.class,
+                    ClusterEvent.UnreachableMember.class);
+        }
 
         if (autoStartGossipTicks) {
             gossipTask = getContext().system().scheduler().schedule(
index fd6664af9e618872eb6f8a656cc7beddb68aa0bc..78fcbd3a1478c9cabe6201893597bf5f1a45008b 100644 (file)
@@ -7,34 +7,29 @@
  */
 package org.opendaylight.controller.remote.rpc.registry.gossip;
 
-import akka.actor.ActorRef;
 import akka.actor.ActorSystem;
+import akka.actor.Address;
 import akka.actor.Props;
 import akka.testkit.TestActorRef;
-import akka.testkit.TestProbe;
 import com.typesafe.config.ConfigFactory;
-import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.remote.rpc.TerminationMonitor;
 
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
+import java.util.HashMap;
+import java.util.Map;
 
 public class BucketStoreTest {
 
     private static ActorSystem system;
     private static BucketStore store;
 
-    private BucketStore mockStore;
-
     @BeforeClass
     public static void setup() {
 
-        system = ActorSystem.create("opendaylight-rpc", ConfigFactory.load().getConfig("odl-cluster"));
+        system = ActorSystem.create("opendaylight-rpc", ConfigFactory.load().getConfig("unit-test"));
         system.actorOf(Props.create(TerminationMonitor.class), "termination-monitor");
 
         store = createStore();
@@ -45,25 +40,108 @@ public class BucketStoreTest {
         system.shutdown();
     }
 
-    @Before
-    public void createMocks(){
-        mockStore = spy(store);
-    }
-
-    @After
-    public void resetMocks(){
-        reset(mockStore);
-    }
-
+    /**
+     * Given a new local bucket
+     * Should replace
+     */
     @Test
-    public void testReceiveUpdateBucket_WhenInputBucketShouldUpdateVersion(){
+    public void testReceiveUpdateBucket(){
         Bucket bucket = new BucketImpl();
         Long expectedVersion = bucket.getVersion();
 
-        mockStore.receiveUpdateBucket(bucket);
+        store.receiveUpdateBucket(bucket);
+
+        Assert.assertEquals(bucket, store.getLocalBucket());
+        Assert.assertEquals(expectedVersion, store.getLocalBucket().getVersion());
+    }
+
+    /**
+     * Given remote buckets
+     * Should merge with local copy of remote buckets
+     */
+    @Test
+    public void testReceiveUpdateRemoteBuckets(){
+
+        Address localAddress = system.provider().getDefaultAddress();
+        Bucket localBucket = new BucketImpl();
+
+        Address a1 = new Address("tcp", "system1");
+        Address a2 = new Address("tcp", "system2");
+        Address a3 = new Address("tcp", "system3");
+
+        Bucket b1 = new BucketImpl();
+        Bucket b2 = new BucketImpl();
+        Bucket b3 = new BucketImpl();
+
+        Map<Address, Bucket> remoteBuckets = new HashMap<>(3);
+        remoteBuckets.put(a1, b1);
+        remoteBuckets.put(a2, b2);
+        remoteBuckets.put(a3, b3);
+        remoteBuckets.put(localAddress, localBucket);
+
+        //Given remote buckets
+        store.receiveUpdateRemoteBuckets(remoteBuckets);
+
+        //Should NOT contain local bucket
+        //Should contain ONLY 3 entries i.e a1, a2, a3
+        Map<Address, Bucket> remoteBucketsInStore = store.getRemoteBuckets();
+        Assert.assertFalse("remote buckets contains local bucket", remoteBucketsInStore.containsKey(localAddress));
+        Assert.assertTrue(remoteBucketsInStore.size() == 3);
+
+        //Add a new remote bucket
+        Address a4 = new Address("tcp", "system4");
+        Bucket b4 = new BucketImpl();
+        remoteBuckets.clear();
+        remoteBuckets.put(a4, b4);
+        store.receiveUpdateRemoteBuckets(remoteBuckets);
+
+        //Should contain a4
+        //Should contain 4 entries now i.e a1, a2, a3, a4
+        remoteBucketsInStore = store.getRemoteBuckets();
+        Assert.assertTrue("Does not contain a4", remoteBucketsInStore.containsKey(a4));
+        Assert.assertTrue(remoteBucketsInStore.size() == 4);
+
+        //Update a bucket
+        Bucket b3_new = new BucketImpl();
+        remoteBuckets.clear();
+        remoteBuckets.put(a3, b3_new);
+        remoteBuckets.put(a1, null);
+        remoteBuckets.put(a2, null);
+        store.receiveUpdateRemoteBuckets(remoteBuckets);
+
+        //Should only update a3
+        remoteBucketsInStore = store.getRemoteBuckets();
+        Bucket b3_inStore = remoteBucketsInStore.get(a3);
+        Assert.assertEquals(b3_new.getVersion(), b3_inStore.getVersion());
+
+        //Should NOT update a1 and a2
+        Bucket b1_inStore = remoteBucketsInStore.get(a1);
+        Bucket b2_inStore = remoteBucketsInStore.get(a2);
+        Assert.assertEquals(b1.getVersion(), b1_inStore.getVersion());
+        Assert.assertEquals(b2.getVersion(), b2_inStore.getVersion());
+        Assert.assertTrue(remoteBucketsInStore.size() == 4);
+
+        //Should update versions map
+        //versions map contains versions for all remote buckets (4) + local bucket
+        //so it should have total 5.
+        Map<Address, Long> versionsInStore = store.getVersions();
+        Assert.assertTrue(String.format("Expected:%s, Actual:%s", 5, versionsInStore.size()),
+                          versionsInStore.size() == 5);
+        Assert.assertEquals(b1.getVersion(), versionsInStore.get(a1));
+        Assert.assertEquals(b2.getVersion(), versionsInStore.get(a2));
+        Assert.assertEquals(b3_new.getVersion(), versionsInStore.get(a3));
+        Assert.assertEquals(b4.getVersion(), versionsInStore.get(a4));
+
+        //Send older version of bucket
+        remoteBuckets.clear();
+        remoteBuckets.put(a3, b3);
+        store.receiveUpdateRemoteBuckets(remoteBuckets);
+
+        //Should NOT update a3
+        remoteBucketsInStore = store.getRemoteBuckets();
+        b3_inStore = remoteBucketsInStore.get(a3);
+        Assert.assertTrue(b3_inStore.getVersion().longValue() == b3_new.getVersion().longValue());
 
-        Assert.assertEquals(bucket, mockStore.getLocalBucket());
-        Assert.assertEquals(expectedVersion, mockStore.getLocalBucket().getVersion());
     }
 
     /**
@@ -72,11 +150,8 @@ public class BucketStoreTest {
      * @return instance of BucketStore class
      */
     private static BucketStore createStore(){
-        TestProbe mockActor = new TestProbe(system);
-        ActorRef mockGossiper = mockActor.ref();
-        final Props props = Props.create(BucketStore.class, mockGossiper);
+        final Props props = Props.create(BucketStore.class);
         final TestActorRef<BucketStore> testRef = TestActorRef.create(system, props, "testStore");
-
         return testRef.underlyingActor();
     }
 }
\ No newline at end of file
index bb60ed6eec05c4151dce935d2fc198d82c98577f..e61b54f067e7bcba09a0ef7d476f7cd3b04c938d 100644 (file)
@@ -45,7 +45,7 @@ public class GossiperTest {
 
     @BeforeClass
     public static void setup() throws InterruptedException {
-        system = ActorSystem.create("opendaylight-rpc", ConfigFactory.load().getConfig("odl-cluster"));
+        system = ActorSystem.create("opendaylight-rpc", ConfigFactory.load().getConfig("unit-test"));
         system.actorOf(Props.create(TerminationMonitor.class), "termination-monitor");
 
         gossiper = createGossiper();
index b578d6f04f087c8d4a3451c26149495538aaf800..8100ed35abd580a13367922ff255e42c61369f93 100644 (file)
@@ -32,10 +32,7 @@ odl-cluster{
 unit-test{
   akka {
     loglevel = "INFO"
-    loggers = ["akka.event.slf4j.Slf4jLogger"]
-    actor {
-      provider = "akka.cluster.ClusterActorRefProvider"
-    }
+    #loggers = ["akka.event.slf4j.Slf4jLogger"]
   }
 }
 
index cd9738c894554a8e609eac1acb4b9fbd9534eac9..2b67edfd9d318d29cbd3508c17a1e8bafd9f4a70 100644 (file)
@@ -35,9 +35,6 @@ final class FlowComparator {
         if (statsFlow == null || storedFlow == null) {
             return false;
         }
-        if (statsFlow.getClass() != storedFlow.getClass()) {
-            return false;
-        }
         if (statsFlow.getContainerName()== null) {
             if (storedFlow.getContainerName()!= null) {
                 return false;
@@ -99,9 +96,6 @@ final class FlowComparator {
         }
         if (storedFlow == null && statsFlow != null) return false;
         if (statsFlow == null && storedFlow != null) return false;
-        if (storedFlow.getClass() != statsFlow.getClass()) {
-            return false;
-        }
         if (storedFlow.getEthernetMatch() == null) {
             if (statsFlow.getEthernetMatch() != null) {
                 return false;
index 451cad48169ea81869ef11047895010715f0e30f..10aec4ca2e85038cdc7ff21dd0ebd4dc4b6cddf6 100644 (file)
@@ -15,11 +15,9 @@ import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMap
 import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNode;
 import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNodeId;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import java.util.List;
+
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
@@ -50,6 +48,12 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
 class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, OpendaylightInventoryListener {
 
     private final Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyExporter.class);
@@ -193,8 +197,9 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
                     @Override
                     public void onSuccess(Optional<Topology> topologyOptional) {
                         if (topologyOptional.isPresent()) {
-                            Topology topologyData = topologyOptional.get();
-                            for (Link link : topologyData.getLink()) {
+                            List<Link> linkList = topologyOptional.get().getLink() != null
+                                    ? topologyOptional.get().getLink() : Collections.<Link> emptyList();
+                            for (Link link : linkList) {
                                 if (id.equals(link.getSource().getSourceNode()) || id.equals(link.getDestination().getDestNode())) {
                                     transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(link));
                                 }
@@ -220,8 +225,9 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
                     @Override
                     public void onSuccess(Optional<Topology> topologyOptional) {
                         if (topologyOptional.isPresent()) {
-                            Topology topologyData = topologyOptional.get();
-                            for (Link link : topologyData.getLink()) {
+                            List<Link> linkList = topologyOptional.get().getLink() != null
+                                    ? topologyOptional.get().getLink() : Collections.<Link> emptyList();
+                            for (Link link : linkList) {
                                 if (id.equals(link.getSource().getSourceTp()) || id.equals(link.getDestination().getDestTp())) {
                                     transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(link));
                                 }
index 0a48e6c67dc8cc290c2b81a1b0eb67c05ac7c618..8e9f9978c4dd837334b07db2d1f6c96764e0ede9 100644 (file)
@@ -173,8 +173,12 @@ public class ConfigPersisterActivator implements BundleActivator {
                         if(configs != null && !configs.isEmpty()) {
                             configPusher.pushConfigs(configs);
                         }
-                        registration = context.registerService(ConfigPusher.class.getName(), configPusher, null);
-                        configPusher.process(autoCloseables, platformMBeanServer, persisterAggregator);
+                        if(context != null) {
+                            registration = context.registerService(ConfigPusher.class.getName(), configPusher, null);
+                            configPusher.process(autoCloseables, platformMBeanServer, persisterAggregator);
+                        } else {
+                            logger.warn("Unable to process configs as BundleContext is null");
+                        }
                     } catch (InterruptedException e) {
                         logger.info("ConfigPusher thread stopped",e);
                     }
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 fa78fa4bd3983c7eee4cb166e54bc5692f0bad54..3b3f71b0ed0f3aad635d88d6b0bb93a3e4229aa3 100644 (file)
@@ -7,8 +7,7 @@
  */
 package org.opendaylight.controller.netconf.monitoring;
 
-import com.google.common.collect.Maps;
-
+import java.util.Collections;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
@@ -18,36 +17,26 @@ import org.opendaylight.controller.netconf.monitoring.xml.JaxBSerializer;
 import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
 import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import java.util.Map;
-
 public class Get extends AbstractNetconfOperation {
 
     private static final Logger logger = LoggerFactory.getLogger(Get.class);
     private final NetconfMonitoringService netconfMonitor;
 
-    public Get(NetconfMonitoringService netconfMonitor) {
+    public Get(final NetconfMonitoringService netconfMonitor) {
         super(MonitoringConstants.MODULE_NAME);
         this.netconfMonitor = netconfMonitor;
     }
 
-    private Element getPlaceholder(Document innerResult) throws NetconfDocumentedException {
-        try {
-            XmlElement rootElement = null;
-            rootElement = XmlElement.fromDomElementWithExpected(innerResult.getDocumentElement(),
-                    XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.RFC4741_TARGET_NAMESPACE);
-            return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
-        } catch (RuntimeException e) {
-            throw new IllegalArgumentException(String.format(
-                    "Input xml in wrong format, Expecting root element %s with child element %s, but was %s",
-                    XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.DATA_KEY,
-                    XmlUtil.toString(innerResult.getDocumentElement())), e);
-        }
+    private Element getPlaceholder(final Document innerResult)
+            throws NetconfDocumentedException {
+        final XmlElement rootElement = XmlElement.fromDomElementWithExpected(
+                innerResult.getDocumentElement(), XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.RFC4741_TARGET_NAMESPACE);
+        return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
     }
 
     @Override
@@ -61,7 +50,7 @@ public class Get extends AbstractNetconfOperation {
     }
 
     @Override
-    public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation)
+    public Document handle(final Document requestMessage, final NetconfOperationChainedExecution subsequentOperation)
             throws NetconfDocumentedException {
         if (subsequentOperation.isExecutionTermination()){
             throw new NetconfDocumentedException(String.format("Subsequent netconf operation expected by %s", this),
@@ -71,29 +60,29 @@ public class Get extends AbstractNetconfOperation {
         }
 
         try {
-            Document innerResult = subsequentOperation.execute(requestMessage);
+            final Document innerResult = subsequentOperation.execute(requestMessage);
 
-            NetconfState netconfMonitoring = new NetconfState(netconfMonitor);
+            final NetconfState netconfMonitoring = new NetconfState(netconfMonitor);
             Element monitoringXmlElement = new JaxBSerializer().toXml(netconfMonitoring);
 
             monitoringXmlElement = (Element) innerResult.importNode(monitoringXmlElement, true);
-            Element monitoringXmlElementPlaceholder = getPlaceholder(innerResult);
+            final Element monitoringXmlElementPlaceholder = getPlaceholder(innerResult);
             monitoringXmlElementPlaceholder.appendChild(monitoringXmlElement);
 
             return innerResult;
-        } catch (RuntimeException e) {
-            String errorMessage = "Get operation for netconf-state subtree failed";
+        } catch (final RuntimeException e) {
+            final String errorMessage = "Get operation for netconf-state subtree failed";
             logger.warn(errorMessage, e);
-            Map<String, String> info = Maps.newHashMap();
-            info.put(NetconfDocumentedException.ErrorSeverity.error.toString(), e.getMessage());
+
             throw new NetconfDocumentedException(errorMessage, NetconfDocumentedException.ErrorType.application,
                     NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error, info);
+                    NetconfDocumentedException.ErrorSeverity.error,
+                    Collections.singletonMap(NetconfDocumentedException.ErrorSeverity.error.toString(), e.getMessage()));
         }
     }
 
     @Override
-    protected Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation)
+    protected Element handle(final Document document, final XmlElement message, final NetconfOperationChainedExecution subsequentOperation)
             throws NetconfDocumentedException {
         throw new UnsupportedOperationException("Never gets called");
     }
index 14c47352a8409d633dca64a01db06759ad79f8f6..9d332c644029ff3c26a2725703e4b348ff046cf0 100644 (file)
@@ -24,7 +24,6 @@ public class NetconfMonitoringActivator implements BundleActivator {
     public void start(final BundleContext context)  {
         monitor = new NetconfMonitoringServiceTracker(context);
         monitor.open();
-
     }
 
     @Override
index 920236b9b67ab0a277a5e166459463bc3ebac562..f99ae54e6dafac6e9ea01f36e85ab46261d9ce67 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.netconf.monitoring.osgi;
 
 import com.google.common.base.Preconditions;
+import java.util.Hashtable;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
 import org.osgi.framework.BundleContext;
@@ -17,43 +18,39 @@ import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Dictionary;
-import java.util.Hashtable;
-
 public class NetconfMonitoringServiceTracker extends ServiceTracker<NetconfMonitoringService, NetconfMonitoringService> {
 
     private static final Logger logger = LoggerFactory.getLogger(NetconfMonitoringServiceTracker.class);
 
     private ServiceRegistration<NetconfOperationServiceFactory> reg;
 
-    NetconfMonitoringServiceTracker(BundleContext context) {
+    NetconfMonitoringServiceTracker(final BundleContext context) {
         super(context, NetconfMonitoringService.class, null);
     }
 
     @Override
-    public NetconfMonitoringService addingService(ServiceReference<NetconfMonitoringService> reference) {
+    public NetconfMonitoringService addingService(final ServiceReference<NetconfMonitoringService> reference) {
         Preconditions.checkState(reg == null, "Monitoring service was already added");
 
-        NetconfMonitoringService netconfMonitoringService = super.addingService(reference);
+        final NetconfMonitoringService netconfMonitoringService = super.addingService(reference);
 
         final NetconfMonitoringOperationService operationService = new NetconfMonitoringOperationService(
                 netconfMonitoringService);
-        NetconfOperationServiceFactory factory = new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
+        final NetconfOperationServiceFactory factory = new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
                 operationService);
 
-        Dictionary<String, ?> props = new Hashtable<>();
-        reg = context.registerService(NetconfOperationServiceFactory.class, factory, props);
+        reg = context.registerService(NetconfOperationServiceFactory.class, factory, new Hashtable<String, Object>());
 
         return netconfMonitoringService;
     }
 
     @Override
-    public void removedService(ServiceReference<NetconfMonitoringService> reference,
-            NetconfMonitoringService netconfMonitoringService) {
+    public void removedService(final ServiceReference<NetconfMonitoringService> reference,
+            final NetconfMonitoringService netconfMonitoringService) {
         if(reg!=null) {
             try {
                 reg.unregister();
-            } catch (Exception e) {
+            } catch (final Exception e) {
                 logger.warn("Ignoring exception while unregistering {}", reg, e);
             }
         }
index 4b07ab090aabfd3727524d255319352747839f4a..962ad17b66c280c5e7fb68cfc279ff30d79c2285 100644 (file)
@@ -18,17 +18,17 @@ import javax.xml.transform.dom.DOMResult;
 
 public class JaxBSerializer {
 
-    public Element toXml(NetconfState monitoringModel) {
-        DOMResult res = null;
+    public Element toXml(final NetconfState monitoringModel) {
+        final DOMResult res;
         try {
-            JAXBContext jaxbContext = JAXBContext.newInstance(NetconfState.class);
-            Marshaller marshaller = jaxbContext.createMarshaller();
+            final JAXBContext jaxbContext = JAXBContext.newInstance(NetconfState.class);
+            final Marshaller marshaller = jaxbContext.createMarshaller();
 
             marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 
             res = new DOMResult();
             marshaller.marshal(monitoringModel, res);
-        } catch (JAXBException e) {
+        } catch (final JAXBException e) {
            throw new RuntimeException("Unable to serialize netconf state " + monitoringModel, e);
         }
         return ((Document)res.getNode()).getDocumentElement();
index 98bda5833e00a83487d9d356a44f0b55db0e82d9..8f5a1c029d8611b9f75c7b4570fc63002d9f1e18 100644 (file)
@@ -28,15 +28,12 @@ public final class NetconfState {
     private Schemas schemas;
     private Sessions sessions;
 
-    public NetconfState(NetconfMonitoringService monitoringService) {
+    public NetconfState(final NetconfMonitoringService monitoringService) {
         this.sessions = monitoringService.getSessions();
         this.schemas = monitoringService.getSchemas();
     }
 
-    public NetconfState() {
-    }
-
-
+    public NetconfState() {}
 
     @XmlElementWrapper(name="schemas")
     @XmlElement(name="schema")
@@ -44,7 +41,7 @@ public final class NetconfState {
         return Collections2.transform(schemas.getSchema(), new Function<Schema, MonitoringSchema>() {
             @Nullable
             @Override
-            public MonitoringSchema apply(@Nullable Schema input) {
+            public MonitoringSchema apply(@Nullable final Schema input) {
                 return new MonitoringSchema(input);
             }
         });
@@ -56,7 +53,7 @@ public final class NetconfState {
         return Collections2.transform(sessions.getSession(), new Function<Session, MonitoringSession>() {
             @Nullable
             @Override
-            public MonitoringSession apply(@Nullable Session input) {
+            public MonitoringSession apply(@Nullable final Session input) {
                 return new MonitoringSession(input);
             }
         });
diff --git a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetTest.java b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetTest.java
new file mode 100644 (file)
index 0000000..5fceac0
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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.monitoring;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.fail;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+
+import java.util.Collections;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
+import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SessionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
+import org.w3c.dom.Document;
+
+public class GetTest {
+
+    @Mock
+    private NetconfMonitoringService monitor;
+    @Mock
+    private Document request;
+    @Mock
+    private NetconfOperationChainedExecution subsequentOperation;
+    private Document incorrectSubsequentResult;
+    private Document correctSubsequentResult;
+
+    private Get get;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        incorrectSubsequentResult = XmlUtil.readXmlToDocument("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>");
+        correctSubsequentResult = XmlUtil.readXmlToDocument("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><data></data></rpc-reply>");
+
+        doReturn(new SessionsBuilder().setSession(Collections.<Session>emptyList()).build()).when(monitor).getSessions();
+        doReturn(new SchemasBuilder().setSchema(Collections.<Schema>emptyList()).build()).when(monitor).getSchemas();
+        doReturn(false).when(subsequentOperation).isExecutionTermination();
+
+        get = new Get(monitor);
+    }
+
+    @Test
+    public void testHandleNoSubsequent() throws Exception {
+        try {
+            get.handle(null, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
+        } catch (final NetconfDocumentedException e) {
+            assertNetconfDocumentedEx(e, NetconfDocumentedException.ErrorSeverity.error, NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorType.application);
+            return;
+        }
+
+        fail("Get should fail without subsequent operation");
+    }
+
+    @Test
+    public void testHandleWrongPlaceholder() throws Exception {
+        doReturn(incorrectSubsequentResult).when(subsequentOperation).execute(request);
+        try {
+            get.handle(request, subsequentOperation);
+        } catch (final NetconfDocumentedException e) {
+            assertNetconfDocumentedEx(e, NetconfDocumentedException.ErrorSeverity.error, NetconfDocumentedException.ErrorTag.invalid_value, NetconfDocumentedException.ErrorType.application);
+            return;
+        }
+
+        fail("Get should fail with wrong xml");
+    }
+
+    @Test
+    public void testHandleRuntimeEx() throws Exception {
+        doThrow(RuntimeException.class).when(subsequentOperation).execute(request);
+        try {
+            get.handle(request, subsequentOperation);
+        } catch (final NetconfDocumentedException e) {
+            assertNetconfDocumentedEx(e, NetconfDocumentedException.ErrorSeverity.error, NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorType.application);
+            assertEquals(1, e.getErrorInfo().size());
+            return;
+        }
+
+        fail("Get should fail with wrong xml");
+    }
+
+    @Test
+    public void testSuccessHandle() throws Exception {
+        doReturn(correctSubsequentResult).when(subsequentOperation).execute(request);
+        assertTrue(get.getHandlingPriority().getPriority().get() > HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.getPriority().get());
+        final Document result = get.handle(request, subsequentOperation);
+        assertThat(XmlUtil.toString(result), CoreMatchers.containsString("sessions"));
+        assertThat(XmlUtil.toString(result), CoreMatchers.containsString("schemas"));
+
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testHandle() throws Exception {
+        get.handle(null, null, null);
+
+    }
+
+    private void assertNetconfDocumentedEx(final NetconfDocumentedException e, final NetconfDocumentedException.ErrorSeverity severity, final NetconfDocumentedException.ErrorTag errorTag, final NetconfDocumentedException.ErrorType type) {
+        assertEquals(severity, e.getErrorSeverity());
+        assertEquals(errorTag, e.getErrorTag());
+        assertEquals(type, e.getErrorType());
+    }
+}
index 02129574da40ec274a22b077614c38653a14770d..d0d587fb84263c02ef99cb0727de1d4c81b28223 100644 (file)
@@ -7,37 +7,40 @@
 */
 package org.opendaylight.controller.netconf.monitoring.xml;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
 import com.google.common.collect.Lists;
+import org.hamcrest.CoreMatchers;
 import org.junit.Test;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.NetconfTcp;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfSsh;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Transport;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Sessions;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SessionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.DateAndTime;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.ZeroBasedCounter32;
-import org.w3c.dom.Element;
-
-import java.util.Date;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 public class JaxBSerializerTest {
 
     @Test
     public void testName() throws Exception {
 
-        NetconfMonitoringService service = new NetconfMonitoringService() {
+        final NetconfMonitoringService service = new NetconfMonitoringService() {
 
             @Override
             public Sessions getSessions() {
@@ -46,19 +49,54 @@ public class JaxBSerializerTest {
 
             @Override
             public Schemas getSchemas() {
-                return new SchemasBuilder().setSchema(Lists.<Schema>newArrayList()).build();
+                return new SchemasBuilder().setSchema(Lists.newArrayList(getMockSchema("id", "v1", Yang.class), getMockSchema("id2", "", Yang.class))).build();
             }
         };
-        NetconfState model = new NetconfState(service);
-        Element xml = new JaxBSerializer().toXml(model);
+        final NetconfState model = new NetconfState(service);
+        final String xml = XmlUtil.toString(new JaxBSerializer().toXml(model));
+
+        assertThat(xml, CoreMatchers.containsString(
+                "<schema>\n" +
+                "<format>yang</format>\n" +
+                "<identifier>id</identifier>\n" +
+                "<location>NETCONF</location>\n" +
+                "<namespace>localhost</namespace>\n" +
+                "<version>v1</version>\n" +
+                "</schema>\n"));
+
+        assertThat(xml, CoreMatchers.containsString(
+                "<session>\n" +
+                "<session-id>1</session-id>\n" +
+                "<in-bad-rpcs>0</in-bad-rpcs>\n" +
+                "<in-rpcs>0</in-rpcs>\n" +
+                "<login-time>loginTime</login-time>\n" +
+                "<out-notifications>0</out-notifications>\n" +
+                "<out-rpc-errors>0</out-rpc-errors>\n" +
+                "<ncme:session-identifier>client</ncme:session-identifier>\n" +
+                "<source-host>address/port</source-host>\n" +
+                "<transport>ncme:netconf-tcp</transport>\n" +
+                "<username>username</username>\n" +
+                "</session>"));
+    }
+
+    private Schema getMockSchema(final String id, final String version, final Class<Yang> format) {
+        final Schema mock = mock(Schema.class);
+
+        doReturn(format).when(mock).getFormat();
+        doReturn(id).when(mock).getIdentifier();
+        doReturn(new Uri("localhost")).when(mock).getNamespace();
+        doReturn(version).when(mock).getVersion();
+        doReturn(Lists.newArrayList(new Schema.Location(Schema.Location.Enumeration.NETCONF))).when(mock).getLocation();
+        doReturn(new SchemaKey(format, id, version)).when(mock).getKey();
+        return mock;
     }
 
-    private Session getMockSession(Class<? extends Transport> transportType) {
-        Session mocked = mock(Session.class);
-        Session1 mockedSession1 = mock(Session1.class);
+    private Session getMockSession(final Class<? extends Transport> transportType) {
+        final Session mocked = mock(Session.class);
+        final Session1 mockedSession1 = mock(Session1.class);
         doReturn("client").when(mockedSession1).getSessionIdentifier();
         doReturn(1L).when(mocked).getSessionId();
-        doReturn(new DateAndTime(new Date().toString())).when(mocked).getLoginTime();
+        doReturn(new DateAndTime("loginTime")).when(mocked).getLoginTime();
         doReturn(new Host(new DomainName("address/port"))).when(mocked).getSourceHost();
         doReturn(new ZeroBasedCounter32(0L)).when(mocked).getInBadRpcs();
         doReturn(new ZeroBasedCounter32(0L)).when(mocked).getInRpcs();
index 13041598d1a149932aa37e6efa8cb6e414decd87..cb8461a29965816320f1de6087e7a13629c4be9e 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>
@@ -60,7 +64,6 @@
       <groupId>org.openexi</groupId>
       <artifactId>nagasena-rta</artifactId>
     </dependency>
-
     <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
       <groupId>xmlunit</groupId>
       <artifactId>xmlunit</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>mockito-configuration</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
@@ -82,7 +89,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 d765ca8b2573702368ca9aca3e65212a8eed1e0a..f39e2c425d039cca549fd574607c52af02eced9e 100644 (file)
@@ -53,8 +53,7 @@ public final class NetconfHelloMessageToXMLEncoder extends NetconfMessageToXMLEn
         Optional<NetconfHelloMessageAdditionalHeader> headerOptional = ((NetconfHelloMessage) msg)
                 .getAdditionalHeader();
 
-        // If additional header present, serialize it along with netconf hello
-        // message
+        // If additional header present, serialize it along with netconf hello message
         if (headerOptional.isPresent()) {
             out.writeBytes(headerOptional.get().toFormattedString().getBytes(Charsets.UTF_8));
         }
index 69c0d53fc12144ad7e780126e5f8d3fe6372a571..bfc8d77e17bc7e4ae799d9b0859bdf3085f5e6af 100644 (file)
@@ -7,26 +7,21 @@
  */
 package org.opendaylight.controller.netconf.nettyutil.handler;
 
-import java.util.List;
-
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufInputStream;
 import io.netty.buffer.ByteBufUtil;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.ByteToMessageDecoder;
+import java.util.List;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder {
     private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class);
 
     @Override
-    @VisibleForTesting
     public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
 
         if (in.readableBytes() != 0) {
index b22b792d52980227d2aa85da39436535a19097b2..0548b1d371a415569dffc1826c02fae4700df45d 100644 (file)
@@ -8,13 +8,15 @@
 
 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..ab94e59a93dcf4e70494f7bf65ba66a28b5915c0 100644 (file)
@@ -8,13 +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;
 
 /**
  * Class Providing username/password authentication option to
- * {@link org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshHandler}
+ * {@link org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler}
  */
 public class LoginPassword extends AuthenticationHandler {
     private final String username;
@@ -26,11 +26,13 @@ public class LoginPassword extends AuthenticationHandler {
     }
 
     @Override
-    public void authenticate(Connection connection) throws IOException {
-        boolean isAuthenticated = connection.authenticateWithPassword(username, password);
+    public String getUsername() {
+        return username;
+    }
 
-        if (!isAuthenticated) {
-            throw new IOException("Authentication failed.");
-        }
+    @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();
-        }
-    }
-}
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/ChannelInputStream.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/ChannelInputStream.java
deleted file mode 100644 (file)
index ba65b9e..0000000
+++ /dev/null
@@ -1,123 +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.virtualsocket;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandler;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Class provides {@link InputStream} functionality to users of virtual socket.
- */
-public class ChannelInputStream extends InputStream implements ChannelInboundHandler {
-    private final Object lock = new Object();
-    private final ByteBuf bb = Unpooled.buffer();
-
-    @Override
-    public int read(byte b[], int off, int len) throws IOException {
-        if (b == null) {
-            throw new NullPointerException();
-        } else if (off < 0 || len < 0 || len > b.length - off) {
-            throw new IndexOutOfBoundsException();
-        } else if (len == 0) {
-            return 0;
-        }
-
-        int bytesRead = 1;
-        synchronized (lock) {
-            int c = read();
-
-            b[off] = (byte)c;
-
-            if(this.bb.readableBytes() == 0) {
-                return bytesRead;
-            }
-
-            int ltr = len-1;
-            ltr = (ltr <= bb.readableBytes()) ? ltr : bb.readableBytes();
-
-            bb.readBytes(b, 1, ltr);
-            bytesRead += ltr;
-        }
-        return bytesRead;
-    }
-
-    @Override
-    public int read() throws IOException {
-        synchronized (lock) {
-            while (this.bb.readableBytes() == 0) {
-                try {
-                    lock.wait();
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                    throw new IllegalStateException(e);
-                }
-            }
-            return this.bb.readByte() & 0xFF;
-        }
-    }
-
-    @Override
-    public int available() throws IOException {
-        synchronized (lock) {
-            return this.bb.readableBytes();
-        }
-    }
-
-    public void channelRegistered(ChannelHandlerContext ctx) {
-        ctx.fireChannelRegistered();
-    }
-
-    public void channelUnregistered(ChannelHandlerContext ctx) {
-        ctx.fireChannelUnregistered();
-    }
-
-    public void channelActive(ChannelHandlerContext ctx) {
-        ctx.fireChannelActive();
-    }
-
-    public void channelInactive(ChannelHandlerContext ctx) {
-        ctx.fireChannelInactive();
-    }
-
-    public void channelRead(ChannelHandlerContext ctx, Object o) {
-        synchronized(lock) {
-            this.bb.discardReadBytes();
-            this.bb.writeBytes((ByteBuf) o);
-            ((ByteBuf) o).release();
-            lock.notifyAll();
-        }
-    }
-
-    public void channelReadComplete(ChannelHandlerContext ctx) {
-        ctx.fireChannelReadComplete();
-    }
-
-    public void userEventTriggered(ChannelHandlerContext ctx, Object o) {
-        ctx.fireUserEventTriggered(o);
-    }
-
-    public void channelWritabilityChanged(ChannelHandlerContext ctx) {
-        ctx.fireChannelWritabilityChanged();
-    }
-
-    public void handlerAdded(ChannelHandlerContext ctx) {
-    }
-
-    public void handlerRemoved(ChannelHandlerContext ctx) {
-    }
-
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {
-        ctx.fireExceptionCaught(throwable);
-    }
-}
-
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/ChannelOutputStream.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/ChannelOutputStream.java
deleted file mode 100644 (file)
index 2dc5235..0000000
+++ /dev/null
@@ -1,89 +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.virtualsocket;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelOutboundHandler;
-import io.netty.channel.ChannelPromise;
-
-import java.io.OutputStream;
-import java.net.SocketAddress;
-
-/**
- * Class provides {@link OutputStream) functionality to users of virtual socket.
- */
-public class ChannelOutputStream extends OutputStream implements ChannelOutboundHandler {
-    private final Object lock = new Object();
-    private ByteBuf buff = Unpooled.buffer();
-    private ChannelHandlerContext ctx;
-
-    @Override
-    public void flush() {
-        synchronized(lock) {
-            ctx.writeAndFlush(buff).awaitUninterruptibly();
-            buff = Unpooled.buffer();
-        }
-    }
-
-    @Override
-    public void write(int b) {
-        synchronized(lock) {
-            buff.writeByte(b);
-        }
-    }
-
-    public void bind(ChannelHandlerContext ctx, SocketAddress localAddress,
-                     ChannelPromise promise) {
-        ctx.bind(localAddress, promise);
-    }
-
-    public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,
-                        SocketAddress localAddress, ChannelPromise promise) {
-        this.ctx = ctx;
-        ctx.connect(remoteAddress, localAddress, promise);
-    }
-
-    public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) {
-        ctx.disconnect(promise);
-    }
-
-    public void close(ChannelHandlerContext ctx, ChannelPromise promise) {
-        ctx.close(promise);
-    }
-
-    public void deregister(ChannelHandlerContext ctx, ChannelPromise channelPromise) {
-        ctx.deregister(channelPromise);
-    }
-
-    public void read(ChannelHandlerContext ctx) {
-        ctx.read();
-    }
-
-    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
-        // pass
-    }
-
-    public void flush(ChannelHandlerContext ctx) {
-        // pass
-    }
-
-    public void handlerAdded(ChannelHandlerContext ctx)
-            throws Exception {
-    }
-
-    public void handlerRemoved(ChannelHandlerContext ctx)
-            throws Exception {
-    }
-
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
-        ctx.fireExceptionCaught(cause);
-    }
-}
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/VirtualSocket.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/VirtualSocket.java
deleted file mode 100644 (file)
index 69cce80..0000000
+++ /dev/null
@@ -1,205 +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.virtualsocket;
-
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.channels.SocketChannel;
-
-/**
- * Handler class providing Socket functionality to OIO client application. By using VirtualSocket user can
- * use OIO application in asynchronous environment and NIO EventLoop. Using VirtualSocket OIO applications
- * are able to use full potential of NIO environment.
- */
-//TODO: refactor - socket should be created when connection is established
-public class VirtualSocket extends Socket implements ChannelHandler {
-    private static final String INPUT_STREAM = "inputStream";
-    private static final String OUTPUT_STREAM = "outputStream";
-
-    private final ChannelInputStream chais = new ChannelInputStream();
-    private final ChannelOutputStream chaos = new ChannelOutputStream();
-    private ChannelHandlerContext ctx;
-
-
-    public InputStream getInputStream() {
-        return this.chais;
-    }
-
-    public OutputStream getOutputStream() {
-        return this.chaos;
-    }
-
-    public void handlerAdded(ChannelHandlerContext ctx) {
-        this.ctx = ctx;
-
-        if (ctx.channel().pipeline().get(OUTPUT_STREAM) == null) {
-            ctx.channel().pipeline().addFirst(OUTPUT_STREAM, chaos);
-        }
-
-        if (ctx.channel().pipeline().get(INPUT_STREAM) == null) {
-            ctx.channel().pipeline().addFirst(INPUT_STREAM, chais);
-        }
-    }
-
-    public void handlerRemoved(ChannelHandlerContext ctx) {
-        if (ctx.channel().pipeline().get(OUTPUT_STREAM) != null) {
-            ctx.channel().pipeline().remove(OUTPUT_STREAM);
-        }
-
-        if (ctx.channel().pipeline().get(INPUT_STREAM) != null) {
-            ctx.channel().pipeline().remove(INPUT_STREAM);
-        }
-    }
-
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {
-        // TODO exceptionCaught is deprecated transform this handler
-        ctx.fireExceptionCaught(throwable);
-    }
-
-
-    @Override
-    public void connect(SocketAddress endpoint) throws IOException {}
-
-    @Override
-    public void connect(SocketAddress endpoint, int timeout) throws IOException {}
-
-    @Override
-    public void bind(SocketAddress bindpoint) throws IOException {}
-
-    @Override
-    public InetAddress getInetAddress() {
-        InetSocketAddress isa = getInetSocketAddress();
-        return isa.getAddress();
-    }
-
-    @Override
-    public InetAddress getLocalAddress() {return null;}
-
-    @Override
-    public int getPort() {
-        return getInetSocketAddress().getPort();
-    }
-
-    private InetSocketAddress getInetSocketAddress() {
-        return (InetSocketAddress)getRemoteSocketAddress();
-    }
-
-    @Override
-    public int getLocalPort() {return -1;}
-
-    @Override
-    public SocketAddress getRemoteSocketAddress() {
-        return this.ctx.channel().remoteAddress();
-    }
-
-    @Override
-    public SocketAddress getLocalSocketAddress() {
-        return this.ctx.channel().localAddress();
-    }
-
-    @Override
-    public SocketChannel getChannel() {return null;}
-
-    @Override
-    public void setTcpNoDelay(boolean on) throws SocketException {}
-
-    @Override
-    public boolean getTcpNoDelay() throws SocketException {return false;}
-
-    @Override
-    public void setSoLinger(boolean on, int linger) throws SocketException {}
-
-    @Override
-    public int getSoLinger() throws SocketException {return -1;}
-
-    @Override
-    public void sendUrgentData(int data) throws IOException {}
-
-    @Override
-    public void setOOBInline(boolean on) throws SocketException {}
-
-    @Override
-    public boolean getOOBInline() throws SocketException {return false;}
-
-    @Override
-    public synchronized void setSoTimeout(int timeout) throws SocketException {}
-
-    @Override
-    public synchronized int getSoTimeout() throws SocketException {return -1;}
-
-    @Override
-    public synchronized void setSendBufferSize(int size) throws SocketException {}
-
-    @Override
-    public synchronized int getSendBufferSize() throws SocketException {return -1;}
-
-    @Override
-    public synchronized void setReceiveBufferSize(int size) throws SocketException {}
-
-    @Override
-    public synchronized int getReceiveBufferSize() throws SocketException {return -1;}
-
-    @Override
-    public void setKeepAlive(boolean on) throws SocketException {}
-
-    @Override
-    public boolean getKeepAlive() throws SocketException {return false;}
-
-    @Override
-    public void setTrafficClass(int tc) throws SocketException {}
-
-    @Override
-    public int getTrafficClass() throws SocketException {return -1;}
-
-    @Override
-    public void setReuseAddress(boolean on) throws SocketException {}
-
-    @Override
-    public boolean getReuseAddress() throws SocketException {return false;}
-
-    @Override
-    public synchronized void close() throws IOException {}
-
-    @Override
-    public void shutdownInput() throws IOException {}
-
-    @Override
-    public void shutdownOutput() throws IOException {}
-
-    @Override
-    public String toString() {
-        return "VirtualSocket{" + getInetAddress() + ":" + getPort() + "}";
-    }
-
-    @Override
-    public boolean isConnected() {return false;}
-
-    @Override
-    public boolean isBound() {return false;}
-
-    @Override
-    public boolean isClosed() {return false;}
-
-    @Override
-    public boolean isInputShutdown() {return false;}
-
-    @Override
-    public boolean isOutputShutdown() {return false;}
-
-    @Override
-    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {}
-}
diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/ChunkedFramingMechanismEncoderTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/ChunkedFramingMechanismEncoderTest.java
new file mode 100644 (file)
index 0000000..9347512
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.doAnswer;
+
+import com.google.common.collect.Lists;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
+
+public class ChunkedFramingMechanismEncoderTest {
+
+    private int chunkSize;
+    @Mock
+    private ChannelHandlerContext ctx;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        chunkSize = 256;
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testIllegalSize() throws Exception {
+        new ChunkedFramingMechanismEncoder(10);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testIllegalSizeMax() throws Exception {
+        new ChunkedFramingMechanismEncoder(Integer.MAX_VALUE);
+    }
+
+    @Test
+    public void testEncode() throws Exception {
+        final List<ByteBuf> chunks = Lists.newArrayList();
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(final InvocationOnMock invocation) throws Throwable {
+                chunks.add((ByteBuf) invocation.getArguments()[0]);
+                return null;
+            }
+        }).when(ctx).write(anyObject());
+
+        final ChunkedFramingMechanismEncoder encoder = new ChunkedFramingMechanismEncoder(chunkSize);
+        final int lastChunkSize = 20;
+        final ByteBuf src = Unpooled.wrappedBuffer(getByteArray(chunkSize * 4 + lastChunkSize));
+        final ByteBuf destination = Unpooled.buffer();
+        encoder.encode(ctx, src, destination);
+        assertEquals(4, chunks.size());
+
+        final int framingSize = "#256\n".getBytes().length + 1/* new line at end */;
+
+        for (final ByteBuf chunk : chunks) {
+            assertEquals(chunkSize + framingSize, chunk.readableBytes());
+        }
+
+        final int lastFramingSize = "#20\n".length() + NetconfMessageConstants.END_OF_CHUNK.length + 1/* new line at end */;
+        assertEquals(lastChunkSize + lastFramingSize, destination.readableBytes());
+    }
+
+    private byte[] getByteArray(final int size) {
+        final byte[] bytes = new byte[size];
+        for (int i = 0; i < size; i++) {
+            bytes[i] = 'a';
+        }
+        return bytes;
+    }
+}
diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/EOMFramingMechanismEncoderTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/EOMFramingMechanismEncoderTest.java
new file mode 100644 (file)
index 0000000..158f3a8
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
+
+public class EOMFramingMechanismEncoderTest {
+
+    @Test
+    public void testEncode() throws Exception {
+        final byte[] content = new byte[50];
+        final ByteBuf source = Unpooled.wrappedBuffer(content);
+        final ByteBuf destination = Unpooled.buffer();
+        new EOMFramingMechanismEncoder().encode(null, source, destination);
+
+        assertEquals(Unpooled.wrappedBuffer(source.array(), NetconfMessageConstants.END_OF_MESSAGE), destination);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/FramingMechanismHandlerFactoryTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/FramingMechanismHandlerFactoryTest.java
new file mode 100644 (file)
index 0000000..4f123f0
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
+
+public class FramingMechanismHandlerFactoryTest {
+
+    @Test
+    public void testCreate() throws Exception {
+        MatcherAssert.assertThat(FramingMechanismHandlerFactory
+                .createHandler(FramingMechanism.CHUNK), CoreMatchers
+                .instanceOf(ChunkedFramingMechanismEncoder.class));
+        MatcherAssert.assertThat(FramingMechanismHandlerFactory
+                .createHandler(FramingMechanism.EOM), CoreMatchers
+                .instanceOf(EOMFramingMechanismEncoder.class));
+    }
+}
\ No newline at end of file
index e088859e82a628a1fa166def6ae743f58e2d0045..a647b9ee172f44fc9e15baf7a284368ab00a8b19 100644 (file)
@@ -7,16 +7,16 @@
  */
 package org.opendaylight.controller.netconf.nettyutil.handler;
 
+import static org.junit.Assert.assertEquals;
+
 import com.google.common.base.Charsets;
 import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-import junit.framework.Assert;
+import java.util.List;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import java.util.List;
-
 public class NetconfChunkAggregatorTest {
 
     private static final String CHUNKED_MESSAGE = "\n#4\n" +
@@ -45,26 +45,26 @@ public class NetconfChunkAggregatorTest {
 
     @Test
     public void testMultipleChunks() throws Exception {
-        List<Object> output = Lists.newArrayList();
-        ByteBuf input = Unpooled.copiedBuffer(CHUNKED_MESSAGE.getBytes(Charsets.UTF_8));
+        final List<Object> output = Lists.newArrayList();
+        final ByteBuf input = Unpooled.copiedBuffer(CHUNKED_MESSAGE.getBytes(Charsets.UTF_8));
         agr.decode(null, input, output);
 
-        Assert.assertEquals(1, output.size());
-        ByteBuf chunk = (ByteBuf) output.get(0);
+        assertEquals(1, output.size());
+        final ByteBuf chunk = (ByteBuf) output.get(0);
 
-        Assert.assertEquals(EXPECTED_MESSAGE, chunk.toString(Charsets.UTF_8));
+        assertEquals(EXPECTED_MESSAGE, chunk.toString(Charsets.UTF_8));
     }
 
     @Test
     public void testOneChunks() throws Exception {
-        List<Object> output = Lists.newArrayList();
-        ByteBuf input = Unpooled.copiedBuffer(CHUNKED_MESSAGE_ONE.getBytes(Charsets.UTF_8));
+        final List<Object> output = Lists.newArrayList();
+        final ByteBuf input = Unpooled.copiedBuffer(CHUNKED_MESSAGE_ONE.getBytes(Charsets.UTF_8));
         agr.decode(null, input, output);
 
-        Assert.assertEquals(1, output.size());
-        ByteBuf chunk = (ByteBuf) output.get(0);
+        assertEquals(1, output.size());
+        final ByteBuf chunk = (ByteBuf) output.get(0);
 
-        Assert.assertEquals(EXPECTED_MESSAGE, chunk.toString(Charsets.UTF_8));
+        assertEquals(EXPECTED_MESSAGE, chunk.toString(Charsets.UTF_8));
     }
 
 
diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoderTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoderTest.java
new file mode 100644 (file)
index 0000000..00d95df
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+
+public class NetconfHelloMessageToXMLEncoderTest {
+
+    @Mock
+    private ChannelHandlerContext ctx;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testEncode() throws Exception {
+        final NetconfMessage msg = new NetconfHelloMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"),
+                NetconfHelloMessageAdditionalHeader.fromString("[tomas;10.0.0.0:10000;tcp;client;]"));
+        final ByteBuf destination = Unpooled.buffer();
+        new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, destination);
+
+        final String encoded = new String(destination.array());
+        assertThat(encoded, containsString("[tomas;10.0.0.0:10000;tcp;client;]"));
+        assertThat(encoded, containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
+    }
+
+    @Test
+    public void testEncodeNoHeader() throws Exception {
+        final NetconfMessage msg = new NetconfHelloMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
+        final ByteBuf destination = Unpooled.buffer();
+        new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, destination);
+
+        final String encoded = new String(destination.array());
+        assertThat(encoded, not(containsString("[tomas;10.0.0.0:10000;tcp;client;]")));
+        assertThat(encoded, containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testEncodeNotHello() throws Exception {
+        final NetconfMessage msg = new NetconfMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
+        new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, null);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java
new file mode 100644 (file)
index 0000000..f0c0d63
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.List;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+
+public class NetconfXMLToHelloMessageDecoderTest {
+
+    @Test
+    public void testDecodeWithHeader() throws Exception {
+        final ByteBuf src = Unpooled.wrappedBuffer(String.format("%s\n%s",
+                "[tomas;10.0.0.0:10000;tcp;client;]", "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>").getBytes());
+        final List<Object> out = Lists.newArrayList();
+        new NetconfXMLToHelloMessageDecoder().decode(null, src, out);
+
+        assertEquals(1, out.size());
+        assertThat(out.get(0), CoreMatchers.instanceOf(NetconfHelloMessage.class));
+        final NetconfHelloMessage hello = (NetconfHelloMessage) out.get(0);
+        assertTrue(hello.getAdditionalHeader().isPresent());
+        assertEquals("[tomas;10.0.0.0:10000;tcp;client;]\n", hello.getAdditionalHeader().get().toFormattedString());
+        assertThat(XmlUtil.toString(hello.getDocument()), CoreMatchers.containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\""));
+    }
+
+    @Test
+    public void testDecodeNoHeader() throws Exception {
+        final ByteBuf src = Unpooled.wrappedBuffer("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+        final List<Object> out = Lists.newArrayList();
+        new NetconfXMLToHelloMessageDecoder().decode(null, src, out);
+
+        assertEquals(1, out.size());
+        assertThat(out.get(0), CoreMatchers.instanceOf(NetconfHelloMessage.class));
+        final NetconfHelloMessage hello = (NetconfHelloMessage) out.get(0);
+        assertFalse(hello.getAdditionalHeader().isPresent());
+    }
+
+    @Test
+    public void testDecodeCaching() throws Exception {
+        final ByteBuf msg1 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+        final ByteBuf msg2 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+        final ByteBuf src = Unpooled.wrappedBuffer("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+        final List<Object> out = Lists.newArrayList();
+        final NetconfXMLToHelloMessageDecoder decoder = new NetconfXMLToHelloMessageDecoder();
+        decoder.decode(null, src, out);
+        decoder.decode(null, msg1, out);
+        decoder.decode(null, msg2, out);
+
+        assertEquals(1, out.size());
+
+        assertEquals(2, Iterables.size(decoder.getPostHelloNetconfMessages()));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testDecodeNotHelloReceived() throws Exception {
+        final ByteBuf msg1 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+        final List<Object> out = Lists.newArrayList();
+        NetconfXMLToHelloMessageDecoder decoder = new NetconfXMLToHelloMessageDecoder();
+        decoder.decode(null, msg1, out);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoderTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoderTest.java
new file mode 100644 (file)
index 0000000..f85a387
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.Lists;
+import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
+import org.junit.Test;
+
+public class NetconfXMLToMessageDecoderTest {
+
+    @Test
+    public void testDecodeNoMoreContent() throws Exception {
+        final ArrayList<Object> out = Lists.newArrayList();
+        new NetconfXMLToMessageDecoder().decode(null, Unpooled.buffer(), out);
+        assertEquals(0, out.size());
+    }
+
+    @Test
+    public void testDecode() throws Exception {
+        final ArrayList<Object> out = Lists.newArrayList();
+        new NetconfXMLToMessageDecoder().decode(null, Unpooled.wrappedBuffer("<msg/>".getBytes()), out);
+        assertEquals(1, out.size());
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/authentication/LoginPasswordTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/authentication/LoginPasswordTest.java
new file mode 100644 (file)
index 0000000..01df1e3
--- /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.netconf.nettyutil.handler.ssh.authentication;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.client.future.AuthFuture;
+import org.junit.Test;
+
+public class LoginPasswordTest {
+
+    @Test
+    public void testLoginPassword() throws Exception {
+        final LoginPassword loginPassword = new LoginPassword("user", "pwd");
+        assertEquals("user", loginPassword.getUsername());
+
+        final ClientSession session = mock(ClientSession.class);
+        doNothing().when(session).addPasswordIdentity("pwd");
+        doReturn(mock(AuthFuture.class)).when(session).auth();
+        loginPassword.authenticate(session);
+
+        verify(session).addPasswordIdentity("pwd");
+        verify(session).auth();
+    }
+}
\ No newline at end of file
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);
             }
         };
index 0a1da7760412edb0308b64d26ee83d92c51a8bee..69a57748ddabc88212411cf6b4ecf3d088a80381 100644 (file)
@@ -75,5 +75,5 @@ public interface INeutronLoadBalancerPoolMemberAware {
      *            instance of deleted LoadBalancerPool object
      * @return void
      */
-    public void NeutronLoadBalancerPoolMemberDeleted(NeutronLoadBalancerPoolMember loadBalancerPoolMember);
+    public void neutronLoadBalancerPoolMemberDeleted(NeutronLoadBalancerPoolMember loadBalancerPoolMember);
 }
index 4a6a291e6a0a1518c68ee181c771139be5146ec5..d92c57bd8a59d9852326e2f2238af9dac2784971 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-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,
@@ -57,6 +57,10 @@ public class Activator extends ComponentActivatorAbstractBase {
     protected static final Logger logger = LoggerFactory
             .getLogger(Activator.class);
 
+    /**
+     * Priority to determine whether to override existing protocol service.
+     */
+    private static final int  PLUGIN_PRIORITY = 10;
 
     /**
      * Function that is used to communicate to dependency manager the list of
@@ -136,6 +140,8 @@ public class Activator extends ComponentActivatorAbstractBase {
             // Set the protocolPluginType property which will be used
             // by SAL
             props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW);
+            props.put(GlobalConstants.PROTOCOLPLUGINPRIORITY.toString(),
+                      Integer.valueOf(PLUGIN_PRIORITY));
             c.setInterface(IPluginInDataPacketService.class.getName(), props);
             // Hook the services coming in from SAL, as optional in
             // case SAL is not yet there, could happen
@@ -165,6 +171,8 @@ public class Activator extends ComponentActivatorAbstractBase {
             // Set the protocolPluginType property which will be used
             // by SAL
             props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW);
+            props.put(GlobalConstants.PROTOCOLPLUGINPRIORITY.toString(),
+                      Integer.valueOf(PLUGIN_PRIORITY));
             c.setInterface(new String[] {
                     IReadFilterInternalListener.class.getName(),
                     IPluginInReadService.class.getName() }, props);
@@ -256,6 +264,8 @@ public class Activator extends ComponentActivatorAbstractBase {
             // Set the protocolPluginType property which will be used
             // by SAL
             props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW);
+            props.put(GlobalConstants.PROTOCOLPLUGINPRIORITY.toString(),
+                      Integer.valueOf(PLUGIN_PRIORITY));
             c.setInterface(
                     new String[] { IPluginInFlowProgrammerService.class.getName(), IMessageListener.class.getName(),
                             IContainerListener.class.getName(), IInventoryShimExternalListener.class.getName(),
index b491c5fcea2e4b53914102a91e88a76591ac5d22..8b6d3c4a1cd7fc98d6820562e73068be331e7372 100644 (file)
@@ -1,11 +1,10 @@
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-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.sal.action;
 
 /**
@@ -34,8 +33,8 @@ public enum ActionType {
     SET_NW_SRC("setNwSrc", 0, 0),
     SET_NW_DST("setNwDst", 0, 0),
     SET_NW_TOS("setNwTos", 0, 0x3f),
-    SET_TP_SRC("setTpSrc", 1, 0xffff),
-    SET_TP_DST("setTpDst", 1, 0xffff),
+    SET_TP_SRC("setTpSrc", 0, 0xffff), // Set transport source port
+    SET_TP_DST("setTpDst", 0, 0xffff), // Set transport destination port
     SET_NEXT_HOP("setNextHop", 0, 0);
 
     private String id;
index 174f2546bad1039f87352b5e0a8bd129ad383732..ceb4553470933330516bd945652a07045dcf7e85 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-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,
@@ -20,7 +19,8 @@ public enum GlobalConstants {
     STATICVLAN("staticvlan"),
     CLUSTERINGSERVICES("clusteringservices"),
     STARTUPHOME("configuration/startup/"),
-    PROTOCOLPLUGINTYPE("protocolPluginType");
+    PROTOCOLPLUGINTYPE("protocolPluginType"),
+    PROTOCOLPLUGINPRIORITY("protocolPluginPriority");
 
     private GlobalConstants(String name) {
         this.name = name;
@@ -31,4 +31,4 @@ public enum GlobalConstants {
     public String toString() {
         return name;
     }
-}
\ No newline at end of file
+}
index 5c09a43feddf4cf66b2486d4d6df6776786b55a1..3fe9a18b3fa545cbdcf279092c272c43a34d4cc1 100644 (file)
@@ -1,12 +1,10 @@
-
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-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.sal.action;
 
 import org.opendaylight.controller.sal.core.ConstructionException;
@@ -176,8 +174,11 @@ public class ActionTest {
         action = new SetTpDst(65535);
         Assert.assertTrue(action.isValid());
 
+        action = new SetTpSrc(0);
+        Assert.assertTrue(action.isValid());
+
         action = new SetTpDst(0);
-        Assert.assertFalse(action.isValid());
+        Assert.assertTrue(action.isValid());
 
         action = new SetTpSrc(-1);
         Assert.assertFalse(action.isValid());
index e9039261a3724fb733f5a260300c291e9712224a..0c9ebab8c3c126a2442a0b8ef87ab30577602a10 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-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,
@@ -40,7 +39,6 @@ import org.opendaylight.controller.sal.packet.LinkEncap;
 import org.opendaylight.controller.sal.packet.Packet;
 import org.opendaylight.controller.sal.packet.PacketResult;
 import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.NetUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -59,9 +57,9 @@ public class DataPacketService implements IPluginOutDataPacketService,
      * adding a new service, removing a service, going through all of
      * them maybe different.
      */
-    private ConcurrentHashMap<String, IPluginInDataPacketService>
+    private ConcurrentHashMap<String, ProtocolService<IPluginInDataPacketService>>
         pluginInDataService =
-        new ConcurrentHashMap<String, IPluginInDataPacketService>();
+        new ConcurrentHashMap<String, ProtocolService<IPluginInDataPacketService>>();
     private Map<String, AtomicInteger> statistics = new HashMap<String, AtomicInteger>();
 
     /**
@@ -186,11 +184,11 @@ public class DataPacketService implements IPluginOutDataPacketService,
                         String t = p.getNode()
                                 .getType();
                         // Now locate the TX dispatcher
-                        IPluginInDataPacketService s = pluginInDataService
-                                .get(t);
-                        if (s != null) {
+                        ProtocolService<IPluginInDataPacketService> service =
+                            pluginInDataService.get(t);
+                        if (service != null) {
                             try {
-                                s.transmitDataPacket(pkt);
+                                service.getService().transmitDataPacket(pkt);
                                 increaseStat("TXPacketSuccess");
                             } catch (Exception e) {
                                 increaseStat("TXPacketFailedForException");
@@ -207,54 +205,11 @@ public class DataPacketService implements IPluginOutDataPacketService,
     }
 
     void setPluginInDataService(Map props, IPluginInDataPacketService s) {
-        if (this.pluginInDataService == null) {
-            logger.error("pluginInDataService store null");
-            return;
-        }
-        String type = null;
-        logger.trace("Received setPluginInDataService request");
-        for (Object e : props.entrySet()) {
-            Map.Entry entry = (Map.Entry) e;
-            logger.trace("Prop key:({}) value:({})",entry.getKey(), entry.getValue());
-        }
-
-        Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
-        if (value instanceof String) {
-            type = (String) value;
-        }
-        if (type == null) {
-            logger.error("Received a PluginInDataService without any "
-                    + "protocolPluginType provided");
-        } else {
-            this.pluginInDataService.put(type, s);
-            logger.debug("Stored the PluginInDataService for type: {}", type);
-        }
+        ProtocolService.set(this.pluginInDataService, props, s, logger);
     }
 
     void unsetPluginInDataService(Map props, IPluginInDataPacketService s) {
-        if (this.pluginInDataService == null) {
-            logger.error("pluginInDataService store null");
-            return;
-        }
-
-        String type = null;
-        logger.trace("Received unsetPluginInDataService request");
-        for (Object e : props.entrySet()) {
-            Map.Entry entry = (Map.Entry) e;
-            logger.trace("Prop key:({}) value:({})",entry.getKey(), entry.getValue());
-        }
-
-        Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
-        if (value instanceof String) {
-            type = (String) value;
-        }
-        if (type == null) {
-            logger.error("Received a PluginInDataService without any "
-                    + "protocolPluginType provided");
-        } else if (this.pluginInDataService.get(type).equals(s)) {
-            this.pluginInDataService.remove(type);
-            logger.debug("Removed the PluginInDataService for type: {}", type);
-        }
+        ProtocolService.unset(this.pluginInDataService, props, s, logger);
     }
 
     void setListenDataPacket(Map props, IListenDataPacket s) {
index 854125b3567a196b940556363ed56c82e99d50c0..60a7882bda552b5e2fa5fddfb7ebafad6d51ccbb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-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,
@@ -38,7 +38,6 @@ import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerSe
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchType;
 import org.opendaylight.controller.sal.utils.EtherTypes;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.IPProtocols;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.Status;
@@ -58,12 +57,12 @@ public class FlowProgrammerService implements IFlowProgrammerService,
 
     protected static final Logger logger = LoggerFactory
             .getLogger(FlowProgrammerService.class);
-    private ConcurrentHashMap<String, IPluginInFlowProgrammerService> pluginFlowProgrammer;
+    private ConcurrentHashMap<String, ProtocolService<IPluginInFlowProgrammerService>> pluginFlowProgrammer;
     private Set<IFlowProgrammerListener> listener;
     private AtomicLong seq;
 
     public FlowProgrammerService() {
-        pluginFlowProgrammer = new ConcurrentHashMap<String, IPluginInFlowProgrammerService>();
+        pluginFlowProgrammer = new ConcurrentHashMap<String, ProtocolService<IPluginInFlowProgrammerService>>();
         listener = new HashSet<IFlowProgrammerListener>();
         seq = new AtomicLong();
         /*
@@ -117,58 +116,11 @@ public class FlowProgrammerService implements IFlowProgrammerService,
 
     // Set the reference to the plugin flow programmer
     public void setService(Map<String, Object> props, IPluginInFlowProgrammerService s) {
-        if (this.pluginFlowProgrammer == null) {
-            logger.error("pluginFlowProgrammer store null");
-            return;
-        }
-
-        if (logger.isTraceEnabled()) {
-            logger.trace("Got a service set request {}", s);
-            for (Map.Entry<String, Object> entry : props.entrySet()) {
-                logger.trace("Prop key:({}) value:({})", entry.getKey(), entry.getValue());
-            }
-        }
-
-        String type = null;
-        Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
-        if (value instanceof String) {
-            type = (String) value;
-        }
-        if (type == null) {
-            logger.error("Received a pluginFlowProgrammer without any "
-                    + "protocolPluginType provided");
-        } else {
-            this.pluginFlowProgrammer.put(type, s);
-            logger.debug("Stored the pluginFlowProgrammer for type: {}", type);
-        }
+        ProtocolService.set(this.pluginFlowProgrammer, props, s, logger);
     }
 
     public void unsetService(Map<String, Object> props, IPluginInFlowProgrammerService s) {
-        if (this.pluginFlowProgrammer == null) {
-            logger.error("pluginFlowProgrammer store null");
-            return;
-        }
-
-        logger.debug("Received unsetpluginFlowProgrammer request");
-        if (logger.isTraceEnabled()) {
-            logger.trace("Got a service set request {}", s);
-            for (Map.Entry<String, Object> entry : props.entrySet()) {
-                logger.trace("Prop key:({}) value:({})", entry.getKey(), entry.getValue());
-            }
-        }
-
-        String type = null;
-        Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
-        if (value instanceof String) {
-            type = (String) value;
-        }
-        if (type == null) {
-            logger.error("Received a pluginFlowProgrammer without any "
-                    + "protocolPluginType provided");
-        } else if (this.pluginFlowProgrammer.get(type).equals(s)) {
-            this.pluginFlowProgrammer.remove(type);
-            logger.debug("Removed the pluginFlowProgrammer for type: {}", type);
-        }
+        ProtocolService.unset(this.pluginFlowProgrammer, props, s, logger);
     }
 
     public void setListener(IFlowProgrammerListener s) {
@@ -182,9 +134,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status addFlow(Node node, Flow flow) {
         if (pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType()).addFlow(
-                        node, flow);
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().addFlow(node, flow);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -193,9 +146,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status removeFlow(Node node, Flow flow) {
         if (pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType())
-                        .removeFlow(node, flow);
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().removeFlow(node, flow);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -204,9 +158,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status removeAllFlows(Node node) {
         if (pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType())
-                        .removeAllFlows(node);
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().removeAllFlows(node);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -215,9 +170,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
         if (pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType())
-                        .modifyFlow(node, oldFlow, newFlow);
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().modifyFlow(node, oldFlow, newFlow);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -226,9 +182,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status addFlowAsync(Node node, Flow flow) {
         if (pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType()).addFlowAsync(
-                        node, flow, getNextRid());
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().addFlowAsync(node, flow, getNextRid());
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -237,9 +194,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status removeFlowAsync(Node node, Flow flow) {
         if (pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType())
-                        .removeFlowAsync(node, flow, getNextRid());
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().removeFlowAsync(node, flow, getNextRid());
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -248,9 +206,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow) {
         if (pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType())
-                        .modifyFlowAsync(node, oldFlow, newFlow, getNextRid());
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().modifyFlowAsync(node, oldFlow, newFlow, getNextRid());
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -508,9 +467,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status syncSendBarrierMessage(Node node) {
         if (this.pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType())
-                        .syncSendBarrierMessage(node);
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().syncSendBarrierMessage(node);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -519,9 +479,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     @Override
     public Status asyncSendBarrierMessage(Node node) {
         if (this.pluginFlowProgrammer != null) {
-            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType())
-                        .asyncSendBarrierMessage(node);
+            ProtocolService<IPluginInFlowProgrammerService> service =
+                this.pluginFlowProgrammer.get(node.getType());
+            if (service != null) {
+                return service.getService().asyncSendBarrierMessage(node);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
diff --git a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/ProtocolService.java b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/ProtocolService.java
new file mode 100644 (file)
index 0000000..e9dc2ad
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2014 NEC Corporation 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.sal.implementation.internal;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+import org.slf4j.Logger;
+
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+
+/**
+ * An instance of this class keeps a protocol plugin service handler.
+ *
+ * @param <T>  Type of protocol plugin service.
+ */
+public final class ProtocolService<T> {
+    /**
+     * Default priority value.
+     */
+    private static final int  DEFAULT_PRIORITY = 0;
+
+    /**
+     * A protocol plugin service handler.
+     */
+    private final T  service;
+
+    /**
+     * A priority value assigned to this protocol plugin.
+     */
+    private final int  priority;
+
+    /**
+     * Set protocol plugin service.
+     *
+     * @param map     A map that keeps protocol plugin services.
+     * @param props   Service properties.
+     * @param s       Protocol plugin service.
+     * @param logger  A logger instance.
+     * @param <S>     Type of protocol plugin service.
+     */
+    public static <S> void set(ConcurrentMap<String, ProtocolService<S>> map,
+                               Map<?, ?> props, S s, Logger logger) {
+        if (map == null) {
+            logger.error("Protocol plugin service store is null.");
+            return;
+        }
+        if (s == null) {
+            logger.error("Protocol plugin service is null.");
+            return;
+        }
+        if (props == null) {
+            logger.error("Service property is null.");
+            return;
+        }
+
+        if (logger.isTraceEnabled()) {
+            logger.trace("Received set service request: {}", s);
+            for (Map.Entry<?, ?> entry: props.entrySet()) {
+                logger.trace("Prop key:({}) value:({})", entry.getKey(),
+                             entry.getValue());
+            }
+        }
+
+        Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
+        if (!(value instanceof String)) {
+            logger.error("Unexpected protocol type: {}", value);
+            return;
+        }
+
+        String type = (String)value;
+        ProtocolService<S> service = new ProtocolService<S>(props, s);
+        ProtocolService<S> old = map.putIfAbsent(type, service);
+        while (old != null) {
+            // Compare priority value.
+            if (old.getPriority() >= service.getPriority()) {
+                logger.trace("Protocol plugin service for {} is already set: " +
+                             "current={}, requested={}", type, old, service);
+                return;
+            }
+
+            if (map.replace(type, old, service)) {
+                break;
+            }
+            old = map.putIfAbsent(type, service);
+        }
+
+        logger.debug("Stored protocol plugin service for {}: {}",
+                     type, service);
+    }
+
+    /**
+     * Unset protocol plugin service.
+     *
+     * @param map     A map that keeps protocol plugin services.
+     * @param props   Service properties.
+     * @param s       Protocol plugin service.
+     * @param logger  A logger instance.
+     * @param <S>     Type of protocol plugin service.
+     */
+    public static <S> void unset(ConcurrentMap<String, ProtocolService<S>> map,
+                                 Map<?, ?> props, S s, Logger logger) {
+        if (map == null) {
+            logger.error("Protocol plugin service store is null.");
+            return;
+        }
+        if (s == null) {
+            logger.error("Protocol plugin service is null.");
+            return;
+        }
+        if (props == null) {
+            logger.error("Service property is null.");
+            return;
+        }
+
+        if (logger.isTraceEnabled()) {
+            logger.trace("Received unset service request: {}", s);
+            for (Map.Entry<?, ?> entry: props.entrySet()) {
+                logger.trace("Prop key:({}) value:({})",
+                             entry.getKey(), entry.getValue());
+            }
+        }
+
+        Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
+        if (!(value instanceof String)) {
+            logger.error("Unexpected protocol type {}: service={}", value, s);
+            return;
+        }
+
+        String type = (String)value;
+        ProtocolService<S> plugin = new ProtocolService<S>(props, s);
+        if (map.remove(type, plugin)) {
+            logger.debug("Removed protocol plugin service for {}: {}",
+                         type, plugin);
+        } else {
+            logger.trace("Ignore unset service request for {}: {}",
+                         type, plugin);
+        }
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param props  Protocol plugin service properties.
+     * @param s      A protocol plugin service handler.
+     */
+    public ProtocolService(Map<?, ?> props, T s) {
+        service = s;
+
+        String key = GlobalConstants.PROTOCOLPLUGINPRIORITY.toString();
+        Object value = props.get(key);
+        if (value instanceof Integer) {
+            priority = ((Integer)value).intValue();
+        } else {
+            priority = DEFAULT_PRIORITY;
+        }
+    }
+
+    /**
+     * Return a protocol plugin service handler.
+     *
+     * @return  A protocol plugin service handler.
+     */
+    public T getService() {
+        return service;
+    }
+
+    /**
+     * Return a priority value assigned to this protocol plugin.
+     *
+     * @return  A priority value.
+     */
+    public int getPriority() {
+        return priority;
+    }
+
+    /**
+     * Determine whether the given object is identical to this object.
+     *
+     * @param o  An object to be compared.
+     * @return   {@code true} if identical. Otherwise {@code false}.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o == null || o.getClass() != getClass()) {
+            return false;
+        }
+
+        ProtocolService plugin = (ProtocolService)o;
+        return (service.equals(plugin.service) && priority == plugin.priority);
+    }
+
+    /**
+     * Return the hash code of this object.
+     *
+     * @return  The hash code.
+     */
+    @Override
+    public int hashCode() {
+        return service.hashCode() + (priority * 31);
+    }
+
+    /**
+     * Return a string representation of this instance.
+     *
+     * @return  A string representation of this instance.
+     */
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("[service=");
+        return builder.append(service).append(", priority=").append(priority).
+            append(']').toString();
+    }
+}
index 12de35f53677492581412017e9c763de96a05c0b..356c0e57c887f29f5d448ba523976f8fe077b5da 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-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,
@@ -43,7 +42,6 @@ import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
 import org.opendaylight.controller.sal.reader.NodeDescription;
 import org.opendaylight.controller.sal.reader.NodeTableStatistics;
 import org.opendaylight.controller.sal.utils.EtherTypes;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.IPProtocols;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.NodeCreator;
@@ -60,8 +58,8 @@ import org.slf4j.LoggerFactory;
 public class ReadService implements IReadService, CommandProvider, IPluginOutReadService {
 
     protected static final Logger logger = LoggerFactory.getLogger(ReadService.class);
-    private ConcurrentHashMap<String, IPluginInReadService> pluginReader =
-        new ConcurrentHashMap<String, IPluginInReadService>();
+    private ConcurrentHashMap<String, ProtocolService<IPluginInReadService>> pluginReader =
+        new ConcurrentHashMap<String, ProtocolService<IPluginInReadService>>();
     private Set<IReadServiceListener> readerListeners =
         new CopyOnWriteArraySet<IReadServiceListener>();
 
@@ -107,58 +105,13 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
 
     // Set the reference to the plugin flow Reader service
     public void setService(Map<?, ?> props, IPluginInReadService s) {
-        if (this.pluginReader == null) {
-            logger.error("pluginReader store null");
-            return;
-        }
-
-        logger.trace("Got a service set request {}", s);
-        String type = null;
-        for (Object e : props.entrySet()) {
-            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) e;
-            logger.trace("Prop key:({}) value:({})", entry.getKey(),
-                    entry.getValue());
-        }
-
-        Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
-        if (value instanceof String) {
-            type = (String) value;
-        }
-        if (type == null) {
-            logger.error("Received a pluginReader without any "
-                    + "protocolPluginType provided");
-        } else {
-            this.pluginReader.put(type, s);
-            logger.debug("Stored the pluginReader for type: {}", type);
-        }
+        ProtocolService.set(this.pluginReader, props, s, logger);
     }
 
     public void unsetService(Map<?, ?> props, IPluginInReadService s) {
-        if (this.pluginReader == null) {
-            logger.error("pluginReader store null");
-            return;
-        }
-
-        String type = null;
-        logger.debug("Received unsetpluginReader request");
-        for (Object e : props.entrySet()) {
-            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) e;
-            logger.trace("Prop key:({}) value:({})", entry.getKey(),
-                    entry.getValue());
-        }
-
-        Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
-        if (value instanceof String) {
-            type = (String) value;
-        }
-        if (type == null) {
-            logger.error("Received a pluginReader without any "
-                    + "protocolPluginType provided");
-        } else if (this.pluginReader.get(type).equals(s)) {
-            this.pluginReader.remove(type);
-            logger.debug("Removed the pluginReader for type: {}", type);
-        }
+        ProtocolService.unset(this.pluginReader, props, s, logger);
     }
+
     public void setReaderListener(IReadServiceListener service) {
         logger.trace("Got a listener set request {}", service);
         this.readerListeners.add(service);
@@ -172,9 +125,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public FlowOnNode readFlow(Node node, Flow flow) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readFlow(node, flow, true);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readFlow(node, flow, true);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -184,9 +138,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public FlowOnNode nonCachedReadFlow(Node node, Flow flow) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readFlow(node, flow, false);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readFlow(node, flow, false);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -196,9 +151,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public List<FlowOnNode> readAllFlows(Node node) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readAllFlow(node, true);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readAllFlow(node, true);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -208,9 +164,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public List<FlowOnNode> nonCachedReadAllFlows(Node node) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readAllFlow(node, false);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readAllFlow(node, false);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -220,9 +177,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public NodeDescription readDescription(Node node) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readDescription(node, true);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readDescription(node, true);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -232,9 +190,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public NodeDescription nonCachedReadDescription(Node node) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readDescription(node, false);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readDescription(node, false);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -245,9 +204,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     public NodeConnectorStatistics readNodeConnector(NodeConnector connector) {
         Node node = connector.getNode();
         if (pluginReader != null && node != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readNodeConnector(connector, true);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readNodeConnector(connector, true);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -259,9 +219,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
             NodeConnector connector) {
         Node node = connector.getNode();
         if (pluginReader != null && node != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readNodeConnector(connector, false);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readNodeConnector(connector, false);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -271,9 +232,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public List<NodeConnectorStatistics> readNodeConnectors(Node node) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readAllNodeConnector(node, true);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readAllNodeConnector(node, true);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -283,9 +245,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public List<NodeTableStatistics> readNodeTable(Node node) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readAllNodeTable(node, true);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readAllNodeTable(node, true);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -297,9 +260,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     public NodeTableStatistics nonCachedReadNodeTable(NodeTable table) {
         Node node = table.getNode();
         if (pluginReader != null && node != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readNodeTable(table, false);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readNodeTable(table, false);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -310,9 +274,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     public NodeTableStatistics readNodeTable(NodeTable table) {
         Node node = table.getNode();
         if (pluginReader != null && node != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readNodeTable(table, true);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readNodeTable(table, true);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -322,9 +287,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     @Override
     public List<NodeConnectorStatistics> nonCachedReadNodeConnectors(Node node) {
         if (pluginReader != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .readAllNodeConnector(node, false);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().readAllNodeConnector(node, false);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
@@ -335,9 +301,10 @@ public class ReadService implements IReadService, CommandProvider, IPluginOutRea
     public long getTransmitRate(NodeConnector connector) {
         Node node = connector.getNode();
         if (pluginReader != null && node != null) {
-            if (this.pluginReader.get(node.getType()) != null) {
-                return this.pluginReader.get(node.getType())
-                        .getTransmitRate(connector);
+            ProtocolService<IPluginInReadService> service =
+                this.pluginReader.get(node.getType());
+            if (service != null) {
+                return service.getService().getTransmitRate(connector);
             }
         }
         logger.warn("Plugin {} unavailable", node.getType());
diff --git a/opendaylight/sal/implementation/src/test/java/org/opendaylight/controller/sal/implementation/ProtocolServiceTest.java b/opendaylight/sal/implementation/src/test/java/org/opendaylight/controller/sal/implementation/ProtocolServiceTest.java
new file mode 100644 (file)
index 0000000..079350b
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2014 NEC Corporation 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.sal.implementation;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.opendaylight.controller.sal.implementation.internal.ProtocolService;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+
+/**
+ * Unit test for {@link ProtocolService}.
+ */
+public class ProtocolServiceTest {
+    private static final Logger LOG =
+        LoggerFactory.getLogger(ProtocolServiceTest.class);
+
+    @Test
+    public void testInstance() {
+        HashSet<ProtocolService<ITestService>> set = new HashSet<>();
+        TestService sv1 = new TestService();
+        HashMap<String, Object> prop1 = new HashMap<>();
+
+        ProtocolService<ITestService> ps1 =
+            new ProtocolService<ITestService>(prop1, sv1);
+        assertEquals(sv1, ps1.getService());
+        // Default priority is 0.
+        assertEquals(0, ps1.getPriority());
+        assertTrue(set.add(ps1));
+        assertFalse(set.add(ps1));
+
+        // Specify the same service and priority.
+        String priKey = GlobalConstants.PROTOCOLPLUGINPRIORITY.toString();
+        prop1.put(priKey, Integer.valueOf(0));
+        ProtocolService<ITestService> ps2 =
+            new ProtocolService<ITestService>(prop1, sv1);
+        assertEquals(sv1, ps2.getService());
+        assertEquals(0, ps2.getPriority());
+        assertEquals(ps1, ps2);
+        assertFalse(set.add(ps1));
+
+        // Specify different priority.
+        prop1.put(priKey, Integer.valueOf(Integer.MAX_VALUE));
+        ps2 = new ProtocolService<ITestService>(prop1, sv1);
+        assertEquals(sv1, ps2.getService());
+        assertEquals(Integer.MAX_VALUE, ps2.getPriority());
+        assertFalse(ps1.equals(ps2));
+        assertTrue(set.add(ps2));
+        assertFalse(set.add(ps2));
+
+        // Specify another service.
+        TestService sv2 = new TestService();
+        prop1.put(priKey, Integer.valueOf(0));
+        ps2 = new ProtocolService<ITestService>(prop1, sv2);
+        assertEquals(sv2, ps2.getService());
+        assertEquals(0, ps2.getPriority());
+        assertFalse(ps1.equals(ps2));
+        assertTrue(set.add(ps2));
+        assertFalse(set.add(ps2));
+    }
+
+    @Test
+    public void testSetUnsetError() {
+        ConcurrentMap<String, ProtocolService<ITestService>> services =
+            new ConcurrentHashMap<>();
+        TestService sv = new TestService();
+        Map<String, Object> props = new HashMap<>();
+
+        // null service.
+        ProtocolService.set(services, props, null, LOG);
+        assertTrue(services.isEmpty());
+
+        ProtocolService.unset(services, props, null, LOG);
+        assertTrue(services.isEmpty());
+
+        // null service property.
+        ProtocolService.set(services, null, sv, LOG);
+        assertTrue(services.isEmpty());
+
+        ProtocolService.unset(services, null, sv, LOG);
+        assertTrue(services.isEmpty());
+
+        // Type is not specified.
+        ProtocolService.set(services, props, sv, LOG);
+        assertTrue(services.isEmpty());
+
+        ProtocolService.unset(services, props, sv, LOG);
+        assertTrue(services.isEmpty());
+
+        // null service map.
+        final String typeKey = GlobalConstants.PROTOCOLPLUGINTYPE.toString();
+        assertEquals(null, props.put(typeKey, "OF"));
+        ProtocolService.set(null, props, sv, LOG);
+        assertTrue(services.isEmpty());
+
+        ProtocolService.unset(null, props, sv, LOG);
+        assertTrue(services.isEmpty());
+    }
+
+    @Test
+    public void testSetUnset() {
+        ConcurrentMap<String, ProtocolService<ITestService>> serviceMap =
+            new ConcurrentHashMap<>();
+        ConcurrentMap<String, ProtocolService<ITestService>> expected =
+            new ConcurrentHashMap<>();
+
+        final String typeKey = GlobalConstants.PROTOCOLPLUGINTYPE.toString();
+        final String priKey = GlobalConstants.PROTOCOLPLUGINPRIORITY.toString();
+        final String[] protocols = {"OF", "PE", "PK"};
+        final int basePri = 0;
+        final int loop = 5;
+
+        // Should override the service if higher priority is specified.
+        for (String proto: protocols) {
+            for (int pri = basePri - loop + 1; pri <= basePri; pri++) {
+                TestService sv = new TestService();
+                Map<String, Object> props = new HashMap<>();
+                assertEquals(null, props.put(typeKey, proto));
+                assertEquals(null, props.put(priKey, Integer.valueOf(pri)));
+                ProtocolService.set(serviceMap, props, sv, LOG);
+
+                ProtocolService<ITestService> service = serviceMap.get(proto);
+                assertNotNull(service);
+                assertEquals(sv, service.getService());
+                assertEquals(pri, service.getPriority());
+
+                ProtocolService<ITestService> service1 =
+                    new ProtocolService<ITestService>(props, sv);
+                expected.put(proto, service1);
+                assertEquals(expected, serviceMap);
+
+                // Unset service request should be ignored if different
+                // parameters are specified.
+                TestService another = new TestService();
+                ProtocolService.unset(serviceMap, props, another, LOG);
+                assertEquals(expected, serviceMap);
+
+                props.put(priKey, Integer.valueOf(Integer.MAX_VALUE));
+                ProtocolService.unset(serviceMap, props, sv, LOG);
+                assertEquals(expected, serviceMap);
+            }
+        }
+
+        // Should reject the set service request if lower priority is specified.
+        for (String proto: protocols) {
+            for (int pri = basePri - loop; pri < basePri; pri++) {
+                TestService sv = new TestService();
+                Map<String, Object> props = new HashMap<>();
+                assertEquals(null, props.put(typeKey, proto));
+                assertEquals(null, props.put(priKey, Integer.valueOf(pri)));
+                ProtocolService.set(serviceMap, props, sv, LOG);
+                assertEquals(expected, serviceMap);
+            }
+        }
+
+        // Unset protocol services.
+        for (String proto: protocols) {
+            ProtocolService<ITestService> service = expected.remove(proto);
+            assertNotNull(service);
+
+            ITestService sv = service.getService();
+            Map<String, Object> props = new HashMap<>();
+            assertEquals(null, props.put(typeKey, proto));
+            assertEquals(null, props.put(priKey, Integer.valueOf(basePri)));
+            ProtocolService.unset(serviceMap, props, sv, LOG);
+            assertEquals(expected, serviceMap);
+
+            // Should be ignored if the specified service does not exist.
+            ProtocolService.unset(serviceMap, props, sv, LOG);
+            assertEquals(expected, serviceMap);
+        }
+
+        assertTrue(serviceMap.isEmpty());
+    }
+}
+
+interface ITestService {
+}
+
+class TestService implements ITestService {
+}
index 6e7fd25e049a17fc997b30c5d2003227e1b9a61f..5e638cf9cc86c3bfbbeef4085cc0dabea51e8c64 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-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,
@@ -1191,7 +1191,7 @@ one.f.flows = {
             var h3 = "Set Transport Source Port";
             var placeholder = "Transport Source Port";
             var id = one.f.flows.id.modal.action.modifyTransportSourcePort;
-            var help = "Range: 1 - 65535";
+            var help = "Range: 0 - 65535";
             var action = 'SET_TP_SRC';
             var name = "Source Port";
             var body = function() {
@@ -1207,7 +1207,7 @@ one.f.flows = {
             var h3 = "Set Transport Destination Port";
             var placeholder = "Transport Destination Port";
             var id = one.f.flows.id.modal.action.modifyTransportDestinationPort;
-            var help = "Range: 1 - 65535";
+            var help = "Range: 0 - 65535";
             var action = 'SET_TP_DST';
             var name = "Destination Port";
             var body = function() {
diff --git a/pom.xml b/pom.xml
index f3f777f8570457488bfa21ec19c767218c39fbe1..10c05e254f84d88d25f1e3e9b5ef3da3af84b7a1 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,7 @@
     <module>opendaylight/forwardingrulesmanager/implementation</module>
     <module>opendaylight/hosttracker/api</module>
     <module>opendaylight/hosttracker/implementation</module>
+    <module>opendaylight/hosttracker/shell</module>
     <module>opendaylight/hosttracker_new/api</module>
     <module>opendaylight/hosttracker_new/implementation</module>
     <module>opendaylight/containermanager/api</module>
@@ -45,6 +46,7 @@
     <module>opendaylight/connectionmanager/api</module>
     <module>opendaylight/connectionmanager/implementation</module>
     <module>opendaylight/security</module>
+    <module>opendaylight/karaf-tomcat-security</module>
 
     <!-- third-parties uncomment them if you need snapshot version of it -->
     <!-- <module>third-party/openflowj</module> -->
     <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>