<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-akka</artifactId>
<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.1.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.5.0-SNAPSHOT</karaf.resources.version>
+ <branding.version>1.2.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.6.0-SNAPSHOT</karaf.resources.version>
<karaf.version>3.0.3</karaf.version>
- <feature.test.version>0.7.0-SNAPSHOT</feature.test.version>
- <karaf.empty.version>1.5.0-SNAPSHOT</karaf.empty.version>
+ <feature.test.version>0.8.0-SNAPSHOT</feature.test.version>
+ <karaf.empty.version>1.6.0-SNAPSHOT</karaf.empty.version>
<surefire.version>2.16</surefire.version>
</properties>
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-yangtools</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
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.7.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/1.2.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.1.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.yangtools/features-yangtools/0.8.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.controller/features-mdsal/1.3.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.2.0-SNAPSHOT/xml/features</repository>
-->
<feature name='odl-akka-all' version='${project.version}' description='OpenDaylight :: Akka :: All'>
<!--
* Basic MD-SAL Provider
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider '>
- <feature version='1.2.0-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.3.0-SNAPSHOT'>odl-mdsal-broker</feature>
<feature version='${project.version}'>odl-controller-model</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
... whatever other bundles you need
* Basic MD-SAL Model feature
<feature name='odl-controller-model' version='${project.version}' description='OpenDaylight :: controller :: Model'>
- <feature version='0.7.0-SNAPSHOT'>odl-yangtools-binding</feature>
- <feature version='0.7.0-SNAPSHOT'>odl-yangtools-models</feature>
+ <feature version='0.8.0-SNAPSHOT'>odl-yangtools-binding</feature>
+ <feature version='0.8.0-SNAPSHOT'>odl-yangtools-models</feature>
<bundle>mvn:org.opendaylight.controller/controller-model/${project.version}</bundle>
... whatever other bundles you need
</feature>
* Config Subsystem example - the config file is your config subsystem configuration
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider'>
- <feature version='1.2.0-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.3.0-SNAPSHOT'>odl-mdsal-broker</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
<configfile finalname="etc/opendaylight/karaf/80-controller.xml">mvn:org.opendaylight.controller/controller-config/${project.version}/xml/config</configfile>
... whatever other bundles you need
* Basic MD-SAL Provider that uses openflowplugin-flow-services (which brings along odl-mdsal-broker)
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider'>
- <feature version='0.1.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
+ <feature version='0.2.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
... whatever other bundles you need
</feature>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../../opendaylight/config/</relativePath>
</parent>
<artifactId>features-config-netty</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../../opendaylight/config/</relativePath>
</parent>
<artifactId>features-config-persister</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../../opendaylight/config/</relativePath>
</parent>
<artifactId>features-config</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-empty</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-extras</artifactId>
<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.1.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.5.0-SNAPSHOT</karaf.resources.version>
+ <branding.version>1.2.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.6.0-SNAPSHOT</karaf.resources.version>
<karaf.version>3.0.3</karaf.version>
- <karaf.empty.version>1.5.0-SNAPSHOT</karaf.empty.version>
+ <karaf.empty.version>1.6.0-SNAPSHOT</karaf.empty.version>
<surefire.version>2.16</surefire.version>
</properties>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<relativePath>../../opendaylight/md-sal</relativePath>
</parent>
<artifactId>features-mdsal</artifactId>
<feature name='odl-netconf-mdsal' version='${project.version}' description="OpenDaylight :: Netconf :: Mdsal">
<feature version='${config.version}'>odl-config-all</feature>
<feature version='${netconf.version}'>odl-netconf-all</feature>
- <!-- TODO remove dependency on sal netconf connector (odl-yangtools-models, sal-netconf-connector, model-inventory-->
- <feature version='${yangtools.version}'>odl-yangtools-models</feature>
- <bundle>mvn:org.opendaylight.controller/sal-netconf-connector/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller.model/model-inventory/${project.version}</bundle>
+ <feature version='${config.version}'>odl-config-netty</feature>
+ <bundle>mvn:org.opendaylight.controller/netconf-tcp/${netconf.version}</bundle>
<bundle>mvn:org.opendaylight.controller/netconf-ssh/${netconf.version}</bundle>
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
<bundle>mvn:org.opendaylight.controller/mdsal-netconf-connector/${netconf.version}</bundle>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<relativePath>../../opendaylight/md-sal</relativePath>
</parent>
<!--
-->
<artifactId>features-netconf-connector</artifactId>
<!-- Optional TODO: Uncomment version if you are not using a parent pom.xml
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
-->
<packaging>jar</packaging>
<properties>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-yangtools</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<classifier>features</classifier>
<type>xml</type>
</dependency>
- <dependency>
+ <!-- dependency>
<groupId>org.opendaylight.aaa</groupId>
<artifactId>features-aaa</artifactId>
<version>${aaa.version}</version>
<classifier>features</classifier>
<type>xml</type>
- </dependency>
+ </dependency -->
<!--
Necessary TODO: Put dependencies for bundles directly referenced
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.7.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/1.2.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.1.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.yangtools/features-yangtools/0.8.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.controller/features-mdsal/1.3.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.2.0-SNAPSHOT/xml/features</repository>
-->
<repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
<repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
<!-- FIXME: This introduces cycle between projects, which makes version updates
harder. Should be moved to different.
-->
- <repository>mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features</repository>
+ <!-- repository>mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features</repository -->
<feature name='odl-netconf-connector-all' version='${project.version}' description='OpenDaylight :: Netconf Connector :: All'>
<!--
Necessary TODO:
* Basic MD-SAL Provider
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider '>
- <feature version='1.2.0-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.3.0-SNAPSHOT'>odl-mdsal-broker</feature>
<feature version='${project.version}'>odl-controller-model</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
... whatever other bundles you need
* Basic MD-SAL Model feature
<feature name='odl-controller-model' version='${project.version}' description='OpenDaylight :: controller :: Model'>
- <feature version='0.7.0-SNAPSHOT'>odl-yangtools-binding</feature>
- <feature version='0.7.0-SNAPSHOT'>odl-yangtools-models</feature>
+ <feature version='0.8.0-SNAPSHOT'>odl-yangtools-binding</feature>
+ <feature version='0.8.0-SNAPSHOT'>odl-yangtools-models</feature>
<bundle>mvn:org.opendaylight.controller/controller-model/${project.version}</bundle>
... whatever other bundles you need
</feature>
* Config Subsystem example - the config file is your config subsystem configuration
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider'>
- <feature version='1.2.0-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.3.0-SNAPSHOT'>odl-mdsal-broker</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
<configfile finalname="etc/opendaylight/karaf/80-controller.xml">mvn:org.opendaylight.controller/controller-config/${project.version}/xml/config</configfile>
... whatever other bundles you need
* Basic MD-SAL Provider that uses openflowplugin-flow-services (which brings along odl-mdsal-broker)
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider'>
- <feature version='0.1.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
+ <feature version='0.2.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
... whatever other bundles you need
</feature>
<!-- FIXME: This introduces cycle between projects, which makes version updates
harder. Should be moved to different.
-->
- <feature version='${aaa.version}'>odl-aaa-netconf-plugin</feature>
+ <!-- feature version='${aaa.version}'>odl-aaa-netconf-plugin</feature -->
<bundle>mvn:org.opendaylight.controller/netconf-ssh/${netconf.version}</bundle>
</feature>
- <feature name='odl-netconf-tcp' version='${netconf.version}' description="OpenDaylight :: Netconf Connector :: TCP">
+ <feature name='odl-netconf-tcp' version='${netconf.version}' description="OpenDaylight :: Netconf Connector :: TCP">
<feature version='${netconf.version}'>odl-netconf-impl</feature>
+ <feature version='${config.version}'>odl-config-netty</feature>
<bundle>mvn:org.opendaylight.controller/netconf-tcp/${netconf.version}</bundle>
- </feature>
+ </feature>
<feature name='odl-message-bus' version='${project.version}'>
<feature version='${project.version}'>odl-netconf-connector</feature>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../../opendaylight/netconf</relativePath>
</parent>
<artifactId>features-netconf</artifactId>
<bundle>mvn:org.opendaylight.controller/ietf-netconf-monitoring-extension/${project.version}</bundle>
<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>
- <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types-20130715/2013.07.15.7-SNAPSHOT</bundle>
+ <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types-20130715/2013.07.15.8-SNAPSHOT</bundle>
</feature>
<feature name='odl-netconf-mapping-api' version='${project.version}' description="OpenDaylight :: Netconf :: Mapping API">
<feature version='${project.version}'>odl-netconf-api</feature>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-controller</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-protocol-framework</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<relativePath>../../opendaylight/md-sal</relativePath>
</parent>
<!--
<artifactId>features-restconf</artifactId>
<groupId>org.opendaylight.controller</groupId>
<!-- Optional TODO: Uncomment version if you are not using a parent pom.xml
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
-->
<packaging>jar</packaging>
<properties>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-yangtools</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<classifier>features</classifier>
<type>xml</type>
</dependency>
- <dependency>
+ <!-- dependency>
<groupId>org.opendaylight.aaa</groupId>
<artifactId>features-aaa</artifactId>
<version>${aaa.version}</version>
<classifier>features</classifier>
<type>xml</type>
- </dependency>
+ </dependency -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
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.7.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/1.2.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.1.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.yangtools/features-yangtools/0.8.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.controller/features-mdsal/1.3.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.2.0-SNAPSHOT/xml/features</repository>
-->
<repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
<repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features</repository>
+ <!-- repository>mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features</repository -->
<feature name='odl-restconf-all' version='${project.version}' description='OpenDaylight :: Restconf :: All'>
<!--
Necessary TODO:
* Basic MD-SAL Provider
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider '>
- <feature version='1.2.0-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.3.0-SNAPSHOT'>odl-mdsal-broker</feature>
<feature version='${project.version}'>odl-controller-model</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
... whatever other bundles you need
* Basic MD-SAL Model feature
<feature name='odl-controller-model' version='${project.version}' description='OpenDaylight :: controller :: Model'>
- <feature version='0.7.0-SNAPSHOT'>odl-yangtools-binding</feature>
- <feature version='0.7.0-SNAPSHOT'>odl-yangtools-models</feature>
+ <feature version='0.8.0-SNAPSHOT'>odl-yangtools-binding</feature>
+ <feature version='0.8.0-SNAPSHOT'>odl-yangtools-models</feature>
<bundle>mvn:org.opendaylight.controller/controller-model/${project.version}</bundle>
... whatever other bundles you need
</feature>
* Config Subsystem example - the config file is your config subsystem configuration
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider'>
- <feature version='1.2.0-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.3.0-SNAPSHOT'>odl-mdsal-broker</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
<configfile finalname="etc/opendaylight/karaf/80-controller.xml">mvn:org.opendaylight.controller/controller-config/${project.version}/xml/config</configfile>
... whatever other bundles you need
* Basic MD-SAL Provider that uses openflowplugin-flow-services (which brings along odl-mdsal-broker)
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider'>
- <feature version='0.1.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
+ <feature version='0.2.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
<bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
... whatever other bundles you need
</feature>
-->
<feature name='odl-restconf' version='${project.version}' description="OpenDaylight :: Restconf">
- <feature version='${aaa.version}'>odl-aaa-authn</feature>
+ <!-- feature version='${aaa.version}'>odl-aaa-authn</feature -->
<feature version='${mdsal.version}'>odl-restconf-noauth</feature>
</feature>
<feature name='odl-restconf-noauth' version='${project.version}' description="OpenDaylight :: Restconf">
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>itests-controller</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>base-features-it</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>itests-controller</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>releasepom</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>karaf.branding</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>OpenDaylight :: Karaf :: Branding</name>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<properties>
- <branding.version>1.1.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.5.0-SNAPSHOT</karaf.resources.version>
+ <branding.version>1.2.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.6.0-SNAPSHOT</karaf.resources.version>
<karaf.localFeature>standard</karaf.localFeature>
<!-- Karaf Maven plugin 3.023 reinstalls already installed
boot features to container, which could be observed
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>karaf-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../karaf-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-empty</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<name>${project.artifactId}</name>
<prerequisites>
<maven>3.1.1</maven>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>opendaylight-karaf-resources</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>distribution.opendaylight-karaf</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-restconf</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
<scope>runtime</scope>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.parent</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../opendaylight/commons/parent</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../commons/enunciate-parent</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>appauth</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>arphandler</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>clustering.services.integrationtest</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<properties>
<sonar.jacoco.itReportPath>../../implementation/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<!-- Sonar jacoco plugin to get integration test coverage info -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>clustering.services</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>clustering.services-implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<!-- Sonar properties using jacoco to retrieve integration test results -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>clustering.stub</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>clustering.test</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>commons.httpclient</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>configuration</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>configuration.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>configuration.integrationtest</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>connectionmanager</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>connectionmanager.implementation</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager.implementation</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager.shell</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>dummy-console</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<description>Dummy Console Interfaces for Equinox-specific CLI</description>
<build>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-adsal</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-empty</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<!-- Bundle dependencies -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-base</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-empty</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
</dependencies>
<feature>odl-base-jackson</feature>
<feature>odl-base-spring-security</feature>
</feature>
- <feature name="odl-base-dummy-console" description="Temporary Dummy Console" version="1.2.0-SNAPSHOT">
- <bundle>mvn:org.opendaylight.controller/dummy-console/1.2.0-SNAPSHOT</bundle>
+ <feature name="odl-base-dummy-console" description="Temporary Dummy Console" version="1.3.0-SNAPSHOT">
+ <bundle>mvn:org.opendaylight.controller/dummy-console/1.3.0-SNAPSHOT</bundle>
</feature>
<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>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>controller-features</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>extras-features</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-nsf</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-empty</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<!-- Feature Dependencies -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>forwarding.staticrouting</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>forwardingrulesmanager.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>forwardingrulesmanager.integrationtest</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<properties>
<sonar.jacoco.itReportPath>../../implementation/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<!-- Sonar jacoco plugin to get integration test coverage info -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker.implementation</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>hosttracker.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<properties>
<sonar.jacoco.itReportPath>../../implementaiton/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<!-- Sonar jacoco plugin to get integration test coverage info -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker.shell</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker_new</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker_new.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>karaf-tomcat-security</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>logging.bridge</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<groupId>org.opendaylight.controller</groupId>
<artifactId>app-northbound</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<name>app-northbound</name>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../commons/opendaylight</relativePath>
</parent>
<artifactId>bundlescanner</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../commons/opendaylight</relativePath>
</parent>
<artifactId>bundlescanner.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>commons.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>connectionmanager.northbound</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/enunciate-parent</relativePath>
</parent>
<artifactId>containermanager.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>controllermanager.northbound</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>flowprogrammer.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>hosttracker.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>httpservice-bridge</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<description>HttpService bridge web application</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>northbound.integrationtest</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/enunciate-parent</relativePath>
</parent>
<artifactId>northbound.client</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>jolokia-bridge</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<description>Jolokia bridge web application</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>networkconfig.bridgedomain.northbound</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>forwarding.staticrouting.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>statistics.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>subnets.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>swagger-ui</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>switchmanager.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>topology.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/enunciate-parent</relativePath>
</parent>
<artifactId>usermanager.northbound</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../opendaylight/commons/opendaylight</relativePath>
</parent>
<scm>
<groupId>org.opendaylight.controller</groupId>
<artifactId>northboundtest</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.parent</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../commons/parent</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>protocol_plugins.openflow</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>protocol_plugins.stub</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>routing.dijkstra_implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal</artifactId>
- <version>0.9.0-SNAPSHOT</version>
+ <version>0.10.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.connection</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.connection.implementation</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.networkconfiguration</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.networkconfiguration.implementation</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustersession</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>samples.loadbalancer</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>adsal-enunciate-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>samples.loadbalancer.northbound</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>samples.simpleforwarding</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>security</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>statisticsmanager</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<!-- Sonar properties using jacoco to retrieve integration test results -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>statisticsmanager.integrationtest</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<properties>
<sonar.jacoco.itReportPath>../../implementation/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<!-- Sonar jacoco plugin to get integration test coverage info -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>switchmanager</artifactId>
- <version>0.8.0-SNAPSHOT</version>
+ <version>0.9.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>switchmanager.integrationtest</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<properties>
<sonar.jacoco.itReportPath>../../implementation/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<!-- Sonar jacoco plugin to get integration test coverage info -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>topologymanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>topologymanager.integrationtest</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<properties>
<sonar.jacoco.itReportPath>../../implementaiton/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<!-- Sonar jacoco plugin to get integration test coverage info -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>topologymanager.shell</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>usermanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>usermanager.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<scm>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web.brandfragment</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>devices.web</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>flows.web</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>osgi-brandfragment.web</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<description>OSGi management web application brand fragment</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>web</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>topology.web</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>troubleshoot.web</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller.archetypes</groupId>
<artifactId>odl-model-project</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<properties>
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
<nexus.repository.release>opendaylight.release</nexus.repository.release>
<nexus.repository.snapshot>opendaylight.release</nexus.repository.snapshot>
- <yang.version>0.7.0-SNAPSHOT</yang.version>
- <yang.codegen.version>0.7.0-SNAPSHOT</yang.codegen.version>
+ <yang.version>0.8.0-SNAPSHOT</yang.version>
+ <yang.codegen.version>0.8.0-SNAPSHOT</yang.codegen.version>
<bundle.plugin.version>2.3.7</bundle.plugin.version>
</properties>
<scm>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-configfile-archetype</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<parent>
<groupId>org.opendaylight.controller.archetypes</groupId>
<artifactId>archetypes-parent</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-distro-archetype</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<name>distribution-karaf-archetype</name>
<properties>
<!-- Optional TODO: Move these properties to your parent pom and possibly
DependencyManagement section of your parent pom -->
- <branding.version>1.1.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.5.0-SNAPSHOT</karaf.resources.version>
+ <branding.version>1.2.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.6.0-SNAPSHOT</karaf.resources.version>
<karaf.version>3.0.3</karaf.version>
</properties>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
<scope>runtime</scope>
<parent>
<groupId>org.opendaylight.controller.archetypes</groupId>
<artifactId>archetypes-parent</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-features-archetype</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<name>opendaylight-karaf-features-archetype</name>
<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.1.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.5.0-SNAPSHOT</karaf.resources.version>
+ <branding.version>1.2.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.6.0-SNAPSHOT</karaf.resources.version>
<karaf.version>3.0.3</karaf.version>
- <feature.test.version>1.5.0-SNAPSHOT</feature.test.version>
- <karaf.empty.version>1.5.0-SNAPSHOT</karaf.empty.version>
+ <feature.test.version>1.6.0-SNAPSHOT</feature.test.version>
+ <karaf.empty.version>1.6.0-SNAPSHOT</karaf.empty.version>
<surefire.version>2.16</surefire.version>
</properties>
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-yangtools</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
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.7.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/1.2.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.1.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.yangtools/features-yangtools/0.8.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.controller/features-mdsal/1.3.0-SNAPSHOT/xml/features</repository>
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.2.0-SNAPSHOT/xml/features</repository>
-->
<feature name='odl-${repoName}-all' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${repoName} :: All'>
<!--
* Basic MD-SAL Provider
<feature name='odl-${repoName}-provider' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${repoName} :: Provider '>
- <feature version='1.2.0-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.3.0-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
* Basic MD-SAL Model feature
<feature name='odl-${repoName}-model' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${repoName} :: Model'>
- <feature version='0.7.0-SNAPSHOT'>odl-yangtools-binding</feature>
- <feature version='0.7.0-SNAPSHOT'>odl-yangtools-models</feature>
+ <feature version='0.8.0-SNAPSHOT'>odl-yangtools-binding</feature>
+ <feature version='0.8.0-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.2.0-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.3.0-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
* 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.1.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
+ <feature version='0.2.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
<bundle>mvn:${groupId}/${repoName}-provider/${symbol_dollar}{project.version}</bundle>
... whatever other bundles you need
</feature>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-startup-archetype</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<name>${project.artifactId}</name>
<parent>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-parent</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>features-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath/>
</parent>
<groupId>${groupId}</groupId>
<maven>3.1.1</maven>
</prerequisites>
<properties>
- <mdsal.version>1.2.0-SNAPSHOT</mdsal.version>
- <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+ <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
+ <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
<configfile.directory>etc/opendaylight/karaf</configfile.directory>
</properties>
<dependencyManagement>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>karaf-parent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
</parent>
<groupId>${groupId}</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<scm>
</scm>
<groupId>org.opendaylight.controller.archetypes</groupId>
<artifactId>archetypes-parent</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>pom</packaging>
<distributionManagement>
<!-- OpenDayLight Released artifact -->
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>concepts</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../opendaylight</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../opendaylight</relativePath>
</parent>
<artifactId>filter-valve</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../opendaylight</relativePath>
</parent>
<artifactId>liblldp</artifactId>
- <version>0.9.0-SNAPSHOT</version>
+ <version>0.10.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
</dependencies>
<build>
<configuration>
<instructions>
<Import-Package>org.slf4j,
- org.apache.commons.lang3.builder,
- org.apache.commons.lang3.tuple
+ org.apache.commons.lang3.*,
+ com.google.common.*
</Import-Package>
<Export-Package>
org.opendaylight.controller.liblldp</Export-Package>
--- /dev/null
+/**
+ *
+ */
+package org.opendaylight.controller.liblldp;
+
+public class CustomTLVKey {
+
+ private int oui;
+ private byte subtype;
+
+ /**
+ * @param oui
+ * @param subtype
+ */
+ public CustomTLVKey(int oui, byte subtype) {
+ this.oui = oui;
+ this.subtype = subtype;
+ }
+
+ /**
+ * @return the oui
+ */
+ public int getOui() {
+ return oui;
+ }
+ /**
+ * @return the subtype
+ */
+ public byte getSubtype() {
+ return subtype;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + oui;
+ result = prime * result + subtype;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ CustomTLVKey other = (CustomTLVKey) obj;
+ if (oui != other.oui) {
+ return false;
+ }
+
+ if (subtype != other.subtype) {
+ return false;
+ }
+
+ return true;
+ }
+
+
+}
package org.opendaylight.controller.liblldp;
-import java.util.ArrayList;
+import com.google.common.collect.Iterables;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
private static final String SYSTEMNAMEID = "SystemNameID";
private static final String PORTID = "PortId";
private static final String TTL = "TTL";
- private static final int LLDPDefaultTlvs = 4;
- private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short) 0)
- .setType((byte) 0);
- public static final byte[] LLDPMulticastMac = { 1, (byte) 0x80,
- (byte) 0xc2, 0, 0, (byte) 0xe };
- private Map<Byte, LLDPTLV> tlvList;
+ private static final int LLDPDefaultTlvs = 3;
+ private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short) 0).setType((byte) 0);
+ public static final byte[] LLDPMulticastMac = { 1, (byte) 0x80, (byte) 0xc2, 0, 0, (byte) 0xe };
+
+ private Map<Byte, LLDPTLV> mandatoryTLVs;
+ private Map<Byte, LLDPTLV> optionalTLVs;
+ private Map<CustomTLVKey, LLDPTLV> customTLVs;
/**
* Default constructor that creates the tlvList LinkedHashMap
*/
public LLDP() {
super();
- tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs);
+ init();
}
/**
- * Constructor that creates the tlvList LinkedHashMap and sets the write
- * access for the same
+ * Constructor that creates the tlvList LinkedHashMap and sets the write access for the same
*/
public LLDP(boolean writeAccess) {
super(writeAccess);
- tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs); // Mandatory
- // TLVs
+ init();
+ }
+
+ private void init() {
+ mandatoryTLVs = new LinkedHashMap<>(LLDPDefaultTlvs);
+ optionalTLVs = new LinkedHashMap<>();
+ customTLVs = new LinkedHashMap<>();
}
/**
return LLDPTLV.TLVType.PortID.getValue();
} else if (typeDesc.equals(TTL)) {
return LLDPTLV.TLVType.TTL.getValue();
+ } else if (typeDesc.equals(SYSTEMNAMEID)) {
+ return LLDPTLV.TLVType.SystemName.getValue();
} else {
return LLDPTLV.TLVType.Unknown.getValue();
}
}
+ private LLDPTLV getFromTLVs(Byte type) {
+ LLDPTLV tlv = null;
+ tlv = mandatoryTLVs.get(type);
+ if (tlv == null) {
+ tlv = optionalTLVs.get(type);
+ }
+ return tlv;
+ }
+
+ private void putToTLVs(final Byte type, final LLDPTLV tlv) {
+ if (type == LLDPTLV.TLVType.ChassisID.getValue() || type == LLDPTLV.TLVType.PortID.getValue()
+ || type == LLDPTLV.TLVType.TTL.getValue()) {
+ mandatoryTLVs.put(type, tlv);
+ } else if (type != LLDPTLV.TLVType.Custom.getValue()) {
+ optionalTLVs.put(type, tlv);
+ }
+ }
+
/**
* @param String
* - description of the type of TLV
* @return LLDPTLV - full TLV
*/
public LLDPTLV getTLV(String type) {
- return tlvList.get(getType(type));
+ return getFromTLVs(getType(type));
+ }
+
+ public LLDPTLV getCustomTLV(CustomTLVKey key) {
+ return customTLVs.get(key);
}
/**
* @return void
*/
public void setTLV(String type, LLDPTLV tlv) {
- tlvList.put(getType(type), tlv);
+ putToTLVs(getType(type), tlv);
}
/**
* - the chassisId to set
*/
public LLDP setChassisId(LLDPTLV chassisId) {
- tlvList.put(getType(CHASSISID), chassisId);
+ setTLV(CHASSISID, chassisId);
return this;
}
* - the chassisId to set
*/
public LLDP setSystemNameId(LLDPTLV systemNameId) {
- tlvList.put(getType(SYSTEMNAMEID), systemNameId);
+ setTLV(SYSTEMNAMEID, systemNameId);
return this;
}
* @return LLDPTLV - the portId TLV
*/
public LLDPTLV getPortId() {
- return tlvList.get(getType(PORTID));
+ return getTLV(PORTID);
}
/**
* @return LLDP
*/
public LLDP setPortId(LLDPTLV portId) {
- tlvList.put(getType(PORTID), portId);
+ setTLV(PORTID, portId);
return this;
}
* @return LLDPTLV - the ttl TLV
*/
public LLDPTLV getTtl() {
- return tlvList.get(getType(TTL));
+ return getTLV(TTL);
}
/**
* @return LLDP
*/
public LLDP setTtl(LLDPTLV ttl) {
- tlvList.put(getType(TTL), ttl);
+ setTLV(TTL, ttl);
return this;
}
/**
* @return the optionalTLVList
*/
- public List<LLDPTLV> getOptionalTLVList() {
- List<LLDPTLV> list = new ArrayList<LLDPTLV>();
- for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
- byte type = entry.getKey();
- if ((type == LLDPTLV.TLVType.ChassisID.getValue())
- || (type == LLDPTLV.TLVType.PortID.getValue())
- || (type == LLDPTLV.TLVType.TTL.getValue())) {
- continue;
- } else {
- list.add(entry.getValue());
- }
- }
- return list;
+ public Iterable<LLDPTLV> getOptionalTLVList() {
+ return optionalTLVs.values();
+ }
+
+ /**
+ * @return the customTlvList
+ */
+ public Iterable<LLDPTLV> getCustomTlvList() {
+ return customTLVs.values();
}
/**
*/
public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
for (LLDPTLV tlv : optionalTLVList) {
- tlvList.put(tlv.getType(), tlv);
+ optionalTLVs.put(tlv.getType(), tlv);
}
return this;
}
+ /**
+ * @param customTLVList
+ * the list of custom TLVs to set
+ * @return this LLDP
+ */
+ public LLDP addCustomTLV(final LLDPTLV customTLV) {
+ CustomTLVKey key = new CustomTLVKey(LLDPTLV.extractCustomOUI(customTLV),
+ LLDPTLV.extractCustomSubtype(customTLV));
+ customTLVs.put(key, customTLV);
+
+ return this;
+ }
+
@Override
- public Packet deserialize(byte[] data, int bitOffset, int size)
- throws PacketException {
+ public Packet deserialize(byte[] data, int bitOffset, int size) throws PacketException {
int lldpOffset = bitOffset; // LLDP start
int lldpSize = size; // LLDP size
if (logger.isTraceEnabled()) {
- logger.trace("LLDP: {} (offset {} bitsize {})", new Object[] {
- HexEncode.bytesToHexString(data), lldpOffset, lldpSize });
+ logger.trace("LLDP: {} (offset {} bitsize {})", new Object[] { HexEncode.bytesToHexString(data),
+ lldpOffset, lldpSize });
}
/*
* Deserialize the TLVs until we reach the end of the packet
LLDPTLV tlv = new LLDPTLV();
tlv.deserialize(data, lldpOffset, lldpSize);
if (tlv.getType() == 0 && tlv.getLength() == 0) {
- break;
+ break;
}
int tlvSize = tlv.getTLVSize(); // Size of current TLV in bits
lldpOffset += tlvSize;
lldpSize -= tlvSize;
- this.tlvList.put(tlv.getType(), tlv);
+ if (tlv.getType() == LLDPTLV.TLVType.Custom.getValue()) {
+ addCustomTLV(tlv);
+ } else {
+ this.putToTLVs(tlv.getType(), tlv);
+ }
}
return this;
}
int startOffset = 0;
byte[] serializedBytes = new byte[getLLDPPacketLength()];
- for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
- LLDPTLV tlv = entry.getValue();
+ final Iterable<LLDPTLV> allTlvs = Iterables.concat(mandatoryTLVs.values(), optionalTLVs.values(), customTLVs.values());
+ for (LLDPTLV tlv : allTlvs) {
int numBits = tlv.getTLVSize();
try {
- BitBufferHelper.setBytes(serializedBytes, tlv.serialize(),
- startOffset, numBits);
+ BitBufferHelper.setBytes(serializedBytes, tlv.serialize(), startOffset, numBits);
} catch (BufferException e) {
throw new PacketException(e.getMessage());
}
}
// Now add the empty LLDPTLV at the end
try {
- BitBufferHelper.setBytes(serializedBytes,
- LLDP.emptyTLV.serialize(), startOffset,
+ BitBufferHelper.setBytes(serializedBytes, LLDP.emptyTLV.serialize(), startOffset,
LLDP.emptyTLV.getTLVSize());
} catch (BufferException e) {
throw new PacketException(e.getMessage());
}
if (logger.isTraceEnabled()) {
- logger.trace("LLDP: serialized: {}",
- HexEncode.bytesToHexString(serializedBytes));
+ logger.trace("LLDP: serialized: {}", HexEncode.bytesToHexString(serializedBytes));
}
return serializedBytes;
}
*/
private int getLLDPPacketLength() {
int len = 0;
- LLDPTLV tlv;
- for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
- tlv = entry.getValue();
- len += tlv.getTLVSize();
+ for (LLDPTLV lldptlv : Iterables.concat(mandatoryTLVs.values(), optionalTLVs.values(), customTLVs.values())) {
+ len += lldptlv.getTLVSize();
}
+
len += LLDP.emptyTLV.getTLVSize();
return len / NetUtils.NumBitsInAByte;
package org.opendaylight.controller.liblldp;
+import org.apache.commons.lang3.ArrayUtils;
+import org.slf4j.LoggerFactory;
+
+import org.slf4j.Logger;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
-
import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.Pair;
private static final String LENGTH = "Length";
private static final String VALUE = "Value";
private static final int LLDPTLVFields = 3;
+
+ /** OpenFlow OUI */
public static final byte[] OFOUI = new byte[] { (byte) 0x00, (byte) 0x26,
- (byte) 0xe1 }; // OpenFlow OUI
- public static final byte[] customTlvSubType = new byte[] { 0 };
- public static final int customTlvOffset = OFOUI.length
- + customTlvSubType.length;
+ (byte) 0xe1 };
+
+ /** Length of Organizationally defined subtype field of TLV in bytes */
+ private static final byte customTlvSubTypeLength = (byte)1;
+
+ /** OpenFlow subtype: nodeConnectorId of source */
+ public static final byte[] CUSTOM_TLV_SUB_TYPE_NODE_CONNECTOR_ID = new byte[] { 0 };
+
+ /** OpenFlow subtype: custom sec = hash code of verification of origin of LLDP */
+ public static final byte[] CUSTOM_TLV_SUB_TYPE_CUSTOM_SEC = new byte[] { 1 };
+
+ public static final int customTlvOffset = OFOUI.length + customTlvSubTypeLength;
public static final byte chassisIDSubType[] = new byte[] { 4 }; // MAC address for the system
public static final byte portIDSubType[] = new byte[] { 7 }; // locally assigned
+ private static final Logger LOG = LoggerFactory.getLogger(LLDPTLV.class);
+
public enum TLVType {
Unknown((byte) 0), ChassisID((byte) 1), PortID((byte) 2), TTL((byte) 3), PortDesc(
(byte) 4), SystemName((byte) 5), SystemDesc((byte) 6), Custom(
* @param portId
* port identifier string
* @return the custom TLV value in byte array
+ * @see {@link #createCustomTLVValue(byte,String)}
*/
static public byte[] createCustomTLVValue(String customString) {
- byte[] customArray = customString.getBytes(Charset.defaultCharset());
- byte[] customValue = new byte[customTlvOffset + customArray.length];
+ byte[] customByteArray = customString.getBytes(Charset.defaultCharset());
+ return createCustomTLVValue(CUSTOM_TLV_SUB_TYPE_NODE_CONNECTOR_ID, customByteArray);
+ }
+
+ /**
+ * Creates the custom TLV value including OUI, subtype and custom string
+ * @param subtype openflow subtype
+ * @param portId
+ * port identifier string
+ * @return the custom TLV value in byte array
+ */
+ static public byte[] createCustomTLVValue(byte[] subtype, byte[] customByteArray) {
+ byte[] customValue = new byte[customTlvOffset + customByteArray.length];
System.arraycopy(OFOUI, 0, customValue, 0, OFOUI.length);
- System.arraycopy(customTlvSubType, 0, customValue, OFOUI.length,
- customTlvSubType.length);
- System.arraycopy(customArray, 0, customValue, customTlvOffset,
- customArray.length);
+ System.arraycopy(subtype, 0, customValue, OFOUI.length, 1);
+ System.arraycopy(customByteArray, 0, customValue, customTlvOffset,
+ customByteArray.length);
return customValue;
}
return customString;
}
+
+ public static int extractCustomOUI(final LLDPTLV lldptlv) {
+ byte[] value = lldptlv.getValue();
+ return BitBufferHelper.getInt(ArrayUtils.subarray(value, 0, 3));
+ }
+
+ public static byte extractCustomSubtype(final LLDPTLV lldptlv) {
+ byte[] value = lldptlv.getValue();
+ return BitBufferHelper.getByte(ArrayUtils.subarray(value, 3, 4));
+ }
}
--- /dev/null
+/**
+ * Copyright (c) 2015 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.liblldp;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.BaseEncoding;
+import com.google.common.primitives.Bytes;
+
+/**
+ *
+ */
+public class LLDPTLVTest {
+
+ /** dummy custom tlv value */
+ private static final String CUSTOM_TLV_ULTIMATE = "What do you get when you multiply 6 by 9?";
+ /** dummy custom tlv value in binary form */
+ private static final byte[] CUSTOM_TLV_ULTIMATE_BIN = new byte[] {
+ 0x57, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x67, 0x65, 0x74,
+ 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69,
+ 0x70, 0x6c, 0x79, 0x20, 0x36, 0x20, 0x62, 0x79, 0x20, 0x39, 0x3f
+ };
+
+ private static final Logger LOG = LoggerFactory.getLogger(LLDPTLVTest.class);
+
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.liblldp.LLDPTLV#createCustomTLVValue(java.lang.String)}
+ * .
+ */
+ @Test
+ public void testCreateCustomTLVValue() {
+ byte[] tlv = LLDPTLV.createCustomTLVValue(CUSTOM_TLV_ULTIMATE);
+
+ byte[] expectedCustomTlv = Bytes.concat(new byte[] {
+ // custom type (7b) + length (9b) = 16b = 2B (skipped)
+ // 0x7f, 24,
+ // openflow OUI
+ 0x00, 0x26, (byte) 0xe1,
+ // subtype
+ 0x00},
+ // custom value
+ CUSTOM_TLV_ULTIMATE_BIN);
+
+ BaseEncoding be = BaseEncoding.base16().withSeparator(" ", 2).lowerCase();
+ LOG.debug("expected: {}", be.encode(expectedCustomTlv));
+ LOG.debug("actual : {}", be.encode(tlv));
+ Assert.assertArrayEquals(expectedCustomTlv, tlv);
+ }
+
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.liblldp.LLDPTLV#getCustomString(byte[], int)}
+ * .
+ * @throws Exception
+ */
+ @Test
+ public void testGetCustomString() throws Exception {
+ byte[] inputCustomTlv = Bytes.concat(new byte[] {
+ // custom type (7b) + length (9b) = 16b = 2B (skipped)
+ // 0x7f, 24,
+ // openflow OUI
+ 0x00, 0x26, (byte) 0xe1,
+ // subtype
+ 0x00},
+ // custom value
+ CUSTOM_TLV_ULTIMATE_BIN);
+
+ String actual = LLDPTLV.getCustomString(inputCustomTlv, inputCustomTlv.length);
+ LOG.debug("actual custom TLV value as string: {}", actual);
+ Assert.assertEquals(CUSTOM_TLV_ULTIMATE, actual);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.liblldp;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.internal.ArrayComparisonFailure;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.primitives.Bytes;
+
+/**
+ * Test of {@link LLDP} serialization feature (TODO: and deserialization)
+ */
+public class LLDPTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LLDPTest.class);
+
+ private static final byte[] CHASSIS_ID_VALUE = "chassis".getBytes();
+ private static final short CHASSIS_ID_LENGTH = (short) CHASSIS_ID_VALUE.length;
+
+ private static final byte[] TTL_VALUE = new byte[] { (byte) 0, (byte) 100 };
+ private static final short TTL_LENGTH = (short) TTL_VALUE.length;
+
+ private static final byte[] PORT_VALUE = "dummy port id".getBytes();
+ private static final short PORT_LENGTH = (short) PORT_VALUE.length;
+
+ private static final byte[] SYSTEM_NAME_VALUE = "dummy system name".getBytes();
+ private static final short SYSTEM_NAME_LENGTH = (short) SYSTEM_NAME_VALUE.length;
+
+ private static final byte SYSTEM_CAPABILITIES_TLV = 8;
+ private static final byte[] SYSTEM_CAPABILITIES_VALUE = "dummy system capabilities".getBytes();
+ private static final short SYSTEM_CAPABILITIES_LENGTH = (short) SYSTEM_CAPABILITIES_VALUE.length;
+
+ private static final byte[] OUI = LLDPTLV.OFOUI;
+
+ private static final byte[] OUI_SUBTYPE_A = new byte[] { (byte) 0 };
+ private static final byte[] CUSTOM_SUBTYPE_A_VALUE = "first custom value A".getBytes();
+ private static final short CUSTOM_SUBTYPE_A_LENGTH = (short) (OUI.length + OUI_SUBTYPE_A.length + CUSTOM_SUBTYPE_A_VALUE.length);
+
+ private static final byte[] OUI_SUBTYPE_B = new byte[] { (byte) 1 };
+ private static final byte[] CUSTOM_SUBTYPE_B_VALUE = "second custom value B".getBytes();
+ private static final short CUSTOM_SUBTYPE_B_LENGTH = (short) (OUI.length + OUI_SUBTYPE_B.length + CUSTOM_SUBTYPE_B_VALUE.length);
+
+ private static final byte[] BYTES_BEFORE_CUSTOM_A = new byte[] { 0x00, 0x26, (byte) 0xe1, OUI_SUBTYPE_A[0] };
+ private static final byte[] BYTES_BEFORE_CUSTOM_B = new byte[] { 0x00, 0x26, (byte) 0xe1, OUI_SUBTYPE_B[0] };
+ private LLDP lldpBuilder;
+
+ @Before
+ public void setup() {
+ lldpBuilder = new LLDP();
+ }
+
+ /**
+ * Tests whether serialization of LLDP packet is correct
+ *
+ * @see LLDP#serialize()
+ * @throws PacketException
+ */
+ @Test
+ public void testSerialize() throws PacketException {
+ lldpBuilder.setChassisId(dummyTlv(LLDPTLV.TLVType.ChassisID.getValue(), CHASSIS_ID_LENGTH, CHASSIS_ID_VALUE));
+ lldpBuilder.setTtl(dummyTlv(LLDPTLV.TLVType.TTL.getValue(), TTL_LENGTH, TTL_VALUE));
+ lldpBuilder.setPortId(dummyTlv(LLDPTLV.TLVType.PortID.getValue(), PORT_LENGTH, PORT_VALUE));
+ lldpBuilder.setSystemNameId(dummyTlv(LLDPTLV.TLVType.SystemName.getValue(), SYSTEM_NAME_LENGTH,
+ SYSTEM_NAME_VALUE));
+
+ // adding optional TLVs for which doesn't exist special set* methods in LLDP
+ final List<LLDPTLV> optionalTLVs = new ArrayList<>();
+ // System Capabilities TLV (type = 7)
+ optionalTLVs.add(dummyTlv(SYSTEM_CAPABILITIES_TLV, SYSTEM_CAPABILITIES_LENGTH, SYSTEM_CAPABILITIES_VALUE));
+ lldpBuilder.setOptionalTLVList(optionalTLVs);
+
+ // adding custom TLVs
+ lldpBuilder.addCustomTLV(dummyCustomTlv(LLDPTLV.TLVType.Custom.getValue(), OUI, OUI_SUBTYPE_A,
+ CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE));
+ lldpBuilder.addCustomTLV(dummyCustomTlv(LLDPTLV.TLVType.Custom.getValue(), OUI, OUI_SUBTYPE_B,
+ CUSTOM_SUBTYPE_B_LENGTH, CUSTOM_SUBTYPE_B_VALUE));
+
+ byte[] serialized = lldpBuilder.serialize();
+
+ int offset = 0;
+ offset = checkTLV(serialized, offset, (byte) 0b00000010, "ChassisID", CHASSIS_ID_LENGTH, CHASSIS_ID_VALUE);
+ offset = checkTLV(serialized, offset, (byte) 0b00000110, "TTL", TTL_LENGTH, TTL_VALUE);
+ offset = checkTLV(serialized, offset, (byte) 0b00000100, "PortID", PORT_LENGTH, PORT_VALUE);
+ offset = checkTLV(serialized, offset, (byte) 0b00001010, "SystemName", SYSTEM_NAME_LENGTH,
+ SYSTEM_NAME_VALUE);
+ offset = checkTLV(serialized, offset, (byte) 0b00010000, "System capabilities",
+ SYSTEM_CAPABILITIES_LENGTH, SYSTEM_CAPABILITIES_VALUE);
+ offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype A",
+ CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE, OUI[0], OUI[1], OUI[2],
+ OUI_SUBTYPE_A[0]);
+ offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype B",
+ CUSTOM_SUBTYPE_B_LENGTH, CUSTOM_SUBTYPE_B_VALUE, OUI[0], OUI[1], OUI[2],
+ OUI_SUBTYPE_B[0]);
+
+ }
+
+ /**
+ * Tests whether serialization of LLDP packet is correct
+ *
+ * @see LLDP#deserialize(byte[], int, int)
+ * @throws Exception
+ */
+ @Test
+ public void testDeserialize() throws Exception {
+
+ byte[] rawLldpTlv = Bytes.concat(
+ awaitedBytes((byte) 0b00000010, CHASSIS_ID_LENGTH, CHASSIS_ID_VALUE, null),
+ awaitedBytes((byte) 0b00000110, TTL_LENGTH, TTL_VALUE, null),
+ awaitedBytes((byte) 0b00000100, PORT_LENGTH, PORT_VALUE, null),
+ awaitedBytes((byte) 0b00001010, SYSTEM_NAME_LENGTH, SYSTEM_NAME_VALUE, null),
+ awaitedBytes((byte) 0b00010010, SYSTEM_CAPABILITIES_LENGTH,
+ SYSTEM_CAPABILITIES_VALUE, null),
+ awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE,
+ BYTES_BEFORE_CUSTOM_A),
+ awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_B_LENGTH, CUSTOM_SUBTYPE_B_VALUE,
+ BYTES_BEFORE_CUSTOM_B));
+
+ lldpBuilder.deserialize(rawLldpTlv, 0, rawLldpTlv.length * NetUtils.NumBitsInAByte);
+ Assert.assertEquals("chassis", new String(lldpBuilder.getChassisId().getValue()));
+ Assert.assertArrayEquals(TTL_VALUE, lldpBuilder.getTtl().getValue());
+ Assert.assertEquals("dummy port id", new String(lldpBuilder.getPortId().getValue()));
+ Assert.assertEquals("dummy system name", new String(lldpBuilder.getSystemNameId().getValue()));
+
+ // optional items check
+ Iterator<LLDPTLV> iteratorTlvOptional = lldpBuilder.getOptionalTLVList().iterator();
+
+ assertTrue(iteratorTlvOptional.hasNext());
+ LLDPTLV item0 = iteratorTlvOptional.next();
+ Assert.assertEquals(5, item0.getType());
+ Assert.assertEquals("dummy system name", new String(item0.getValue()));
+ assertTrue(iteratorTlvOptional.hasNext());
+
+ assertTrue(iteratorTlvOptional.hasNext());
+ LLDPTLV item1 = iteratorTlvOptional.next();
+ Assert.assertEquals(9, item1.getType());
+ Assert.assertEquals("dummy system capabilities", new String(item1.getValue()));
+ assertFalse(iteratorTlvOptional.hasNext());
+
+ // custom items check
+ Iterable<LLDPTLV> customTlvs = lldpBuilder.getCustomTlvList();
+ Iterator<LLDPTLV> iteratorLLDPTLV = customTlvs.iterator();
+ assertEquals(true, iteratorLLDPTLV.hasNext());
+ checkCustomTlv(iteratorLLDPTLV.next(), "first custom value A");
+ assertEquals(true, iteratorLLDPTLV.hasNext());
+ checkCustomTlv(iteratorLLDPTLV.next(), "second custom value B");
+ assertEquals(false, iteratorLLDPTLV.hasNext());
+ }
+
+ /**
+ * Test of {@link LLDP#addCustomTLV(LLDPTLV)}
+ * @throws PacketException
+ */
+ @Test
+ public void testAddCustomTLV() throws PacketException {
+ byte[] customA = awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE,
+ BYTES_BEFORE_CUSTOM_A);
+ byte[] customB = awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_B_LENGTH, CUSTOM_SUBTYPE_B_VALUE,
+ BYTES_BEFORE_CUSTOM_B);
+
+ Packet lldptlvA = new LLDPTLV().deserialize(customA, 0, customA.length);
+ assertTrue(lldptlvA instanceof LLDPTLV);
+ Packet lldptlvB = new LLDPTLV().deserialize(customB, 0, customB.length);
+ assertTrue(lldptlvB instanceof LLDPTLV);
+
+ lldpBuilder.addCustomTLV((LLDPTLV) lldptlvA);
+ lldpBuilder.addCustomTLV((LLDPTLV) lldptlvB);
+
+ Iterator<LLDPTLV> customTLVsIterator = lldpBuilder.getCustomTlvList().iterator();
+ assertTrue(customTLVsIterator.hasNext());
+ customTLVsIterator.next();
+ assertTrue(customTLVsIterator.hasNext());
+ customTLVsIterator.next();
+ assertFalse(customTLVsIterator.hasNext());
+ }
+
+ @Test
+ public void testGetCustomTLV() throws PacketException {
+ int ouiInt = BitBufferHelper.getInt(OUI);
+ CustomTLVKey key = new CustomTLVKey(ouiInt, OUI_SUBTYPE_A[0]);
+ LLDPTLV customTLV = lldpBuilder.getCustomTLV(key);
+ assertNull(customTLV);
+
+ byte[] customA = awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE,
+ BYTES_BEFORE_CUSTOM_A);
+ lldpBuilder.deserialize(customA, 0, customA.length);
+
+ customTLV = lldpBuilder.getCustomTLV(key);
+ assertNotNull(customTLV);
+ assertEquals(ouiInt, LLDPTLV.extractCustomOUI(customTLV));
+ assertEquals(OUI_SUBTYPE_A[0], LLDPTLV.extractCustomSubtype(customTLV));
+ }
+
+ /**
+ * @param customItem
+ * @param expectedValue
+ */
+ private static void checkCustomTlv(LLDPTLV customItem, String expectedValue) {
+ Assert.assertEquals(127, customItem.getType());
+ LOG.debug("custom TLV1.length: {}", customItem.getLength());
+ Assert.assertEquals(expectedValue,
+ new String(
+ LLDPTLV.getCustomString(
+ customItem.getValue(),
+ customItem.getLength()))
+ );
+ }
+
+ private static int checkTLV(byte[] serializedData, int offset, byte typeTLVBits, String typeTLVName, short lengthTLV,
+ byte[] valueTLV, byte... bytesBeforeValue) throws ArrayComparisonFailure {
+ byte[] concreteTlvAwaited = awaitedBytes(typeTLVBits, lengthTLV, valueTLV, bytesBeforeValue);
+ int concreteTlvAwaitLength = concreteTlvAwaited.length;
+ assertArrayEquals("Serialization problem " + typeTLVName, concreteTlvAwaited,
+ ArrayUtils.subarray(serializedData, offset, offset + concreteTlvAwaitLength));
+ return offset + concreteTlvAwaitLength;
+ }
+
+ private static byte[] awaitedBytes(byte typeTLV, short length, byte[] value, byte[] bytesBeforeValue) {
+ byte[] awaited = ArrayUtils.EMPTY_BYTE_ARRAY;
+
+ // 0 - the less meaning byte (right), 1 most meaning byte (left)
+ byte lengthByte0 = (byte) length;
+ byte lengthByte1 = (byte) (length >> 8);
+
+ awaited = ArrayUtils.addAll(awaited, (byte) (typeTLV | lengthByte1), lengthByte0);
+ awaited = ArrayUtils.addAll(awaited, bytesBeforeValue);
+ awaited = ArrayUtils.addAll(awaited, value);
+ return awaited;
+ }
+
+ private static LLDPTLV dummyCustomTlv(final byte tlvType, byte[] oui, byte[] ouiSubtype, short customLength,
+ byte[] subtypeValue) {
+ byte[] fullCustomValue = new byte[0];
+ fullCustomValue = ArrayUtils.addAll(fullCustomValue, oui);
+ fullCustomValue = ArrayUtils.addAll(fullCustomValue, ouiSubtype);
+ fullCustomValue = ArrayUtils.addAll(fullCustomValue, subtypeValue);
+ return dummyTlv(tlvType, customLength, fullCustomValue);
+ }
+
+ private static LLDPTLV dummyTlv(final byte concreteTlv, final short concreteLength, final byte[] concreteValue) {
+ LLDPTLV tlv = new LLDPTLV();
+ tlv.setType(concreteTlv).setLength(concreteLength).setValue(concreteValue);
+ return tlv;
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">\r
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">\r
+\r
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">\r
+ <layout class="org.apache.log4j.PatternLayout">\r
+ <param name="ConversionPattern" value="%-6p %d{HH:mm:ss.SSS} [%10.10t] %30.30c %x - %m%n" />\r
+ </layout>\r
+ </appender>\r
+\r
+ <logger name="org.opendaylight.controller.liblldp" additivity="false">\r
+ <level value="DEBUG" />\r
+ <appender-ref ref="console" />\r
+ </logger>\r
+\r
+ <root>\r
+ <priority value="INFO" />\r
+ <appender-ref ref="console" />\r
+ </root>\r
+</log4j:configuration>\r
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.parent</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../parent</relativePath>
</parent>
<artifactId>commons.logback_settings</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
- <akka.version>2.3.9</akka.version>
- <appauth.version>0.5.0-SNAPSHOT</appauth.version>
- <archetype-app-northbound>0.1.0-SNAPSHOT</archetype-app-northbound>
- <arphandler.version>0.6.0-SNAPSHOT</arphandler.version>
+ <akka.version>2.3.10</akka.version>
+ <appauth.version>0.6.0-SNAPSHOT</appauth.version>
+ <archetype-app-northbound>0.2.0-SNAPSHOT</archetype-app-northbound>
+ <arphandler.version>0.7.0-SNAPSHOT</arphandler.version>
<!-- Plugin Versions -->
- <bundlescanner.api.version>0.5.0-SNAPSHOT</bundlescanner.api.version>
- <bundlescanner.implementation.version>0.5.0-SNAPSHOT</bundlescanner.implementation.version>
- <bundlescanner.version>0.5.0-SNAPSHOT</bundlescanner.version>
- <clustering.services.version>0.6.0-SNAPSHOT</clustering.services.version>
- <clustering.services_implementation.version>0.5.0-SNAPSHOT</clustering.services_implementation.version>
- <clustering.stub.version>0.5.0-SNAPSHOT</clustering.stub.version>
- <clustering.test.version>0.5.0-SNAPSHOT</clustering.test.version>
- <commmons.northbound.version>0.5.0-SNAPSHOT</commmons.northbound.version>
+ <bundlescanner.api.version>0.6.0-SNAPSHOT</bundlescanner.api.version>
+ <bundlescanner.implementation.version>0.6.0-SNAPSHOT</bundlescanner.implementation.version>
+ <bundlescanner.version>0.6.0-SNAPSHOT</bundlescanner.version>
+ <clustering.services.version>0.7.0-SNAPSHOT</clustering.services.version>
+ <clustering.services_implementation.version>0.6.0-SNAPSHOT</clustering.services_implementation.version>
+ <clustering.stub.version>0.6.0-SNAPSHOT</clustering.stub.version>
+ <clustering.test.version>0.6.0-SNAPSHOT</clustering.test.version>
+ <commmons.northbound.version>0.6.0-SNAPSHOT</commmons.northbound.version>
<!-- Third Party Versions -->
<codahale.metrics.version>3.0.1</codahale.metrics.version>
<commons.tomcat.api>7.0.53.v201406060720</commons.tomcat.api>
<commons.tomcat.util>7.0.53.v201406070630</commons.tomcat.util>
- <commons.checkstyle.version>0.1.0-SNAPSHOT</commons.checkstyle.version>
- <commons.httpclient.version>0.2.0-SNAPSHOT</commons.httpclient.version>
- <commons.logback_settings.version>0.1.0-SNAPSHOT</commons.logback_settings.version>
+ <commons.checkstyle.version>0.2.0-SNAPSHOT</commons.checkstyle.version>
+ <commons.httpclient.version>0.3.0-SNAPSHOT</commons.httpclient.version>
+ <commons.logback_settings.version>0.2.0-SNAPSHOT</commons.logback_settings.version>
<commons.net.version>3.0.1</commons.net.version>
- <commons.opendaylight.commons.httpclient>0.2.0-SNAPSHOT</commons.opendaylight.commons.httpclient>
- <commons.opendaylight.concepts.version>0.6.0-SNAPSHOT</commons.opendaylight.concepts.version>
- <commons.opendaylight.version>1.5.0-SNAPSHOT</commons.opendaylight.version>
- <commons.parent.version>1.1.0-SNAPSHOT</commons.parent.version>
- <commons.httpclient.version>0.2.0-SNAPSHOT</commons.httpclient.version>
- <concepts.version>0.6.0-SNAPSHOT</concepts.version>
+ <commons.opendaylight.commons.httpclient>0.3.0-SNAPSHOT</commons.opendaylight.commons.httpclient>
+ <commons.opendaylight.concepts.version>0.7.0-SNAPSHOT</commons.opendaylight.concepts.version>
+ <commons.opendaylight.version>1.6.0-SNAPSHOT</commons.opendaylight.version>
+ <commons.parent.version>1.2.0-SNAPSHOT</commons.parent.version>
+ <commons.httpclient.version>0.3.0-SNAPSHOT</commons.httpclient.version>
+ <concepts.version>0.7.0-SNAPSHOT</concepts.version>
<concurrentlinkedhashmap.version>1.4</concurrentlinkedhashmap.version>
- <config.version>0.3.0-SNAPSHOT</config.version>
- <aaa.version>0.2.0-SNAPSHOT</aaa.version>
+ <config.version>0.4.0-SNAPSHOT</config.version>
+ <aaa.version>0.3.0-SNAPSHOT</aaa.version>
<config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
<config.clustering.configfile>05-clustering.xml</config.clustering.configfile>
<config.netty.configfile>00-netty.xml</config.netty.configfile>
<config.netconf.mdsal.configfile>08-mdsal-netconf.xml</config.netconf.mdsal.configfile>
<config.restconf.configfile>10-rest-connector.xml</config.restconf.configfile>
<config.netconf.connector.configfile>99-netconf-connector.xml</config.netconf.connector.configfile>
- <configuration.implementation.version>0.5.0-SNAPSHOT</configuration.implementation.version>
- <configuration.version>0.5.0-SNAPSHOT</configuration.version>
- <connectionmanager.version>0.2.0-SNAPSHOT</connectionmanager.version>
- <containermanager.it.version>0.6.0-SNAPSHOT</containermanager.it.version>
- <containermanager.northbound.version>0.5.0-SNAPSHOT</containermanager.northbound.version>
- <containermanager.shell.version>0.6.0-SNAPSHOT</containermanager.shell.version>
- <containermanager.version>0.6.0-SNAPSHOT</containermanager.version>
- <controllermanager.northbound.version>0.1.0-SNAPSHOT</controllermanager.northbound.version>
- <devices.web.version>0.5.0-SNAPSHOT</devices.web.version>
- <dummy-console.version>1.2.0-SNAPSHOT</dummy-console.version>
+ <configuration.implementation.version>0.6.0-SNAPSHOT</configuration.implementation.version>
+ <configuration.version>0.6.0-SNAPSHOT</configuration.version>
+ <connectionmanager.version>0.3.0-SNAPSHOT</connectionmanager.version>
+ <containermanager.it.version>0.7.0-SNAPSHOT</containermanager.it.version>
+ <containermanager.northbound.version>0.6.0-SNAPSHOT</containermanager.northbound.version>
+ <containermanager.shell.version>0.7.0-SNAPSHOT</containermanager.shell.version>
+ <containermanager.version>0.7.0-SNAPSHOT</containermanager.version>
+ <controllermanager.northbound.version>0.2.0-SNAPSHOT</controllermanager.northbound.version>
+ <devices.web.version>0.6.0-SNAPSHOT</devices.web.version>
+ <dummy-console.version>1.3.0-SNAPSHOT</dummy-console.version>
<config.statistics.manager.configfile>30-statistics-manager.xml</config.statistics.manager.configfile>
- <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>
<!-- OpenEXI third party lib for netconf-->
<exi.nagasena.version>0000.0002.0038.0</exi.nagasena.version>
<felix.util.version>1.6.0</felix.util.version>
- <features.test.version>1.5.0-SNAPSHOT</features.test.version>
- <filtervalve.version>1.5.0-SNAPSHOT</filtervalve.version>
+ <features.test.version>1.6.0-SNAPSHOT</features.test.version>
+ <filtervalve.version>1.6.0-SNAPSHOT</filtervalve.version>
<findbugs.maven.plugin.version>2.4.0</findbugs.maven.plugin.version>
- <flowprogrammer.northbound.version>0.5.0-SNAPSHOT</flowprogrammer.northbound.version>
- <flows.web.version>0.5.0-SNAPSHOT</flows.web.version>
- <forwarding.staticrouting>0.6.0-SNAPSHOT</forwarding.staticrouting>
- <forwarding.staticrouting.northbound.version>0.5.0-SNAPSHOT</forwarding.staticrouting.northbound.version>
- <forwardingrulesmanager.implementation.version>0.5.0-SNAPSHOT</forwardingrulesmanager.implementation.version>
- <forwardingrulesmanager.version>0.7.0-SNAPSHOT</forwardingrulesmanager.version>
- <hosttracker.api.version>0.6.0-SNAPSHOT</hosttracker.api.version>
- <hosttracker.implementation.version>0.6.0-SNAPSHOT</hosttracker.implementation.version>
- <hosttracker.northbound.version>0.5.0-SNAPSHOT</hosttracker.northbound.version>
- <hosttracker.shell.version>1.1.0-SNAPSHOT</hosttracker.shell.version>
- <hosttracker_new.api.version>0.5.0-SNAPSHOT</hosttracker_new.api.version>
- <hosttracker_new.implementation.version>0.5.0-SNAPSHOT</hosttracker_new.implementation.version>
- <httpservice-bridge.northbound.version>0.1.0-SNAPSHOT</httpservice-bridge.northbound.version>
- <ietf-inet-types.version>2010.09.24.7-SNAPSHOT</ietf-inet-types.version>
- <ietf-restconf.version>2013.10.19.7-SNAPSHOT</ietf-restconf.version>
- <ietf-topology.version>2013.10.21.7-SNAPSHOT</ietf-topology.version>
- <ietf-yang-types.version>2010.09.24.7-SNAPSHOT</ietf-yang-types.version>
+ <flowprogrammer.northbound.version>0.6.0-SNAPSHOT</flowprogrammer.northbound.version>
+ <flows.web.version>0.6.0-SNAPSHOT</flows.web.version>
+ <forwarding.staticrouting>0.7.0-SNAPSHOT</forwarding.staticrouting>
+ <forwarding.staticrouting.northbound.version>0.6.0-SNAPSHOT</forwarding.staticrouting.northbound.version>
+ <forwardingrulesmanager.implementation.version>0.6.0-SNAPSHOT</forwardingrulesmanager.implementation.version>
+ <forwardingrulesmanager.version>0.8.0-SNAPSHOT</forwardingrulesmanager.version>
+ <hosttracker.api.version>0.7.0-SNAPSHOT</hosttracker.api.version>
+ <hosttracker.implementation.version>0.7.0-SNAPSHOT</hosttracker.implementation.version>
+ <hosttracker.northbound.version>0.6.0-SNAPSHOT</hosttracker.northbound.version>
+ <hosttracker.shell.version>1.2.0-SNAPSHOT</hosttracker.shell.version>
+ <hosttracker_new.api.version>0.6.0-SNAPSHOT</hosttracker_new.api.version>
+ <hosttracker_new.implementation.version>0.6.0-SNAPSHOT</hosttracker_new.implementation.version>
+ <httpservice-bridge.northbound.version>0.2.0-SNAPSHOT</httpservice-bridge.northbound.version>
+ <ietf-inet-types.version>2010.09.24.8-SNAPSHOT</ietf-inet-types.version>
+ <ietf-restconf.version>2013.10.19.8-SNAPSHOT</ietf-restconf.version>
+ <ietf-topology.version>2013.10.21.8-SNAPSHOT</ietf-topology.version>
+ <ietf-yang-types.version>2010.09.24.8-SNAPSHOT</ietf-yang-types.version>
<jdepend.maven.plugin.version>2.0-beta-2</jdepend.maven.plugin.version>
<jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
- <jolokia-bridge.version>0.1.0-SNAPSHOT</jolokia-bridge.version>
+ <jolokia-bridge.version>0.2.0-SNAPSHOT</jolokia-bridge.version>
<jolokia.version>1.1.4</jolokia.version>
<jsr311.api.version>1.1.1</jsr311.api.version>
<jsr311.v2.api.version>2.0</jsr311.v2.api.version>
- <karaf.branding.version>1.1.0-SNAPSHOT</karaf.branding.version>
+ <karaf.branding.version>1.2.0-SNAPSHOT</karaf.branding.version>
<karaf.shell.version>${karaf.version}</karaf.shell.version>
<leveldb.version>0.7</leveldb.version>
<leveldbjni.version>1.8</leveldbjni.version>
<lifecycle.mapping.version>1.0.0</lifecycle.mapping.version>
- <logging.bridge.version>0.5.0-SNAPSHOT</logging.bridge.version>
+ <logging.bridge.version>0.6.0-SNAPSHOT</logging.bridge.version>
<maven.plugin.api.version>3.0.5</maven.plugin.api.version>
<mimepull.version>1.9.4</mimepull.version>
- <mdsal.version>1.2.0-SNAPSHOT</mdsal.version>
- <netconf.version>0.3.0-SNAPSHOT</netconf.version>
- <networkconfig.bridgedomain.northbound.version>0.1.0-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
+ <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
+ <netconf.version>0.4.0-SNAPSHOT</netconf.version>
+ <networkconfig.bridgedomain.northbound.version>0.2.0-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
<!-- ODL repository / plugin repository -->
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
- <northbound.commons.version>0.5.0-SNAPSHOT</northbound.commons.version>
- <northbound.hosttracker.version>1.5.0-SNAPSHOT</northbound.hosttracker.version>
- <northbound.jolokia.version>1.5.0-SNAPSHOT</northbound.jolokia.version>
- <opendaylight-l2-types.version>2013.08.27.7-SNAPSHOT</opendaylight-l2-types.version>
- <osgi-brandfragment.web.version>0.1.0-SNAPSHOT</osgi-brandfragment.web.version>
+ <northbound.commons.version>0.6.0-SNAPSHOT</northbound.commons.version>
+ <northbound.hosttracker.version>1.6.0-SNAPSHOT</northbound.hosttracker.version>
+ <northbound.jolokia.version>1.6.0-SNAPSHOT</northbound.jolokia.version>
+ <opendaylight-l2-types.version>2013.08.27.8-SNAPSHOT</opendaylight-l2-types.version>
+ <osgi-brandfragment.web.version>0.2.0-SNAPSHOT</osgi-brandfragment.web.version>
<parboiled.version>1.1.6</parboiled.version>
<parboiled.scala.version>1.1.6</parboiled.scala.version>
<propertymavenplugin.version>1.0-alpha-2</propertymavenplugin.version>
<protobuf.version>2.5.0</protobuf.version>
- <protocol-framework.version>0.6.0-SNAPSHOT</protocol-framework.version>
- <protocol_plugins.openflow.version>0.5.0-SNAPSHOT</protocol_plugins.openflow.version>
- <protocol_plugins.stub.version>0.5.0-SNAPSHOT</protocol_plugins.stub.version>
- <routing.dijkstra_implementation.version>0.5.0-SNAPSHOT</routing.dijkstra_implementation.version>
- <sal.connection.version>0.2.0-SNAPSHOT</sal.connection.version>
- <sal.implementation.version>0.5.0-SNAPSHOT</sal.implementation.version>
- <sal.networkconfiguration.version>0.1.0-SNAPSHOT</sal.networkconfiguration.version>
- <sal.version>0.9.0-SNAPSHOT</sal.version>
+ <protocol-framework.version>0.7.0-SNAPSHOT</protocol-framework.version>
+ <protocol_plugins.openflow.version>0.6.0-SNAPSHOT</protocol_plugins.openflow.version>
+ <protocol_plugins.stub.version>0.6.0-SNAPSHOT</protocol_plugins.stub.version>
+ <routing.dijkstra_implementation.version>0.6.0-SNAPSHOT</routing.dijkstra_implementation.version>
+ <sal.connection.version>0.3.0-SNAPSHOT</sal.connection.version>
+ <sal.implementation.version>0.6.0-SNAPSHOT</sal.implementation.version>
+ <sal.networkconfiguration.version>0.2.0-SNAPSHOT</sal.networkconfiguration.version>
+ <sal.version>0.10.0-SNAPSHOT</sal.version>
<salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
- <samples.loadbalancer>0.6.0-SNAPSHOT</samples.loadbalancer>
- <samples.loadbalancer.northbound.version>0.5.0-SNAPSHOT</samples.loadbalancer.northbound.version>
- <samples.simpleforwarding.version>0.5.0-SNAPSHOT</samples.simpleforwarding.version>
- <sanitytest.version>0.5.0-SNAPSHOT</sanitytest.version>
+ <samples.loadbalancer>0.7.0-SNAPSHOT</samples.loadbalancer>
+ <samples.loadbalancer.northbound.version>0.6.0-SNAPSHOT</samples.loadbalancer.northbound.version>
+ <samples.simpleforwarding.version>0.6.0-SNAPSHOT</samples.simpleforwarding.version>
+ <sanitytest.version>0.6.0-SNAPSHOT</sanitytest.version>
<scala.version>2.10</scala.version>
<scala.micro.version>4</scala.micro.version>
- <security.version>0.5.0-SNAPSHOT</security.version>
- <karaf.security.version>0.5.0-SNAPSHOT</karaf.security.version>
+ <security.version>0.6.0-SNAPSHOT</security.version>
+ <karaf.security.version>0.6.0-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>
<spring-security-karaf.version>3.1.4.RELEASE</spring-security-karaf.version>
<spring-security.version>3.1.3.RELEASE</spring-security.version>
<spring.version>3.1.3.RELEASE</spring.version>
- <statistics.northbound.version>0.5.0-SNAPSHOT</statistics.northbound.version>
- <statisticsmanager.implementation.version>0.5.0-SNAPSHOT</statisticsmanager.implementation.version>
- <statisticsmanager.version>0.6.0-SNAPSHOT</statisticsmanager.version>
- <subnets.northbound.version>0.5.0-SNAPSHOT</subnets.northbound.version>
+ <statistics.northbound.version>0.6.0-SNAPSHOT</statistics.northbound.version>
+ <statisticsmanager.implementation.version>0.6.0-SNAPSHOT</statisticsmanager.implementation.version>
+ <statisticsmanager.version>0.7.0-SNAPSHOT</statisticsmanager.version>
+ <subnets.northbound.version>0.6.0-SNAPSHOT</subnets.northbound.version>
<surefire.version>2.15</surefire.version>
- <switchmanager.api.version>0.8.0-SNAPSHOT</switchmanager.api.version>
- <switchmanager.implementation.version>0.5.0-SNAPSHOT</switchmanager.implementation.version>
- <switchmanager.northbound.version>0.5.0-SNAPSHOT</switchmanager.northbound.version>
+ <switchmanager.api.version>0.9.0-SNAPSHOT</switchmanager.api.version>
+ <switchmanager.implementation.version>0.6.0-SNAPSHOT</switchmanager.implementation.version>
+ <switchmanager.northbound.version>0.6.0-SNAPSHOT</switchmanager.northbound.version>
<testvm.argLine>-Xmx1024m -XX:MaxPermSize=256m</testvm.argLine>
- <topology.northbound.version>0.5.0-SNAPSHOT</topology.northbound.version>
- <topology.web.version>0.5.0-SNAPSHOT</topology.web.version>
- <topologymanager.version>0.5.0-SNAPSHOT</topologymanager.version>
- <topologymanager.shell.version>1.1.0-SNAPSHOT</topologymanager.shell.version>
- <troubleshoot.web.version>0.5.0-SNAPSHOT</troubleshoot.web.version>
+ <topology.northbound.version>0.6.0-SNAPSHOT</topology.northbound.version>
+ <topology.web.version>0.6.0-SNAPSHOT</topology.web.version>
+ <topologymanager.version>0.6.0-SNAPSHOT</topologymanager.version>
+ <topologymanager.shell.version>1.2.0-SNAPSHOT</topologymanager.shell.version>
+ <troubleshoot.web.version>0.6.0-SNAPSHOT</troubleshoot.web.version>
<typesafe.config.version>1.2.0</typesafe.config.version>
<uncommons.maths.version>1.2.2a</uncommons.maths.version>
- <usermanager.implementation.version>0.5.0-SNAPSHOT</usermanager.implementation.version>
- <usermanager.northbound.version>0.1.0-SNAPSHOT</usermanager.northbound.version>
- <usermanager.version>0.5.0-SNAPSHOT</usermanager.version>
- <nsf.version>0.5.0-SNAPSHOT</nsf.version>
- <web.version>0.5.0-SNAPSHOT</web.version>
- <yang-ext.version>2013.09.07.7-SNAPSHOT</yang-ext.version>
- <yang-jmx-generator.version>1.1.0-SNAPSHOT</yang-jmx-generator.version>
- <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+ <usermanager.implementation.version>0.6.0-SNAPSHOT</usermanager.implementation.version>
+ <usermanager.northbound.version>0.2.0-SNAPSHOT</usermanager.northbound.version>
+ <usermanager.version>0.6.0-SNAPSHOT</usermanager.version>
+ <nsf.version>0.6.0-SNAPSHOT</nsf.version>
+ <web.version>0.6.0-SNAPSHOT</web.version>
+ <yang-ext.version>2013.09.07.8-SNAPSHOT</yang-ext.version>
+ <yang-jmx-generator.version>1.2.0-SNAPSHOT</yang-jmx-generator.version>
+ <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
<sshd-core.version>0.14.0</sshd-core.version>
<jmh.version>0.9.7</jmh.version>
<lmax.version>3.3.0</lmax.version>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>httpservice-bridge</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>jolokia-bridge</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</dependency>
<!-- Karaf Dependencies -->
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
<executions>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
<executions>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.parent</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>protocol-framework</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>${project.artifactId}</name>
<description>Common protocol framework</description>
if (LocalServerChannel.class.equals(channelClass) == false) {
// makes no sense for LocalServer and produces warning
b.childOption(ChannelOption.SO_KEEPALIVE, true);
+ b.childOption(ChannelOption.TCP_NODELAY , true);
}
b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
customizeBootstrap(b);
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>config-api</artifactId>
@Immutable
public class CommitStatus {
private final List<ObjectName> newInstances, reusedInstances,
- recreatedInstances;
+ recreatedInstances;
/**
* @param newInstances newly created instances
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-artifacts</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-manager</artifactId>
static final String SUBCLASS2 = "subclass2";
@ServiceInterfaceAnnotation(value = SIMPLE, osgiRegistrationType = Executor.class,
- namespace = "ns", revision = "rev", localName = SIMPLE)
+ namespace = "ns", revision = "rev", localName = SIMPLE)
static interface SimpleSI extends AbstractServiceInterface {
}
}
@ServiceInterfaceAnnotation(value = SUBCLASS2, osgiRegistrationType = ExecutorService.class,
- namespace = "ns", revision = "rev", localName = SUBCLASS2)
+ namespace = "ns", revision = "rev", localName = SUBCLASS2)
static interface SubSI2 extends SubSI {
import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
@ServiceInterfaceAnnotation(value = TestingParallelAPSPConfigMXBean.NAME, osgiRegistrationType = TestingAPSP.class,
-namespace = "namespace", revision = "rev", localName = TestingParallelAPSPConfigMXBean.NAME)
+ namespace = "namespace", revision = "rev", localName = TestingParallelAPSPConfigMXBean.NAME)
public interface TestingParallelAPSPConfigMXBean {
static final String NAME = "apsp";
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>config-module-archetype</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>config-netty-config</artifactId>
<description>Configuration files for sal-rest-connector</description>
<parent>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-parent</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
- <config.version>0.3.0-SNAPSHOT</config.version>
- <mdsal.version>1.2.0-SNAPSHOT</mdsal.version>
- <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+ <config.version>0.4.0-SNAPSHOT</config.version>
+ <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
+ <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
<jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
<config.file>src/main/config/default-config.xml</config.file>
</properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-directory-xml-adapter</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-file-xml-adapter</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>config-plugin-parent</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-util</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>logback-config-loader</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>logback-config</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>netty-config-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>netty-event-executor-config</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>netty-threadgroup-config</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>netty-timer-config</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>shutdown-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>shutdown-impl</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>threadpool-config-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>threadpool-config-impl</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>yang-jmx-generator-it</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>yang-jmx-generator-plugin</artifactId>
private static class SieASTVisitor extends ASTVisitor {
protected String packageName, descriptionAnotValue, sieAnnotValue,
- sieAnnotOsgiRegistrationType, type, extnds, javadoc;
+ sieAnnotOsgiRegistrationType, type, extnds, javadoc;
protected Map<String, String> methodDescriptions = Maps.newHashMap();
@Override
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
public abstract class AbstractAttribute implements AttributeIfc {
private final String attributeYangName, upperCaseCammelCase,
- lowerCaseCammelCase;
+ lowerCaseCammelCase;
protected final DataSchemaNode node;
private static String getLocalName(DataSchemaNode attrNode) {
protected Map<String, Module> namesToModules; // are module names globally
// unique?
protected Module configModule, rpcContextModule, threadsModule,
- threadsJavaModule, bgpListenerJavaModule, ietfInetTypesModule,
- jmxModule, jmxImplModule, testFilesModule, testFiles1Module;
+ threadsJavaModule, bgpListenerJavaModule, ietfInetTypesModule,
+ jmxModule, jmxImplModule, testFilesModule, testFiles1Module;
public static final String EVENTBUS_MXB_NAME = "eventbus";
public static final String ASYNC_EVENTBUS_MXB_NAME = "async-eventbus";
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>yang-test-plugin</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<parent>
<artifactId>sal-parent</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>md-sal-config</artifactId>
<description>Configuration files for md-sal</description>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>mdsal-artifacts</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>messagebus-api</artifactId>
<parent>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>sal-parent</artifactId>\r
- <version>1.2.0-SNAPSHOT</version>\r
+ <version>1.3.0-SNAPSHOT</version>\r
</parent>\r
\r
<artifactId>messagebus-config</artifactId>\r
<parent>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>sal-parent</artifactId>\r
- <version>1.2.0-SNAPSHOT</version>\r
+ <version>1.3.0-SNAPSHOT</version>\r
</parent>\r
\r
<artifactId>messagebus-impl</artifactId>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>messagebus-api</artifactId>\r
- <version>1.2.0-SNAPSHOT</version>\r
+ <version>1.3.0-SNAPSHOT</version>\r
</dependency>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>messagebus-spi</artifactId>\r
- <version>1.2.0-SNAPSHOT</version>\r
+ <version>1.3.0-SNAPSHOT</version>\r
</dependency>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
public EventSourceTopic(final NotificationPattern notificationPattern, final String nodeIdPattern, final EventSourceService eventSource) {
this.notificationPattern = Preconditions.checkNotNull(notificationPattern);
this.sourceService = eventSource;
-
- // FIXME: regex should be the language of nodeIdPattern
- final String regex = Util.wildcardToRegex(nodeIdPattern);
- this.nodeIdPattern = Pattern.compile(regex);
+ this.nodeIdPattern = Pattern.compile(nodeIdPattern);
this.topicId = new TopicId(Util.getUUIDIdent());
}
.child(TopologyTypes.class)
.augmentation(TopologyTypes1.class);
- private final Map<DataChangeListener, ListenerRegistration<DataChangeListener>> topicListenerRegistrations =
+ private final Map<EventSourceTopic, ListenerRegistration<DataChangeListener>> topicListenerRegistrations =
new ConcurrentHashMap<>();
private final Map<NodeKey, RoutedRpcRegistration<EventSourceService>> routedRpcRegistrations =
- new ConcurrentHashMap<>();;
+ new ConcurrentHashMap<>();
private final DataBroker dataBroker;
private final RpcRegistration<EventAggregatorService> aggregatorRpcReg;
final NotificationPattern notificationPattern = new NotificationPattern(input.getNotificationPattern());
final String nodeIdPattern = input.getNodeIdPattern().getValue();
- final Pattern nodeIdPatternRegex = Pattern.compile(Util.wildcardToRegex(nodeIdPattern));
+ final Pattern nodeIdPatternRegex = Pattern.compile(nodeIdPattern);
final EventSourceTopic eventSourceTopic = new EventSourceTopic(notificationPattern, nodeIdPattern, eventSourceService);
registerTopic(eventSourceTopic);
}
public void register(final EventSource eventSource){
- NodeKey nodeKey = eventSource.getSourceNodeKey();
+ NodeKey nodeKey = eventSource.getSourceNodeKey();
final KeyedInstanceIdentifier<Node, NodeKey> sourcePath = EVENT_SOURCE_TOPOLOGY_PATH.child(Node.class, nodeKey);
RoutedRpcRegistration<EventSourceService> reg = rpcRegistry.addRoutedRpcImplementation(EventSourceService.class, eventSource);
reg.registerPath(NodeContext.class, sourcePath);
routedRpcRegistrations.put(nodeKey,reg);
insert(sourcePath);
+
+ for(EventSourceTopic est : topicListenerRegistrations.keySet()){
+ est.notifyNode(EVENT_SOURCE_TOPOLOGY_PATH.child(Node.class, nodeKey));
+ }
}
public void unRegister(final EventSource eventSource){
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
import javax.xml.transform.dom.DOMSource;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
private static final NodeIdentifier TOPIC_NOTIFICATION_ARG = new NodeIdentifier(TopicNotification.QNAME);
private static final NodeIdentifier EVENT_SOURCE_ARG = new NodeIdentifier(QName.create(TopicNotification.QNAME, "node-id"));
+ private static final NodeIdentifier TOPIC_ID_ARG = new NodeIdentifier(QName.create(TopicNotification.QNAME, "topic-id"));
private static final NodeIdentifier PAYLOAD_ARG = new NodeIdentifier(QName.create(TopicNotification.QNAME, "payload"));
private static final NodeIdentifier STREAM_QNAME = new NodeIdentifier(QName.create(CreateSubscriptionInput.QNAME,"stream"));
private final DOMMountPoint netconfMount;
private final DOMNotificationPublishService domPublish;
- private final Set<String> activeStreams = new ConcurrentSkipListSet<>();
private final Map<String, String> urnPrefixToStreamMap;
- private final ConcurrentHashMap<TopicId,ListenerRegistration<NetconfEventSource>> listenerRegistrationMap = new ConcurrentHashMap<>();
- public NetconfEventSource(final Node node, final Map<String, String> streamMap, final DOMMountPoint netconfMount, final DOMNotificationPublishService publishService, final MountPoint bindingMount) {
+ private final ConcurrentHashMap<String, StreamNotificationTopicRegistration> streamNotifRegistrationMap = new ConcurrentHashMap<>();
+
+ public NetconfEventSource(final Node node, final Map<String, String> streamMap, final DOMMountPoint netconfMount, final DOMNotificationPublishService publishService) {
this.netconfMount = netconfMount;
this.node = node;
this.nodeId = node.getNodeId().getValue();
this.urnPrefixToStreamMap = streamMap;
this.domPublish = publishService;
+ this.initializeStreamNotifRegistrationMap();
LOG.info("NetconfEventSource [{}] created.", nodeId);
}
+ private void initializeStreamNotifRegistrationMap(){
+ for(String streamName : this.urnPrefixToStreamMap.values()){
+ streamNotifRegistrationMap.put(streamName, new StreamNotificationTopicRegistration(streamName, this.nodeId, this.netconfMount, this));
+ }
+ }
+
@Override
public Future<RpcResult<JoinTopicOutput>> joinTopic(final JoinTopicInput input) {
+
final NotificationPattern notificationPattern = input.getNotificationPattern();
final List<SchemaPath> matchingNotifications = getMatchingNotifications(notificationPattern);
- return registerNotificationListener(input.getTopicId(),matchingNotifications);
+ return registerTopic(input.getTopicId(),matchingNotifications);
+
}
- private synchronized Future<RpcResult<JoinTopicOutput>> registerNotificationListener(final TopicId topicId, final List<SchemaPath> notificationsToSubscribe){
- if(listenerRegistrationMap.containsKey(topicId)){
- final String errMessage = "Can not join topic twice. Topic " + topicId.getValue() + " has been joined to node " + this.nodeId;
- return immediateFuture(RpcResultBuilder.<JoinTopicOutput>failed().withError(ErrorType.APPLICATION, errMessage).build());
- }
- ListenerRegistration<NetconfEventSource> registration = null;
- JoinTopicStatus joinTopicStatus = JoinTopicStatus.Down;
- final Optional<DOMNotificationService> notifyService = netconfMount.getService(DOMNotificationService.class);
+ private synchronized Future<RpcResult<JoinTopicOutput>> registerTopic(final TopicId topicId, final List<SchemaPath> notificationsToSubscribe){
- if(notifyService.isPresent()) {
- for (final SchemaPath qName : notificationsToSubscribe) {
- startSubscription(qName);
+ JoinTopicStatus joinTopicStatus = JoinTopicStatus.Down;
+ if(notificationsToSubscribe != null && notificationsToSubscribe.isEmpty() == false){
+ final Optional<DOMNotificationService> notifyService = netconfMount.getService(DOMNotificationService.class);
+ if(notifyService.isPresent()){
+ int subscribedStreams = 0;
+ for(SchemaPath schemaNotification : notificationsToSubscribe){
+ final Optional<String> streamName = resolveStream(schemaNotification.getLastComponent());
+ if(streamName.isPresent()){
+ LOG.info("Stream {} is activating, TopicId {}", streamName.get(), topicId.getValue() );
+ StreamNotificationTopicRegistration streamReg = streamNotifRegistrationMap.get(streamName.get());
+ streamReg.activateStream();
+ for(SchemaPath notificationPath : notificationsToSubscribe){
+ LOG.info("Notification listener is registering, Notification {}, TopicId {}", notificationPath, topicId.getValue() );
+ streamReg.registerNotificationListenerTopic(notificationPath, topicId);
+ }
+ subscribedStreams = subscribedStreams + 1;
+ }
+ }
+ if(subscribedStreams > 0){
+ joinTopicStatus = JoinTopicStatus.Up;
+ }
}
- registration = notifyService.get().registerNotificationListener(this, notificationsToSubscribe);
}
- if(registration != null){
- listenerRegistrationMap.put(topicId,registration);
- joinTopicStatus = JoinTopicStatus.Up;
- }
final JoinTopicOutput output = new JoinTopicOutputBuilder().setStatus(joinTopicStatus).build();
return immediateFuture(RpcResultBuilder.success(output).build());
- }
- private void startSubscription(final SchemaPath path) {
- final String streamName = resolveStream(path.getLastComponent());
- startSubscription(streamName);
}
private void resubscribeToActiveStreams() {
- for (final String streamName : activeStreams) {
- startSubscription(streamName);
- }
- }
-
- private synchronized void startSubscription(final String streamName) {
- if(streamIsActive(streamName) == false){
- LOG.info("Stream {} is not active on node {}. Will subscribe.", streamName, nodeId);
- final ContainerNode input = Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(CreateSubscriptionInput.QNAME))
- .withChild(ImmutableNodes.leafNode(STREAM_QNAME, streamName))
- .build();
- netconfMount.getService(DOMRpcService.class).get().invokeRpc(CREATE_SUBSCRIPTION, input);
- activeStreams.add(streamName);
+ for (StreamNotificationTopicRegistration streamReg : streamNotifRegistrationMap.values()){
+ streamReg.reActivateStream();
}
}
- private String resolveStream(final QName qName) {
+ private Optional<String> resolveStream(final QName qName) {
String streamName = null;
for (final Map.Entry<String, String> entry : urnPrefixToStreamMap.entrySet()) {
break;
}
}
-
- return streamName;
- }
-
- private boolean streamIsActive(final String streamName) {
- return activeStreams.contains(streamName);
+ return Optional.fromNullable(streamName);
}
@Override
public void onNotification(final DOMNotification notification) {
- final ContainerNode topicNotification = Builders.containerBuilder()
- .withNodeIdentifier(TOPIC_NOTIFICATION_ARG)
- .withChild(ImmutableNodes.leafNode(EVENT_SOURCE_ARG, nodeId))
- .withChild(encapsulate(notification))
- .build();
- try {
- domPublish.putNotification(new TopicDOMNotification(topicNotification));
- } catch (final InterruptedException e) {
- throw Throwables.propagate(e);
+ SchemaPath notificationPath = notification.getType();
+ LOG.info("Notification {} has come.",notification.getType());
+ for(StreamNotificationTopicRegistration streamReg : streamNotifRegistrationMap.values()){
+ for(TopicId topicId : streamReg.getNotificationTopicIds(notificationPath)){
+ publishNotification(notification, topicId);
+ LOG.info("Notification {} has been published for TopicId {}",notification.getType(), topicId.getValue());
+ }
}
}
+ private void publishNotification(final DOMNotification notification, TopicId topicId){
+ final ContainerNode topicNotification = Builders.containerBuilder()
+ .withNodeIdentifier(TOPIC_NOTIFICATION_ARG)
+ .withChild(ImmutableNodes.leafNode(TOPIC_ID_ARG, topicId))
+ .withChild(ImmutableNodes.leafNode(EVENT_SOURCE_ARG, nodeId))
+ .withChild(encapsulate(notification))
+ .build();
+ try {
+ domPublish.putNotification(new TopicDOMNotification(topicNotification));
+ } catch (final InterruptedException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
private AnyXmlNode encapsulate(final DOMNotification body) {
// FIXME: Introduce something like AnyXmlWithNormalizedNodeData in Yangtools
final Document doc = XmlUtil.newDocument();
final String regex = Util.wildcardToRegex(notificationPattern.getValue());
final Pattern pattern = Pattern.compile(regex);
- return Util.expandQname(getAvailableNotifications(), pattern);
+ List<SchemaPath> availableNotifications = getAvailableNotifications();
+ if(availableNotifications == null || availableNotifications.isEmpty()){
+ return null;
+ }
+ return Util.expandQname(availableNotifications, pattern);
}
@Override
public void close() throws Exception {
- for(ListenerRegistration<NetconfEventSource> registration : listenerRegistrationMap.values()){
- registration.close();
+ for(StreamNotificationTopicRegistration streamReg : streamNotifRegistrationMap.values()){
+ streamReg.deactivateStream();
}
}
return qNs;
}
+ private class StreamNotificationTopicRegistration{
+
+ final private String streamName;
+ final private DOMMountPoint netconfMount;
+ final private String nodeId;
+ final private NetconfEventSource notificationListener;
+ private boolean active;
+
+ private ConcurrentHashMap<SchemaPath, ListenerRegistration<NetconfEventSource>> notificationRegistrationMap = new ConcurrentHashMap<>();
+ private ConcurrentHashMap<SchemaPath, ArrayList<TopicId>> notificationTopicMap = new ConcurrentHashMap<>();
+
+ public StreamNotificationTopicRegistration(final String streamName, final String nodeId, final DOMMountPoint netconfMount, NetconfEventSource notificationListener) {
+ this.streamName = streamName;
+ this.netconfMount = netconfMount;
+ this.nodeId = nodeId;
+ this.notificationListener = notificationListener;
+ this.active = false;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public void reActivateStream(){
+ if(this.isActive()){
+ LOG.info("Stream {} is reactivated active on node {}.", this.streamName, this.nodeId);
+ final ContainerNode input = Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(CreateSubscriptionInput.QNAME))
+ .withChild(ImmutableNodes.leafNode(STREAM_QNAME, this.streamName))
+ .build();
+ netconfMount.getService(DOMRpcService.class).get().invokeRpc(CREATE_SUBSCRIPTION, input);
+ }
+ }
+
+ public void activateStream() {
+ if(this.isActive() == false){
+ LOG.info("Stream {} is not active on node {}. Will subscribe.", this.streamName, this.nodeId);
+ final ContainerNode input = Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(CreateSubscriptionInput.QNAME))
+ .withChild(ImmutableNodes.leafNode(STREAM_QNAME, this.streamName))
+ .build();
+ netconfMount.getService(DOMRpcService.class).get().invokeRpc(CREATE_SUBSCRIPTION, input);
+ this.active = true;
+ } else {
+ LOG.info("Stream {} is now active on node {}", this.streamName, this.nodeId);
+ }
+ }
+
+ public void deactivateStream() {
+ for(ListenerRegistration<NetconfEventSource> reg : notificationRegistrationMap.values()){
+ reg.close();
+ }
+ this.active = false;
+ }
+
+ public String getStreamName() {
+ return streamName;
+ }
+
+ public ArrayList<TopicId> getNotificationTopicIds(SchemaPath notificationPath){
+ return notificationTopicMap.get(notificationPath);
+ }
+
+ public void registerNotificationListenerTopic(SchemaPath notificationPath, TopicId topicId){
+ final Optional<DOMNotificationService> notifyService = netconfMount.getService(DOMNotificationService.class);
+ if(notificationPath != null && notifyService.isPresent()){
+ ListenerRegistration<NetconfEventSource> registration = notifyService.get().registerNotificationListener(this.notificationListener,notificationPath);
+ notificationRegistrationMap.put(notificationPath, registration);
+ ArrayList<TopicId> topicIds = getNotificationTopicIds(notificationPath);
+ if(topicIds == null){
+ topicIds = new ArrayList<>();
+ topicIds.add(topicId);
+ } else {
+ if(topicIds.contains(topicId) == false){
+ topicIds.add(topicId);
+ }
+ }
+ notificationTopicMap.put(notificationPath, topicIds);
+ }
+ }
+
+ }
}
package org.opendaylight.controller.messagebus.eventsources.netconf;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+
import org.opendaylight.controller.config.yang.messagebus.app.impl.NamespaceToStream;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
import org.opendaylight.controller.md.sal.binding.api.MountPointService;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
public final class NetconfEventSourceManager implements DataChangeListener, AutoCloseable {
- private static final Logger LOGGER = LoggerFactory.getLogger(NetconfEventSourceManager.class);
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfEventSourceManager.class);
private static final TopologyKey NETCONF_TOPOLOGY_KEY = new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()));
private static final InstanceIdentifier<Node> NETCONF_DEVICE_PATH = InstanceIdentifier.create(NetworkTopology.class)
.child(Topology.class, NETCONF_TOPOLOGY_KEY)
private void initialize(final DataBroker dataBroker){
Preconditions.checkNotNull(dataBroker);
listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, NETCONF_DEVICE_PATH, this, DataChangeScope.SUBTREE);
- LOGGER.info("NetconfEventSourceManager initialized.");
+ LOG.info("NetconfEventSourceManager initialized.");
}
private Map<String,String> namespaceToStreamMapping(final List<NamespaceToStream> namespaceMapping) {
@Override
public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> event) {
- LOGGER.debug("[DataChangeEvent<InstanceIdentifier<?>, DataObject>: {}]", event);
+ LOG.debug("[DataChangeEvent<InstanceIdentifier<?>, DataObject>: {}]", event);
for (final Map.Entry<InstanceIdentifier<?>, DataObject> changeEntry : event.getCreatedData().entrySet()) {
if (changeEntry.getValue() instanceof Node) {
nodeUpdated(changeEntry.getKey(),(Node) changeEntry.getValue());
throw new IllegalStateException("Node is null");
}
if ( isNetconfNode(node) == false ) {
- LOGGER.debug("OnDataChanged Event. Not a Netconf node.");
+ LOG.debug("OnDataChanged Event. Not a Netconf node.");
return;
}
if ( isEventSource(node) == false ) {
- LOGGER.debug("OnDataChanged Event. Node an EventSource node.");
+ LOG.debug("OnDataChanged Event. Node an EventSource node.");
return;
}
if(node.getAugmentation(NetconfNode.class).getConnectionStatus() != ConnectionStatus.Connected ) {
private void createEventSource(final InstanceIdentifier<?> key, final Node node) {
final Optional<DOMMountPoint> netconfMount = domMounts.getMountPoint(domMountPath(node.getNodeId()));
- final Optional<MountPoint> bindingMount = bindingMounts.getMountPoint(key);
-
- if(netconfMount.isPresent() && bindingMount.isPresent()) {
+ if(netconfMount.isPresent()) {
final NetconfEventSource netconfEventSource =
- new NetconfEventSource(node, streamMap, netconfMount.get(), publishService, bindingMount.get());
+ new NetconfEventSource(node, streamMap, netconfMount.get(), publishService);
final EventSourceRegistration<NetconfEventSource> registration = eventSourceRegistry.registerEventSource(netconfEventSource);
+ LOG.info("Event source {} has been registered",node.getNodeId().getValue());
eventSourceRegistration.putIfAbsent(key, registration);
}
*/
package org.opendaylight.controller.messagebus.app.impl;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
+//import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.md.sal.binding.api.BindingService;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import java.lang.reflect.Field;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
public class NetconfEventSourceTest {
streamMap.put("uriStr1", "string2");
domMountPointMock = mock(DOMMountPoint.class);
DOMNotificationPublishService domNotificationPublishServiceMock = mock(DOMNotificationPublishService.class);
- MountPoint mountPointMock = mock(MountPoint.class);
RpcConsumerRegistry rpcConsumerRegistryMock = mock(RpcConsumerRegistry.class);
Optional<BindingService> onlyOptionalMock = (Optional<BindingService>) mock(Optional.class);
NotificationsService notificationsServiceMock = mock(NotificationsService.class);
- doReturn(onlyOptionalMock).when(mountPointMock).getService(RpcConsumerRegistry.class);
- doReturn(rpcConsumerRegistryMock).when(onlyOptionalMock).get();
doReturn(notificationsServiceMock).when(rpcConsumerRegistryMock).getRpcService(NotificationsService.class);
org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node node
= mock(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.class);
org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId nodeId
= new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId("NodeId1");
doReturn(nodeId).when(node).getNodeId();
- netconfEventSource = new NetconfEventSource(node, streamMap, domMountPointMock, domNotificationPublishServiceMock, mountPointMock);
+ netconfEventSource = new NetconfEventSource(node, streamMap, domMountPointMock, domNotificationPublishServiceMock);
}
@Test
verify(dataObjectMock, times(2)).isConnected();
}
- @Test
- public void onDataChangedResubscribeTest() throws Exception{
-
- InstanceIdentifier brmIdent = InstanceIdentifier.create(Nodes.class)
- .child(Node.class, new NodeKey(new NodeId("brm"))).augmentation(NetconfNode.class);
-
- AsyncDataChangeEvent asyncDataChangeEventMock = mock(AsyncDataChangeEvent.class);
- NetconfNode dataObjectMock = mock(NetconfNode.class);
- Map<InstanceIdentifier, DataObject> dataChangeMap = new HashMap<>();
- dataChangeMap.put(brmIdent, dataObjectMock);
- doReturn(dataChangeMap).when(asyncDataChangeEventMock).getUpdatedData();
- doReturn(new HashMap<InstanceIdentifier, DataObject>()).when(asyncDataChangeEventMock).getOriginalData();
- doReturn(true).when(dataObjectMock).isConnected();
-
- Set<String> localSet = getActiveStreams();
- localSet.add("activeStream1");
-
- Optional<DOMService> optionalMock = (Optional<DOMService>) mock(Optional.class);
- doReturn(optionalMock).when(domMountPointMock).getService(DOMRpcService.class);
- DOMRpcService domRpcServiceMock = mock(DOMRpcService.class);
- doReturn(domRpcServiceMock).when(optionalMock).get();
- CheckedFuture checkedFutureMock = mock(CheckedFuture.class);
- doReturn(checkedFutureMock).when(domRpcServiceMock).invokeRpc(any(SchemaPath.class), any(ContainerNode.class));
-
- netconfEventSource.onDataChanged(asyncDataChangeEventMock);
- verify(dataObjectMock, times(1)).isConnected();
- assertEquals("Size of set has not been set correctly.", 1, getActiveStreams().size());
- }
-
@Test
public void joinTopicTest() throws Exception{
joinTopicTestHelper();
DOMNotificationService domNotificationServiceMock = mock(DOMNotificationService.class);
doReturn(domNotificationServiceMock).when(domNotificationServiceOptionalMock).get();
- ListenerRegistration listenerRegistrationMock = mock(ListenerRegistration.class);
- doReturn(listenerRegistrationMock).when(domNotificationServiceMock).registerNotificationListener(any(NetconfEventSource.class), any(List.class));
+ ListenerRegistration<NetconfEventSource> listenerRegistrationMock = (ListenerRegistration<NetconfEventSource>)mock(ListenerRegistration.class);
+ doReturn(listenerRegistrationMock).when(domNotificationServiceMock).registerNotificationListener(any(NetconfEventSource.class), any(SchemaPath.class));
Optional<DOMService> optionalMock = (Optional<DOMService>) mock(Optional.class);
doReturn(optionalMock).when(domMountPointMock).getService(DOMRpcService.class);
doReturn(checkedFutureMock).when(domRpcServiceMock).invokeRpc(any(SchemaPath.class), any(ContainerNode.class));
}
-//TODO: create Test for NetConfEventSource#onNotification
-
- private Set getActiveStreams() throws Exception{
- Field nesField = NetconfEventSource.class.getDeclaredField("activeStreams");
- nesField.setAccessible(true);
- return (Set) nesField.get(netconfEventSource);
- }
-
}
\ No newline at end of file
*/
public class UtilTest {
- @Test
- public void testWildcardToRegex() throws Exception {
- // empty wildcard string
- createAndAssertRegex("", "^$");
-
- // wildcard string is a char to be replaced
- createAndAssertRegex("*", "^.*$");
- createAndAssertRegex("?", "^.$");
- final String relevantChars = "()[]$^.{}|\\";
- for (final char c : relevantChars.toCharArray()) {
- final char oneChar[] = {c};
- final String wildcardStr = new String(oneChar);
- final String expectedRegex = "^\\" + c + "$";
- createAndAssertRegex(wildcardStr, expectedRegex);
- }
-
- // wildcard string consists of more chars
- createAndAssertRegex("a", "^a$");
- createAndAssertRegex("aBc", "^aBc$");
- createAndAssertRegex("a1b2C34", "^a1b2C34$");
- createAndAssertRegex("*?()[]$^.{}|\\X", "^.*.\\(\\)\\[\\]\\$\\^\\.\\{\\}\\|\\\\X$");
- createAndAssertRegex("a*BB?37|42$", "^a.*BB.37\\|42\\$$");
- }
-
@Test
public void testResultFor() throws Exception {
{
}
}
- private static void createAndAssertRegex(final String wildcardStr, final String expectedRegex) {
- assertEquals("Incorrect regex string.", expectedRegex, Util.wildcardToRegex(wildcardStr));
- }
-
private static List<SchemaPath> createSchemaPathList() {
final QName qname1 = QName.create("urn:odl:xxx", "2015-01-01", "localName");
final QName qname2 = QName.create("urn:odl:yyy", "2015-01-01", "localName");
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>messagebus-spi</artifactId>
<parent>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>model-inventory</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>model-topology</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-parent</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-akka-raft-example</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-akka-raft</artifactId>
<packaging>bundle</packaging>
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import java.io.Serializable;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
.snapshotIndex(replicatedLog().getSnapshotIndex())
.snapshotTerm(replicatedLog().getSnapshotTerm())
.votedFor(context.getTermInformation().getVotedFor())
- .peerAddresses(ImmutableMap.copyOf(context.getPeerAddresses()));
+ .peerAddresses(new HashMap<>(context.getPeerAddresses()));
ReplicatedLogEntry lastLogEntry = getLastLogEntry();
if (lastLogEntry != null) {
Optional<ActorRef> roleChangeNotifier = getRoleChangeNotifier();
if(!Objects.equal(oldBehaviorLeaderId, currentBehavior.getLeaderId())) {
if(roleChangeNotifier.isPresent()) {
- roleChangeNotifier.get().tell(new LeaderStateChanged(getId(), currentBehavior.getLeaderId()), getSelf());
+ roleChangeNotifier.get().tell(newLeaderStateChanged(getId(), currentBehavior.getLeaderId()), getSelf());
}
onLeaderChanged(oldBehaviorLeaderId, currentBehavior.getLeaderId());
}
}
+ protected LeaderStateChanged newLeaderStateChanged(String memberId, String leaderId) {
+ return new LeaderStateChanged(memberId, leaderId);
+ }
+
/**
* When a derived RaftActor needs to persist something it must call
* persistData.
import static org.junit.Assert.assertEquals;
import akka.actor.ActorRef;
+import akka.actor.InvalidActorNameException;
import akka.actor.PoisonPill;
import akka.actor.Props;
import akka.actor.Terminated;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.Uninterruptibles;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
TestActorRef<MessageCollectorActor> collectorActor = factory.createTestActor(
MessageCollectorActor.props().withDispatcher(Dispatchers.DefaultDispatcherId()),
factory.generateActorId(id + "-collector"));
- return factory.createTestActor(TestRaftActor.props(id,
- peerAddresses != null ? peerAddresses : Collections.<String, String>emptyMap(),
- configParams, collectorActor), id);
+
+ InvalidActorNameException lastEx = null;
+ for(int i = 0; i < 10; i++) {
+ try {
+ return factory.createTestActor(TestRaftActor.props(id,
+ peerAddresses != null ? peerAddresses : Collections.<String, String>emptyMap(),
+ configParams, collectorActor), id);
+ } catch (InvalidActorNameException e) {
+ lastEx = e;
+ Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
+ }
+ }
+
+ throw lastEx;
}
protected void killActor(TestActorRef<TestRaftActor> leaderActor) {
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-api</artifactId>
<packaging>bundle</packaging>
package org.opendaylight.controller.sal.binding.api;
import java.util.EventListener;
-
import org.opendaylight.yangtools.yang.binding.Notification;
/**
* capture of this interface.
*
* @param <T> the interested notification type
+ * @deprecated Deprecated unused API.
*/
+@Deprecated
public interface NotificationListener<T extends Notification> extends EventListener {
/**
* Invoked to deliver a notification.
import java.util.EventListener;
import java.util.concurrent.ExecutorService;
-
import org.opendaylight.controller.md.sal.common.api.notify.NotificationPublishService;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.Notification;
* Interface for a notification service that provides publish/subscribe capabilities for YANG
* modeled notifications. This interface is a combination of the {@link NotificationService} and
* {@link NotificationPublishService} interfaces.
+ *
+ * @deprecated Please use {@link org.opendaylight.controller.md.sal.binding.api.NotificationPublishService}.
*/
+@Deprecated
public interface NotificationProviderService extends NotificationService, NotificationPublishService<Notification> {
/**
* </pre>
* The <code>onStart</code> method will be invoked when someone publishes a <code>Start</code> notification and
* the <code>onStop</code> method will be invoked when someone publishes a <code>Stop</code> notification.
+ *
+ * @deprecated Please use {@link org.opendaylight.controller.md.sal.binding.api.NotificationService} instead.
*/
+@Deprecated
public interface NotificationService extends BindingAwareService {
/**
* Registers a generic listener implementation for a specified notification type.
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-broker-impl</artifactId>
<packaging>bundle</packaging>
<configuration>
<instructions>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
- <Export-package>org.opendaylight.controller.sal.binding.spi.*,</Export-package>
+ <Export-Package>
+ org.opendaylight.controller.sal.binding.spi.*,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.binding.impl.rev131028.*,
+ org.opendaylight.controller.config.yang.md.sal.binding.impl
+ </Export-Package>
<Private-Package>
- org.opendaylight.controller.config.yang.md.sal.binding.impl,
org.opendaylight.controller.sal.binding.impl,
org.opendaylight.controller.sal.binding.impl.*,
org.opendaylight.controller.sal.binding.codegen,
org.opendaylight.controller.md.sal.binding.compat,
org.opendaylight.controller.md.sal.binding.spi,
<!--org.opendaylight.controller.sal.binding.dom.*,-->
- org.opendaylight.controller.sal.binding.osgi.*,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.binding.impl.rev131028.*
+ org.opendaylight.controller.sal.binding.osgi.*
</Private-Package>
</instructions>
</configuration>
package org.opendaylight.controller.md.sal.binding.compat;
import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
private NotificationInvoker(final NotificationListener listener) {
delegate = listener;
final Map<Class<? extends Notification>, InvokerContext> builder = new HashMap<>();
- for(final Class<?> iface : listener.getClass().getInterfaces()) {
+ for(final TypeToken<?> ifaceToken : TypeToken.of(listener.getClass()).getTypes().interfaces()) {
+ Class<?> iface = ifaceToken.getRawType();
if(NotificationListener.class.isAssignableFrom(iface) && BindingReflections.isBindingClass(iface)) {
@SuppressWarnings("unchecked")
final Class<? extends NotificationListener> listenerType = (Class<? extends NotificationListener>) iface;
package org.opendaylight.controller.md.sal.binding.impl;
import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
public static Map<SchemaPath, NotificationListenerInvoker> createInvokerMapFor(final Class<? extends NotificationListener> implClz) {
final Map<SchemaPath, NotificationListenerInvoker> builder = new HashMap<>();
- for(final Class<?> iface : implClz.getInterfaces()) {
+ for(final TypeToken<?> ifaceToken : TypeToken.of(implClz).getTypes().interfaces()) {
+ Class<?> iface = ifaceToken.getRawType();
if(NotificationListener.class.isAssignableFrom(iface) && BindingReflections.isBindingClass(iface)) {
@SuppressWarnings("unchecked")
final Class<? extends NotificationListener> listenerType = (Class<? extends NotificationListener>) iface;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import java.util.concurrent.TimeUnit;
import org.opendaylight.controller.md.sal.binding.compat.HeliumNotificationProviderServiceAdapter;
import com.google.common.collect.ImmutableList;
final CountDownLatch latch = new CountDownLatch(1);
final TwoLevelListChanged testData = createTestData();
- final NotifTestListener testNotifListener = new NotifTestListener(latch);
+ final NotifTestListenerChild testNotifListener = new NotifTestListenerChild(latch);
final ListenerRegistration<NotificationListener> listenerRegistration =
notificationProviderService.registerNotificationListener(testNotifListener);
notificationProviderService.publish(testData);
- latch.await();
+ latch.await(500L, TimeUnit.MILLISECONDS);
assertTrue(testNotifListener.getReceivedNotifications().size() == 1);
assertEquals(testData, testNotifListener.getReceivedNotifications().get(0));
listenerRegistration.close();
}
+ private static class NotifTestListenerChild extends NotifTestListener {
+
+ public NotifTestListenerChild(final CountDownLatch latch) {
+ super(latch);
+ }
+ }
private static class NotifTestListener implements OpendaylightMdsalListTestListener {
private List<TwoLevelListChanged> receivedNotifications = new ArrayList<>();
private CountDownLatch latch;
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-config</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-dom-it</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-it</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-util</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-clustering-commons</artifactId>
*/
package org.opendaylight.controller.cluster.notifications;
-import java.io.Serializable;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
/**
- * A message initiated internally from the RaftActor when some state of a leader has changed
+ * A local message initiated internally from the RaftActor when some state of a leader has changed.
*
* @author Thomas Pantelis
*/
-public class LeaderStateChanged implements Serializable {
- private static final long serialVersionUID = 1L;
-
+public class LeaderStateChanged {
private final String memberId;
private final String leaderId;
- public LeaderStateChanged(String memberId, String leaderId) {
- this.memberId = memberId;
+ public LeaderStateChanged(@Nonnull String memberId, @Nullable String leaderId) {
+ this.memberId = Preconditions.checkNotNull(memberId);
this.leaderId = leaderId;
}
- public String getMemberId() {
+ public @Nonnull String getMemberId() {
return memberId;
}
- public String getLeaderId() {
+ public @Nullable String getLeaderId() {
return leaderId;
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-clustering-config</artifactId>
<description>Configuration files for md-sal clustering</description>
]
}
+
+ persistence {
+ # By default the snapshots/journal directories live in KARAF_HOME. You can choose to put it somewhere else by
+ # modifying the following two properties. The directory location specified may be a relative or absolute path.
+ # The relative path is always relative to KARAF_HOME.
+
+ # snapshot-store.local.dir = "target/snapshots"
+ # journal.leveldb.dir = "target/journal"
+
+ }
}
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-common-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-common-impl</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-common-util</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-common</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-connector-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-distributed-datastore</artifactId>
<packaging>bundle</packaging>
Preconditions.checkArgument(cohorts != null, "Cohorts must not be null.");
LOG.debug("Tx: {} is submitted for execution.", transaction.getIdentifier());
+ if(cohorts.isEmpty()){
+ return Futures.immediateCheckedFuture(null);
+ }
+
final AsyncNotifyingSettableFuture clientSubmitFuture =
new AsyncNotifyingSettableFuture(clientFutureCallbackExecutor);
import org.opendaylight.controller.cluster.datastore.messages.PeerAddressResolved;
import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener;
import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener;
+import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged;
import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
import org.opendaylight.controller.cluster.datastore.modification.Modification;
import org.opendaylight.controller.cluster.datastore.modification.ModificationPayload;
import org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification;
import org.opendaylight.controller.cluster.datastore.utils.Dispatchers;
import org.opendaylight.controller.cluster.datastore.utils.MessageTracker;
+import org.opendaylight.controller.cluster.notifications.LeaderStateChanged;
import org.opendaylight.controller.cluster.notifications.RegisterRoleChangeListener;
import org.opendaylight.controller.cluster.notifications.RoleChangeNotifier;
import org.opendaylight.controller.cluster.raft.RaftActor;
import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
import org.opendaylight.controller.cluster.raft.protobuff.client.messages.CompositeModificationByteStringPayload;
import org.opendaylight.controller.cluster.raft.protobuff.client.messages.CompositeModificationPayload;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
return roleChangeNotifier;
}
+ @Override
+ protected LeaderStateChanged newLeaderStateChanged(String memberId, String leaderId) {
+ return new ShardLeaderStateChanged(memberId, leaderId,
+ isLeader() ? Optional.<DataTree>of(store.getDataTree()) : Optional.<DataTree>absent());
+ }
+
private void onDatastoreContext(DatastoreContext context) {
datastoreContext = context;
import akka.serialization.Serialization;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
+import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import org.opendaylight.controller.cluster.datastore.messages.ActorInitialized;
import org.opendaylight.controller.cluster.datastore.messages.FindLocalShard;
import org.opendaylight.controller.cluster.datastore.messages.FindPrimary;
+import org.opendaylight.controller.cluster.datastore.messages.LocalPrimaryShardFound;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardFound;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardNotFound;
import org.opendaylight.controller.cluster.datastore.messages.PeerAddressResolved;
-import org.opendaylight.controller.cluster.datastore.messages.PrimaryFound;
+import org.opendaylight.controller.cluster.datastore.messages.RemoteFindPrimary;
+import org.opendaylight.controller.cluster.datastore.messages.RemotePrimaryShardFound;
+import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged;
import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
import org.opendaylight.controller.cluster.datastore.utils.Dispatchers;
-import org.opendaylight.controller.cluster.notifications.LeaderStateChanged;
import org.opendaylight.controller.cluster.notifications.RegisterRoleChangeListener;
import org.opendaylight.controller.cluster.notifications.RoleChangeNotification;
import org.opendaylight.controller.cluster.raft.RaftState;
import org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
onFollowerInitialSyncStatus((FollowerInitialSyncUpStatus) message);
} else if(message instanceof ShardNotInitializedTimeout) {
onShardNotInitializedTimeout((ShardNotInitializedTimeout)message);
- } else if(message instanceof LeaderStateChanged) {
- onLeaderStateChanged((LeaderStateChanged)message);
+ } else if(message instanceof ShardLeaderStateChanged) {
+ onLeaderStateChanged((ShardLeaderStateChanged)message);
} else {
unknownMessage(message);
}
}
- private void onLeaderStateChanged(LeaderStateChanged leaderStateChanged) {
+ private void checkReady(){
+ if (isReadyWithLeaderId()) {
+ LOG.info("{}: All Shards are ready - data store {} is ready, available count is {}",
+ persistenceId(), type, waitTillReadyCountdownLatch.getCount());
+
+ waitTillReadyCountdownLatch.countDown();
+ }
+ }
+
+ private void onLeaderStateChanged(ShardLeaderStateChanged leaderStateChanged) {
LOG.info("{}: Received LeaderStateChanged message: {}", persistenceId(), leaderStateChanged);
ShardInformation shardInformation = findShardInformation(leaderStateChanged.getMemberId());
if(shardInformation != null) {
+ shardInformation.setLocalDataTree(leaderStateChanged.getLocalShardDataTree());
shardInformation.setLeaderId(leaderStateChanged.getLeaderId());
- if (isReadyWithLeaderId()) {
- LOG.info("{}: All Shards are ready - data store {} is ready, available count is {}",
- persistenceId(), type, waitTillReadyCountdownLatch.getCount());
-
- waitTillReadyCountdownLatch.countDown();
- }
-
+ checkReady();
} else {
LOG.debug("No shard found with member Id {}", leaderStateChanged.getMemberId());
}
ShardInformation shardInformation = findShardInformation(roleChanged.getMemberId());
if(shardInformation != null) {
shardInformation.setRole(roleChanged.getNewRole());
-
- if (isReadyWithLeaderId()) {
- LOG.info("{}: All Shards are ready - data store {} is ready, available count is {}",
- persistenceId(), type, waitTillReadyCountdownLatch.getCount());
-
- waitTillReadyCountdownLatch.countDown();
- }
-
+ checkReady();
mBean.setSyncStatus(isInSync());
}
}
info.updatePeerAddress(getShardIdentifier(memberName, shardName).toString(),
getShardActorPath(shardName, memberName), getSelf());
}
+
+ checkReady();
}
private void onDatastoreContext(DatastoreContext context) {
LOG.debug("{}: In findPrimary: {}", persistenceId(), message);
final String shardName = message.getShardName();
+ final boolean canReturnLocalShardState = !(message instanceof RemoteFindPrimary);
// First see if the there is a local replica for the shard
final ShardInformation info = localShards.get(shardName);
sendResponse(info, message.isWaitUntilReady(), true, new Supplier<Object>() {
@Override
public Object get() {
- Object found = new PrimaryFound(info.getSerializedLeaderActor());
+ String primaryPath = info.getSerializedLeaderActor();
+ Object found = canReturnLocalShardState && info.isLeader() ?
+ new LocalPrimaryShardFound(primaryPath, info.getLocalShardDataTree().get()) :
+ new RemotePrimaryShardFound(primaryPath);
if(LOG.isDebugEnabled()) {
LOG.debug("{}: Found primary for {}: {}", persistenceId(), shardName, found);
LOG.debug("{}: findPrimary for {} forwarding to remote ShardManager {}", persistenceId(),
shardName, path);
- getContext().actorSelection(path).forward(message, getContext());
+ getContext().actorSelection(path).forward(new RemoteFindPrimary(shardName,
+ message.isWaitUntilReady()), getContext());
return;
}
}
private ActorRef actor;
private ActorPath actorPath;
private final Map<String, String> peerAddresses;
+ private Optional<DataTree> localShardDataTree;
// flag that determines if the actor is ready for business
private boolean actorInitialized = false;
return shardId;
}
+ void setLocalDataTree(Optional<DataTree> localShardDataTree) {
+ this.localShardDataTree = localShardDataTree;
+ }
+
+ Optional<DataTree> getLocalShardDataTree() {
+ return localShardDataTree;
+ }
+
Map<String, String> getPeerAddresses() {
return peerAddresses;
}
}
boolean isShardReadyWithLeaderId() {
- return isShardReady() && (isLeader() || peerAddresses.containsKey(leaderId));
+ return isShardReady() && (isLeader() || peerAddresses.get(leaderId) != null);
}
boolean isShardInitialized() {
import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState;
import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
import org.opendaylight.controller.md.sal.common.util.jmx.QueuedNotificationManagerMXBeanImpl;
-import org.opendaylight.controller.md.sal.common.util.jmx.ThreadExecutorStats;
import org.opendaylight.controller.md.sal.common.util.jmx.ThreadExecutorStatsMXBeanImpl;
import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
-import org.opendaylight.yangtools.util.concurrent.ListenerNotificationQueueStats;
import org.opendaylight.yangtools.util.concurrent.QueuedNotificationManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return getOnDemandRaftState().getInMemoryJournalLogSize();
}
- @Override
- public ThreadExecutorStats getDataStoreExecutorStats() {
- // FIXME: this particular thing does not work, as it really is DS-specific
- return null;
- }
-
- @Override
- public ThreadExecutorStats getNotificationMgrExecutorStats() {
- return notificationExecutorStatsBean.toThreadExecutorStats();
- }
-
- @Override
- public List<ListenerNotificationQueueStats> getCurrentNotificationMgrListenerQueueStats() {
- return notificationManagerStatsBean.getCurrentListenerQueueStats();
- }
-
- @Override
- public int getMaxNotificationMgrListenerQueueSize() {
- return notificationManagerStatsBean.getMaxListenerQueueSize();
- }
-
/**
* resets the counters related to transactions
*/
import java.util.List;
import org.opendaylight.controller.cluster.raft.client.messages.FollowerInfo;
-import org.opendaylight.controller.md.sal.common.util.jmx.ThreadExecutorStats;
-import org.opendaylight.yangtools.util.concurrent.ListenerNotificationQueueStats;
/**
* @author: syedbahm
boolean isSnapshotCaptureInitiated();
- ThreadExecutorStats getDataStoreExecutorStats();
-
- ThreadExecutorStats getNotificationMgrExecutorStats();
-
- List<ListenerNotificationQueueStats> getCurrentNotificationMgrListenerQueueStats();
-
- int getMaxNotificationMgrListenerQueueSize();
-
void resetTransactionCounters();
long getInMemoryJournalDataSize();
private final String shardName;
private final boolean waitUntilReady;
- public FindPrimary(String shardName, boolean waitUntilReady){
+ public FindPrimary(String shardName, boolean waitUntilReady) {
Preconditions.checkNotNull(shardName, "shardName should not be null");
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("FindPrimary [shardName=").append(shardName).append(", waitUntilReady=").append(waitUntilReady)
- .append("]");
+ builder.append(getClass().getName()).append(" [shardName=").append(shardName).append(", waitUntilReady=")
+ .append(waitUntilReady).append("]");
return builder.toString();
}
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Brocade Communications 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.messages;
+
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import org.apache.commons.lang3.ObjectUtils;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+
+/**
+ * Local message sent in reply to FindPrimaryShard to indicate the primary shard is local to the caller.
+ *
+ * @author Thomas Pantelis
+ */
+public class LocalPrimaryShardFound {
+
+ private final String primaryPath;
+ private final DataTree localShardDataTree;
+
+ public LocalPrimaryShardFound(@Nonnull String primaryPath, @Nonnull DataTree localShardDataTree) {
+ this.primaryPath = Preconditions.checkNotNull(primaryPath);
+ this.localShardDataTree = Preconditions.checkNotNull(localShardDataTree);
+ }
+
+ public @Nonnull String getPrimaryPath() {
+ return primaryPath;
+ }
+
+ public @Nonnull DataTree getLocalShardDataTree() {
+ return localShardDataTree;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("LocalPrimaryShardFound [primaryPath=").append(primaryPath).append(", localShardDataTree=")
+ .append(ObjectUtils.identityToString(localShardDataTree)).append("]");
+ return builder.toString();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Brocade Communications 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.messages;
+
+/**
+ * A remote message sent to locate the primary shard.
+ *
+ * @author Thomas Pantelis
+ */
+public class RemoteFindPrimary extends FindPrimary {
+ private static final long serialVersionUID = 1L;
+
+ public RemoteFindPrimary(String shardName, boolean waitUntilReady) {
+ super(shardName, waitUntilReady);
+ }
+}
import java.io.Serializable;
-public class PrimaryFound implements Serializable {
+/**
+ * Local or remote message sent in reply to FindPrimaryShard to indicate the primary shard is remote to the caller.
+ */
+public class RemotePrimaryShardFound implements Serializable {
private static final long serialVersionUID = 1L;
private final String primaryPath;
- public PrimaryFound(final String primaryPath) {
+ public RemotePrimaryShardFound(final String primaryPath) {
this.primaryPath = primaryPath;
}
return primaryPath;
}
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- PrimaryFound that = (PrimaryFound) o;
-
- if (!primaryPath.equals(that.primaryPath)) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return primaryPath.hashCode();
- }
-
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("PrimaryFound [primaryPath=").append(primaryPath).append("]");
+ builder.append("RemotePrimaryShardFound [primaryPath=").append(primaryPath).append("]");
return builder.toString();
}
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Brocade Communications 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.messages;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.notifications.LeaderStateChanged;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+
+/**
+ * A local message derived from LeaderStateChanged containing additional Shard-specific info that is sent
+ * when some state of the shard leader has changed. This message is used by the ShardManager to maintain
+ * current Shard information.
+ *
+ * @author Thomas Pantelis
+ */
+public class ShardLeaderStateChanged extends LeaderStateChanged {
+
+ private final Optional<DataTree> localShardDataTree;
+
+ public ShardLeaderStateChanged(@Nonnull String memberId, @Nonnull String leaderId,
+ @Nonnull Optional<DataTree> localShardDataTree) {
+ super(memberId, leaderId);
+ this.localShardDataTree = Preconditions.checkNotNull(localShardDataTree);
+ }
+
+ public @Nonnull Optional<DataTree> getLocalShardDataTree() {
+ return localShardDataTree;
+ }
+}
import org.opendaylight.controller.cluster.datastore.exceptions.UnknownMessageException;
import org.opendaylight.controller.cluster.datastore.messages.FindLocalShard;
import org.opendaylight.controller.cluster.datastore.messages.FindPrimary;
+import org.opendaylight.controller.cluster.datastore.messages.LocalPrimaryShardFound;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardFound;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardNotFound;
-import org.opendaylight.controller.cluster.datastore.messages.PrimaryFound;
import org.opendaylight.controller.cluster.datastore.messages.PrimaryShardInfo;
+import org.opendaylight.controller.cluster.datastore.messages.RemotePrimaryShardFound;
import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
import org.opendaylight.controller.cluster.reporting.MetricsReporter;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
return future.transform(new Mapper<Object, PrimaryShardInfo>() {
@Override
public PrimaryShardInfo checkedApply(Object response) throws Exception {
- if(response instanceof PrimaryFound) {
- PrimaryFound found = (PrimaryFound)response;
-
- LOG.debug("Primary found {}", found.getPrimaryPath());
- ActorSelection actorSelection = actorSystem.actorSelection(found.getPrimaryPath());
- PrimaryShardInfo info = new PrimaryShardInfo(actorSelection, Optional.<DataTree>absent());
- primaryShardInfoCache.put(shardName, Futures.successful(info));
- return info;
+ if(response instanceof RemotePrimaryShardFound) {
+ LOG.debug("findPrimaryShardAsync received: {}", response);
+ return onPrimaryShardFound(shardName, ((RemotePrimaryShardFound)response).getPrimaryPath(), null);
+ } else if(response instanceof LocalPrimaryShardFound) {
+ LOG.debug("findPrimaryShardAsync received: {}", response);
+ LocalPrimaryShardFound found = (LocalPrimaryShardFound)response;
+ return onPrimaryShardFound(shardName, found.getPrimaryPath(), found.getLocalShardDataTree());
} else if(response instanceof NotInitializedException) {
throw (NotInitializedException)response;
} else if(response instanceof PrimaryNotFoundException) {
}, FIND_PRIMARY_FAILURE_TRANSFORMER, getClientDispatcher());
}
+ private PrimaryShardInfo onPrimaryShardFound(String shardName, String primaryActorPath,
+ DataTree localShardDataTree) {
+ ActorSelection actorSelection = actorSystem.actorSelection(primaryActorPath);
+ PrimaryShardInfo info = new PrimaryShardInfo(actorSelection, Optional.fromNullable(localShardDataTree));
+ primaryShardInfoCache.put(shardName, Futures.successful(info));
+ return info;
+ }
+
/**
* Finds a local shard given its shard name and return it's ActorRef
*
package org.opendaylight.controller.cluster.datastore;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
domDataWriteTransaction.put(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.builder().build(), mock(NormalizedNode.class));
}
+ @Test
+ public void testEmptyTransactionSubmitSucceeds() throws ExecutionException, InterruptedException {
+ DOMStore domStore = mock(DOMStore.class);
+ ConcurrentDOMDataBroker dataBroker = new ConcurrentDOMDataBroker(ImmutableMap.of(LogicalDatastoreType.OPERATIONAL,
+ domStore, LogicalDatastoreType.CONFIGURATION, domStore), futureExecutor);
+
+ CheckedFuture<Void, TransactionCommitFailedException> submit1 = dataBroker.newWriteOnlyTransaction().submit();
+
+ assertNotNull(submit1);
+
+ submit1.get();
+
+ CheckedFuture<Void, TransactionCommitFailedException> submit2 = dataBroker.newReadWriteTransaction().submit();
+
+ assertNotNull(submit2);
+
+ submit2.get();
+ }
+
}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import akka.testkit.JavaTestKit;
import akka.testkit.TestActorRef;
import akka.util.Timeout;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.opendaylight.controller.cluster.datastore.messages.ActorInitialized;
import org.opendaylight.controller.cluster.datastore.messages.FindLocalShard;
import org.opendaylight.controller.cluster.datastore.messages.FindPrimary;
+import org.opendaylight.controller.cluster.datastore.messages.LocalPrimaryShardFound;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardFound;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardNotFound;
-import org.opendaylight.controller.cluster.datastore.messages.PrimaryFound;
+import org.opendaylight.controller.cluster.datastore.messages.RemotePrimaryShardFound;
+import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged;
import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
import org.opendaylight.controller.cluster.datastore.utils.MessageCollectorActor;
import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
import org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus;
import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import scala.concurrent.Await;
shardManager.tell(new UpdateSchemaContext(TestModel.createTestContext()), getRef());
shardManager.tell(new ActorInitialized(), mockShardActor);
- shardManager.tell(new LeaderStateChanged(memberId, memberId), getRef());
+ DataTree mockDataTree = mock(DataTree.class);
+ shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree)), getRef());
MessageCollectorActor.expectFirstMatching(mockShardActor, RegisterRoleChangeListener.class);
shardManager.tell((new RoleChangeNotification(memberId, RaftState.Candidate.name(),
shardManager.tell(new FindPrimary(Shard.DEFAULT_NAME, false), getRef());
- PrimaryFound primaryFound = expectMsgClass(duration("5 seconds"), PrimaryFound.class);
+ LocalPrimaryShardFound primaryFound = expectMsgClass(duration("5 seconds"), LocalPrimaryShardFound.class);
assertTrue("Unexpected primary path " + primaryFound.getPrimaryPath(),
primaryFound.getPrimaryPath().contains("member-1-shard-default"));
+ assertSame("getLocalShardDataTree", mockDataTree, primaryFound.getLocalShardDataTree() );
+ }};
+ }
+
+ @Test
+ public void testOnReceiveFindPrimaryForNonLocalLeaderShardBeforeMemberUp() throws Exception {
+ new JavaTestKit(getSystem()) {{
+ final ActorRef shardManager = getSystem().actorOf(newPropsShardMgrWithMockShardActor());
+
+ shardManager.tell(new UpdateSchemaContext(TestModel.createTestContext()), getRef());
+ shardManager.tell(new ActorInitialized(), mockShardActor);
+
+ String memberId2 = "member-2-shard-default-" + shardMrgIDSuffix;
+ String memberId1 = "member-1-shard-default-" + shardMrgIDSuffix;
+ shardManager.tell(new RoleChangeNotification(memberId1,
+ RaftState.Candidate.name(), RaftState.Follower.name()), mockShardActor);
+ shardManager.tell(new LeaderStateChanged(memberId1, memberId2), mockShardActor);
+
+ shardManager.tell(new FindPrimary(Shard.DEFAULT_NAME, false), getRef());
+
+ expectMsgClass(duration("5 seconds"), NoShardLeaderException.class);
}};
}
String memberId1 = "member-1-shard-default-" + shardMrgIDSuffix;
shardManager.tell(new RoleChangeNotification(memberId1,
RaftState.Candidate.name(), RaftState.Follower.name()), mockShardActor);
- shardManager.tell(new LeaderStateChanged(memberId1, memberId2), mockShardActor);
+ shardManager.tell(new ShardLeaderStateChanged(memberId1, memberId2, Optional.<DataTree>absent()), mockShardActor);
shardManager.tell(new FindPrimary(Shard.DEFAULT_NAME, false), getRef());
- PrimaryFound primaryFound = expectMsgClass(duration("5 seconds"), PrimaryFound.class);
+ RemotePrimaryShardFound primaryFound = expectMsgClass(duration("5 seconds"), RemotePrimaryShardFound.class);
assertTrue("Unexpected primary path " + primaryFound.getPrimaryPath(),
primaryFound.getPrimaryPath().contains("member-2-shard-default"));
}};
expectMsgClass(duration("5 seconds"), NoShardLeaderException.class);
- shardManager.tell(new LeaderStateChanged(memberId, memberId), mockShardActor);
+ DataTree mockDataTree = mock(DataTree.class);
+ shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree)), mockShardActor);
shardManager.tell(new FindPrimary(Shard.DEFAULT_NAME, false), getRef());
- PrimaryFound primaryFound = expectMsgClass(duration("5 seconds"), PrimaryFound.class);
+ LocalPrimaryShardFound primaryFound = expectMsgClass(duration("5 seconds"), LocalPrimaryShardFound.class);
assertTrue("Unexpected primary path " + primaryFound.getPrimaryPath(),
primaryFound.getPrimaryPath().contains("member-1-shard-default"));
+ assertSame("getLocalShardDataTree", mockDataTree, primaryFound.getLocalShardDataTree() );
}};
}
expectNoMsg(FiniteDuration.create(150, TimeUnit.MILLISECONDS));
- shardManager.tell(new LeaderStateChanged(memberId, memberId), mockShardActor);
+ DataTree mockDataTree = mock(DataTree.class);
+ shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree)), mockShardActor);
- PrimaryFound primaryFound = expectMsgClass(duration("5 seconds"), PrimaryFound.class);
+ LocalPrimaryShardFound primaryFound = expectMsgClass(duration("5 seconds"), LocalPrimaryShardFound.class);
assertTrue("Unexpected primary path " + primaryFound.getPrimaryPath(),
primaryFound.getPrimaryPath().contains("member-1-shard-default"));
+ assertSame("getLocalShardDataTree", mockDataTree, primaryFound.getLocalShardDataTree() );
expectNoMsg(FiniteDuration.create(200, TimeUnit.MILLISECONDS));
}};
shardManager2.tell(new ActorInitialized(), mockShardActor2);
String memberId2 = "member-2-shard-astronauts-" + shardMrgIDSuffix;
- shardManager2.tell(new LeaderStateChanged(memberId2, memberId2), mockShardActor2);
+ shardManager2.tell(new ShardLeaderStateChanged(memberId2, memberId2,
+ Optional.of(mock(DataTree.class))), mockShardActor2);
shardManager2.tell(new RoleChangeNotification(memberId2,
RaftState.Candidate.name(), RaftState.Leader.name()), mockShardActor2);
shardManager1.tell(new FindPrimary("astronauts", false), getRef());
- PrimaryFound found = expectMsgClass(duration("5 seconds"), PrimaryFound.class);
+ RemotePrimaryShardFound found = expectMsgClass(duration("5 seconds"), RemotePrimaryShardFound.class);
String path = found.getPrimaryPath();
assertTrue("Unexpected primary path " + path, path.contains("member-2-shard-astronauts-config"));
}
@Test
- public void testRoleChangeNotificationAndLeaderStateChangedReleaseReady() throws Exception {
+ public void testRoleChangeNotificationAndShardLeaderStateChangedReleaseReady() throws Exception {
new JavaTestKit(getSystem()) {
{
TestActorRef<ShardManager> shardManager = TestActorRef.create(getSystem(), newShardMgrProps());
verify(ready, never()).countDown();
- shardManager.underlyingActor().onReceiveCommand(new LeaderStateChanged(memberId, memberId));
+ shardManager.underlyingActor().onReceiveCommand(new ShardLeaderStateChanged(memberId, memberId,
+ Optional.of(mock(DataTree.class))));
verify(ready, times(1)).countDown();
}
@Test
- public void testRoleChangeNotificationToFollowerWithLeaderStateChangedReleaseReady() throws Exception {
+ public void testRoleChangeNotificationToFollowerWithShardLeaderStateChangedReleaseReady() throws Exception {
new JavaTestKit(getSystem()) {
{
TestActorRef<ShardManager> shardManager = TestActorRef.create(getSystem(), newShardMgrProps());
verify(ready, never()).countDown();
- shardManager.underlyingActor().onReceiveCommand(new LeaderStateChanged(memberId, "member-2-shard-default-" + shardMrgIDSuffix));
+ shardManager.underlyingActor().onReceiveCommand(MockClusterWrapper.createMemberUp("member-2", getRef().path().toString()));
+
+ shardManager.underlyingActor().onReceiveCommand(new ShardLeaderStateChanged(memberId,
+ "member-2-shard-default-" + shardMrgIDSuffix, Optional.of(mock(DataTree.class))));
verify(ready, times(1)).countDown();
}};
}
+ @Test
+ public void testReadyCountDownForMemberUpAfterLeaderStateChanged() throws Exception {
+ new JavaTestKit(getSystem()) {
+ {
+ TestActorRef<ShardManager> shardManager = TestActorRef.create(getSystem(), newShardMgrProps());
+
+ String memberId = "member-1-shard-default-" + shardMrgIDSuffix;
+ shardManager.underlyingActor().onReceiveCommand(new RoleChangeNotification(
+ memberId, null, RaftState.Follower.name()));
+
+ verify(ready, never()).countDown();
+
+ shardManager.underlyingActor().onReceiveCommand(new ShardLeaderStateChanged(memberId,
+ "member-2-shard-default-" + shardMrgIDSuffix, Optional.of(mock(DataTree.class))));
+
+ shardManager.underlyingActor().onReceiveCommand(MockClusterWrapper.createMemberUp("member-2", getRef().path().toString()));
+
+ verify(ready, times(1)).countDown();
+
+ }};
+ }
@Test
public void testRoleChangeNotificationDoNothingForUnknownShard() throws Exception {
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListenerReply;
import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener;
import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListenerReply;
+import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged;
import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
import org.opendaylight.controller.cluster.datastore.modification.DeleteModification;
import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
import org.opendaylight.controller.cluster.datastore.modification.ModificationPayload;
import org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification;
import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
-import org.opendaylight.controller.cluster.datastore.utils.MessageCollectorActor;
import org.opendaylight.controller.cluster.datastore.utils.MockDataChangeListener;
import org.opendaylight.controller.cluster.datastore.utils.MockDataTreeChangeListener;
import org.opendaylight.controller.cluster.datastore.utils.SerializationUtils;
import org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus;
import org.opendaylight.controller.cluster.raft.client.messages.FindLeader;
import org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply;
+import org.opendaylight.controller.cluster.raft.messages.RequestVote;
import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
import org.opendaylight.controller.cluster.raft.utils.InMemorySnapshotStore;
+import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
shard.tell(new RegisterRoleChangeListener(), listener);
- // TODO: MessageCollectorActor exists as a test util in both the akka-raft and distributed-datastore
- // projects. Need to move it to commons as a regular utility and then we can get rid of this arbitrary
- // sleep.
- Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
+ MessageCollectorActor.expectFirstMatching(listener, RegisterRoleChangeListenerReply.class);
- List<Object> allMatching = MessageCollectorActor.getAllMatching(listener, RegisterRoleChangeListenerReply.class);
+ ShardLeaderStateChanged leaderStateChanged = MessageCollectorActor.expectFirstMatching(listener,
+ ShardLeaderStateChanged.class);
+ assertEquals("getLocalShardDataTree present", true,
+ leaderStateChanged.getLocalShardDataTree().isPresent());
+ assertSame("getLocalShardDataTree", shard.underlyingActor().getDataStore().getDataTree(),
+ leaderStateChanged.getLocalShardDataTree().get());
- assertEquals(1, allMatching.size());
+ MessageCollectorActor.clearMessages(listener);
+
+ // Force a leader change
+
+ shard.tell(new RequestVote(10000, "member2", 50, 50), getRef());
+
+ leaderStateChanged = MessageCollectorActor.expectFirstMatching(listener,
+ ShardLeaderStateChanged.class);
+ assertEquals("getLocalShardDataTree present", false,
+ leaderStateChanged.getLocalShardDataTree().isPresent());
+
+ shard.tell(PoisonPill.getInstance(), ActorRef.noSender());
}
};
}
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doReturn;
import org.apache.commons.lang.time.StopWatch;
import org.junit.Assert;
import org.junit.Test;
+import org.mockito.Mockito;
import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
import org.opendaylight.controller.cluster.datastore.ClusterWrapper;
import org.opendaylight.controller.cluster.datastore.Configuration;
import org.opendaylight.controller.cluster.datastore.exceptions.PrimaryNotFoundException;
import org.opendaylight.controller.cluster.datastore.messages.FindLocalShard;
import org.opendaylight.controller.cluster.datastore.messages.FindPrimary;
+import org.opendaylight.controller.cluster.datastore.messages.LocalPrimaryShardFound;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardFound;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardNotFound;
-import org.opendaylight.controller.cluster.datastore.messages.PrimaryFound;
import org.opendaylight.controller.cluster.datastore.messages.PrimaryShardInfo;
+import org.opendaylight.controller.cluster.datastore.messages.RemotePrimaryShardFound;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.concurrent.Await;
}
@Test
- public void testFindPrimaryShardAsyncPrimaryFound() throws Exception {
+ public void testFindPrimaryShardAsyncRemotePrimaryFound() throws Exception {
TestActorRef<MessageCollectorActor> shardManager =
TestActorRef.create(getSystem(), Props.create(MessageCollectorActor.class));
mock(Configuration.class), dataStoreContext) {
@Override
protected Future<Object> doAsk(ActorRef actorRef, Object message, Timeout timeout) {
- return Futures.successful((Object) new PrimaryFound(expPrimaryPath));
+ return Futures.successful((Object) new RemotePrimaryShardFound(expPrimaryPath));
}
};
-
Future<PrimaryShardInfo> foobar = actorContext.findPrimaryShardAsync("foobar");
PrimaryShardInfo actual = Await.result(foobar, Duration.apply(5000, TimeUnit.MILLISECONDS));
cached = actorContext.getPrimaryShardInfoCache().getIfPresent("foobar");
assertNull(cached);
+ }
+
+ @Test
+ public void testFindPrimaryShardAsyncLocalPrimaryFound() throws Exception {
+
+ TestActorRef<MessageCollectorActor> shardManager =
+ TestActorRef.create(getSystem(), Props.create(MessageCollectorActor.class));
+
+ DatastoreContext dataStoreContext = DatastoreContext.newBuilder().dataStoreType("config").
+ shardLeaderElectionTimeout(100, TimeUnit.MILLISECONDS).build();
+ final DataTree mockDataTree = Mockito.mock(DataTree.class);
+ final String expPrimaryPath = "akka://test-system/find-primary-shard";
+ ActorContext actorContext =
+ new ActorContext(getSystem(), shardManager, mock(ClusterWrapper.class),
+ mock(Configuration.class), dataStoreContext) {
+ @Override
+ protected Future<Object> doAsk(ActorRef actorRef, Object message, Timeout timeout) {
+ return Futures.successful((Object) new LocalPrimaryShardFound(expPrimaryPath, mockDataTree));
+ }
+ };
+
+ Future<PrimaryShardInfo> foobar = actorContext.findPrimaryShardAsync("foobar");
+ PrimaryShardInfo actual = Await.result(foobar, Duration.apply(5000, TimeUnit.MILLISECONDS));
+
+ assertNotNull(actual);
+ assertEquals("LocalShardDataTree present", true, actual.getLocalShardDataTree().isPresent());
+ assertSame("LocalShardDataTree", mockDataTree, actual.getLocalShardDataTree().get());
+ assertTrue("Unexpected PrimaryShardActor path " + actual.getPrimaryShardActor().path(),
+ expPrimaryPath.endsWith(actual.getPrimaryShardActor().pathString()));
+
+ Future<PrimaryShardInfo> cached = actorContext.getPrimaryShardInfoCache().getIfPresent("foobar");
+
+ PrimaryShardInfo cachedInfo = Await.result(cached, FiniteDuration.apply(1, TimeUnit.MILLISECONDS));
+
+ assertEquals(cachedInfo, actual);
+
+ // Wait for 200 Milliseconds. The cached entry should have been removed.
+
+ Uninterruptibles.sleepUninterruptibly(200, TimeUnit.MILLISECONDS);
+
+ cached = actorContext.getPrimaryShardInfoCache().getIfPresent("foobar");
+
+ assertNull(cached);
}
@Test
TestActorRef<MockShardManager> shardManagerActorRef = TestActorRef.create(getSystem(), MockShardManager.props());
MockShardManager shardManagerActor = shardManagerActorRef.underlyingActor();
- shardManagerActor.addFindPrimaryResp("shard1", new PrimaryFound(shardActorRef1.path().toString()));
- shardManagerActor.addFindPrimaryResp("shard2", new PrimaryFound(shardActorRef2.path().toString()));
+ shardManagerActor.addFindPrimaryResp("shard1", new RemotePrimaryShardFound(shardActorRef1.path().toString()));
+ shardManagerActor.addFindPrimaryResp("shard2", new RemotePrimaryShardFound(shardActorRef2.path().toString()));
shardManagerActor.addFindPrimaryResp("shard3", new NoShardLeaderException("not found"));
Configuration mockConfig = mock(Configuration.class);
}
- private static ClusterEvent.MemberUp createMemberUp(String memberName, String address) {
+ public static ClusterEvent.MemberUp createMemberUp(String memberName, String address) {
akka.cluster.UniqueAddress uniqueAddress = new UniqueAddress(
AddressFromURIString.parse(address), 55);
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-core-api</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-broker-impl</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-core-spi</artifactId>
<packaging>bundle</packaging>
<parent>\r
<artifactId>sal-parent</artifactId>\r
<groupId>org.opendaylight.controller</groupId>\r
- <version>1.2.0-SNAPSHOT</version>\r
+ <version>1.3.0-SNAPSHOT</version>\r
</parent>\r
<artifactId>sal-dom-xsql-config</artifactId>\r
<description>Configuration files for md-sal</description>\r
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-dom-xsql</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-dummy-distributed-datastore</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-inmemory-datastore</artifactId>
<parent>\r
<artifactId>sal-parent</artifactId>\r
<groupId>org.opendaylight.controller</groupId>\r
- <version>1.2.0-SNAPSHOT</version>\r
+ <version>1.3.0-SNAPSHOT</version>\r
</parent>\r
\r
<groupId>org.opendaylight.controller</groupId>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>sal-dom-xsql</artifactId>\r
- <version>1.2.0-SNAPSHOT</version>\r
+ <version>1.3.0-SNAPSHOT</version>\r
</dependency>\r
</dependencies>\r
\r
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-netconf-connector</artifactId>
+++ /dev/null
-/*
- * Copyright (c) 2015 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.connect.netconf.util;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Transforms an instance of yang instance identifier to a filter like structure in normalized node format. Can be also used to nest the edit-config rpc content.
- * For each argument of the id, a specific normalized node is created to ensure schema context conformance.
- */
-public abstract class InstanceIdToNodes<T extends PathArgument> implements Identifiable<T> {
-
- private final T identifier;
-
- @Override
- public T getIdentifier() {
- return identifier;
- }
-
- protected InstanceIdToNodes(final T identifier) {
- this.identifier = identifier;
- }
-
- abstract InstanceIdToNodes<?> getChild(final PathArgument child) throws DataNormalizationException;
-
- public abstract NormalizedNode<?, ?> create(YangInstanceIdentifier legacyData, Optional<NormalizedNode<?, ?>> deepestChild, Optional<ModifyAction> operation);
-
- private static abstract class SimpleTypeNormalization<T extends PathArgument> extends InstanceIdToNodes<T> {
-
- protected SimpleTypeNormalization(final T identifier) {
- super(identifier);
- }
-
- @Override
- public NormalizedNode<?, ?> create(final YangInstanceIdentifier id, final Optional<NormalizedNode<?, ?>> deepestChild, final Optional<ModifyAction> operation) {
- checkNotNull(id);
- final PathArgument pathArgument = Iterables.get(id.getPathArguments(), 0);
- final NormalizedNodeAttrBuilder<? extends PathArgument, Object, ? extends NormalizedNode<? extends PathArgument, Object>> builder = getBuilder(pathArgument);
-
- if(deepestChild.isPresent()) {
- builder.withValue(deepestChild.get().getValue());
- }
-
- addModifyOpIfPresent(operation, builder);
- return builder.build();
- }
-
- protected abstract NormalizedNodeAttrBuilder<? extends PathArgument, Object, ? extends NormalizedNode<? extends PathArgument, Object>> getBuilder(PathArgument node);
-
- @Override
- public InstanceIdToNodes<?> getChild(final PathArgument child) {
- return null;
- }
- }
-
-
- public void addModifyOpIfPresent(final Optional<ModifyAction> operation, final AttributesBuilder<?> builder) {
- if(operation.isPresent()) {
- builder.withAttributes(Collections.singletonMap(NetconfMessageTransformUtil.NETCONF_OPERATION_QNAME, NetconfMessageTransformUtil.modifyOperationToXmlString(operation.get())));
- }
- }
-
- private static final class LeafNormalization extends SimpleTypeNormalization<NodeIdentifier> {
-
- protected LeafNormalization(final LeafSchemaNode potential) {
- super(new NodeIdentifier(potential.getQName()));
- }
-
- @Override
- protected NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> getBuilder(final PathArgument node) {
- return Builders.leafBuilder().withNodeIdentifier(getIdentifier());
- }
- }
-
- private static final class LeafListEntryNormalization extends SimpleTypeNormalization<NodeWithValue> {
-
- public LeafListEntryNormalization(final LeafListSchemaNode potential) {
- super(new NodeWithValue(potential.getQName(), null));
- }
-
- @Override
- protected NormalizedNodeAttrBuilder<NodeWithValue, Object, LeafSetEntryNode<Object>> getBuilder(final PathArgument node) {
- Preconditions.checkArgument(node instanceof NodeWithValue);
- return Builders.leafSetEntryBuilder().withNodeIdentifier((NodeWithValue) node).withValue(((NodeWithValue) node).getValue());
- }
-
- }
-
- private static abstract class CompositeNodeNormalizationOperation<T extends PathArgument> extends
- InstanceIdToNodes<T> {
-
- protected CompositeNodeNormalizationOperation(final T identifier) {
- super(identifier);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public final NormalizedNode<?, ?> create(final YangInstanceIdentifier id, final Optional<NormalizedNode<?, ?>> lastChild, final Optional<ModifyAction> operation) {
- checkNotNull(id);
- final Iterator<PathArgument> iterator = id.getPathArguments().iterator();
- final PathArgument legacyData = iterator.next();
-
- if (!isMixin(this) && getIdentifier().getNodeType() != null) {
- checkArgument(getIdentifier().getNodeType().equals(legacyData.getNodeType()),
- "Node QName must be %s was %s", getIdentifier().getNodeType(), legacyData.getNodeType());
- }
- final NormalizedNodeContainerBuilder builder = createBuilder(legacyData);
-
- if (iterator.hasNext()) {
- final PathArgument childPath = iterator.next();
- final InstanceIdToNodes childOp = getChildOperation(childPath);
-
- final YangInstanceIdentifier childId = YangInstanceIdentifier.create(Iterables.skip(id.getPathArguments(), 1));
- builder.addChild(childOp.create(childId, lastChild, operation));
- } else {
- if(lastChild.isPresent()) {
- builder.withValue(Lists.newArrayList((Collection<?>) lastChild.get().getValue()));
- }
- if(operation.isPresent()) {
- Preconditions.checkArgument(builder instanceof AttributesBuilder<?>);
- addModifyOpIfPresent(operation, ((AttributesBuilder<?>) builder));
- }
- }
-
- return builder.build();
- }
-
- private InstanceIdToNodes getChildOperation(final PathArgument childPath) {
- final InstanceIdToNodes childOp;
- try {
- childOp = getChild(childPath);
- } catch (final DataNormalizationException e) {
- throw new IllegalArgumentException(String.format("Failed to process child node %s", childPath), e);
- }
- checkArgument(childOp != null, "Node %s is not allowed inside %s", childPath, getIdentifier());
- return childOp;
- }
-
- @SuppressWarnings("rawtypes")
- protected abstract NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode);
- }
-
- static boolean isMixin(final InstanceIdToNodes<?> op) {
- return op instanceof MixinNormalizationOp;
- }
-
- private static abstract class DataContainerNormalizationOperation<T extends PathArgument> extends
- CompositeNodeNormalizationOperation<T> {
-
- private final DataNodeContainer schema;
- private final Map<PathArgument, InstanceIdToNodes<?>> byArg;
-
- protected DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema) {
- super(identifier);
- this.schema = schema;
- this.byArg = new ConcurrentHashMap<>();
- }
-
- @Override
- public InstanceIdToNodes<?> getChild(final PathArgument child) throws DataNormalizationException {
- InstanceIdToNodes<?> potential = byArg.get(child);
- if (potential != null) {
- return potential;
- }
- potential = fromLocalSchema(child);
- return register(potential);
- }
-
- private InstanceIdToNodes<?> fromLocalSchema(final PathArgument child) throws DataNormalizationException {
- if (child instanceof AugmentationIdentifier) {
- return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames()
- .iterator().next());
- }
- return fromSchemaAndQNameChecked(schema, child.getNodeType());
- }
-
- private InstanceIdToNodes<?> register(final InstanceIdToNodes<?> potential) {
- if (potential != null) {
- byArg.put(potential.getIdentifier(), potential);
- }
- return potential;
- }
- }
-
- private static final class ListItemNormalization extends
- DataContainerNormalizationOperation<NodeIdentifierWithPredicates> {
-
- protected ListItemNormalization(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) {
- super(identifier, schema);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument currentArg) {
- final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder = Builders
- .mapEntryBuilder().withNodeIdentifier((NodeIdentifierWithPredicates) currentArg);
- for (final Entry<QName, Object> keyValue : ((NodeIdentifierWithPredicates) currentArg).getKeyValues().entrySet()) {
- builder.addChild(Builders.leafBuilder()
- //
- .withNodeIdentifier(new NodeIdentifier(keyValue.getKey())).withValue(keyValue.getValue())
- .build());
- }
- return builder;
- }
-
- }
-
- private static final class UnkeyedListItemNormalization extends DataContainerNormalizationOperation<NodeIdentifier> {
-
- protected UnkeyedListItemNormalization(final ListSchemaNode schema) {
- super(new NodeIdentifier(schema.getQName()), schema);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.unkeyedListEntryBuilder().withNodeIdentifier(getIdentifier());
- }
-
- }
-
- private static final class ContainerTransformation extends DataContainerNormalizationOperation<NodeIdentifier> {
-
- protected ContainerTransformation(final ContainerSchemaNode schema) {
- super(new NodeIdentifier(schema.getQName()), schema);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.containerBuilder().withNodeIdentifier(getIdentifier());
- }
- }
-
- /**
- * Marker interface for Mixin nodes normalization operations
- */
- private interface MixinNormalizationOp {}
-
-
- private static final class OrderedLeafListMixinNormalization extends UnorderedLeafListMixinNormalization {
-
-
- public OrderedLeafListMixinNormalization(final LeafListSchemaNode potential) {
- super(potential);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier());
- }
- }
-
- private static class UnorderedLeafListMixinNormalization extends CompositeNodeNormalizationOperation<NodeIdentifier> implements MixinNormalizationOp {
-
- private final InstanceIdToNodes<?> innerOp;
-
- public UnorderedLeafListMixinNormalization(final LeafListSchemaNode potential) {
- super(new NodeIdentifier(potential.getQName()));
- innerOp = new LeafListEntryNormalization(potential);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier());
- }
-
- @Override
- public InstanceIdToNodes<?> getChild(final PathArgument child) {
- if (child instanceof NodeWithValue) {
- return innerOp;
- }
- return null;
- }
- }
-
- private static final class AugmentationNormalization extends DataContainerNormalizationOperation<AugmentationIdentifier> implements MixinNormalizationOp {
-
- public AugmentationNormalization(final AugmentationSchema augmentation, final DataNodeContainer schema) {
- //super();
- super(augmentationIdentifierFrom(augmentation), augmentationProxy(augmentation, schema));
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier());
- }
- }
-
- private static class UnorderedMapMixinNormalization extends CompositeNodeNormalizationOperation<NodeIdentifier> implements MixinNormalizationOp {
-
- private final ListItemNormalization innerNode;
-
- public UnorderedMapMixinNormalization(final ListSchemaNode list) {
- super(new NodeIdentifier(list.getQName()));
- this.innerNode = new ListItemNormalization(new NodeIdentifierWithPredicates(list.getQName(),
- Collections.<QName, Object>emptyMap()), list);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.mapBuilder().withNodeIdentifier(getIdentifier());
- }
-
- @Override
- public InstanceIdToNodes<?> getChild(final PathArgument child) {
- if (child.getNodeType().equals(getIdentifier().getNodeType())) {
- return innerNode;
- }
- return null;
- }
- }
-
- private static class UnkeyedListMixinNormalization extends CompositeNodeNormalizationOperation<NodeIdentifier> implements MixinNormalizationOp {
-
- private final UnkeyedListItemNormalization innerNode;
-
- public UnkeyedListMixinNormalization(final ListSchemaNode list) {
- super(new NodeIdentifier(list.getQName()));
- this.innerNode = new UnkeyedListItemNormalization(list);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.unkeyedListBuilder().withNodeIdentifier(getIdentifier());
- }
-
- @Override
- public InstanceIdToNodes<?> getChild(final PathArgument child) {
- if (child.getNodeType().equals(getIdentifier().getNodeType())) {
- return innerNode;
- }
- return null;
- }
-
- }
-
- private static final class OrderedMapMixinNormalization extends UnorderedMapMixinNormalization {
-
- public OrderedMapMixinNormalization(final ListSchemaNode list) {
- super(list);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.orderedMapBuilder().withNodeIdentifier(getIdentifier());
- }
-
- }
-
- private static class ChoiceNodeNormalization extends CompositeNodeNormalizationOperation<NodeIdentifier> implements MixinNormalizationOp {
-
- private final ImmutableMap<PathArgument, InstanceIdToNodes<?>> byArg;
-
- protected ChoiceNodeNormalization(final ChoiceSchemaNode schema) {
- super(new NodeIdentifier(schema.getQName()));
- final ImmutableMap.Builder<PathArgument, InstanceIdToNodes<?>> byArgBuilder = ImmutableMap.builder();
-
- for (final ChoiceCaseNode caze : schema.getCases()) {
- for (final DataSchemaNode cazeChild : caze.getChildNodes()) {
- final InstanceIdToNodes<?> childOp = fromDataSchemaNode(cazeChild);
- byArgBuilder.put(childOp.getIdentifier(), childOp);
- }
- }
- byArg = byArgBuilder.build();
- }
-
- @Override
- public InstanceIdToNodes<?> getChild(final PathArgument child) {
- return byArg.get(child);
- }
-
- @Override
- protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
- return Builders.choiceBuilder().withNodeIdentifier(getIdentifier());
- }
- }
-
- private static class AnyXmlNormalization extends InstanceIdToNodes<NodeIdentifier> {
-
- protected AnyXmlNormalization(final AnyXmlSchemaNode schema) {
- super(new NodeIdentifier(schema.getQName()));
- }
-
- @Override
- public InstanceIdToNodes<?> getChild(final PathArgument child) throws DataNormalizationException {
- return null;
- }
-
- @Override
- public NormalizedNode<?, ?> create(final YangInstanceIdentifier legacyData, final Optional<NormalizedNode<?, ?>> deepestChild, final Optional<ModifyAction> operation) {
- if(deepestChild.isPresent()) {
- Preconditions.checkState(deepestChild instanceof AnyXmlNode);
- final NormalizedNodeAttrBuilder<NodeIdentifier, DOMSource, AnyXmlNode> anyXmlBuilder =
- Builders.anyXmlBuilder().withNodeIdentifier(getIdentifier()).withValue(((AnyXmlNode) deepestChild).getValue());
- addModifyOpIfPresent(operation, anyXmlBuilder);
- return anyXmlBuilder.build();
- }
-
- final NormalizedNodeAttrBuilder<NodeIdentifier, DOMSource, AnyXmlNode> builder =
- Builders.anyXmlBuilder().withNodeIdentifier(getIdentifier());
- addModifyOpIfPresent(operation, builder);
- return builder.build();
- }
-
- }
-
- private static Optional<DataSchemaNode> findChildSchemaNode(final DataNodeContainer parent, final QName child) {
- DataSchemaNode potential = parent.getDataChildByName(child);
- if (potential == null) {
- final Iterable<ChoiceSchemaNode> choices = FluentIterable.from(parent.getChildNodes()).filter(ChoiceSchemaNode.class);
- potential = findChoice(choices, child);
- }
- return Optional.fromNullable(potential);
- }
-
- private static InstanceIdToNodes<?> fromSchemaAndQNameChecked(final DataNodeContainer schema, final QName child) throws DataNormalizationException {
- final Optional<DataSchemaNode> potential = findChildSchemaNode(schema, child);
- if (!potential.isPresent()) {
- throw new DataNormalizationException(String.format("Supplied QName %s is not valid according to schema %s, potential children nodes: %s", child, schema, schema.getChildNodes()));
- }
-
- final DataSchemaNode result = potential.get();
- // We try to look up if this node was added by augmentation
- if ((schema instanceof DataSchemaNode) && result.isAugmenting()) {
- return fromAugmentation(schema, (AugmentationTarget) schema, result);
- }
- return fromDataSchemaNode(result);
- }
-
- private static ChoiceSchemaNode findChoice(final Iterable<ChoiceSchemaNode> choices, final QName child) {
- org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode foundChoice = null;
- choiceLoop:
- for (final ChoiceSchemaNode choice : choices) {
- for (final ChoiceCaseNode caze : choice.getCases()) {
- if (findChildSchemaNode(caze, child).isPresent()) {
- foundChoice = choice;
- break choiceLoop;
- }
- }
- }
- return foundChoice;
- }
-
- private static AugmentationIdentifier augmentationIdentifierFrom(final AugmentationSchema augmentation) {
- final ImmutableSet.Builder<QName> potentialChildren = ImmutableSet.builder();
- for (final DataSchemaNode child : augmentation.getChildNodes()) {
- potentialChildren.add(child.getQName());
- }
- return new AugmentationIdentifier(potentialChildren.build());
- }
-
- private static DataNodeContainer augmentationProxy(final AugmentationSchema augmentation, final DataNodeContainer schema) {
- final Set<DataSchemaNode> children = new HashSet<>();
- for (final DataSchemaNode augNode : augmentation.getChildNodes()) {
- children.add(schema.getDataChildByName(augNode.getQName()));
- }
- return new NodeContainerProxy(null, children);
- }
-
- /**
- * Returns a SchemaPathUtil for provided child node
- * <p/>
- * If supplied child is added by Augmentation this operation returns
- * a SchemaPathUtil for augmentation,
- * otherwise returns a SchemaPathUtil for child as
- * call for {@link #fromDataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode)}.
- */
- private static InstanceIdToNodes<?> fromAugmentation(final DataNodeContainer parent,
- final AugmentationTarget parentAug, final DataSchemaNode child) {
- AugmentationSchema augmentation = null;
- for (final AugmentationSchema aug : parentAug.getAvailableAugmentations()) {
- final DataSchemaNode potential = aug.getDataChildByName(child.getQName());
- if (potential != null) {
- augmentation = aug;
- break;
- }
-
- }
- if (augmentation != null) {
- return new AugmentationNormalization(augmentation, parent);
- } else {
- return fromDataSchemaNode(child);
- }
- }
-
- private static InstanceIdToNodes<?> fromDataSchemaNode(final DataSchemaNode potential) {
- if (potential instanceof ContainerSchemaNode) {
- return new ContainerTransformation((ContainerSchemaNode) potential);
- } else if (potential instanceof ListSchemaNode) {
- return fromListSchemaNode((ListSchemaNode) potential);
- } else if (potential instanceof LeafSchemaNode) {
- return new LeafNormalization((LeafSchemaNode) potential);
- } else if (potential instanceof ChoiceSchemaNode) {
- return new ChoiceNodeNormalization((ChoiceSchemaNode) potential);
- } else if (potential instanceof LeafListSchemaNode) {
- return fromLeafListSchemaNode((LeafListSchemaNode) potential);
- } else if (potential instanceof AnyXmlSchemaNode) {
- return new AnyXmlNormalization((AnyXmlSchemaNode) potential);
- }
- return null;
- }
-
- private static InstanceIdToNodes<?> fromListSchemaNode(final ListSchemaNode potential) {
- final List<QName> keyDefinition = potential.getKeyDefinition();
- if (keyDefinition == null || keyDefinition.isEmpty()) {
- return new UnkeyedListMixinNormalization(potential);
- }
- if (potential.isUserOrdered()) {
- return new OrderedMapMixinNormalization(potential);
- }
- return new UnorderedMapMixinNormalization(potential);
- }
-
- private static InstanceIdToNodes<?> fromLeafListSchemaNode(final LeafListSchemaNode potential) {
- if (potential.isUserOrdered()) {
- return new OrderedLeafListMixinNormalization(potential);
- }
- return new UnorderedLeafListMixinNormalization(potential);
- }
-
- public static NormalizedNode<?, ?> serialize(final SchemaContext ctx, final YangInstanceIdentifier id) {
- return serialize(ctx, id, Optional.<NormalizedNode<?, ?>>absent(), Optional.<ModifyAction>absent());
- }
-
- public static NormalizedNode<?, ?> serialize(final SchemaContext ctx, final YangInstanceIdentifier id, final NormalizedNode<?, ?> deepestElement) {
- return serialize(ctx, id, Optional.<NormalizedNode<?, ?>>of(deepestElement), Optional.<ModifyAction>absent());
- }
-
- public static NormalizedNode<?, ?> serialize(final SchemaContext ctx, final YangInstanceIdentifier id, final Optional<NormalizedNode<?, ?>> deepestElement, final Optional<ModifyAction> operation) {
- Preconditions.checkNotNull(ctx);
- Preconditions.checkNotNull(id);
- final PathArgument topLevelElement = id.getPathArguments().iterator().next();
- final DataSchemaNode dataChildByName = ctx.getDataChildByName(topLevelElement.getNodeType());
- Preconditions.checkNotNull(dataChildByName, "Cannot find %s node in schema context. Instance identifier has to start from root", topLevelElement);
- try {
- final InstanceIdToNodes<?> instanceIdToNodes = fromSchemaAndQNameChecked(ctx, topLevelElement.getNodeType());
- return instanceIdToNodes.create(id, deepestElement, operation);
- } catch (final DataNormalizationException e) {
- throw new IllegalArgumentException("Unable to serialize: " + id, e);
- }
- }
-}
// Default operation
if(defaultOperation.isPresent()) {
- editBuilder.withChild(Builders.leafBuilder().withNodeIdentifier(toId(NETCONF_DEFAULT_OPERATION_QNAME)).withValue(NetconfMessageTransformUtil.modifyOperationToXmlString(defaultOperation.get())).build());
+ final String opString = defaultOperation.get().name().toLowerCase();
+ editBuilder.withChild(Builders.leafBuilder().withNodeIdentifier(toId(NETCONF_DEFAULT_OPERATION_QNAME)).withValue(opString).build());
}
// Error option
import com.google.common.collect.Lists;
import java.io.IOException;
import java.net.URI;
+import java.util.AbstractMap;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
final NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, DOMSource, AnyXmlNode> anyXmlBuilder = Builders.anyXmlBuilder().withNodeIdentifier(toId(NETCONF_FILTER_QNAME));
anyXmlBuilder.withAttributes(Collections.singletonMap(NETCONF_TYPE_QNAME, SUBTREE));
- final NormalizedNode<?, ?> filterContent = InstanceIdToNodes.serialize(ctx, identifier);
+ final NormalizedNode<?, ?> filterContent = ImmutableNodes.fromInstanceId(ctx, identifier);
final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_FILTER_QNAME.getLocalName(), Optional.of(NETCONF_FILTER_QNAME.getNamespace().toString()));
element.setAttributeNS(NETCONF_FILTER_QNAME.getNamespace().toString(), NETCONF_TYPE_QNAME.getLocalName(), "subtree");
"Data has to be either container or a list node when creating structure for top level element, but was: %s", lastChildOverride.get());
configContent = lastChildOverride.get();
} else {
- configContent = InstanceIdToNodes.serialize(ctx, dataPath, lastChildOverride, operation);
+ final Entry<QName, ModifyAction> modifyOperation =
+ operation.isPresent() ? new AbstractMap.SimpleEntry<>(NETCONF_OPERATION_QNAME, operation.get()) : null;
+ configContent = ImmutableNodes.fromInstanceId(ctx, dataPath, lastChildOverride, Optional.fromNullable(modifyOperation));
}
final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_CONFIG_QNAME.getLocalName(), Optional.of(NETCONF_CONFIG_QNAME.getNamespace().toString()));
return SchemaPath.create(true, rpc);
}
- public static String modifyOperationToXmlString(final ModifyAction operation) {
- return operation.name().toLowerCase();
- }
-
// FIXME similar code is in netconf-notifications-impl , DRY
public static void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext context)
throws IOException, XMLStreamException {
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.UsesNode;
-class NodeContainerProxy implements ContainerSchemaNode {
+/**
+ * Simple proxy for container like schema nodes, where user provides a collection of children schema nodes
+ */
+public final class NodeContainerProxy implements ContainerSchemaNode {
private final Map<QName, DataSchemaNode> childNodes;
private final QName qName;
public List<UnknownSchemaNode> getUnknownSchemaNodes() {
return Collections.emptyList();
}
-}
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 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.connect.netconf.util;
-
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.io.ByteSource;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-
-public class InstanceIdToNodesTest {
-
- private static final String NS = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:normalization:test";
- private static final String REVISION = "2014-03-13";
- private static final QName ID = QName.create(NS, REVISION, "id");
- private SchemaContext ctx;
-
- private final YangInstanceIdentifier.NodeIdentifier rootContainer = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "test"));
- private final YangInstanceIdentifier.NodeIdentifier outerContainer = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "outer-container"));
- private final YangInstanceIdentifier.NodeIdentifier augmentedLeaf = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "augmented-leaf"));
- private final YangInstanceIdentifier.AugmentationIdentifier augmentation = new YangInstanceIdentifier.AugmentationIdentifier(Collections.singleton(augmentedLeaf.getNodeType()));
-
- private final YangInstanceIdentifier.NodeIdentifier outerList = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "outer-list"));
- private final YangInstanceIdentifier.NodeIdentifierWithPredicates outerListWithKey = new YangInstanceIdentifier.NodeIdentifierWithPredicates(QName.create(NS, REVISION, "outer-list"), ID, 1);
- private final YangInstanceIdentifier.NodeIdentifier choice = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "outer-choice"));
- private final YangInstanceIdentifier.NodeIdentifier leafFromCase = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "one"));
-
- private final YangInstanceIdentifier.NodeIdentifier leafList = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "ordered-leaf-list"));
- private final YangInstanceIdentifier.NodeWithValue leafListWithValue = new YangInstanceIdentifier.NodeWithValue(leafList.getNodeType(), "abcd");
-
- static SchemaContext createTestContext() throws IOException, YangSyntaxErrorException {
- final YangParserImpl parser = new YangParserImpl();
- return parser.parseSources(Collections2.transform(Collections.singletonList("/schemas/filter-test.yang"), new Function<String, ByteSource>() {
- @Override
- public ByteSource apply(final String input) {
- return new ByteSource() {
- @Override
- public InputStream openStream() throws IOException {
- return InstanceIdToNodesTest.class.getResourceAsStream(input);
- }
- };
- }
- }));
- }
-
- @Before
- public void setUp() throws Exception {
- ctx = createTestContext();
-
- }
-
- @Test
- public void testInAugment() throws Exception {
- final ContainerNode expectedFilter = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
- Builders.containerBuilder().withNodeIdentifier(outerContainer).withChild(
- Builders.augmentationBuilder().withNodeIdentifier(augmentation).withChild(
- Builders.leafBuilder().withNodeIdentifier(augmentedLeaf).build()
- ).build()
- ).build()
- ).build();
-
- final NormalizedNode<?, ?> filter = InstanceIdToNodes.serialize(ctx, YangInstanceIdentifier.create(rootContainer, outerContainer, augmentation, augmentedLeaf));
- assertEquals(expectedFilter, filter);
- }
-
- @Test
- public void testInAugmentLeafOverride() throws Exception {
- final LeafNode<Object> lastLeaf = Builders.leafBuilder().withNodeIdentifier(augmentedLeaf).withValue("randomValue").build();
-
- final ContainerNode expectedFilter = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
- Builders.containerBuilder().withNodeIdentifier(outerContainer).withChild(
- Builders.augmentationBuilder().withNodeIdentifier(augmentation).withChild(
- lastLeaf
- ).build()
- ).build()
- ).build();
-
- final NormalizedNode<?, ?> filter = InstanceIdToNodes.serialize(ctx, YangInstanceIdentifier.create(rootContainer, outerContainer, augmentation, augmentedLeaf), lastLeaf);
- assertEquals(expectedFilter, filter);
- }
-
- @Test
- public void testListChoice() throws Exception {
- final ContainerNode expectedFilter = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
- Builders.mapBuilder().withNodeIdentifier(outerList).withChild(
- Builders.mapEntryBuilder().withNodeIdentifier(outerListWithKey).withChild(
- Builders.leafBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ID)).withValue(1).build()
- ).withChild(
- Builders.choiceBuilder().withNodeIdentifier(choice).withChild(
- Builders.leafBuilder().withNodeIdentifier(leafFromCase).build()
- ).build()
- ).build()
- ).build()
- ).build();
-
- final NormalizedNode<?, ?> filter = InstanceIdToNodes.serialize(ctx, YangInstanceIdentifier.create(rootContainer, outerList, outerListWithKey, choice, leafFromCase));
- assertEquals(expectedFilter, filter);
- }
-
- @Test
- public void testTopContainerLastChildOverride() throws Exception {
- final ContainerNode expectedStructure = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
- Builders.mapBuilder().withNodeIdentifier(outerList).withChild(
- Builders.mapEntryBuilder().withNodeIdentifier(outerListWithKey).withChild(
- Builders.leafBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ID)).withValue(1).build()
- ).withChild(
- Builders.choiceBuilder().withNodeIdentifier(choice).withChild(
- Builders.leafBuilder().withNodeIdentifier(leafFromCase).build()
- ).build()
- ).build()
- ).build()
- ).build();
-
- final NormalizedNode<?, ?> filter = InstanceIdToNodes.serialize(ctx, YangInstanceIdentifier.create(rootContainer), expectedStructure);
- assertEquals(expectedStructure, filter);
- }
-
- @Test
- public void testListLastChildOverride() throws Exception {
- final MapEntryNode outerListEntry = Builders.mapEntryBuilder().withNodeIdentifier(outerListWithKey).withChild(
- Builders.leafBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ID)).withValue(1).build()
- ).build();
- final MapNode lastChild = Builders.mapBuilder().withNodeIdentifier(this.outerList).withChild(
- outerListEntry
- ).build();
- final ContainerNode expectedStructure = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
- lastChild
- ).build();
-
- NormalizedNode<?, ?> filter = InstanceIdToNodes.serialize(ctx, YangInstanceIdentifier.create(rootContainer, outerList, outerListWithKey), outerListEntry);
- assertEquals(expectedStructure, filter);
- filter = InstanceIdToNodes.serialize(ctx, YangInstanceIdentifier.create(rootContainer, outerList, outerListWithKey));
- assertEquals(expectedStructure, filter);
- }
-
- @Test
- public void testLeafList() throws Exception {
- final ContainerNode expectedFilter = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
- Builders.orderedLeafSetBuilder().withNodeIdentifier(leafList).withChild(
- Builders.leafSetEntryBuilder().withNodeIdentifier(leafListWithValue).withValue(leafListWithValue.getValue()).build()
- ).build()
- ).build();
-
- final NormalizedNode<?, ?> filter = InstanceIdToNodes.serialize(ctx, YangInstanceIdentifier.create(rootContainer, leafList, leafListWithValue));
- assertEquals(expectedFilter, filter);
- }
-}
\ No newline at end of file
+++ /dev/null
-module normalization-test {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:normalization:test";
- prefix "norm-test";
-
- revision "2014-03-13" {
- description "Initial revision.";
- }
-
- grouping outer-grouping {
- }
-
- container test {
- list outer-list {
- key id;
- leaf id {
- type uint16;
- }
- choice outer-choice {
- case one {
- leaf one {
- type string;
- }
- }
- case two-three {
- leaf two {
- type string;
- }
- leaf three {
- type string;
- }
- }
- }
- list inner-list {
- key name;
- ordered-by user;
-
- leaf name {
- type string;
- }
- leaf value {
- type string;
- }
- }
- }
-
- list unkeyed-list {
- leaf name {
- type string;
- }
- }
-
- leaf-list unordered-leaf-list {
- type string;
- }
-
- leaf-list ordered-leaf-list {
- ordered-by user;
- type string;
- }
-
- container outer-container {
- }
-
- anyxml any-xml-data;
- }
-
- augment /norm-test:test/norm-test:outer-container {
-
- leaf augmented-leaf {
- type string;
- }
- }
-}
\ No newline at end of file
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-remote</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-remoterpc-connector</artifactId>
<packaging>bundle</packaging>
LOG.debug("Create rpc registry and broker actors");
rpcRegistry =
- getContext().actorOf(Props.create(RpcRegistry.class).
+ getContext().actorOf(RpcRegistry.props().
withMailbox(config.getMailBoxName()), config.getRpcRegistryName());
rpcBroker =
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
+
import org.opendaylight.controller.remote.rpc.registry.gossip.Copier;
import org.opendaylight.controller.sal.connector.api.RpcRouter;
}
}
+ public Set<RpcRouter.RouteIdentifier<?, ?, ?>> getRoutes() {
+ return table.keySet();
+ }
+
public void addRoute(RpcRouter.RouteIdentifier<?,?,?> routeId){
table.put(routeId, System.currentTimeMillis());
}
package org.opendaylight.controller.remote.rpc.registry;
import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.japi.Creator;
import akka.japi.Option;
import akka.japi.Pair;
import com.google.common.base.Preconditions;
import org.opendaylight.controller.remote.rpc.registry.RpcRegistry.Messages.SetLocalRouter;
import org.opendaylight.controller.remote.rpc.registry.gossip.Bucket;
import org.opendaylight.controller.remote.rpc.registry.gossip.BucketStore;
+import org.opendaylight.controller.remote.rpc.registry.mbeans.RemoteRpcRegistryMXBean;
+import org.opendaylight.controller.remote.rpc.registry.mbeans.RemoteRpcRegistryMXBeanImpl;
import org.opendaylight.controller.sal.connector.api.RpcRouter;
import org.opendaylight.controller.sal.connector.api.RpcRouter.RouteIdentifier;
getLocalBucket().setData(new RoutingTable());
}
+ public static Props props() {
+ return Props.create(new RpcRegistryCreator());
+ }
+
@Override
protected void handleReceive(Object message) throws Exception {
//TODO: if sender is remote, reject message
}
}
}
+
+ private static class RpcRegistryCreator implements Creator<RpcRegistry> {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public RpcRegistry create() throws Exception {
+ RpcRegistry registry = new RpcRegistry();
+ RemoteRpcRegistryMXBean mxBean = new RemoteRpcRegistryMXBeanImpl(registry);
+ return registry;
+ }
+ }
}
import akka.actor.Address;
import akka.actor.Props;
import akka.cluster.ClusterActorRefProvider;
-import com.google.common.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
}
}
- protected BucketImpl<T> getLocalBucket() {
+ public BucketImpl<T> getLocalBucket() {
return localBucket;
}
versions.put(selfAddress, localBucket.getVersion());
}
- protected Map<Address, Bucket<T>> getRemoteBuckets() {
+ public Map<Address, Bucket<T>> getRemoteBuckets() {
return remoteBuckets;
}
- @VisibleForTesting
- Map<Address, Long> getVersions() {
+ public Map<Address, Long> getVersions() {
return versions;
}
}
--- /dev/null
+package org.opendaylight.controller.remote.rpc.registry.mbeans;
+
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * JMX bean to check remote rpc registry
+ */
+
+public interface RemoteRpcRegistryMXBean {
+
+ Set<String> getGlobalRpc();
+
+ String getBucketVersions();
+
+ Set<String> getLocalRegisteredRoutedRpc();
+
+ Map<String,String> findRpcByName(String name);
+
+ Map<String,String> findRpcByRoute(String route);
+}
--- /dev/null
+package org.opendaylight.controller.remote.rpc.registry.mbeans;
+
+import akka.actor.Address;
+import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
+import org.opendaylight.controller.remote.rpc.registry.RoutingTable;
+import org.opendaylight.controller.remote.rpc.registry.RpcRegistry;
+import org.opendaylight.controller.remote.rpc.registry.gossip.Bucket;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+
+public class RemoteRpcRegistryMXBeanImpl extends AbstractMXBean implements RemoteRpcRegistryMXBean {
+
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ private final String NULL_CONSTANT = "null";
+
+ private final String LOCAL_CONSTANT = "local";
+
+ private final String ROUTE_CONSTANT = "route:";
+
+ private final String NAME_CONSTANT = " | name:";
+
+ private final RpcRegistry rpcRegistry;
+
+ public RemoteRpcRegistryMXBeanImpl(final RpcRegistry rpcRegistry) {
+ super("RemoteRpcRegistry", "RemoteRpcBroker", null);
+ this.rpcRegistry = rpcRegistry;
+ registerMBean();
+ }
+
+ @Override
+ public Set<String> getGlobalRpc() {
+ RoutingTable table = rpcRegistry.getLocalBucket().getData();
+ Set<String> globalRpc = new HashSet<>(table.getRoutes().size());
+ for(RpcRouter.RouteIdentifier<?, ?, ?> route : table.getRoutes()){
+ if(route.getRoute() == null) {
+ globalRpc.add(route.getType() != null ? route.getType().toString() : NULL_CONSTANT);
+ }
+ }
+ if(log.isDebugEnabled()) {
+ log.debug("Locally registered global RPCs {}", globalRpc);
+ }
+ return globalRpc;
+ }
+
+ @Override
+ public Set<String> getLocalRegisteredRoutedRpc() {
+ RoutingTable table = rpcRegistry.getLocalBucket().getData();
+ Set<String> routedRpc = new HashSet<>(table.getRoutes().size());
+ for(RpcRouter.RouteIdentifier<?, ?, ?> route : table.getRoutes()){
+ if(route.getRoute() != null) {
+ StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
+ builder.append(route.getRoute().toString()).append(NAME_CONSTANT).append(route.getType() != null ?
+ route.getType().toString() : NULL_CONSTANT);
+ routedRpc.add(builder.toString());
+ }
+ }
+ if(log.isDebugEnabled()) {
+ log.debug("Locally registered routed RPCs {}", routedRpc);
+ }
+ return routedRpc;
+ }
+
+ @Override
+ public Map<String, String> findRpcByName(final String name) {
+ RoutingTable localTable = rpcRegistry.getLocalBucket().getData();
+ // Get all RPCs from local bucket
+ Map<String, String> rpcMap = new HashMap<>(getRpcMemberMapByName(localTable, name, LOCAL_CONSTANT));
+
+ // Get all RPCs from remote bucket
+ Map<Address, Bucket<RoutingTable>> buckets = rpcRegistry.getRemoteBuckets();
+ for(Address address : buckets.keySet()) {
+ RoutingTable table = buckets.get(address).getData();
+ rpcMap.putAll(getRpcMemberMapByName(table, name, address.toString()));
+ }
+ if(log.isDebugEnabled()) {
+ log.debug("list of RPCs {} searched by name {}", rpcMap, name);
+ }
+ return rpcMap;
+ }
+
+ @Override
+ public Map<String, String> findRpcByRoute(String routeId) {
+ RoutingTable localTable = rpcRegistry.getLocalBucket().getData();
+ Map<String, String> rpcMap = new HashMap<>(getRpcMemberMapByRoute(localTable, routeId, LOCAL_CONSTANT));
+
+ Map<Address, Bucket<RoutingTable>> buckets = rpcRegistry.getRemoteBuckets();
+ for(Address address : buckets.keySet()) {
+ RoutingTable table = buckets.get(address).getData();
+ rpcMap.putAll(getRpcMemberMapByRoute(table, routeId, address.toString()));
+
+ }
+ if(log.isDebugEnabled()) {
+ log.debug("list of RPCs {} searched by route {}", rpcMap, routeId);
+ }
+ return rpcMap;
+ }
+
+ /**
+ * Search if the routing table route String contains routeName
+ */
+
+ private Map<String,String> getRpcMemberMapByRoute(final RoutingTable table, final String routeName,
+ final String address) {
+ Set<RpcRouter.RouteIdentifier<?, ?, ?>> routes = table.getRoutes();
+ Map<String, String> rpcMap = new HashMap<>(routes.size());
+ for(RpcRouter.RouteIdentifier<?, ?, ?> route : table.getRoutes()){
+ if(route.getRoute() != null) {
+ String routeString = route.getRoute().toString();
+ if(routeString.contains(routeName)) {
+ StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
+ builder.append(routeString).append(NAME_CONSTANT).append(route.getType() != null ?
+ route.getType().toString() : NULL_CONSTANT);
+ rpcMap.put(builder.toString(), address);
+ }
+ }
+ }
+ return rpcMap;
+ }
+
+ /**
+ * Search if the routing table route type contains name
+ */
+ private Map<String, String> getRpcMemberMapByName(final RoutingTable table, final String name,
+ final String address) {
+ Set<RpcRouter.RouteIdentifier<?, ?, ?>> routes = table.getRoutes();
+ Map<String, String> rpcMap = new HashMap<>(routes.size());
+ for(RpcRouter.RouteIdentifier<?, ?, ?> route : routes){
+ if(route.getType() != null) {
+ String type = route.getType().toString();
+ if(type.contains(name)) {
+ StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
+ builder.append(route.getRoute() != null ? route.getRoute().toString(): NULL_CONSTANT)
+ .append(NAME_CONSTANT).append(type);
+ rpcMap.put(builder.toString(), address);
+ }
+ }
+ }
+ return rpcMap;
+ }
+
+
+
+ @Override
+ public String getBucketVersions() {
+ return rpcRegistry.getVersions().toString();
+ }
+
+}
\ No newline at end of file
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-rest-connector-config</artifactId>
<description>Configuration files for sal-rest-connector</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-rest-connector</artifactId>
<packaging>bundle</packaging>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-model-export</artifactId>
<!-- FIXME: remove explicit version, once model export package is part of yangtools-artefacts -->
- <version>0.7.0-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
</dependency>
<dependency>
import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.opendaylight.yangtools.yang.data.impl.schema.ResultAlreadySetException;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
NormalizedNode<?, ?> partialResult = resultHolder.getResult();
final NormalizedNode<?, ?> result;
- // unwrap result from augmentation and choice nodes on PUT
+ // FIXME: Also II should be updated unwrap result from augmentation and choice nodes on PUT
if (!isPost()) {
while (partialResult instanceof AugmentationNode || partialResult instanceof ChoiceNode) {
final Object childNode = ((DataContainerNode) partialResult).getValue().iterator().next();
}
}
- if (partialResult instanceof MapNode) {
+ if (partialResult instanceof MapNode && !isPost()) {
result = Iterables.getOnlyElement(((MapNode) partialResult).getValue());
} else {
result = partialResult;
}
return new NormalizedNodeContext(path,result);
+ } catch (final RestconfDocumentedException e) {
+ throw e;
+ } catch (final ResultAlreadySetException e) {
+ LOG.debug("Error parsing json input:", e);
+
+ throw new RestconfDocumentedException("Error parsing json input: Failed to create new parse result data. " +
+ "Are you creating multiple resources/subresources in POST request?");
} catch (final Exception e) {
LOG.debug("Error parsing json input", e);
final NormalizedNode<?, ?> result = parse(path,doc);
return new NormalizedNodeContext(path,result);
+ } catch (final RestconfDocumentedException e){
+ throw e;
} catch (final Exception e) {
LOG.debug("Error parsing xml input", e);
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
final YangInstanceIdentifier parentPath, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) {
// FIXME: This is doing correct post for container and list children
// not sure if this will work for choice case
- final YangInstanceIdentifier path;
- if(payload instanceof MapEntryNode) {
- path = parentPath.node(payload.getNodeType()).node(payload.getIdentifier());
+ if(payload instanceof MapNode) {
+ final YangInstanceIdentifier mapPath = parentPath.node(payload.getIdentifier());
+ final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, mapPath);
+ rWTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
+ ensureParentsByMerge(datastore, mapPath, rWTransaction, schemaContext);
+ for(final MapEntryNode child : ((MapNode) payload).getValue()) {
+ final YangInstanceIdentifier childPath = mapPath.node(child.getIdentifier());
+ checkItemDoesNotExists(rWTransaction, datastore, childPath);
+ rWTransaction.put(datastore, childPath, child);
+ }
} else {
- path = parentPath.node(payload.getIdentifier());
+ final YangInstanceIdentifier path;
+ if(payload instanceof MapEntryNode) {
+ path = parentPath.node(payload.getNodeType()).node(payload.getIdentifier());
+ } else {
+ path = parentPath.node(payload.getIdentifier());
+ }
+ checkItemDoesNotExists(rWTransaction,datastore, path);
+ ensureParentsByMerge(datastore, path, rWTransaction, schemaContext);
+ rWTransaction.put(datastore, path, payload);
}
+ return rWTransaction.submit();
+ }
- final ListenableFuture<Optional<NormalizedNode<?, ?>>> futureDatastoreData = rWTransaction.read(datastore, path);
+ private void checkItemDoesNotExists(final DOMDataReadWriteTransaction rWTransaction,final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+ final ListenableFuture<Boolean> futureDatastoreData = rWTransaction.exists(store, path);
try {
- final Optional<NormalizedNode<?, ?>> optionalDatastoreData = futureDatastoreData.get();
- if (optionalDatastoreData.isPresent() && payload.equals(optionalDatastoreData.get())) {
+ if (futureDatastoreData.get()) {
final String errMsg = "Post Configuration via Restconf was not executed because data already exists";
- LOG.trace(errMsg + ":{}", path);
+ LOG.debug(errMsg + ":{}", path);
rWTransaction.cancel();
throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
ErrorTag.DATA_EXISTS);
LOG.trace("It wasn't possible to get data loaded from datastore at path " + path);
}
- ensureParentsByMerge(datastore, path, rWTransaction, schemaContext);
- rWTransaction.merge(datastore, path, payload);
- LOG.trace("Post " + datastore.name() + " via Restconf: {}", path);
- return rWTransaction.submit();
}
private CheckedFuture<Void, TransactionCommitFailedException> putDataViaTransaction(
final InstanceIdentifierBuilder builder = YangInstanceIdentifier.builder();
final Module latestModule = globalSchema.findModuleByName(startModule, null);
+
+ if (latestModule == null) {
+ throw new RestconfDocumentedException("The module named '" + startModule + "' does not exist.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
+ }
+
final InstanceIdentifierContext<?> iiWithSchemaNode = collectPathArguments(builder, pathArgs, latestModule, null,
toMountPointIdentifier);
return retValue;
}
throw new RestconfDocumentedException("RpcError message", null, retValue.getErrors());
- }
- catch (final InterruptedException e) {
+ } catch (final InterruptedException e) {
throw new RestconfDocumentedException(
"The operation was interrupted while executing and did not complete.", ErrorType.RPC,
ErrorTag.PARTIAL_OPERATION);
- }
- catch (final ExecutionException e) {
+ } catch (final ExecutionException e) {
Throwable cause = e.getCause();
- if (cause instanceof CancellationException) {
- throw new RestconfDocumentedException("The operation was cancelled while executing.", ErrorType.RPC,
- ErrorTag.PARTIAL_OPERATION);
- } else if (cause != null) {
+ if (cause != null) {
while (cause.getCause() != null) {
cause = cause.getCause();
}
throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
e);
}
+ } catch (final CancellationException e) {
+ throw new RestconfDocumentedException("The operation was cancelled while executing.", ErrorType.RPC,
+ ErrorTag.PARTIAL_OPERATION);
}
}
import java.util.Collection;
import java.util.Collections;
import org.opendaylight.controller.config.yang.md.sal.rest.connector.Config;
+import org.opendaylight.controller.config.yang.md.sal.rest.connector.Delete;
import org.opendaylight.controller.config.yang.md.sal.rest.connector.Get;
import org.opendaylight.controller.config.yang.md.sal.rest.connector.Operational;
import org.opendaylight.controller.config.yang.md.sal.rest.connector.Post;
@Override
public Config getConfig() {
final Config config = new Config();
+
final Get get = new Get();
get.setReceivedRequests(stats.getConfigGet());
+ get.setSuccessfulResponses(stats.getSuccessGetConfig());
+ get.setFailedResponses(stats.getFailureGetConfig());
config.setGet(get);
+
final Post post = new Post();
post.setReceivedRequests(stats.getConfigPost());
+ post.setSuccessfulResponses(stats.getSuccessPost());
+ post.setFailedResponses(stats.getFailurePost());
config.setPost(post);
+
final Put put = new Put();
put.setReceivedRequests(stats.getConfigPut());
+ put.setSuccessfulResponses(stats.getSuccessPut());
+ put.setFailedResponses(stats.getFailurePut());
config.setPut(put);
+
+ final Delete delete = new Delete();
+ delete.setReceivedRequests(stats.getConfigDelete());
+ delete.setSuccessfulResponses(stats.getSuccessDelete());
+ delete.setFailedResponses(stats.getFailureDelete());
+ config.setDelete(delete);
+
return config;
}
final Operational operational = new Operational();
final Get get = new Get();
get.setReceivedRequests(opGet);
+ get.setSuccessfulResponses(stats.getSuccessGetOperational());
+ get.setFailedResponses(stats.getFailureGetOperational());
operational.setGet(get);
return operational;
}
final BigInteger rpcInvoke = stats.getRpc();
final Rpcs rpcs = new Rpcs();
rpcs.setReceivedRequests(rpcInvoke);
- return rpcs ;
+ return rpcs;
}
-}
+}
\ No newline at end of file
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import org.opendaylight.controller.sal.rest.api.RestconfService;
AtomicLong configPost = new AtomicLong();
AtomicLong configPut = new AtomicLong();
AtomicLong configDelete = new AtomicLong();
+ AtomicLong successGetConfig = new AtomicLong();
+ AtomicLong successGetOperational = new AtomicLong();
+ AtomicLong successPost = new AtomicLong();
+ AtomicLong successPut = new AtomicLong();
+ AtomicLong successDelete = new AtomicLong();
+ AtomicLong failureGetConfig = new AtomicLong();
+ AtomicLong failureGetOperational = new AtomicLong();
+ AtomicLong failurePost = new AtomicLong();
+ AtomicLong failurePut = new AtomicLong();
+ AtomicLong failureDelete = new AtomicLong();
private static final StatisticsRestconfServiceWrapper INSTANCE = new StatisticsRestconfServiceWrapper(RestconfImpl.getInstance());
@Override
public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
configGet.incrementAndGet();
- return delegate.readConfigurationData(identifier, uriInfo);
+ NormalizedNodeContext normalizedNodeContext = null;
+ try {
+ normalizedNodeContext = delegate.readConfigurationData(identifier, uriInfo);
+ if (normalizedNodeContext.getData() != null) {
+ successGetConfig.incrementAndGet();
+ }
+ else {
+ failureGetConfig.incrementAndGet();
+ }
+ } catch (Exception e) {
+ failureGetConfig.incrementAndGet();
+ throw e;
+ }
+ return normalizedNodeContext;
}
@Override
public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo uriInfo) {
operationalGet.incrementAndGet();
- return delegate.readOperationalData(identifier, uriInfo);
+ NormalizedNodeContext normalizedNodeContext = null;
+ try {
+ normalizedNodeContext = delegate.readOperationalData(identifier, uriInfo);
+ if (normalizedNodeContext.getData() != null) {
+ successGetOperational.incrementAndGet();
+ }
+ else {
+ failureGetOperational.incrementAndGet();
+ }
+ } catch (Exception e) {
+ failureGetOperational.incrementAndGet();
+ throw e;
+ }
+ return normalizedNodeContext;
}
@Override
public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload) {
configPut.incrementAndGet();
- return delegate.updateConfigurationData(identifier, payload);
+ Response response = null;
+ try {
+ response = delegate.updateConfigurationData(identifier, payload);
+ if (response.getStatus() == Status.OK.getStatusCode()) {
+ successPut.incrementAndGet();
+ }
+ else {
+ failurePut.incrementAndGet();
+ }
+ } catch (Exception e) {
+ failurePut.incrementAndGet();
+ throw e;
+ }
+ return response;
}
@Override
public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
configPost.incrementAndGet();
- return delegate.createConfigurationData(identifier, payload, uriInfo);
+ Response response = null;
+ try {
+ response = delegate.createConfigurationData(identifier, payload, uriInfo);
+ if (response.getStatus() == Status.OK.getStatusCode()) {
+ successPost.incrementAndGet();
+ }
+ else {
+ failurePost.incrementAndGet();
+ }
+ } catch (Exception e) {
+ failurePost.incrementAndGet();
+ throw e;
+ }
+ return response;
}
@Override
public Response createConfigurationData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
configPost.incrementAndGet();
- return delegate.createConfigurationData(payload, uriInfo);
+ Response response = null;
+ try {
+ response = delegate.createConfigurationData(payload, uriInfo);
+ if (response.getStatus() == Status.OK.getStatusCode()) {
+ successPost.incrementAndGet();
+ }
+ else {
+ failurePost.incrementAndGet();
+ }
+ }catch (Exception e) {
+ failurePost.incrementAndGet();
+ throw e;
+ }
+ return response;
}
@Override
public Response deleteConfigurationData(final String identifier) {
- return delegate.deleteConfigurationData(identifier);
+ configDelete.incrementAndGet();
+ Response response = null;
+ try {
+ response = delegate.deleteConfigurationData(identifier);
+ if (response.getStatus() == Status.OK.getStatusCode()) {
+ successDelete.incrementAndGet();
+ }
+ else {
+ failureDelete.incrementAndGet();
+ }
+ } catch (Exception e) {
+ failureDelete.incrementAndGet();
+ throw e;
+ }
+ return response;
}
@Override
public BigInteger getRpc() {
return BigInteger.valueOf(rpc.get());
}
-}
+
+ public BigInteger getSuccessGetConfig() {
+ return BigInteger.valueOf(successGetConfig.get());
+ }
+
+ public BigInteger getSuccessGetOperational() {
+ return BigInteger.valueOf(successGetOperational.get());
+ }
+
+ public BigInteger getSuccessPost() {
+ return BigInteger.valueOf(successPost.get());
+ }
+
+ public BigInteger getSuccessPut() {
+ return BigInteger.valueOf(successPut.get());
+ }
+
+ public BigInteger getSuccessDelete() {
+ return BigInteger.valueOf(successDelete.get());
+ }
+
+ public BigInteger getFailureGetConfig() {
+ return BigInteger.valueOf(failureGetConfig.get());
+ }
+
+ public BigInteger getFailureGetOperational() {
+ return BigInteger.valueOf(failureGetOperational.get());
+ }
+
+ public BigInteger getFailurePost() {
+ return BigInteger.valueOf(failurePost.get());
+ }
+
+ public BigInteger getFailurePut() {
+ return BigInteger.valueOf(failurePut.get());
+ }
+
+ public BigInteger getFailureDelete() {
+ return BigInteger.valueOf(failureDelete.get());
+ }
+}
\ No newline at end of file
leaf received-requests {
type uint64;
}
+
+ leaf successful-responses {
+ type uint64;
+ }
+
+ leaf failed-responses {
+ type uint64;
+ }
}
augment "/config:modules/config:module/config:configuration" {
container put {
uses statistics;
}
+
+ container delete {
+ uses statistics;
+ }
}
container operational {
@SuppressWarnings("unchecked")
final CheckedFuture<Void, TransactionCommitFailedException> expFuture = mock(CheckedFuture.class);
- final NormalizedNode<?, ?> dummyNode2 = createDummyNode("dummy:namespace2", "2014-07-01", "dummy local name2");
-
- when(rwTransaction.read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class))).thenReturn(
- wrapDummyNode(dummyNode2));
-
when(rwTransaction.exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class))).thenReturn(
- wrapExistence(true));
+ wrapExistence(false));
when(rwTransaction.submit()).thenReturn(expFuture);
final InOrder inOrder = inOrder(domDataBroker, rwTransaction);
inOrder.verify(domDataBroker).newReadWriteTransaction();
- inOrder.verify(rwTransaction).merge(LogicalDatastoreType.CONFIGURATION, instanceID, dummyNode);
+ inOrder.verify(rwTransaction).exists(LogicalDatastoreType.CONFIGURATION, instanceID);
+ inOrder.verify(rwTransaction).put(LogicalDatastoreType.CONFIGURATION, instanceID, dummyNode);
inOrder.verify(rwTransaction).submit();
}
@Test(expected = RestconfDocumentedException.class)
public void testCommitConfigurationDataPostAlreadyExists() {
- when(rwTransaction.read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class))).thenReturn(
- dummyNodeInFuture);
+ final CheckedFuture<Boolean, ReadFailedException> successFuture = Futures.immediateCheckedFuture(Boolean.TRUE);
+ when(rwTransaction.exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class))).thenReturn(
+ successFuture);
try {
// Schema context is only necessary for ensuring parent structure
brokerFacade.commitConfigurationDataPost((SchemaContext)null, instanceID, dummyNode);
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-rest-docgen-maven</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-rest-docgen</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sal-restconf-broker</artifactId>
<packaging>bundle</packaging>
<parent>
<artifactId>sal-parent</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>clustering-it</artifactId>
<groupId>org.opendaylight.controller.samples</groupId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>clustering-it-config</artifactId>
<packaging>jar</packaging>
<parent>
<artifactId>clustering-it</artifactId>
<groupId>org.opendaylight.controller.samples</groupId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>clustering-it-model</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>clustering-it</artifactId>
<packaging>pom</packaging>
<parent>
<artifactId>clustering-it</artifactId>
<groupId>org.opendaylight.controller.samples</groupId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>clustering-it-provider</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.samples</groupId>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>toaster-config</artifactId>
<description>Configuration files for toaster</description>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sample-toaster-consumer</artifactId>
<packaging>bundle</packaging>
<properties>
- <sal-binding-api.version>1.2.0-SNAPSHOT</sal-binding-api.version>
+ <sal-binding-api.version>1.3.0-SNAPSHOT</sal-binding-api.version>
</properties>
<dependencies>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sample-toaster-it</artifactId>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sample-toaster-provider</artifactId>
<packaging>bundle</packaging>
<properties>
- <sal-binding-api.version>1.2.0-SNAPSHOT</sal-binding-api.version>
+ <sal-binding-api.version>1.3.0-SNAPSHOT</sal-binding-api.version>
</properties>
<dependencies>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
</parent>
<artifactId>sample-toaster</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>config-netconf-connector</artifactId>
<packaging>bundle</packaging>
}
public static Map<String/* Namespace from yang file */,
- Map<String /* Name of module entry from yang file */, ModuleConfig>> transformMbeToModuleConfigs
- (final BeanReader configRegistryClient, Map<String/* Namespace from yang file */,
- Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
+ Map<String /* Name of module entry from yang file */, ModuleConfig>> transformMbeToModuleConfigs (
+ final BeanReader configRegistryClient, Map<String/* Namespace from yang file */,
+ Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
Map<String, Map<String, ModuleConfig>> namespaceToModuleNameToModuleConfig = Maps.newHashMap();
}
public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- if(ref.get() == null || ref.get().get() == null) {
- getYangStoreSnapshot();
+
+ YangStoreContext context = ref.get().get();
+
+ if(context == null) {
+ context = getYangStoreSnapshot();
}
this.listeners.add(listener);
- listener.onCapabilitiesAdded(NetconfOperationServiceFactoryImpl.setupCapabilities(ref.get().get()));
+ listener.onCapabilitiesAdded(NetconfOperationServiceFactoryImpl.setupCapabilities(context));
return new AutoCloseable() {
@Override
private final Map<String /* Namespace from yang file */,
- Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
+ Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>config-persister-impl</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>ietf-netconf-monitoring-extension</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>ietf-netconf-monitoring</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>ietf-netconf-notifications</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>ietf-netconf</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>mdsal-netconf-connector</artifactId>
<packaging>bundle</packaging>
<artifactId>xmlunit</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <!--TODO remove this dependency on sal-netconf-connector - move InstanceIdToNodes to netconf-util,
- remove odl-yangtools-models, sal-netconf-connector, model-inventory dependency from the odl-netconf-mdsal feature in mdsal features with this-->
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-netconf-connector</artifactId>
- </dependency>
-
</dependencies>
<build>
@Override
public java.lang.AutoCloseable createInstance() {
final MdsalNetconfOperationServiceFactory mdsalNetconfOperationServiceFactory =
- new MdsalNetconfOperationServiceFactory(getRootSchemaServiceDependency()) {
- @Override
- public void close() throws Exception {
- super.close();
- getMapperAggregatorDependency().onRemoveNetconfOperationServiceFactory(this);
- }
- };
+ new MdsalNetconfOperationServiceFactory(getRootSchemaServiceDependency()) {
+ @Override
+ public void close() throws Exception {
+ super.close();
+ getMapperAggregatorDependency().onRemoveNetconfOperationServiceFactory(this);
+ }
+ };
getDomBrokerDependency().registerConsumer(mdsalNetconfOperationServiceFactory);
getMapperAggregatorDependency().onAddNetconfOperationServiceFactory(mdsalNetconfOperationServiceFactory);
return mdsalNetconfOperationServiceFactory;
import org.opendaylight.controller.netconf.mdsal.connector.ops.Datastore;
import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.sal.connect.netconf.util.InstanceIdToNodes;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
protected Element serializeNodeWithParentStructure(Document document, YangInstanceIdentifier dataRoot, NormalizedNode node) {
if (!dataRoot.equals(ROOT)) {
return (Element) transformNormalizedNode(document,
- InstanceIdToNodes.serialize(schemaContext.getCurrentContext(), dataRoot, node),
+ ImmutableNodes.fromInstanceId(schemaContext.getCurrentContext(), dataRoot, node),
ROOT);
}
return (Element) transformNormalizedNode(document, node, ROOT);
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>mdsal-netconf-monitoring</artifactId>
<packaging>bundle</packaging>
tx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(NetconfState.class), state);
// FIXME first attempt (right after we register to binding broker) always fails
// Is it due to the fact that we are writing from the onSessionInitiated callback ?
- final CheckedFuture<Void, TransactionCommitFailedException> submit = tx.submit();
-
- Futures.addCallback(submit, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void aVoid) {
- LOG.debug("Netconf state updated successfully");
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- LOG.warn("Unable to update netconf state", throwable);
- }
- });
+ try {
+ tx.submit().checkedGet();
+ LOG.debug("Netconf state updated successfully");
+ } catch (TransactionCommitFailedException e) {
+ LOG.warn("Unable to update netconf state", e);
+ }
}
@Override
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-api</artifactId>
<packaging>bundle</packaging>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-artifacts</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>netconf-auth</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-cli</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-client</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-config</artifactId>
<description>Configuration files for netconf</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-connector-config</artifactId>
<description>Configuration files for netconf-connector</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-impl</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-it</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-mapping-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-mdsal-config</artifactId>
<description>Configuration files for netconf for mdsal</description>
<password>admin</password>
</module>
+
+ <!--TCP endpoint for MD-SAL netconf server -->
+ <!--<module>-->
+ <!--<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp">prefix:netconf-northbound-tcp</type>-->
+ <!--<name>netconf-mdsal-tcp-server</name>-->
+ <!--<dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp">-->
+ <!--<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound">prefix:netconf-server-dispatcher</type>-->
+ <!--<name>netconf-mdsal-server-dispatcher</name>-->
+ <!--</dispatcher>-->
+ <!--</module>-->
+
</modules>
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:mapper?module=netconf-mdsal-mapper&revision=2015-01-14</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:monitoring?module=netconf-mdsal-monitoring&revision=2015-02-18</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh?module=netconf-northbound-ssh&revision=2015-01-14</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp?module=netconf-northbound-tcp&revision=2015-04-23</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl?module=netconf-northbound-impl&revision=2015-01-12</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled?module=threadpool-impl-scheduled&revision=2013-12-01</capability>
</required-capabilities>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-monitoring</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-netty-util</artifactId>
<packaging>bundle</packaging>
--- /dev/null
+/*
+ * Copyright (c) 2015 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 com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.io.Writer;
+import javax.annotation.concurrent.NotThreadSafe;
+
+/**
+ * Custom BufferedWriter optimized for netconf pipeline implemented instead of default BufferedWriter provided by jdk.
+ * <p/>
+ * The line separator instance field in java.io.BufferedWriter is
+ * assigned using AccessController and takes considerable amount of time especially
+ * if lots of BufferedWriters are created in the system.
+ * <p/>
+ * This implementation should only be used if newLine method is not required
+ * such as netconf message to XML encoders.
+ * Methods in this implementation are not synchronized.
+ */
+@NotThreadSafe
+public final class BufferedWriter extends Writer {
+
+ private static final int DEFAULT_CHAR_BUFFER_SIZE = 8192;
+
+ private final Writer writer;
+ private final char buffer[];
+ private final int bufferSize;
+
+ private int nextChar = 0;
+
+ public BufferedWriter(final Writer writer) {
+ this(writer, DEFAULT_CHAR_BUFFER_SIZE);
+ }
+
+ public BufferedWriter(final Writer writer, final int bufferSize) {
+ super(writer);
+ Preconditions.checkArgument(bufferSize > 0, "Buffer size <= 0");
+ this.writer = writer;
+ this.buffer = new char[bufferSize];
+ this.bufferSize = bufferSize;
+ }
+
+ private void flushBuffer() throws IOException {
+ if (nextChar == 0)
+ return;
+ writer.write(buffer, 0, nextChar);
+ nextChar = 0;
+ }
+
+ @Override
+ public void write(final int c) throws IOException {
+ if (nextChar >= bufferSize)
+ flushBuffer();
+ buffer[nextChar++] = (char) c;
+ }
+
+ @Override
+ public void write(final char[] buffer, final int offset, final int length) throws IOException {
+ if ((offset < 0) || (offset > buffer.length) || (length < 0) ||
+ ((offset + length) > buffer.length) || ((offset + length) < 0)) {
+ throw new IndexOutOfBoundsException(String.format("Buffer size: %d, Offset: %d, Length: %d", buffer.length, offset, length));
+ } else if (length == 0) {
+ return;
+ }
+
+ if (length >= bufferSize) {
+ flushBuffer();
+ writer.write(buffer, offset, length);
+ return;
+ }
+
+ int b = offset;
+ final int t = offset + length;
+ while (b < t) {
+ final int d = Math.min(bufferSize - nextChar, t - b);
+ System.arraycopy(buffer, b, this.buffer, nextChar, d);
+ b += d;
+ nextChar += d;
+ if (nextChar >= bufferSize)
+ flushBuffer();
+ }
+ }
+
+ @Override
+ public void write(final String string, final int offset, final int length) throws IOException {
+ int b = offset;
+ final int t = offset + length;
+ while (b < t) {
+ final int d = Math.min(bufferSize - nextChar, t - b);
+ string.getChars(b, b + d, buffer, nextChar);
+ b += d;
+ nextChar += d;
+ if (nextChar >= bufferSize)
+ flushBuffer();
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ flushBuffer();
+ writer.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ try {
+ flushBuffer();
+ } finally {
+ writer.close();
+ }
+ }
+}
import io.netty.buffer.ByteBufOutputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
-import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
try (OutputStream os = new ByteBufOutputStream(out)) {
// Wrap OutputStreamWriter with BufferedWriter as suggested in javadoc for OutputStreamWriter
- StreamResult result = new StreamResult(new BufferedWriter(new OutputStreamWriter(os)));
+
+ // Using custom BufferedWriter that does not provide newLine method as performance improvement
+ // see javadoc for org.opendaylight.controller.netconf.nettyutil.handler.BufferedWriter
+ StreamResult result = new StreamResult(new org.opendaylight.controller.netconf.nettyutil.handler.BufferedWriter(new OutputStreamWriter(os)));
DOMSource source = new DOMSource(msg.getDocument());
ThreadLocalTransformers.getPrettyTransformer().transform(source, result);
}
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>bundle</packaging>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>netconf-ssh</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netty-config-api</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>netconf-tcp</artifactId>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-util</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>threadpool-config-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netty-config-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</instructions>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>config</id>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+ <additionalConfiguration>
+ <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+ </additionalConfiguration>
+ </generator>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+ <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-jmx-generator-plugin</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
</plugins>
</build>
--- /dev/null
+package org.opendaylight.controller.config.yang.netconf.northbound.tcp;
+
+import io.netty.channel.ChannelFuture;
+import io.netty.util.concurrent.GenericFutureListener;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import org.opendaylight.controller.netconf.api.NetconfServerDispatcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfNorthboundTcpModule extends org.opendaylight.controller.config.yang.netconf.northbound.tcp.AbstractNetconfNorthboundTcpModule {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfNorthboundTcpModule.class);
+
+
+ public NetconfNorthboundTcpModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public NetconfNorthboundTcpModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.netconf.northbound.tcp.NetconfNorthboundTcpModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ final NetconfServerDispatcher dispatch = getDispatcherDependency();
+ final ChannelFuture tcpServer = dispatch.createServer(getInetAddress());
+
+ tcpServer.addListener(new GenericFutureListener<ChannelFuture>() {
+ @Override
+ public void operationComplete(ChannelFuture future) throws Exception {
+ if (future.isDone() && future.isSuccess()) {
+ LOG.info("Netconf TCP endpoint started successfully at {}", getInetAddress());
+ } else {
+ LOG.warn("Unable to start TCP netconf server at {}", getInetAddress(), future.cause());
+ throw new RuntimeException("Unable to start TCP netconf server", future.cause());
+ }
+ }
+ });
+
+ return new NetconfServerCloseable(tcpServer);
+ }
+
+ private InetSocketAddress getInetAddress() {
+ try {
+ final InetAddress inetAd = InetAddress.getByName(getBindingAddress().getIpv4Address() == null ? getBindingAddress().getIpv6Address().getValue() : getBindingAddress().getIpv4Address().getValue());
+ return new InetSocketAddress(inetAd, getPort().getValue());
+ } catch (final UnknownHostException e) {
+ throw new IllegalArgumentException("Unable to bind netconf endpoint to address " + getBindingAddress(), e);
+ }
+ }
+
+ private static final class NetconfServerCloseable implements AutoCloseable {
+ private final ChannelFuture localServer;
+
+ public NetconfServerCloseable(final ChannelFuture localServer) {
+ this.localServer = localServer;
+ }
+
+ @Override
+ public void close() throws Exception {
+ if(localServer.isDone()) {
+ localServer.channel().close();
+ } else {
+ localServer.cancel(true);
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+* Generated file
+*
+* Generated from: yang module name: netconf-northbound-tcp yang module local name: netconf-northbound-tcp
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Thu Apr 23 16:34:55 CEST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.netconf.northbound.tcp;
+public class NetconfNorthboundTcpModuleFactory extends org.opendaylight.controller.config.yang.netconf.northbound.tcp.AbstractNetconfNorthboundTcpModuleFactory {
+
+}
--- /dev/null
+module netconf-northbound-tcp {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp";
+ prefix "nni";
+
+ import netconf-northbound-mapper { prefix nnm; revision-date 2015-01-14; }
+ import netconf-northbound { prefix nn; revision-date 2015-01-14; }
+ import config { prefix config; revision-date 2013-04-05; }
+ import threadpool {prefix th;}
+ import netty {prefix netty;}
+ import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
+
+ organization "Cisco Systems, Inc.";
+
+ description
+ "This module contains the base YANG definitions for
+ a default implementation of netconf northbound tcp server";
+
+ revision "2015-04-23" {
+ description
+ "Initial revision.";
+ }
+
+ identity netconf-northbound-tcp {
+ base config:module-type;
+ config:java-name-prefix NetconfNorthboundTcp;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case netconf-northbound-tcp {
+ when "/config:modules/config:module/config:type = 'netconf-northbound-tcp'";
+
+ leaf port {
+ type inet:port-number;
+ default 2831;
+ }
+
+ leaf binding-address {
+ type inet:ip-address;
+ default "0.0.0.0";
+ }
+
+ container dispatcher {
+ uses config:service-ref {
+ refine type {
+ config:required-identity nn:netconf-server-dispatcher;
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-testtool</artifactId>
private final List<NetconfMessage> preparedMessages;
private final NetconfDeviceCommunicator sessionListener;
private final List<Integer> editBatches;
+ private final int editAmount;
public AsyncExecutionStrategy(final Parameters params, final List<NetconfMessage> editConfigMsgs, final NetconfDeviceCommunicator sessionListener) {
this.params = params;
this.preparedMessages = editConfigMsgs;
this.sessionListener = sessionListener;
- this.editBatches = countEditBatchSizes(params);
+ this.editBatches = countEditBatchSizes(params, editConfigMsgs.size());
+ editAmount = editConfigMsgs.size();
}
- private static List<Integer> countEditBatchSizes(final Parameters params) {
+ private static List<Integer> countEditBatchSizes(final Parameters params, final int amount) {
final List<Integer> editBatches = Lists.newArrayList();
- if (params.editBatchSize != params.editCount) {
- final int fullBatches = params.editCount / params.editBatchSize;
+ if (params.editBatchSize != amount) {
+ final int fullBatches = amount / params.editBatchSize;
for (int i = 0; i < fullBatches; i++) {
editBatches.add(params.editBatchSize);
}
- if (params.editCount % params.editBatchSize != 0) {
- editBatches.add(params.editCount % params.editBatchSize);
+ if (amount % params.editBatchSize != 0) {
+ editBatches.add(amount % params.editBatchSize);
}
} else {
editBatches.add(params.editBatchSize);
}
}
- Preconditions.checkState(responseCounter.get() == params.editCount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
+ Preconditions.checkState(responseCounter.get() == editAmount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
}
}
@Arg(dest = "msg-timeout")
public long msgTimeout;
+ @Arg(dest = "tcp-header")
+ public String tcpHeader;
+
+ @Arg(dest = "thread-amount")
+ public int threadAmount;
+
static ArgumentParser getParser() {
final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf stress client");
.setDefault(false)
.dest("ssh");
+ parser.addArgument("--tcp-header")
+ .type(String.class)
+ .required(false)
+ .dest("tcp-header");
+
+ parser.addArgument("--thread-amount")
+ .type(Integer.class)
+ .setDefault(1)
+ .dest("thread-amount");
+
// TODO add get-config option instead of edit + commit
// TODO different edit config content
import ch.qos.logback.classic.Level;
import com.google.common.base.Charsets;
import com.google.common.base.Stopwatch;
-import com.google.common.collect.Lists;
import com.google.common.io.Files;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timer;
-import io.netty.util.concurrent.GlobalEventExecutor;
import java.io.IOException;
-import java.net.InetSocketAddress;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.NetconfClientSession;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.controller.sal.connect.api.RemoteDevice;
import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.CommitInput;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditConfigInput;
import org.opendaylight.yangtools.yang.common.QName;
" <target>\n" +
" <candidate/>\n" +
" </target>\n" +
+ " <default-operation>none</default-operation>" +
" <config/>\n" +
" </edit-config>\n" +
"</rpc>");
}
}
- private static final String MSG_ID_PLACEHOLDER = "{MSG_ID}";
private static final String MSG_ID_PLACEHOLDER_REGEX = "\\{MSG_ID\\}";
+ private static final String PHYS_ADDR_PLACEHOLDER = "{PHYS_ADDR}";
+
+ private static long macStart = 0xAABBCCDD0000L;
public static void main(final String[] args) {
final Parameters params = parseArgs(args, Parameters.getParser());
params.validate();
- // TODO remove
- try {
- Thread.sleep(10000);
- } catch (final InterruptedException e) {
-// e.printStackTrace();
- }
-
final ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.setLevel(params.debug ? Level.DEBUG : Level.INFO);
+ final int threadAmount = params.threadAmount;
+ LOG.info("thread amount: " + threadAmount);
+ final int requestsPerThread = params.editCount / params.threadAmount;
+ LOG.info("requestsPerThread: " + requestsPerThread);
+ final int leftoverRequests = params.editCount % params.threadAmount;
+ LOG.info("leftoverRequests: " + leftoverRequests);
+
+
LOG.info("Preparing messages");
// Prepare all msgs up front
- final List<NetconfMessage> preparedMessages = Lists.newArrayListWithCapacity(params.editCount);
+ final List<List<NetconfMessage>> allPreparedMessages = new ArrayList<>(threadAmount);
+ for (int i = 0; i < threadAmount; i++) {
+ if (i != threadAmount - 1) {
+ allPreparedMessages.add(new ArrayList<NetconfMessage>(requestsPerThread));
+ } else {
+ allPreparedMessages.add(new ArrayList<NetconfMessage>(requestsPerThread + leftoverRequests));
+ }
+ }
+
final String editContentString;
- boolean needsModification = false;
try {
editContentString = Files.toString(params.editContent, Charsets.UTF_8);
- if(editContentString.contains(MSG_ID_PLACEHOLDER)) {
- needsModification = true;
- };
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new IllegalArgumentException("Cannot read content of " + params.editContent);
}
- for (int i = 0; i < params.editCount; i++) {
- final Document msg = XmlUtil.createDocumentCopy(editBlueprint);
- msg.getDocumentElement().setAttribute("message-id", Integer.toString(i));
- final NetconfMessage netconfMessage = new NetconfMessage(msg);
-
- final Element editContentElement;
- try {
- // Insert message id where needed
- final String specificEditContent = needsModification ?
- editContentString.replaceAll(MSG_ID_PLACEHOLDER_REGEX, Integer.toString(i)) :
- editContentString;
-
- editContentElement = XmlUtil.readXmlToElement(specificEditContent);
- final Node config = ((Element) msg.getDocumentElement().getElementsByTagName("edit-config").item(0)).
- getElementsByTagName("config").item(0);
- config.appendChild(msg.importNode(editContentElement, true));
- } catch (final IOException | SAXException e) {
- throw new IllegalArgumentException("Edit content file is unreadable", e);
+ for (int i = 0; i < threadAmount; i++) {
+ final List<NetconfMessage> preparedMessages = allPreparedMessages.get(i);
+ int padding = 0;
+ if (i == threadAmount - 1) {
+ padding = leftoverRequests;
+ }
+ for (int j = 0; j < requestsPerThread + padding; j++) {
+ LOG.debug("id: " + (i * requestsPerThread + j));
+ preparedMessages.add(prepareMessage(i * requestsPerThread + j, editContentString));
}
-
- preparedMessages.add(netconfMessage);
-
}
-
final NioEventLoopGroup nioGroup = new NioEventLoopGroup();
final Timer timer = new HashedWheelTimer();
final NetconfClientDispatcherImpl netconfClientDispatcher = configureClientDispatcher(params, nioGroup, timer);
- final NetconfDeviceCommunicator sessionListener = getSessionListener(params.getInetAddress());
+ final List<StressClientCallable> callables = new ArrayList<>(threadAmount);
+ for (final List<NetconfMessage> messages : allPreparedMessages) {
+ callables.add(new StressClientCallable(params, netconfClientDispatcher, messages));
+ }
- final NetconfClientConfiguration cfg = getNetconfClientConfiguration(params, sessionListener);
+ final ExecutorService executorService = Executors.newFixedThreadPool(threadAmount);
- LOG.info("Connecting to netconf server {}:{}", params.ip, params.port);
- final NetconfClientSession netconfClientSession;
+ LOG.info("Starting stress test");
+ final Stopwatch started = Stopwatch.createStarted();
try {
- netconfClientSession = netconfClientDispatcher.createClient(cfg).get();
+ final List<Future<Boolean>> futures = executorService.invokeAll(callables);
+ for (final Future<Boolean> future : futures) {
+ try {
+ future.get(4L, TimeUnit.MINUTES);
+ } catch (ExecutionException | TimeoutException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ executorService.shutdownNow();
} catch (final InterruptedException e) {
- throw new RuntimeException(e);
- } catch (final ExecutionException e) {
- throw new RuntimeException("Unable to connect", e);
+ throw new RuntimeException("Unable to execute requests", e);
}
-
- LOG.info("Starting stress test");
- final Stopwatch started = Stopwatch.createStarted();
- getExecutionStrategy(params, preparedMessages, sessionListener).invoke();
started.stop();
LOG.info("FINISHED. Execution time: {}", started);
LOG.info("Requests per second: {}", (params.editCount * 1000.0 / started.elapsed(TimeUnit.MILLISECONDS)));
// Cleanup
- netconfClientSession.close();
timer.stop();
try {
nioGroup.shutdownGracefully().get(20L, TimeUnit.SECONDS);
}
}
- private static ExecutionStrategy getExecutionStrategy(final Parameters params, final List<NetconfMessage> preparedMessages, final NetconfDeviceCommunicator sessionListener) {
- if(params.async) {
- return new AsyncExecutionStrategy(params, preparedMessages, sessionListener);
- } else {
- return new SyncExecutionStrategy(params, preparedMessages, sessionListener);
+ static NetconfMessage prepareMessage(final int id, final String editContentString) {
+ final Document msg = XmlUtil.createDocumentCopy(editBlueprint);
+ msg.getDocumentElement().setAttribute("message-id", Integer.toString(id));
+ final NetconfMessage netconfMessage = new NetconfMessage(msg);
+
+ final Element editContentElement;
+ try {
+ // Insert message id where needed
+ String specificEditContent = editContentString.replaceAll(MSG_ID_PLACEHOLDER_REGEX, Integer.toString(id));
+
+ final StringBuilder stringBuilder = new StringBuilder(specificEditContent);
+ int idx = stringBuilder.indexOf(PHYS_ADDR_PLACEHOLDER);
+ while (idx!= -1) {
+ stringBuilder.replace(idx, idx + PHYS_ADDR_PLACEHOLDER.length(), getMac(macStart++));
+ idx = stringBuilder.indexOf(PHYS_ADDR_PLACEHOLDER);
+ }
+ specificEditContent = stringBuilder.toString();
+
+ editContentElement = XmlUtil.readXmlToElement(specificEditContent);
+ final Node config = ((Element) msg.getDocumentElement().getElementsByTagName("edit-config").item(0)).
+ getElementsByTagName("config").item(0);
+ config.appendChild(msg.importNode(editContentElement, true));
+ } catch (final IOException | SAXException e) {
+ throw new IllegalArgumentException("Edit content file is unreadable", e);
}
+
+ return netconfMessage;
}
private static NetconfClientDispatcherImpl configureClientDispatcher(final Parameters params, final NioEventLoopGroup nioGroup, final Timer timer) {
return netconfClientDispatcher;
}
- private static NetconfClientConfiguration getNetconfClientConfiguration(final Parameters params, final NetconfDeviceCommunicator sessionListener) {
- final NetconfClientConfigurationBuilder netconfClientConfigurationBuilder = NetconfClientConfigurationBuilder.create();
- netconfClientConfigurationBuilder.withSessionListener(sessionListener);
- netconfClientConfigurationBuilder.withAddress(params.getInetAddress());
- netconfClientConfigurationBuilder.withProtocol(params.ssh ? NetconfClientConfiguration.NetconfClientProtocol.SSH : NetconfClientConfiguration.NetconfClientProtocol.TCP);
- netconfClientConfigurationBuilder.withConnectionTimeoutMillis(20000L);
- netconfClientConfigurationBuilder.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
- return netconfClientConfigurationBuilder.build();
- }
+ public static String getMac(long mac) {
+ StringBuilder m = new StringBuilder(Long.toString(mac, 16));
+
+ for (int i = m.length(); i < 12; i++) {
+ m.insert(0, "0");
+ }
+
+ for (int j = m.length() - 2; j >= 2; j-=2) {
+ m.insert(j, ":");
+ }
- static NetconfDeviceCommunicator getSessionListener(final InetSocketAddress inetAddress) {
- final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> loggingRemoteDevice = new LoggingRemoteDevice();
- return new NetconfDeviceCommunicator(new RemoteDeviceId("secure-test", inetAddress), loggingRemoteDevice);
+ return m.toString();
}
private static Parameters parseArgs(final String[] args, final ArgumentParser parser) {
}
- private static class LoggingRemoteDevice implements RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> {
+ static class LoggingRemoteDevice implements RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> {
@Override
public void onRemoteSessionUp(final NetconfSessionPreferences remoteSessionCapabilities, final NetconfDeviceCommunicator netconfDeviceCommunicator) {
LOG.info("Session established");
--- /dev/null
+/*
+ * Copyright (c) 2015 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.test.tool.client.stress;
+
+import io.netty.util.concurrent.GlobalEventExecutor;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.controller.sal.connect.api.RemoteDevice;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class StressClientCallable implements Callable<Boolean>{
+
+ private static final Logger LOG = LoggerFactory.getLogger(StressClientCallable.class);
+
+ private Parameters params;
+ private final NetconfDeviceCommunicator sessionListener;
+ private final NetconfClientDispatcherImpl netconfClientDispatcher;
+ private final NetconfClientConfiguration cfg;
+ private final NetconfClientSession netconfClientSession;
+ private final ExecutionStrategy executionStrategy;
+
+ public StressClientCallable(final Parameters params,
+ final NetconfClientDispatcherImpl netconfClientDispatcher,
+ final List<NetconfMessage> preparedMessages) {
+ this.params = params;
+ this.sessionListener = getSessionListener(params.getInetAddress());
+ this.netconfClientDispatcher = netconfClientDispatcher;
+ cfg = getNetconfClientConfiguration(this.params, this.sessionListener);
+
+ LOG.info("Connecting to netconf server {}:{}", params.ip, params.port);
+ try {
+ netconfClientSession = netconfClientDispatcher.createClient(cfg).get();
+ } catch (final InterruptedException e) {
+ throw new RuntimeException(e);
+ } catch (final ExecutionException e) {
+ throw new RuntimeException("Unable to connect", e);
+ }
+ executionStrategy = getExecutionStrategy(params, preparedMessages, sessionListener);
+ }
+
+ @Override
+ public Boolean call() throws Exception {
+ executionStrategy.invoke();
+ netconfClientSession.close();
+ return true;
+ }
+
+ private static ExecutionStrategy getExecutionStrategy(final Parameters params, final List<NetconfMessage> preparedMessages, final NetconfDeviceCommunicator sessionListener) {
+ if(params.async) {
+ return new AsyncExecutionStrategy(params, preparedMessages, sessionListener);
+ } else {
+ return new SyncExecutionStrategy(params, preparedMessages, sessionListener);
+ }
+ }
+
+ private static NetconfDeviceCommunicator getSessionListener(final InetSocketAddress inetAddress) {
+ final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> loggingRemoteDevice = new StressClient.LoggingRemoteDevice();
+ return new NetconfDeviceCommunicator(new RemoteDeviceId("secure-test", inetAddress), loggingRemoteDevice);
+ }
+
+ private static NetconfClientConfiguration getNetconfClientConfiguration(final Parameters params, final NetconfDeviceCommunicator sessionListener) {
+ final NetconfClientConfigurationBuilder netconfClientConfigurationBuilder = NetconfClientConfigurationBuilder.create();
+ netconfClientConfigurationBuilder.withSessionListener(sessionListener);
+ netconfClientConfigurationBuilder.withAddress(params.getInetAddress());
+ if(params.tcpHeader != null) {
+ final String header = params.tcpHeader.replaceAll("\"", "").trim() + "\n";
+ netconfClientConfigurationBuilder.withAdditionalHeader(new NetconfHelloMessageAdditionalHeader(null, null, null, null, null) {
+ @Override
+ public String toFormattedString() {
+ LOG.debug("Sending TCP header {}", header);
+ return header;
+ }
+ });
+ }
+ netconfClientConfigurationBuilder.withProtocol(params.ssh ? NetconfClientConfiguration.NetconfClientProtocol.SSH : NetconfClientConfiguration.NetconfClientProtocol.TCP);
+ netconfClientConfigurationBuilder.withConnectionTimeoutMillis(20000L);
+ netconfClientConfigurationBuilder.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
+ return netconfClientConfigurationBuilder.build();
+ }
+}
private final List<NetconfMessage> preparedMessages;
private final NetconfDeviceCommunicator sessionListener;
private final List<Integer> editBatches;
+ private final int editAmount;
public SyncExecutionStrategy(final Parameters params, final List<NetconfMessage> preparedMessages, final NetconfDeviceCommunicator sessionListener) {
this.params = params;
this.preparedMessages = preparedMessages;
this.sessionListener = sessionListener;
- editBatches = countEditBatchSizes(params);
+ this.editBatches = countEditBatchSizes(params, preparedMessages.size());
+ editAmount = preparedMessages.size();
}
- private static List<Integer> countEditBatchSizes(final Parameters params) {
+ private static List<Integer> countEditBatchSizes(final Parameters params, final int amount) {
final List<Integer> editBatches = Lists.newArrayList();
- if (params.editBatchSize != params.editCount) {
- final int fullBatches = params.editCount / params.editBatchSize;
+ if (params.editBatchSize != amount) {
+ final int fullBatches = amount / params.editBatchSize;
for (int i = 0; i < fullBatches; i++) {
editBatches.add(params.editBatchSize);
}
- if (params.editCount % params.editBatchSize != 0) {
- editBatches.add(params.editCount % params.editBatchSize);
+ if (amount % params.editBatchSize != 0) {
+ editBatches.add(amount % params.editBatchSize);
}
} else {
editBatches.add(params.editBatchSize);
sessionListener.sendRequest(StressClient.COMMIT_MSG, StressClient.COMMIT_QNAME));
}
- Preconditions.checkState(responseCounter.get() == params.editCount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
+ Preconditions.checkState(responseCounter.get() == editAmount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
}
private void waitForResponse(AtomicInteger responseCounter, final ListenableFuture<RpcResult<NetconfMessage>> netconfMessageFuture) {
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>netconf-usermanager</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-util</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.5.0-SNAPSHOT</version>
+ <version>1.6.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>netconf-subsystem</artifactId>
- <version>0.3.0-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.parent</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>opendaylight/commons/parent</relativePath>
</parent>
<artifactId>releasepom</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>controller</name>
<!-- Used by Sonar to set project name -->