<parent>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>commons.opendaylight</artifactId>\r
- <version>1.4.2-SNAPSHOT</version>\r
+ <version>1.5.0-SNAPSHOT</version>\r
<relativePath>../../opendaylight/commons/opendaylight</relativePath>\r
</parent>\r
<artifactId>features-adsal-compatibility</artifactId>\r
<packaging>jar</packaging>\r
<properties>\r
<features.file>features.xml</features.file>\r
- <feature.test.version>0.6.2-SNAPSHOT</feature.test.version>\r
+ <feature.test.version>0.7.0-SNAPSHOT</feature.test.version>\r
</properties>\r
<dependencies>\r
<!--\r
<dependency>\r
<groupId>org.opendaylight.yangtools</groupId>\r
<artifactId>features-yangtools</artifactId>\r
- <version>0.6.2-SNAPSHOT</version>\r
+ <version>0.7.0-SNAPSHOT</version>\r
<classifier>features</classifier>\r
<type>xml</type>\r
</dependency>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>features-mdsal</artifactId>\r
- <version>1.1-SNAPSHOT</version>\r
+ <version>1.2.0-SNAPSHOT</version>\r
<classifier>features</classifier>\r
<type>xml</type>\r
</dependency>\r
<dependency>\r
<groupId>org.opendaylight.openflowplugin</groupId>\r
<artifactId>features-openflowplugin</artifactId>\r
- <version>0.0.3-SNAPSHOT</version>\r
+ <version>0.1.0-SNAPSHOT</version>\r
<classifier>features</classifier>\r
<type>xml</type>\r
</dependency>\r
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<!-- Bundle dependencies -->
<feature version="${sal.version}">odl-adsal-core</feature>
<bundle>mvn:org.opendaylight.controller/clustering.services/${clustering.services.version}</bundle>
<bundle>mvn:org.opendaylight.controller/clustering.services-implementation/${clustering.services_implementation.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/clustering.stub/${clustering.stub.version}</bundle>
</feature>
<feature name="odl-adsal-configuration" description="OpenDaylight :: AD-SAL :: Configuration" version="${configuration.version}">
<feature version="${sal.version}">odl-adsal-core</feature>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.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.0.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.4.2-SNAPSHOT</karaf.resources.version>
+ <branding.version>1.1.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.5.0-SNAPSHOT</karaf.resources.version>
<karaf.version>3.0.1</karaf.version>
- <feature.test.version>0.6.2-SNAPSHOT</feature.test.version>
- <karaf.empty.version>1.4.2-SNAPSHOT</karaf.empty.version>
+ <feature.test.version>0.7.0-SNAPSHOT</feature.test.version>
+ <karaf.empty.version>1.5.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.6.2-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.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.6.2-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/1.1-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.0.3-SNAPSHOT/xml/features</repository>
+ <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>
-->
<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.1-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.2.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.6.2-SNAPSHOT'>odl-yangtools-binding</feature>
- <feature version='0.6.2-SNAPSHOT'>odl-yangtools-models</feature>
+ <feature version='0.7.0-SNAPSHOT'>odl-yangtools-binding</feature>
+ <feature version='0.7.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.1-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.2.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.0.3-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
+ <feature version='0.1.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>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-base</artifactId>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-test</artifactId>
- <version>0.6.2-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<!-- dependency for opendaylight-karaf-empty for use by testing -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-empty</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.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.1.0-SNAPSHOT">
- <bundle>mvn:org.opendaylight.controller/dummy-console/1.1.0-SNAPSHOT</bundle>
+ <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>
<feature name="odl-base-felix-dm" description="Felix Dependency Manager" version="${felix.dependencymanager.version}">
<bundle>mvn:org.osgi/org.osgi.compendium/${osgi.compendium.version}</bundle>
<bundle>wrap:mvn:io.netty/netty-common/${netty.version}</bundle>
<bundle>wrap:mvn:io.netty/netty-handler/${netty.version}</bundle>
<bundle>wrap:mvn:io.netty/netty-codec-http/${netty.version}</bundle>
- <bundle>mvn:org.opendaylight.controller.thirdparty/ganymed/1.1-SNAPSHOT</bundle>
+ <bundle>mvn:org.opendaylight.controller.thirdparty/ganymed/1.2.0-SNAPSHOT</bundle>
</feature>
<feature name="odl-base-jersey" description="Jersey" version="${jersey.version}">
<feature>odl-base-gemini-web</feature>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>extras-features</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../../opendaylight/md-sal</relativePath>
</parent>
<artifactId>features-flow</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../../opendaylight/md-sal</relativePath>
</parent>
<artifactId>features-mdsal</artifactId>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-test</artifactId>
- <version>0.6.2-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
<feature name='odl-mdsal-all' version='${project.version}' description="OpenDaylight :: MDSAL :: All">
<feature version='${project.version}'>odl-mdsal-broker</feature>
<feature version='${project.version}'>odl-mdsal-clustering</feature>
- <feature version='${project.version}'>odl-restconf</feature>
<feature version='${project.version}'>odl-mdsal-xsql</feature>
<feature version='${project.version}'>odl-toaster</feature>
</feature>
<bundle>mvn:org.opendaylight.controller/sal-inmemory-datastore/${project.version}</bundle>
<configfile finalname="${config.configfile.directory}/${config.mdsal.configfile}">mvn:org.opendaylight.controller/md-sal-config/${mdsal.version}/xml/config</configfile>
</feature>
- <feature name='odl-restconf' version='${project.version}' description="OpenDaylight :: Restconf">
- <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
- <feature>war</feature>
- <!-- presently we need sal-remote to be listed BEFORE sal-rest-connector because sal-rest-connector
- has a yang file which augments a yang file in sal-remote, and order seems to matter -->
- <bundle>mvn:org.opendaylight.controller/sal-remote/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/sal-rest-connector/${project.version}</bundle>
- <bundle>mvn:com.google.code.gson/gson/${gson.version}</bundle>
- <bundle>mvn:org.opendaylight.yangtools/yang-data-codec-gson/${yangtools.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
- <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-codec-http/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-common/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-handler/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
- <configfile finalname="${config.configfile.directory}/${config.restconf.configfile}">mvn:org.opendaylight.controller/sal-rest-connector-config/${mdsal.version}/xml/config</configfile>
- </feature>
<feature name='odl-toaster' version='${project.version}' description="OpenDaylight :: Toaster">
<feature version='${yangtools.version}'>odl-yangtools-common</feature>
<feature version='${yangtools.version}'>odl-yangtools-binding</feature>
<bundle>mvn:org.opendaylight.controller/sal-karaf-xsql/${project.version}</bundle>
<configfile finalname="${config.configfile.directory}/${config.xsql.configfile}">mvn:org.opendaylight.controller/sal-dom-xsql-config/${project.version}/xml/config</configfile>
</feature>
- <feature name ='odl-mdsal-apidocs' version='${project.version}'>
- <feature version='${project.version}'>odl-restconf</feature>
- <bundle>mvn:org.opendaylight.controller/sal-rest-docgen/${project.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.datatype/jackson-datatype-json-org/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
- <bundle>wrap:mvn:org.json/json/${org.json.version}</bundle>
- </feature>
<feature name ='odl-mdsal-clustering-commons' version='${project.version}'>
<feature version='${project.version}'>odl-mdsal-broker</feature>
<feature version='${akka.version}'>odl-akka-system</feature>
<configfile finalname="configuration/initial/module-shards.conf">mvn:org.opendaylight.controller/sal-clustering-config/${project.version}/xml/moduleshardconf</configfile>
<configfile finalname="configuration/initial/modules.conf">mvn:org.opendaylight.controller/sal-clustering-config/${project.version}/xml/moduleconf</configfile>
</feature>
-
- <feature name='odl-clustering-test-app' version='${project.version}'>
- <feature version='${project.version}'>odl-mdsal-clustering</feature>
- <feature version='${project.version}'>odl-restconf</feature>
- <feature version='${yangtools.version}'>odl-yangtools-models</feature>
- <bundle>mvn:org.opendaylight.controller.samples/clustering-it-model/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller.samples/clustering-it-provider/${project.version}</bundle>
- <configfile finalname="${config.configfile.directory}/20-clustering-test-app.xml">mvn:org.opendaylight.controller.samples/clustering-it-config/${project.version}/xml/config</configfile>
- <configfile finalname="configuration/initial/module-shards.conf" override="true" >mvn:org.opendaylight.controller.samples/clustering-it-config/${project.version}/xml/testmoduleshardconf</configfile>
- <configfile finalname="configuration/initial/modules.conf" override="true">mvn:org.opendaylight.controller.samples/clustering-it-config/${project.version}/xml/testmoduleconf</configfile>
- </feature>
</features>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.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.0-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
-->
<packaging>jar</packaging>
<properties>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-yangtools</artifactId>
- <version>0.6.2-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.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.6.2-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/1.1-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.0.3-SNAPSHOT/xml/features</repository>
+ <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.controller/features-mdsal/${mdsal.version}/xml/features</repository>
<repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
* Basic MD-SAL Provider
<feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider '>
- <feature version='1.1-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.2.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.6.2-SNAPSHOT'>odl-yangtools-binding</feature>
- <feature version='0.6.2-SNAPSHOT'>odl-yangtools-models</feature>
+ <feature version='0.7.0-SNAPSHOT'>odl-yangtools-binding</feature>
+ <feature version='0.7.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.1-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.2.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.0.3-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
+ <feature version='0.1.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>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../../opendaylight/netconf</relativePath>
</parent>
<artifactId>features-netconf</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<!-- Feature Dependencies -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-controller</artifactId>
<module>adsal-compatibility</module>
<module>akka</module>
<module>netconf-connector</module>
+ <module>restconf</module>
</modules>
</project>
\ No newline at end of file
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>features-protocol-framework</artifactId>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Necessary TODO: Put your copyright here.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-parent</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>../../opendaylight/md-sal</relativePath>
+ </parent>
+ <!--
+ Necessary TODO: Hookup your parent pom here, else you will not get necessary versions,
+ maven repos etc. If you run this archetype in a subdirectory of your project, it
+ will pick the pom.xml from the parent directory as the parent pom, which may or may
+ not be correct.
+ -->
+ <artifactId>features-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>
+ -->
+ <packaging>jar</packaging>
+ <properties>
+ <features.file>features.xml</features.file>
+ </properties>
+ <dependencies>
+ <!--
+ Necessary TODO: Put dependencies on any feature repos
+ you use in your features.xml file.
+
+ Note: they will need to be <type>xml</xml>
+ and <classifier>features</classifier>.
+ One other thing to watch for is to make sure they are
+ <scope>compile</compile>, which they should be by default,
+ but be cautious lest they be at a different scope in a parent pom.
+
+ Examples:
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>0.7.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>
+ <classifier>features</classifier>
+ <type>xml</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.openflowplugin</groupId>
+ <artifactId>features-openflowplugin</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ </dependency>
+ -->
+
+ <!--
+ Necessary TODO: Put dependencies for bundles directly referenced
+ in your features.xml file. For every <bundle> reference in your
+ features.xml file, you need a corresponding dependency here.
+
+ Examples:
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>controller-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>controller-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ -->
+
+ <!--
+ Necessary TODO: Put dependencies for configfiles directly referenced
+ in your features.xml file. For every <configfile> reference in your
+ features.xml file, you need a corresponding dependency here.
+
+ Example (presuming here version is coming from the parent pom):
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>controller-config</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </dependency>
+ -->
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>${yangtools.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>features-mdsal</artifactId>
+ <version>${mdsal.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>features-aaa</artifactId>
+ <version>${aaa.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-remote</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-rest-connector</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-buffer</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-handler</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-rest-connector-config</artifactId>
+ <version>${mdsal.version}</version>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-json-org</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-jaxb-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-base</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-codec-gson</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller.samples</groupId>
+ <artifactId>clustering-it-model</artifactId>
+ <version>${mdsal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.samples</groupId>
+ <artifactId>clustering-it-provider</artifactId>
+ <version>${mdsal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.samples</groupId>
+ <artifactId>clustering-it-config</artifactId>
+ <version>${mdsal.version}</version>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.samples</groupId>
+ <artifactId>clustering-it-config</artifactId>
+ <version>${mdsal.version}</version>
+ <type>xml</type>
+ <classifier>testmoduleshardconf</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.samples</groupId>
+ <artifactId>clustering-it-config</artifactId>
+ <version>${mdsal.version}</version>
+ <type>xml</type>
+ <classifier>testmoduleconf</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-rest-docgen</artifactId>
+ </dependency>
+
+ <!--
+ Optional TODO: Remove TODO comments.
+ -->
+ <!-- test to validate features.xml -->
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-test</artifactId>
+ <version>${yangtools.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- dependency for opendaylight-karaf-empty for use by testing -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>opendaylight-karaf-empty</artifactId>
+ <version>${commons.opendaylight.version}</version>
+ <type>zip</type>
+ </dependency>
+ <!-- Uncomment this if you get an error : java.lang.NoSuchMethodError: org.slf4j.helpers.MessageFormatter.format(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Lorg/slf4j/helpers/FormattingTuple;
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>1.7.2</version>
+ </dependency>
+ -->
+
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.version}</version>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=summary</url>
+ </scm>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<features name="odl-controller-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+ <!--
+ Necessary TODO: Please read the features guidelines:
+ https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Feature_Best_Practices
+ -->
+ <!--
+ Necessary TODO: Add repo entries for the repositories of features you refer to
+ in this feature file but do not define here.
+ Examples:
+ <repository>mvn:org.opendaylight.yangtools/features-yangtools/0.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.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>
+ <feature name='odl-restconf-all' version='${project.version}' description='OpenDaylight :: Restconf :: All'>
+ <!--
+ Necessary TODO:
+ List all of the user consumable features you define in this feature file here.
+ Generally you would *not* list individual bundles here, but only features defined in *this* file.
+ It is useful to list them in the same order they occur in the file.
+
+ Examples:
+ <feature version='${project.version}'>odl-controller-provider</feature>
+ <feature version='${project.version}'>odl-controller-model</feature>
+ -->
+ <feature version='${project.version}'>odl-restconf</feature>
+ <feature version='${project.version}'>odl-mdsal-apidocs</feature>
+ <feature version='${project.version}'>odl-clustering-test-app</feature>
+ </feature>
+ <!--
+ Necessary TODO: Define your features. It is useful to list then in order of dependency. So if A depends on B, list A first.
+ When naming your features please be mindful of the guidelines:
+ https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines
+ Particularly:
+ a) Prefixing names with 'odl-': https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Feature_Naming
+ b) Descriptions: https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Description
+ c) Avoid start-levels: https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Avoid_start-levels
+
+ It's also nice to list inside a feature, first the features it needs, then the bundles it needs, then the configfiles.
+ Examples:
+
+ * Basic MD-SAL Provider
+ <feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider '>
+ <feature version='1.2.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
+ </feature>
+
+ * 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>
+ <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>
+ <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
+ </feature>
+
+ * 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>
+ <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='${mdsal.version}'>odl-restconf-noauth</feature>
+ </feature>
+ <feature name='odl-restconf-noauth' version='${project.version}' description="OpenDaylight :: Restconf">
+ <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+ <feature>war</feature>
+ <!-- presently we need sal-remote to be listed BEFORE sal-rest-connector because sal-rest-connector
+ has a yang file which augments a yang file in sal-remote, and order seems to matter -->
+ <bundle>mvn:org.opendaylight.controller/sal-remote/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-rest-connector/${project.version}</bundle>
+ <bundle>mvn:com.google.code.gson/gson/${gson.version}</bundle>
+ <bundle>mvn:org.opendaylight.yangtools/yang-data-codec-gson/${yangtools.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
+ <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
+ <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
+ <bundle>mvn:io.netty/netty-codec-http/${netty.version}</bundle>
+ <bundle>mvn:io.netty/netty-common/${netty.version}</bundle>
+ <bundle>mvn:io.netty/netty-handler/${netty.version}</bundle>
+ <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
+ <configfile finalname="${config.configfile.directory}/${config.restconf.configfile}">mvn:org.opendaylight.controller/sal-rest-connector-config/${mdsal.version}/xml/config</configfile>
+ </feature>
+ <feature name ='odl-mdsal-apidocs' version='${project.version}' description="OpenDaylight :: MDSAL :: APIDOCS">
+ <feature version='${project.version}'>odl-restconf</feature>
+ <bundle>mvn:org.opendaylight.controller/sal-rest-docgen/${project.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.datatype/jackson-datatype-json-org/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
+ <bundle>wrap:mvn:org.json/json/${org.json.version}</bundle>
+ </feature>
+
+ <feature name='odl-clustering-test-app' version='${project.version}'>
+ <feature version='${project.version}'>odl-mdsal-clustering</feature>
+ <feature version='${project.version}'>odl-restconf</feature>
+ <feature version='${yangtools.version}'>odl-yangtools-models</feature>
+ <bundle>mvn:org.opendaylight.controller.samples/clustering-it-model/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller.samples/clustering-it-provider/${project.version}</bundle>
+ <configfile finalname="${config.configfile.directory}/20-clustering-test-app.xml">mvn:org.opendaylight.controller.samples/clustering-it-config/${project.version}/xml/config</configfile>
+ <configfile finalname="configuration/initial/module-shards.conf" override="true" >mvn:org.opendaylight.controller.samples/clustering-it-config/${project.version}/xml/testmoduleshardconf</configfile>
+ <configfile finalname="configuration/initial/modules.conf" override="true">mvn:org.opendaylight.controller.samples/clustering-it-config/${project.version}/xml/testmoduleconf</configfile>
+ </feature>
+
+ <feature name='odl-toaster-rest' version='${project.version}'>
+ <feature version='${project.version}'>odl-restconf</feature>
+ <feature version='${project.version}'>odl-toaster</feature>
+ </feature>
+
+ <feature name='odl-toaster-ui' version='${project.version}'>
+ <feature version='${project.version}'>odl-mdsal-apidocs</feature>
+ <feature version='${project.version}'>odl-mdsal-xsql</feature>
+ <feature version='${project.version}'>odl-toaster-rest</feature>
+ </feature>
+ <!-- Optional TODO: Remove TODO Comments -->
+
+</features>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>itests-controller</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../opendaylight/commons/opendaylight</relativePath>
</parent>
<artifactId>itests-controller</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>appauth</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<groupId>org.opendaylight.controller.archetypes</groupId>
<artifactId>odl-model-project</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<properties>
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>\r
<nexus.repository.release>opendaylight.release</nexus.repository.release>
<nexus.repository.snapshot>opendaylight.release</nexus.repository.snaphot>
- <yang.version>0.6.2-SNAPSHOT</yang.version>\r
- <yang.codegen.version>0.6.2-SNAPSHOT</yang.codegen.version>\r
+ <yang.version>0.7.0-SNAPSHOT</yang.version>\r
+ <yang.codegen.version>0.7.0-SNAPSHOT</yang.codegen.version>\r
<bundle.plugin.version>2.3.7</bundle.plugin.version>\r
</properties>\r
<scm>\r
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-configfile-archetype</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<parent>
<groupId>org.opendaylight.controller.archetypes</groupId>
<artifactId>archetypes-parent</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-distro-archetype</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>1.1.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.0.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.4.2-SNAPSHOT</karaf.resources.version>
+ <branding.version>1.1.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.5.0-SNAPSHOT</karaf.resources.version>
<karaf.version>3.0.1</karaf.version>
</properties>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.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.1.1-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-features-archetype</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>1.1.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.0.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.4.2-SNAPSHOT</karaf.resources.version>
+ <branding.version>1.1.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.5.0-SNAPSHOT</karaf.resources.version>
<karaf.version>3.0.1</karaf.version>
- <feature.test.version>0.6.2-SNAPSHOT</feature.test.version>
- <karaf.empty.version>1.4.2-SNAPSHOT</karaf.empty.version>
+ <feature.test.version>0.7.0-SNAPSHOT</feature.test.version>
+ <karaf.empty.version>1.5.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.6.2-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin</groupId>
<artifactId>features-openflowplugin</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.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.6.2-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/1.1-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.0.3-SNAPSHOT/xml/features</repository>
+ <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>
-->
<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.1-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.2.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.6.2-SNAPSHOT'>odl-yangtools-binding</feature>
- <feature version='0.6.2-SNAPSHOT'>odl-yangtools-models</feature>
+ <feature version='0.7.0-SNAPSHOT'>odl-yangtools-binding</feature>
+ <feature version='0.7.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.1-SNAPSHOT'>odl-mdsal-broker</feature>
+ <feature version='1.2.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.0.3-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
+ <feature version='0.1.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
<bundle>mvn:${groupId}/${repoName}-provider/${symbol_dollar}{project.version}</bundle>
... whatever other bundles you need
</feature>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<scm>
</scm>
<groupId>org.opendaylight.controller.archetypes</groupId>
<artifactId>archetypes-parent</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<distributionManagement>
<!-- OpenDayLight Released artifact -->
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>arphandler</artifactId>
- <version>0.5.2-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.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>clustering.services.integrationtest</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>clustering.services</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>clustering.services-implementation</artifactId>
- <version>0.4.3-SNAPSHOT</version>
+ <version>0.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>clustering.stub</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>clustering.test</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>concepts</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../opendaylight</relativePath>
</parent>
<artifactId>filter-valve</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>commons.httpclient</artifactId>
- <version>0.1.2-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>commons.integrationtest</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../opendaylight</relativePath>
</parent>
<artifactId>liblldp</artifactId>
- <version>0.8.1-SNAPSHOT</version>
+ <version>0.9.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<relativePath>../parent</relativePath>
</parent>
<artifactId>commons.logback_settings</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<packaging>pom</packaging>
<prerequisites>
<maven>3.0</maven>
<akka.version>2.3.4</akka.version>
<aopalliance.version>1.0.0</aopalliance.version>
- <appauth.version>0.4.2-SNAPSHOT</appauth.version>
- <archetype-app-northbound>0.0.1-SNAPSHOT</archetype-app-northbound>
+ <appauth.version>0.5.0-SNAPSHOT</appauth.version>
+ <archetype-app-northbound>0.1.0-SNAPSHOT</archetype-app-northbound>
<aries.util.version>1.1.0</aries.util.version>
- <arphandler.version>0.5.2-SNAPSHOT</arphandler.version>
+ <arphandler.version>0.6.0-SNAPSHOT</arphandler.version>
<!-- Controller Modules Versions -->
<asm.version>4.1</asm.version>
<!-- Plugin Versions -->
<bouncycastle.version>1.50</bouncycastle.version>
<bundle.plugin.version>2.4.0</bundle.plugin.version>
- <bundlescanner.api.version>0.4.2-SNAPSHOT</bundlescanner.api.version>
- <bundlescanner.implementation.version>0.4.2-SNAPSHOT</bundlescanner.implementation.version>
- <bundlescanner.version>0.4.2-SNAPSHOT</bundlescanner.version>
+ <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>
<checkstyle.version>2.12</checkstyle.version>
- <clustering.services.version>0.5.1-SNAPSHOT</clustering.services.version>
- <clustering.services_implementation.version>0.4.3-SNAPSHOT</clustering.services_implementation.version>
- <clustering.stub.version>0.4.2-SNAPSHOT</clustering.stub.version>
- <clustering.test.version>0.4.2-SNAPSHOT</clustering.test.version>
- <commmons.northbound.version>0.4.2-SNAPSHOT</commmons.northbound.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>
<!-- 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.0.3-SNAPSHOT</commons.checkstyle.version>
+ <commons.checkstyle.version>0.1.0-SNAPSHOT</commons.checkstyle.version>
<commons.fileupload.version>1.2.2</commons.fileupload.version>
- <commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
+ <commons.httpclient.version>0.2.0-SNAPSHOT</commons.httpclient.version>
<commons.io.version>2.4</commons.io.version>
<commons.lang3.version>3.1</commons.lang3.version>
- <commons.logback_settings.version>0.0.2-SNAPSHOT</commons.logback_settings.version>
+ <commons.logback_settings.version>0.1.0-SNAPSHOT</commons.logback_settings.version>
<commons.net.version>3.0.1</commons.net.version>
- <commons.opendaylight.commons.httpclient>0.1.2-SNAPSHOT</commons.opendaylight.commons.httpclient>
- <commons.opendaylight.concepts.version>0.5.2-SNAPSHOT</commons.opendaylight.concepts.version>
- <commons.opendaylight.version>1.4.2-SNAPSHOT</commons.opendaylight.version>
- <commons.parent.version>1.0.2-SNAPSHOT</commons.parent.version>
+ <commons.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>
<compiler.version>2.3.2</compiler.version>
- <commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
- <concepts.version>0.5.2-SNAPSHOT</concepts.version>
+ <commons.httpclient.version>0.2.0-SNAPSHOT</commons.httpclient.version>
+ <concepts.version>0.6.0-SNAPSHOT</concepts.version>
<concurrentlinkedhashmap.version>1.4</concurrentlinkedhashmap.version>
- <config.version>0.2.5-SNAPSHOT</config.version>
- <aaa.version>0.1.0-SNAPSHOT</aaa.version>
+ <config.version>0.3.0-SNAPSHOT</config.version>
+ <aaa.version>0.2.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.toaster.configfile>03-toaster-sample.xml</config.toaster.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.4.3-SNAPSHOT</configuration.implementation.version>
- <configuration.version>0.4.3-SNAPSHOT</configuration.version>
- <connectionmanager.version>0.1.2-SNAPSHOT</connectionmanager.version>
- <containermanager.it.version>0.5.2-SNAPSHOT</containermanager.it.version>
- <containermanager.northbound.version>0.4.2-SNAPSHOT</containermanager.northbound.version>
- <containermanager.shell.version>0.5.2-SNAPSHOT</containermanager.shell.version>
- <containermanager.version>0.5.2-SNAPSHOT</containermanager.version>
- <controllermanager.northbound.version>0.0.2-SNAPSHOT</controllermanager.northbound.version>
- <devices.web.version>0.4.2-SNAPSHOT</devices.web.version>
- <dummy-console.version>1.1.0-SNAPSHOT</dummy-console.version>
+ <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>
<eclipse.persistence.version>2.5.0</eclipse.persistence.version>
<eclipse.jdt.core.compiler.batch.version>3.8.0.I20120518-2145</eclipse.jdt.core.compiler.batch.version>
<!-- enforcer version -->
<exi.nagasena.version>0000.0002.0038.0</exi.nagasena.version>
<felix.util.version>1.6.0</felix.util.version>
- <filtervalve.version>1.4.2-SNAPSHOT</filtervalve.version>
+ <filtervalve.version>1.5.0-SNAPSHOT</filtervalve.version>
<findbugs.maven.plugin.version>2.4.0</findbugs.maven.plugin.version>
- <flowprogrammer.northbound.version>0.4.2-SNAPSHOT</flowprogrammer.northbound.version>
- <flows.web.version>0.4.2-SNAPSHOT</flows.web.version>
- <forwarding.staticrouting>0.5.2-SNAPSHOT</forwarding.staticrouting>
- <forwarding.staticrouting.northbound.version>0.4.2-SNAPSHOT</forwarding.staticrouting.northbound.version>
- <forwardingrulesmanager.implementation.version>0.4.2-SNAPSHOT</forwardingrulesmanager.implementation.version>
- <forwardingrulesmanager.version>0.6.0-SNAPSHOT</forwardingrulesmanager.version>
- <ganymed.version>1.1-SNAPSHOT</ganymed.version>
- <hosttracker.api.version>0.5.2-SNAPSHOT</hosttracker.api.version>
- <hosttracker.implementation.version>0.5.2-SNAPSHOT</hosttracker.implementation.version>
- <hosttracker.northbound.version>0.4.2-SNAPSHOT</hosttracker.northbound.version>
- <hosttracker.shell.version>1.0.0-SNAPSHOT</hosttracker.shell.version>
- <hosttracker_new.api.version>0.4.2-SNAPSHOT</hosttracker_new.api.version>
- <hosttracker_new.implementation.version>0.4.2-SNAPSHOT</hosttracker_new.implementation.version>
- <httpservice-bridge.northbound.version>0.0.2-SNAPSHOT</httpservice-bridge.northbound.version>
- <ietf-inet-types.version>2010.09.24.4-SNAPSHOT</ietf-inet-types.version>
- <ietf-restconf.version>2013.10.19.1-SNAPSHOT</ietf-restconf.version>
- <ietf-topology.version>2013.10.21.2-SNAPSHOT</ietf-topology.version>
- <ietf-yang-types.version>2010.09.24.4-SNAPSHOT</ietf-yang-types.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>
+ <ganymed.version>1.2.0-SNAPSHOT</ganymed.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>
<jdepend.maven.plugin.version>2.0-beta-2</jdepend.maven.plugin.version>
<jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
- <jolokia-bridge.version>0.0.2-SNAPSHOT</jolokia-bridge.version>
+ <jolokia-bridge.version>0.1.0-SNAPSHOT</jolokia-bridge.version>
<jolokia.version>1.1.4</jolokia.version>
<jsr305.api.version>2.0.1</jsr305.api.version>
<jsr311.api.version>1.1.1</jsr311.api.version>
<jsr311.v2.api.version>2.0</jsr311.v2.api.version>
- <karaf.branding.version>1.0.0-SNAPSHOT</karaf.branding.version>
+ <karaf.branding.version>1.1.0-SNAPSHOT</karaf.branding.version>
<karaf.shell.version>3.0.0</karaf.shell.version>
<karaf.version>3.0.1</karaf.version>
<leveldb.version>0.7</leveldb.version>
<leveldbjni.version>1.8</leveldbjni.version>
<lifecycle.mapping.version>1.0.0</lifecycle.mapping.version>
<logback.version>1.0.9</logback.version>
- <logging.bridge.version>0.4.2-SNAPSHOT</logging.bridge.version>
+ <logging.bridge.version>0.5.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.1-SNAPSHOT</mdsal.version>
- <netconf.version>0.2.5-SNAPSHOT</netconf.version>
- <networkconfig.bridgedomain.northbound.version>0.0.3-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
- <networkconfig.neutron.implementation.version>0.4.2-SNAPSHOT</networkconfig.neutron.implementation.version>
- <networkconfig.neutron.northbound.version>0.4.2-SNAPSHOT</networkconfig.neutron.northbound.version>
- <networkconfig.neutron.version>0.4.2-SNAPSHOT</networkconfig.neutron.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>
+ <networkconfig.neutron.implementation.version>0.5.0-SNAPSHOT</networkconfig.neutron.implementation.version>
+ <networkconfig.neutron.northbound.version>0.5.0-SNAPSHOT</networkconfig.neutron.northbound.version>
+ <networkconfig.neutron.version>0.5.0-SNAPSHOT</networkconfig.neutron.version>
<!-- ODL repository / plugin repository -->
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
- <northbound.commons.version>0.4.2-SNAPSHOT</northbound.commons.version>
- <northbound.hosttracker.version>1.4.2-SNAPSHOT</northbound.hosttracker.version>
- <northbound.jolokia.version>1.4.2-SNAPSHOT</northbound.jolokia.version>
- <opendaylight-l2-types.version>2013.08.27.4-SNAPSHOT</opendaylight-l2-types.version>
- <osgi-brandfragment.web.version>0.0.2-SNAPSHOT</osgi-brandfragment.web.version>
+ <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>
<pax.exam.version>4.0.0</pax.exam.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.5.0-SNAPSHOT</protocol-framework.version>
- <protocol_plugins.openflow.version>0.4.2-SNAPSHOT</protocol_plugins.openflow.version>
- <protocol_plugins.stub.version>0.4.2-SNAPSHOT</protocol_plugins.stub.version>
- <routing.dijkstra_implementation.version>0.4.2-SNAPSHOT</routing.dijkstra_implementation.version>
- <sal.connection.version>0.1.2-SNAPSHOT</sal.connection.version>
- <sal.implementation.version>0.4.2-SNAPSHOT</sal.implementation.version>
- <sal.networkconfiguration.version>0.0.3-SNAPSHOT</sal.networkconfiguration.version>
- <sal.version>0.8.1-SNAPSHOT</sal.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>
<salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
- <samples.loadbalancer>0.5.2-SNAPSHOT</samples.loadbalancer>
- <samples.loadbalancer.northbound.version>0.4.2-SNAPSHOT</samples.loadbalancer.northbound.version>
- <samples.simpleforwarding.version>0.4.2-SNAPSHOT</samples.simpleforwarding.version>
- <sanitytest.version>0.4.2-SNAPSHOT</sanitytest.version>
+ <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>
<scala.version>2.10</scala.version>
<scala.micro.version>4</scala.micro.version>
- <security.version>0.4.2-SNAPSHOT</security.version>
- <karaf.security.version>0.4.2-SNAPSHOT</karaf.security.version>
+ <security.version>0.5.0-SNAPSHOT</security.version>
+ <karaf.security.version>0.5.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.4.2-SNAPSHOT</statistics.northbound.version>
- <statisticsmanager.implementation.version>0.4.2-SNAPSHOT</statisticsmanager.implementation.version>
- <statisticsmanager.version>0.5.1-SNAPSHOT</statisticsmanager.version>
- <subnets.northbound.version>0.4.2-SNAPSHOT</subnets.northbound.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>
<surefire.version>2.15</surefire.version>
- <switchmanager.api.version>0.7.1-SNAPSHOT</switchmanager.api.version>
- <switchmanager.implementation.version>0.4.2-SNAPSHOT</switchmanager.implementation.version>
- <switchmanager.northbound.version>0.4.2-SNAPSHOT</switchmanager.northbound.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>
<testvm.argLine>-Xmx1024m -XX:MaxPermSize=256m</testvm.argLine>
- <topology.northbound.version>0.4.2-SNAPSHOT</topology.northbound.version>
- <topology.web.version>0.4.2-SNAPSHOT</topology.web.version>
- <topologymanager.version>0.4.2-SNAPSHOT</topologymanager.version>
- <topologymanager.shell.version>1.0.0-SNAPSHOT</topologymanager.shell.version>
- <troubleshoot.web.version>0.4.2-SNAPSHOT</troubleshoot.web.version>
+ <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>
<typesafe.config.version>1.2.0</typesafe.config.version>
<uncommons.maths.version>1.2.2a</uncommons.maths.version>
- <usermanager.implementation.version>0.4.2-SNAPSHOT</usermanager.implementation.version>
- <usermanager.northbound.version>0.0.2-SNAPSHOT</usermanager.northbound.version>
- <usermanager.version>0.4.2-SNAPSHOT</usermanager.version>
- <nsf.version>0.4.2-SNAPSHOT</nsf.version>
- <web.version>0.4.2-SNAPSHOT</web.version>
+ <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>
<xtend.dstdir>src/main/xtend-gen</xtend.dstdir>
- <yang-ext.version>2013.09.07.4-SNAPSHOT</yang-ext.version>
- <yang-jmx-generator.version>1.0.0-SNAPSHOT</yang-jmx-generator.version>
- <yangtools.version>0.6.2-SNAPSHOT</yangtools.version>
+ <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>
<sshd-core.version>0.12.0</sshd-core.version>
<jmh.version>0.9.7</jmh.version>
</properties>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>httpservice-bridge</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>jolokia-bridge</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
<!-- Karaf Dependencies -->
<dependency>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>ietf-yang-types-20130715</artifactId>
- <version>2013.07.15.1-SNAPSHOT</version>
+ <version>2013.07.15.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<executions>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>checkstyle</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<executions>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<prerequisites>
<maven>3.0</maven>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>protocol-framework</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>${project.artifactId}</name>
<description>Common protocol framework</description>
promise.setSuccess(session);
}
- protected final void negotiationFailed(final Throwable cause) {
+ protected void negotiationFailed(final Throwable cause) {
LOG.debug("Negotiation on channel {} failed", channel, cause);
channel.close();
promise.setFailure(cause);
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>config-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-manager</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>config-module-archetype</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>config-netty-config</artifactId>
<description>Configuration files for sal-rest-connector</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
public class ConfigFeaturesListener implements FeaturesListener, AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(ConfigFeaturesListener.class);
- private static final int QUEUE_SIZE = 100;
+ private static final int QUEUE_SIZE = 1000;
private BlockingQueue<FeatureEvent> queue = new LinkedBlockingQueue<FeatureEvent>(QUEUE_SIZE);
Thread pushingThread = null;
*/
public class FeatureConfigPusher {
private static final Logger logger = LoggerFactory.getLogger(FeatureConfigPusher.class);
+ private static final int MAX_RETRIES=100;
+ private static final int RETRY_PAUSE_MILLIS=1;
private FeaturesService featuresService = null;
private ConfigPusher pusher = null;
/*
}
private boolean isInstalled(Feature feature) {
- List<Feature> installedFeatures = Arrays.asList(featuresService.listInstalledFeatures());
- return installedFeatures.contains(feature);
+ for(int retries=0;retries<MAX_RETRIES;retries++) {
+ try {
+ List<Feature> installedFeatures = Arrays.asList(featuresService.listInstalledFeatures());
+ if(installedFeatures.contains(feature)) {
+ return true;
+ } else {
+ logger.warn("Karaf featuresService.listInstalledFeatures() has not yet finished installing feature (retry {}) {} {}",retries,feature.getName(),feature.getVersion());
+ }
+ } catch (Exception e) {
+ if(retries < MAX_RETRIES) {
+ logger.warn("Karaf featuresService.listInstalledFeatures() has thrown an exception, retry {}, Exception {}", retries,e);
+ } else {
+ logger.error("Giving up on Karaf featuresService.listInstalledFeatures() which has thrown an exception, retry {}, Exception {}", retries,e);
+ throw e;
+ }
+ }
+ try {
+ Thread.sleep(RETRY_PAUSE_MILLIS);
+ } catch (InterruptedException e1) {
+ throw new IllegalStateException(e1);
+ }
+ }
+ logger.error("Giving up (after {} retries) on Karaf featuresService.listInstalledFeatures() which has not yet finished installing feature {} {}",MAX_RETRIES,feature.getName(),feature.getVersion());
+ return false;
}
private LinkedHashSet<FeatureConfigSnapshotHolder> pushConfig(LinkedHashSet<FeatureConfigSnapshotHolder> configs) throws InterruptedException {
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>config-plugin-parent</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-util</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<prerequisites>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>yang-jmx-generator-it</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>yang-jmx-generator-plugin</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
import java.util.Map;
import java.util.Set;
+import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException;
import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.YangModelSearchUtils;
Map<File, String> testedFilesToYangModules = new HashMap<>();
Map<String, String> testedYangModulesToExpectedConflictingName = new HashMap<>();
+ @Ignore
@Test
public void testNameConflicts() throws Exception {
prepareSamples();
}
- leaf simpleInt {
+ leaf simpleInt1 {
type uint32;
default 99L;
}
}
}
- leaf simpleInt {
+ leaf simpleInt2 {
type uint32;
}
case impl-netconf {
when "/config:modules/config:module/config:type = 'impl-netconf'";
// root runtime bean
- leaf created-sessions {
+ leaf created-sessions-1 {
type uint32;
}
case netconf {
when "/config:modules/config:module/config:type = 'netconf'";
// root runtime bean
- leaf created-sessions {
+ leaf created-sessions2 {
type uint32;
}
case netconf {
when "/config:modules/config:module/config:type = 'netconf'";
- container dto-a {
+ container dto-a2 {
leaf simple-arg {
type uint32;
}
case netconf {
when "/config:modules/config:module/config:type = 'netconf'";
// root runtime bean
- leaf created-sessions {
+ leaf created-sessions2 {
type uint32;
}
case netconf {
when "/config:modules/config:module/config:type = 'netconf'";
// root runtime bean
- leaf created-sessions {
+ leaf created-sessions2 {
type uint32;
}
case netconf1 {
when "/config:modules/config:module/config:type = 'netconf1'";
// root runtime bean
- leaf created-sessions {
+ leaf created-sessions2 {
type uint32;
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>configuration</artifactId>
- <version>0.4.3-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.3-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>configuration.integrationtest</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>connectionmanager</artifactId>
- <version>0.1.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>connectionmanager.implementation</artifactId>
- <version>0.1.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager</artifactId>
- <version>0.5.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager.implementation</artifactId>
- <version>0.5.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager.shell</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>opendaylight-karaf-empty</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>opendaylight-karaf-resources</artifactId>
--- /dev/null
+@echo off
+rem
+rem
+rem Licensed to the Apache Software Foundation (ASF) under one or more
+rem contributor license agreements. See the NOTICE file distributed with
+rem this work for additional information regarding copyright ownership.
+rem The ASF licenses this file to You under the Apache License, Version 2.0
+rem (the "License"); you may not use this file except in compliance with
+rem the License. You may obtain a copy of the License at
+rem
+rem http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+rem
+
+rem
+rem handle specific scripts; the SCRIPT_NAME is exactly the name of the Karaf
+rem script; for example karaf.bat, start.bat, stop.bat, admin.bat, client.bat, ...
+rem
+rem if "%KARAF_SCRIPT%" == "SCRIPT_NAME" (
+rem Actions go here...
+rem )
+
+rem
+rem general settings which should be applied for all scripts go here; please keep
+rem in mind that it is possible that scripts might be executed more than once, e.g.
+rem in example of the start script where the start script is executed first and the
+rem karaf script afterwards.
+rem
+
+rem
+rem The following section shows the possible configuration options for the default
+rem karaf scripts
+rem
+rem Window name of the windows console
+rem SET KARAF_TITLE
+rem Location of Java installation
+rem SET JAVA_HOME
+rem Minimum memory for the JVM
+rem SET JAVA_MIN_MEM
+rem Maximum memory for the JVM
+rem SET JAVA_MAX_MEM
+rem Minimum perm memory for the JVM
+rem SET JAVA_PERM_MEM
+rem Maximum perm memory for the JVM
+rem SET JAVA_MAX_PERM_MEM
+rem Karaf home folder
+rem SET KARAF_HOME
+rem Karaf data folder
+rem SET KARAF_DATA
+rem Karaf base folder
+rem SET KARAF_BASE
+rem Karaf etc folder
+rem SET KARAF_ETC
+rem Additional available Karaf options
+rem SET KARAF_OPTS
+rem Enable debug mode
+rem SET KARAF_DEBUG
+IF "%JAVA_MAX_PERM_MEM%"=="" SET JAVA_MAX_PERM_MEM=512m
+IF "%JAVA_MAX_MEM%"=="" SET JAVA_MAX_MEM=2048m
# default Openflow version = 1.0, we also support 1.3.
# ovsdb.of.version=1.3
+# ovsdb can be configured with ml2 to perform l3 forwarding. The config below enables that functionality, which is
+# disabled by default.
+# ovsdb.l3.fwd.enabled=yes
+
# ovsdb can be configured with ml2 to perform l3 forwarding. When used in that scenario, the mac address of the default
# gateway --on the external subnet-- is expected to be resolved from its inet address. The config below overrides that
# specific arp/neighDiscovery lookup.
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>distribution.opendaylight-karaf</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>distribution.opendaylight</artifactId>
- <version>0.1.2-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<prerequisites>
<maven>3.0</maven>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-inmemory-datastore</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-topology</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</dependency>
<!-- toaster example I'm pretty sure we should trim -->
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-clustering-config</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlets</artifactId>
+ <version>8.1.14.v20131031</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-client</artifactId>
+ <version>8.1.14.v20131031</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-continuation</artifactId>
+ <version>8.1.14.v20131031</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ <version>8.1.14.v20131031</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>8.1.14.v20131031</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-io</artifactId>
+ <version>8.1.14.v20131031</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ <version>8.1.14.v20131031</version>
+ </dependency>
</dependencies>
</profile>
<profile>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>swagger-ui</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</profile>
# default Openflow version = 1.3, we also support 1.0.
ovsdb.of.version=1.3
+# ovsdb can be configured with ml2 to perform l3 forwarding. The config below enables that functionality, which is
+# disabled by default.
+# ovsdb.l3.fwd.enabled=yes
+
# ovsdb can be configured with ml2 to perform l3 forwarding. When used in that scenario, the mac address of the default
# gateway --on the external subnet-- is expected to be resolved from its inet address. The config below overrides that
# specific arp/neighDiscovery lookup.
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.0-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<scm>
<groupId>org.opendaylight.controller</groupId>
<artifactId>distribution.p2site</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<build>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>sanitytest</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>dummy-console</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>forwarding.staticrouting</artifactId>
- <version>0.5.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>forwardingrulesmanager</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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>forwardingrulesmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>forwardingrulesmanager.integrationtest</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker</artifactId>
- <version>0.5.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker.implementation</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>hosttracker.integrationtest</artifactId>
- <version>0.5.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker.shell</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker_new</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker_new.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>releasepom</artifactId>
- <version>0.1.2-SNAPSHOT</version>
- <relativePath>../..</relativePath>
- </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>karaf.branding</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <packaging>bundle</packaging>
- <name>OpenDaylight :: Karaf :: Branding</name>
+ <artifactId>releasepom</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>karaf.branding</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+ <name>OpenDaylight :: Karaf :: Branding</name>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>2.4.0</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
- <Import-Package>*</Import-Package>
- <Private-Package>!*</Private-Package>
- <Export-Package>
- org.apache.karaf.branding
- </Export-Package>
- <Spring-Context>*;public-context:=false</Spring-Context>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>2.4.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Import-Package>*</Import-Package>
+ <Private-Package>!*</Private-Package>
+ <Export-Package>org.apache.karaf.branding</Export-Package>
+ <Spring-Context>*;public-context:=false</Spring-Context>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>karaf-tomcat-security</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>logging.bridge</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<artifactId>sal-parent</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>compatibility-parent</artifactId>
<packaging>pom</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>compatibility-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-compatibility</artifactId>
<packaging>bundle</packaging>
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractDataChangeListener <T extends DataObject> implements AutoCloseable,DataChangeListener{
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractDataChangeListener.class);
+ protected InventoryAndReadAdapter adapter;
+ protected final Class<T> clazz;
+ protected ListenerRegistration<DataChangeListener> listenerRegistration;
+
+ public AbstractDataChangeListener(final InventoryAndReadAdapter adapter, DataBroker db, final Class<T> clazz) {
+ this.adapter = Preconditions.checkNotNull(adapter, "InventoryAndReadAdapter can not be null!");
+ this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
+ Preconditions.checkNotNull(db, "DataBroker can not be null!");
+ registrationListener(db, 5);
+ }
+
+ @Override
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+ Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
+ /* All DataObjects for create */
+ final Map<InstanceIdentifier<?>, DataObject> createdData = changeEvent.getCreatedData() != null
+ ? changeEvent.getCreatedData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+ /* All DataObjects for remove */
+ final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null
+ ? changeEvent.getRemovedPaths() : Collections.<InstanceIdentifier<?>> emptySet();
+ /* All DataObjects for updates */
+ final Map<InstanceIdentifier<?>, DataObject> updateData = changeEvent.getUpdatedData() != null
+ ? changeEvent.getUpdatedData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+ /* All Original DataObjects */
+ final Map<InstanceIdentifier<?>, DataObject> originalData = changeEvent.getOriginalData() != null
+ ? changeEvent.getOriginalData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+ this.createData(createdData);
+ this.updateData(updateData, originalData);
+ this.removeData(removeData, originalData);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void createData(final Map<InstanceIdentifier<?>, DataObject> createdData) {
+ final Set<InstanceIdentifier<?>> keys = createdData.keySet() != null
+ ? createdData.keySet() : Collections.<InstanceIdentifier<?>> emptySet();
+ for (InstanceIdentifier<?> key : keys) {
+ if (clazz.equals(key.getTargetType())) {
+ InstanceIdentifier<T> createKeyIdent = key.firstIdentifierOf(clazz);
+ final Optional<DataObject> value = Optional.of(createdData.get(key));
+ if (value.isPresent()) {
+ this.add(createKeyIdent, (T)value.get());
+ }
+ }
+ }
+ }
+
+ abstract protected void add(InstanceIdentifier<T> createKeyIdent, T node);
+
+ @SuppressWarnings("unchecked")
+ private void updateData(final Map<InstanceIdentifier<?>, DataObject> updateData, final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+ final Set<InstanceIdentifier<?>> keys = updateData.keySet() != null
+ ? updateData.keySet() : Collections.<InstanceIdentifier<?>> emptySet();
+ for (InstanceIdentifier<?> key : keys) {
+ if (clazz.equals(key.getTargetType())) {
+ InstanceIdentifier<T> updateKeyIdent = key.firstIdentifierOf(clazz);
+ final Optional<DataObject> value = Optional.of(updateData.get(key));
+ final Optional<DataObject> original = Optional.of(originalData.get(key));
+ if (value.isPresent() && original.isPresent()) {
+ this.update(updateKeyIdent, (T)original.get(), (T)value.get());
+ }
+ }
+ }
+ }
+
+ abstract protected void update(InstanceIdentifier<T> updateKeyIdent, T node,
+ T node2);
+
+ @SuppressWarnings("unchecked")
+ private void removeData(final Set<InstanceIdentifier<?>> removeData, final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+ for (InstanceIdentifier<?> key : removeData) {
+ if (clazz.equals(key.getTargetType())) {
+ final InstanceIdentifier<T> ident = key.firstIdentifierOf(clazz);
+ final DataObject removeValue = originalData.get(key);
+ this.remove(ident, (T)removeValue);
+ }
+ }
+ }
+
+ abstract protected void remove(InstanceIdentifier<T> ident, T removeValue);
+
+ protected void registrationListener(final DataBroker db, int i) {
+ try {
+ listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ getWildCardPath(), this, DataChangeScope.BASE);
+ } catch (final Exception e) {
+ if (i >= 1) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e1) {
+ LOG.error("Thread interrupted '{}'", e1);
+ Thread.currentThread().interrupt();
+ }
+ registrationListener(db, --i);
+ } else {
+ LOG.error("AbstractDataChangeListener registration fail!", e);
+ throw new IllegalStateException("AbstractDataChangeListener registration Listener fail! System needs restart.", e);
+ }
+ }
+ }
+
+ protected abstract InstanceIdentifier<?> getWildCardPath();
+
+ @Override
+ public void close() {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.error("Error by stop AbstractDataChangeListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ }
+}
\ No newline at end of file
protected Object[] getImplementations() {
return new Object[] {
dataPacketService,
+ inventory,
};
}
_instanceConfigure((ComponentActivator)imp, c, containerName);
} else if (imp instanceof DataPacketServiceAdapter) {
_instanceConfigure((DataPacketServiceAdapter)imp, c, containerName);
+ } else if (imp instanceof InventoryAndReadAdapter) {
+ _instanceConfigure((InventoryAndReadAdapter)imp, c, containerName);
} else {
throw new IllegalArgumentException(String.format("Unhandled implementation class %s", imp.getClass()));
}
.setRequired(false));
}
+ private void _instanceConfigure(final InventoryAndReadAdapter imp, final Component it, String containerName) {
+ it.setInterface(new String[] {
+ IPluginInInventoryService.class.getName(),
+ IPluginInReadService.class.getName(),
+ }, properties());
+
+ it.add(createServiceDependency()
+ .setService(IPluginOutReadService.class)
+ .setCallbacks("setReadPublisher", "unsetReadPublisher")
+ .setRequired(false));
+ it.add(createServiceDependency()
+ .setService(IPluginOutInventoryService.class)
+ .setCallbacks("setInventoryPublisher", "unsetInventoryPublisher")
+ .setRequired(false));
+ }
+
private void _configure(final TopologyAdapter imp, final Component it) {
it.setInterface(IPluginInTopologyService.class.getName(), properties());
*/
package org.opendaylight.controller.sal.compatibility;
-import com.google.common.collect.Iterables;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class InventoryAndReadAdapter implements IPluginInReadService, IPluginInInventoryService, OpendaylightInventoryListener, OpendaylightFlowStatisticsListener, OpendaylightFlowTableStatisticsListener, OpendaylightPortStatisticsListener {
+import com.google.common.collect.Iterables;
+
+public class InventoryAndReadAdapter implements IPluginInReadService, IPluginInInventoryService, OpendaylightFlowStatisticsListener, OpendaylightFlowTableStatisticsListener, OpendaylightPortStatisticsListener {
private static final Logger LOG = LoggerFactory.getLogger(InventoryAndReadAdapter.class);
private static final short OPENFLOWV10_TABLE_ID = 0;
* @param id Table id
* @return Table contents, or null if not present
*/
- private Table readConfigTable(final Node node, final short id) {
+ private Table readOperationalTable(final Node node, final short id) {
final InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class)
- .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, InventoryMapping.toNodeKey(node))
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, NodeMapping.toNodeKey(node))
.augmentation(FlowCapableNode.class)
.child(Table.class, new TableKey(id))
.build();
- return (Table) startChange().readConfigurationData(tableRef);
+ return (Table) startChange().readOperationalData(tableRef);
}
@Override
public List<FlowOnNode> readAllFlow(final Node node, final boolean cached) {
final ArrayList<FlowOnNode> output = new ArrayList<>();
- final Table table = readConfigTable(node, OPENFLOWV10_TABLE_ID);
+ final Table table = readOperationalTable(node, OPENFLOWV10_TABLE_ID);
if (table != null) {
final List<Flow> flows = table.getFlow();
LOG.trace("Number of flows installed in table 0 of node {} : {}", node, flows.size());
}
}
- // TODO (main): Shall we send request to the switch? It will make async request to the switch.
- // Once the plugin receives a response, it will let the adaptor know through onFlowStatisticsUpdate()
- // If we assume that md-sal statistics manager will always be running, then it is not required
- // But if not, then sending request will collect the latest data for adaptor at least.
- getFlowStatisticsService().getAllFlowsStatisticsFromAllFlowTables(
- new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder().setNode(NodeMapping.toNodeRef(node)).build());
return output;
}
@Override
public FlowOnNode readFlow(final Node node, final org.opendaylight.controller.sal.flowprogrammer.Flow targetFlow, final boolean cached) {
FlowOnNode ret = null;
- final Table table = readConfigTable(node, OPENFLOWV10_TABLE_ID);
+ final Table table = readOperationalTable(node, OPENFLOWV10_TABLE_ID);
if (table != null) {
final List<Flow> flows = table.getFlow();
InventoryAndReadAdapter.LOG.trace("Number of flows installed in table 0 of node {} : {}", node, flows.size());
@Override
public NodeTableStatistics readNodeTable(final NodeTable nodeTable, final boolean cached) {
NodeTableStatistics nodeStats = null;
- final Table table = readConfigTable(nodeTable.getNode(), (short) nodeTable.getID());
+ final Table table = readOperationalTable(nodeTable.getNode(), (short) nodeTable.getID());
if (table != null) {
final FlowTableStatisticsData tableStats = table.getAugmentation(FlowTableStatisticsData.class);
if (tableStats != null) {
return nodeStats;
}
- @Override
- public void onNodeConnectorRemoved(final NodeConnectorRemoved update) {
+ public void onNodeConnectorRemovedInternal(final NodeConnectorRemoved update) {
// Never received
}
- @Override
- public void onNodeRemoved(final NodeRemoved notification) {
+ public void onNodeRemovedInternal(final NodeRemoved notification) {
this.removeNodeConnectors(notification.getNodeRef().getValue());
try {
final Node aDNode = NodeMapping.toADNode(notification.getNodeRef());
}
}
- @Override
- public void onNodeConnectorUpdated(final NodeConnectorUpdated update) {
+ public void onNodeConnectorUpdatedInternal(final NodeConnectorUpdated update) {
final NodeConnectorRef ref = update.getNodeConnectorRef();
final UpdateType updateType;
if (!this.isKnownNodeConnector(ref.getValue())) {
}
}
- @Override
- public void onNodeUpdated(final NodeUpdated notification) {
+ public void onNodeUpdatedInternal(final NodeUpdated notification) {
final NodeRef ref = notification.getNodeRef();
final UpdateType updateType;
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NCDataChangeListener extends AbstractDataChangeListener<NodeConnector> {
+ private static final Logger LOG = LoggerFactory.getLogger(NodeDataChangeListener.class);
+ private ListenerRegistration<DataChangeListener> listenerRegistration;
+ public NCDataChangeListener (final InventoryAndReadAdapter adapter, final DataBroker db) {
+ super(adapter,db,NodeConnector.class);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<NodeConnector> createKeyIdent, NodeConnector node) {
+ FlowCapableNodeConnector fcnc = node.getAugmentation(FlowCapableNodeConnector.class);
+ if(fcnc != null) {
+ FlowCapableNodeConnectorUpdatedBuilder fcncub = new FlowCapableNodeConnectorUpdatedBuilder(fcnc);
+ NodeConnectorUpdatedBuilder builder = new NodeConnectorUpdatedBuilder();
+ builder.setId(node.getId());
+ builder.setNodeConnectorRef(new NodeConnectorRef(createKeyIdent));
+ builder.addAugmentation(FlowCapableNodeConnectorUpdated.class, fcncub.build());
+ adapter.onNodeConnectorUpdatedInternal(builder.build());
+ }
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<NodeConnector> updateKeyIdent, NodeConnector original,
+ NodeConnector update) {
+ add(updateKeyIdent,update);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<NodeConnector> ident, NodeConnector removeValue) {
+ NodeConnectorRemovedBuilder builder = new NodeConnectorRemovedBuilder();
+ builder.setNodeConnectorRef(new NodeConnectorRef(ident));
+ adapter.onNodeConnectorRemovedInternal(builder.build());
+ }
+
+ protected InstanceIdentifier<NodeConnector> getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NodeDataChangeListener extends AbstractDataChangeListener<Node> {
+ private static final Logger LOG = LoggerFactory.getLogger(NodeDataChangeListener.class);
+
+
+ public NodeDataChangeListener (final InventoryAndReadAdapter adapter, final DataBroker db) {
+ super(adapter,db,Node.class);
+ }
+
+ protected void add(InstanceIdentifier<Node> createKeyIdent, Node node) {
+ FlowCapableNode fcn = node.getAugmentation(FlowCapableNode.class);
+ if(fcn != null) {
+ FlowCapableNodeUpdatedBuilder fcbnu = new FlowCapableNodeUpdatedBuilder(fcn);
+ NodeUpdatedBuilder builder = new NodeUpdatedBuilder();
+ builder.setId(node.getId());
+ builder.setNodeRef(new NodeRef(createKeyIdent));
+ builder.setNodeConnector(node.getNodeConnector());
+ builder.addAugmentation(FlowCapableNodeUpdated.class, fcbnu.build());
+ adapter.onNodeUpdatedInternal(builder.build());
+ }
+ }
+
+ protected void update(InstanceIdentifier<Node> updateKeyIdent, Node original,
+ Node update) {
+ this.add(updateKeyIdent, update);
+ }
+
+ protected void remove(InstanceIdentifier<Node> ident, Node removeValue) {
+ NodeRemovedBuilder builder = new NodeRemovedBuilder();
+ builder.setNodeRef(new NodeRef(ident));
+ adapter.onNodeRemovedInternal(builder.build());
+ }
+
+ protected InstanceIdentifier<Node> getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class);
+ }
+
+}
* @return
*/
private static NodeId toNodeId(org.opendaylight.controller.sal.core.Node aDNode) {
- return new NodeId(aDNode.getType() + ":" + String.valueOf(aDNode.getID()));
+ String targetPrefix = null;
+ if (NodeIDType.OPENFLOW.equals(aDNode.getType())) {
+ targetPrefix = OPENFLOW_ID_PREFIX;
+ } else {
+ targetPrefix = aDNode.getType() + ":";
+ }
+
+ return new NodeId(targetPrefix + String.valueOf(aDNode.getID()));
+ }
+
+ /**
+ * @param aDNode
+ * @return md-sal {@link NodeKey}
+ */
+ public static NodeKey toNodeKey(org.opendaylight.controller.sal.core.Node aDNode) {
+ return new NodeKey(toNodeId(aDNode));
}
public static String toNodeConnectorType(final NodeConnectorId ncId, final NodeId nodeId) {
import java.util.Collection;
import java.util.Collections;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
inv.setNodeConnectorStatisticsService(session.getRpcService(OpendaylightPortStatisticsService.class));
inv.setTopologyDiscovery(session.getRpcService(FlowTopologyDiscoveryService.class));
inv.setDataProviderService(session.getSALService(DataProviderService.class));
+
+ final NodeDataChangeListener ndcl = new NodeDataChangeListener(inv,session.getSALService(DataBroker.class));
+ final NCDataChangeListener ncdcl = new NCDataChangeListener(inv,session.getSALService(DataBroker.class));
+
// FIXME: remember registration for clean shutdown
subscribe.registerNotificationListener(inv);
*/
package org.opendaylight.controller.sal.compatibility.topology;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
-
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader;
import org.opendaylight.controller.sal.compatibility.NodeMapping;
import org.opendaylight.controller.sal.core.ConstructionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Function;
-import com.google.common.collect.FluentIterable;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.regex.Pattern;
+
+import static com.google.common.base.Preconditions.checkNotNull;
public final class TopologyMapping {
private static final Logger LOG = LoggerFactory.getLogger(TopologyMapping.class);
+ private final static Pattern NUMBERS_ONLY = Pattern.compile("[0-9]+");
private TopologyMapping() {
throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
public static NodeConnector toADNodeConnector(final TpId source, final NodeId nodeId) throws ConstructionException {
checkNotNull(source);
- return new NodeConnector(NodeConnectorIDType.OPENFLOW, Short.valueOf(toADNodeConnectorId(source)), toADNode(nodeId));
+ String nodeConnectorIdStripped = toADNodeConnectorId(source);
+ if (NUMBERS_ONLY.matcher(nodeConnectorIdStripped).matches()) {
+ return new NodeConnector(NodeConnectorIDType.OPENFLOW, Short.valueOf(nodeConnectorIdStripped), toADNode(nodeId));
+ }
+ LOG.debug("NodeConnectorId does not match openflow id type, using " + NodeMapping.MD_SAL_TYPE + "instead");
+ NodeConnectorIDType.registerIDType(NodeMapping.MD_SAL_TYPE, String.class, NodeMapping.MD_SAL_TYPE);
+ return new NodeConnector(NodeMapping.MD_SAL_TYPE, nodeConnectorIdStripped, toADNode(nodeId));
}
public static String toADNodeConnectorId(final TpId nodeConnectorId) {
public static Node toADNode(final NodeId nodeId) throws ConstructionException {
checkNotNull(nodeId);
- return new Node(NodeIDType.OPENFLOW, Long.valueOf(toADNodeId(nodeId)));
+ String nodeIdStripped = toADNodeId(nodeId);
+ if (NUMBERS_ONLY.matcher(nodeIdStripped).matches()) {
+ return new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeIdStripped));
+ }
+ LOG.debug("NodeId does not match openflow id type, using " + NodeMapping.MD_SAL_TYPE + "instead");
+ NodeIDType.registerIDType(NodeMapping.MD_SAL_TYPE, String.class);
+ return new Node(NodeMapping.MD_SAL_TYPE, nodeId.getValue());
}
}
Assert.assertEquals(0xCC4E241C4A000000L, NodeMapping.openflowFullNodeIdToLong("14721743935839928320").longValue());
}
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#toNodeKey(org.opendaylight.controller.sal.core.Node)}
+ * .
+ * @throws ConstructionException
+ */
+ @Test
+ public void testToNodeKey() throws ConstructionException {
+ org.opendaylight.controller.sal.core.Node aDNode = new org.opendaylight.controller.sal.core.Node(NodeIDType.OPENFLOW, 42L);
+ NodeKey nodeKey = NodeMapping.toNodeKey(aDNode);
+ Assert.assertEquals("openflow:42", nodeKey.getId().getValue());
+ }
+
/**
* @param nodeId
* @param portId
Assert.assertEquals("OF|00:00:00:00:00:00:00:01", observedNode.toString());
}
+ /**
+ * Test method for {@link org.opendaylight.controller.sal.compatibility.topology.TopologyMapping#toADNodeConnector(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId, org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId)}.
+ * @throws ConstructionException
+ */
+ @Test
+ public void bug1309ToADNodeConnector() throws ConstructionException {
+ NodeId nodeId = new NodeId("some_unknown_node");
+ TpId source = new TpId("192.168.0.1");
+ NodeConnector observedNodeConnector = TopologyMapping.toADNodeConnector(source, nodeId);
+
+ Assert.assertEquals("MD_SAL_DEPRECATED|192.168.0.1@MD_SAL_DEPRECATED|some_unknown_node", observedNodeConnector.toString());
+ }
+
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.md</groupId>
<artifactId>forwardingrules-manager</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.md</groupId>
<artifactId>inventory-manager</artifactId>
*/
package org.opendaylight.controller.md.inventory.manager;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
+import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
+
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+
class FlowCapableInventoryProvider implements AutoCloseable, Runnable, TransactionChainListener {
private static final Logger LOG = LoggerFactory.getLogger(FlowCapableInventoryProvider.class);
private static final int QUEUE_DEPTH = 500;
final NodeChangeCommiter changeCommiter = new NodeChangeCommiter(FlowCapableInventoryProvider.this);
this.listenerRegistration = this.notificationService.registerNotificationListener(changeCommiter);
- this.txChain = dataBroker.createTransactionChain(this);
+ this.txChain = (dataBroker.createTransactionChain(this));
thread = new Thread(this);
thread.setDaemon(true);
thread.setName("FlowCapableInventoryProvider");
void enqueue(final InventoryOperation op) {
try {
queue.put(op);
- } catch (InterruptedException e) {
+ } catch (final InterruptedException e) {
LOG.warn("Failed to enqueue operation {}", op, e);
}
}
- @Override
- public void close() throws InterruptedException {
- LOG.info("Flow Capable Inventory Provider stopped.");
- if (this.listenerRegistration != null) {
- try {
- this.listenerRegistration.close();
- } catch (Exception e) {
- LOG.error("Failed to stop inventory provider", e);
- }
- listenerRegistration = null;
- }
-
- if (thread != null) {
- thread.interrupt();
- thread.join();
- thread = null;
- }
- if (txChain != null) {
- txChain.close();
- txChain = null;
- }
-
-
- }
-
@Override
public void run() {
try {
for (; ; ) {
InventoryOperation op = queue.take();
-
- final ReadWriteTransaction tx = txChain.newReadWriteTransaction();
- LOG.debug("New operations available, starting transaction {}", tx.getIdentifier());
-
int ops = 0;
+ final ArrayList<InventoryOperation> opsToApply = new ArrayList<>(MAX_BATCH);
do {
- op.applyOperation(tx);
-
+ opsToApply.add(op);
ops++;
if (ops < MAX_BATCH) {
op = queue.poll();
op = null;
}
} while (op != null);
-
- LOG.debug("Processed {} operations, submitting transaction {}", ops, tx.getIdentifier());
-
- final CheckedFuture<Void, TransactionCommitFailedException> result = tx.submit();
- Futures.addCallback(result, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void aVoid) {
- //NOOP
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- LOG.error("Transaction {} failed.", tx.getIdentifier(), throwable);
- }
- });
+ submitOperations(opsToApply);
}
- } catch (InterruptedException e) {
+ } catch (final InterruptedException e) {
LOG.info("Processing interrupted, terminating", e);
}
}
}
+ /**
+ * Starts new empty transaction, custimizes it with submitted operations
+ * and submit it to data broker.
+ *
+ * If transaction chain failed during customization of transaction
+ * it allocates new chain and empty transaction and customizes it
+ * with submitted operations.
+ *
+ * This does not retry failed transaction. It only retries it when
+ * chain failed during customization of transaction chain.
+ *
+ * @param opsToApply
+ */
+ private void submitOperations(final ArrayList<InventoryOperation> opsToApply) {
+ final ReadWriteTransaction tx = createCustomizedTransaction(opsToApply);
+ LOG.debug("Processed {} operations, submitting transaction {}", opsToApply.size(), tx.getIdentifier());
+ try {
+ tx.submit();
+ } catch (final IllegalStateException e) {
+ /*
+ * Transaction chain failed during doing batch, so we need to null
+ * tx chain and continue processing queue.
+ *
+ * We fail current txChain which was allocated with createTransaction.
+ */
+ failCurrentChain(txChain);
+ /*
+ * We will retry transaction once in order to not loose any data.
+ *
+ */
+ final ReadWriteTransaction retryTx = createCustomizedTransaction(opsToApply);
+ retryTx.submit();
+ }
+ }
+
+ /**
+ * Creates new empty ReadWriteTransaction. If transaction chain
+ * was failed, it will allocate new transaction chain
+ * and assign it with this Operation Executor.
+ *
+ * This call is synchronized to prevent reace with {@link #failCurrentChain(TransactionChain)}.
+ *
+ * @return New Empty ReadWrite transaction, which continues this chain or starts new transaction
+ * chain.
+ */
+ private synchronized ReadWriteTransaction newEmptyTransaction() {
+ try {
+ if(txChain == null) {
+ // Chain was broken so we need to replace it.
+ txChain = dataBroker.createTransactionChain(this);
+ }
+ return txChain.newReadWriteTransaction();
+ } catch (final IllegalStateException e) {
+ LOG.debug("Chain is broken, need to allocate new transaction chain.",e);
+ /*
+ * Chain was broken by previous transaction,
+ * but there was race between this.
+ * Chain will be closed by #onTransactionChainFailed method.
+ */
+ txChain = dataBroker.createTransactionChain(this);
+ return txChain.newReadWriteTransaction();
+ }
+ }
+
+ /**
+ * Creates customized not-submitted transaction, which is ready to be submitted.
+ *
+ * @param opsToApply Operations which are used to customize transaction.
+ * @return Non-empty transaction.
+ */
+ private ReadWriteTransaction createCustomizedTransaction(final ArrayList<InventoryOperation> opsToApply) {
+ final ReadWriteTransaction tx = newEmptyTransaction();
+ for(final InventoryOperation op : opsToApply) {
+ op.applyOperation(tx);
+ }
+ return tx;
+ }
+
+ private synchronized void failCurrentChain(final TransactionChain<?, ?> chain) {
+ if(txChain == chain) {
+ txChain = null;
+ }
+ }
+
@Override
public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction,
final Throwable cause) {
LOG.error("Failed to export Flow Capable Inventory, Transaction {} failed.", transaction.getIdentifier(), cause);
-
+ chain.close();
+ if(txChain == chain) {
+ // Current chain is broken, so we will null it, in order to not use it.
+ failCurrentChain(chain);
+ }
}
@Override
public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
// NOOP
}
+
+ @Override
+ public void close() throws InterruptedException {
+ LOG.info("Flow Capable Inventory Provider stopped.");
+ if (this.listenerRegistration != null) {
+ try {
+ this.listenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.error("Failed to stop inventory provider", e);
+ }
+ listenerRegistration = null;
+ }
+
+ if (thread != null) {
+ thread.interrupt();
+ thread.join();
+ thread = null;
+ }
+ if (txChain != null) {
+ try {
+ txChain.close();
+ } catch (final IllegalStateException e) {
+ // It is possible chain failed and was closed by #onTransactionChainFailed
+ LOG.debug("Chain was already closed.");
+ }
+ txChain = null;
+ }
+ }
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>md-sal-config</artifactId>
<description>Configuration files for md-sal</description>
<parent>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>model-flow-base</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>model-flow-service</artifactId>
<packaging>bundle</packaging>
}
augment "/inv:nodes/inv:node/table" {
- ext:augment-identifier "flow-cookie-mapping";
- list flow-cookie-map {
- key "cookie";
- leaf cookie {
- type flow:flow-cookie;
+ ext:augment-identifier "flow-hash-id-mapping";
+ description "Flow is identified by match and priority on device. So Operational/DS
+ has to simulate that behavior and contract between FlowId and match+priority
+ identification should represent Flow hashCode. Flow has to contain only
+ match priority and flowCookie for create a hashCode";
+ list flow-hash-id-map {
+ key "hash";
+ leaf hash {
+ type string;
}
- leaf-list flow-ids {
+ leaf flow-id {
type flow-id;
}
}
<parent>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>model-flow-statistics</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>model-inventory</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>model-topology</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-akka-raft</artifactId>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-clustering-commons</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
LOG = context.getLogger();
- if (lastIndex() >= 0) {
- context.setCommitIndex(lastIndex());
- }
-
followers = context.getPeerAddresses().keySet();
for (String followerId : followers) {
FollowerLogInformation followerLogInformation =
new FollowerLogInformationImpl(followerId,
- new AtomicLong(lastIndex()),
+ new AtomicLong(context.getCommitIndex()),
new AtomicLong(-1));
followerToLog.put(followerId, followerLogInformation);
public static class MockPayload extends Payload implements Serializable {
private String value = "";
+ public MockPayload(){
+
+ }
+
public MockPayload(String s) {
this.value = s;
}
return index;
}
}
+
+ public static class MockReplicatedLogBuilder {
+ private ReplicatedLog mockLog = new SimpleReplicatedLog();
+
+ public MockReplicatedLogBuilder createEntries(int start, int end, int term) {
+ for (int i=start; i<end; i++) {
+ this.mockLog.append(new ReplicatedLogImplEntry(i, term, new MockRaftActorContext.MockPayload("foo" + i)));
+ }
+ return this;
+ }
+
+ public MockReplicatedLogBuilder addEntry(int index, int term, MockPayload payload) {
+ this.mockLog.append(new ReplicatedLogImplEntry(index, term, payload));
+ return this;
+ }
+
+ public ReplicatedLog build() {
+ return this.mockLog;
+ }
+ }
}
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.testkit.JavaTestKit;
-import akka.util.Timeout;
import com.google.protobuf.ByteString;
import junit.framework.Assert;
import org.junit.Test;
import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
-import scala.concurrent.Await;
-import scala.concurrent.Future;
-import scala.concurrent.duration.Duration;
-import scala.concurrent.duration.FiniteDuration;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import static akka.pattern.Patterns.ask;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
}
public Object executeLocalOperation(ActorRef actor, Object message) throws Exception {
- FiniteDuration operationDuration = Duration.create(5, TimeUnit.SECONDS);
- Timeout operationTimeout = new Timeout(operationDuration);
- Future<Object> future = ask(actor, message, operationTimeout);
-
- try {
- return Await.result(future, operationDuration);
- } catch (Exception e) {
- throw e;
- }
+ return MessageCollectorActor.getAllMessages(actor);
}
public ByteString getNextChunk (ByteString bs, int offset){
import org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat;
import org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot;
import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
import org.opendaylight.controller.cluster.raft.messages.InstallSnapshot;
import org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply;
import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
+import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
+import org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
import org.opendaylight.controller.protobuff.messages.cluster.raft.InstallSnapshotMessages;
import java.io.ByteArrayOutputStream;
actorContext.getReplicatedLog().removeFrom(0);
- actorContext.getReplicatedLog().append(new ReplicatedLogImplEntry(0, 1,
- new MockRaftActorContext.MockPayload("foo")));
-
- ReplicatedLogImplEntry entry =
- new ReplicatedLogImplEntry(1, 1,
- new MockRaftActorContext.MockPayload("foo"));
-
- actorContext.getReplicatedLog().append(entry);
+ actorContext.setReplicatedLog(
+ new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 2, 1)
+ .build());
Leader leader = new Leader(actorContext);
RaftState raftState = leader
- .handleMessage(senderActor, new Replicate(null, "state-id",entry));
+ .handleMessage(senderActor, new Replicate(null, "state-id",actorContext.getReplicatedLog().get(1)));
// State should not change
assertEquals(RaftState.Leader, raftState);
new ReplicatedLogImplEntry(newEntryIndex, currentTerm,
new MockRaftActorContext.MockPayload("D"));
-
RaftState raftState = leader.handleMessage(senderActor, new SendInstallSnapshot());
assertEquals(RaftState.Leader, raftState);
return null;
}
+ public static class ForwardMessageToBehaviorActor extends MessageCollectorActor {
+ private static AbstractRaftActorBehavior behavior;
+
+ public ForwardMessageToBehaviorActor(){
+
+ }
+
+ @Override public void onReceive(Object message) throws Exception {
+ super.onReceive(message);
+ behavior.handleMessage(sender(), message);
+ }
+
+ public static void setBehavior(AbstractRaftActorBehavior behavior){
+ ForwardMessageToBehaviorActor.behavior = behavior;
+ }
+ }
+
+ @Test
+ public void testLeaderCreatedWithCommitIndexLessThanLastIndex() throws Exception {
+ new JavaTestKit(getSystem()) {{
+
+ ActorRef leaderActor = getSystem().actorOf(Props.create(MessageCollectorActor.class));
+
+ MockRaftActorContext leaderActorContext =
+ new MockRaftActorContext("leader", getSystem(), leaderActor);
+
+ ActorRef followerActor = getSystem().actorOf(Props.create(ForwardMessageToBehaviorActor.class));
+
+ MockRaftActorContext followerActorContext =
+ new MockRaftActorContext("follower", getSystem(), followerActor);
+
+ Follower follower = new Follower(followerActorContext);
+
+ ForwardMessageToBehaviorActor.setBehavior(follower);
+
+ Map<String, String> peerAddresses = new HashMap();
+ peerAddresses.put(followerActor.path().toString(),
+ followerActor.path().toString());
+
+ leaderActorContext.setPeerAddresses(peerAddresses);
+
+ leaderActorContext.getReplicatedLog().removeFrom(0);
+
+ //create 3 entries
+ leaderActorContext.setReplicatedLog(
+ new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 3, 1).build());
+
+ leaderActorContext.setCommitIndex(1);
+
+ followerActorContext.getReplicatedLog().removeFrom(0);
+
+ // follower too has the exact same log entries and has the same commit index
+ followerActorContext.setReplicatedLog(
+ new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 3, 1).build());
+
+ followerActorContext.setCommitIndex(1);
+
+ Leader leader = new Leader(leaderActorContext);
+
+ leader.handleMessage(leaderActor, new SendHeartBeat());
+
+ AppendEntriesMessages.AppendEntries appendEntries =
+ (AppendEntriesMessages.AppendEntries) MessageCollectorActor
+ .getFirstMatching(followerActor, AppendEntriesMessages.AppendEntries.class);
+
+ assertNotNull(appendEntries);
+
+ assertEquals(1, appendEntries.getLeaderCommit());
+ assertEquals(1, appendEntries.getLogEntries(0).getIndex());
+ assertEquals(0, appendEntries.getPrevLogIndex());
+
+ AppendEntriesReply appendEntriesReply =
+ (AppendEntriesReply) MessageCollectorActor.getFirstMatching(
+ leaderActor, AppendEntriesReply.class);
+
+ assertNotNull(appendEntriesReply);
+
+ // follower returns its next index
+ assertEquals(2, appendEntriesReply.getLogLastIndex());
+ assertEquals(1, appendEntriesReply.getLogLastTerm());
+
+ }};
+ }
+
+
+ @Test
+ public void testLeaderCreatedWithCommitIndexLessThanFollowersCommitIndex() throws Exception {
+ new JavaTestKit(getSystem()) {{
+
+ ActorRef leaderActor = getSystem().actorOf(Props.create(MessageCollectorActor.class));
+
+ MockRaftActorContext leaderActorContext =
+ new MockRaftActorContext("leader", getSystem(), leaderActor);
+
+ ActorRef followerActor = getSystem().actorOf(
+ Props.create(ForwardMessageToBehaviorActor.class));
+
+ MockRaftActorContext followerActorContext =
+ new MockRaftActorContext("follower", getSystem(), followerActor);
+
+ Follower follower = new Follower(followerActorContext);
+
+ ForwardMessageToBehaviorActor.setBehavior(follower);
+
+ Map<String, String> peerAddresses = new HashMap();
+ peerAddresses.put(followerActor.path().toString(),
+ followerActor.path().toString());
+
+ leaderActorContext.setPeerAddresses(peerAddresses);
+
+ leaderActorContext.getReplicatedLog().removeFrom(0);
+
+ leaderActorContext.setReplicatedLog(
+ new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 3, 1).build());
+
+ leaderActorContext.setCommitIndex(1);
+
+ followerActorContext.getReplicatedLog().removeFrom(0);
+
+ followerActorContext.setReplicatedLog(
+ new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 3, 1).build());
+
+ // follower has the same log entries but its commit index > leaders commit index
+ followerActorContext.setCommitIndex(2);
+
+ Leader leader = new Leader(leaderActorContext);
+
+ leader.handleMessage(leaderActor, new SendHeartBeat());
+
+ AppendEntriesMessages.AppendEntries appendEntries =
+ (AppendEntriesMessages.AppendEntries) MessageCollectorActor
+ .getFirstMatching(followerActor, AppendEntriesMessages.AppendEntries.class);
+
+ assertNotNull(appendEntries);
+
+ assertEquals(1, appendEntries.getLeaderCommit());
+ assertEquals(1, appendEntries.getLogEntries(0).getIndex());
+ assertEquals(0, appendEntries.getPrevLogIndex());
+
+ AppendEntriesReply appendEntriesReply =
+ (AppendEntriesReply) MessageCollectorActor.getFirstMatching(
+ leaderActor, AppendEntriesReply.class);
+
+ assertNotNull(appendEntriesReply);
+
+ assertEquals(2, appendEntriesReply.getLogLastIndex());
+ assertEquals(1, appendEntriesReply.getLogLastTerm());
+
+ }};
+ }
+
private static class LeaderTestKit extends JavaTestKit {
private LeaderTestKit(ActorSystem actorSystem) {
package org.opendaylight.controller.cluster.raft.utils;
+import akka.actor.ActorRef;
import akka.actor.UntypedActor;
+import akka.pattern.Patterns;
+import akka.util.Timeout;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.duration.Duration;
+import scala.concurrent.duration.FiniteDuration;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.TimeUnit;
public class MessageCollectorActor extends UntypedActor {
messages.add(message);
}
}
+
+ public static List<Object> getAllMessages(ActorRef actor) throws Exception {
+ FiniteDuration operationDuration = Duration.create(5, TimeUnit.SECONDS);
+ Timeout operationTimeout = new Timeout(operationDuration);
+ Future<Object> future = Patterns.ask(actor, "get-all-messages", operationTimeout);
+
+ try {
+ return (List<Object>) Await.result(future, operationDuration);
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * Get the first message that matches the specified class
+ * @param actor
+ * @param clazz
+ * @return
+ */
+ public static Object getFirstMatching(ActorRef actor, Class clazz) throws Exception {
+ List<Object> allMessages = getAllMessages(actor);
+
+ for(Object message : allMessages){
+ if(message.getClass().equals(clazz)){
+ return message;
+ }
+ }
+
+ return null;
+ }
+
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-api</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-broker-impl</artifactId>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-data-codec</artifactId>
- <version>0.6.2-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-config</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-dom-it</artifactId>
<packaging>jar</packaging>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-test-model</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-it</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-binding-util</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-clustering-commons</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-clustering-config</artifactId>
<description>Configuration files for md-sal clustering</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-common-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-common-impl</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-common-util</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-common</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-connector-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-distributed-datastore</artifactId>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-inmemory-datastore</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-clustering-commons</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-akka-raft</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-core-api</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-broker-impl</artifactId>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-inmemory-datastore</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
package org.opendaylight.controller.md.sal.dom.broker.impl;
import static com.google.common.base.Preconditions.checkState;
-import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import java.util.EnumMap;
public CheckedFuture<Void,TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
LOG.debug("Transaction: {} submitted with cohorts {}.", transaction.getIdentifier(), cohorts);
- return coordinator.submit(transaction, cohorts, Optional.<DOMDataCommitErrorListener> absent());
+ return coordinator.submit(transaction, cohorts);
}
}
*/
package org.opendaylight.controller.md.sal.dom.broker.impl;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
* {@link org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType} type.
*
*/
-public class DOMDataBrokerTransactionChainImpl extends AbstractDOMForwardedTransactionFactory<DOMStoreTransactionChain>
- implements DOMTransactionChain, DOMDataCommitErrorListener {
+final class DOMDataBrokerTransactionChainImpl extends AbstractDOMForwardedTransactionFactory<DOMStoreTransactionChain>
+ implements DOMTransactionChain {
+ private static enum State {
+ RUNNING,
+ CLOSING,
+ CLOSED,
+ FAILED,
+ }
+ private static final AtomicIntegerFieldUpdater<DOMDataBrokerTransactionChainImpl> COUNTER_UPDATER =
+ AtomicIntegerFieldUpdater.newUpdater(DOMDataBrokerTransactionChainImpl.class, "counter");
+ private static final AtomicReferenceFieldUpdater<DOMDataBrokerTransactionChainImpl, State> STATE_UPDATER =
+ AtomicReferenceFieldUpdater.newUpdater(DOMDataBrokerTransactionChainImpl.class, State.class, "state");
private static final Logger LOG = LoggerFactory.getLogger(DOMDataBrokerTransactionChainImpl.class);
private final AtomicLong txNum = new AtomicLong();
private final DOMDataCommitExecutor coordinator;
private final TransactionChainListener listener;
private final long chainId;
- private volatile boolean failed = false;
+ private volatile State state = State.RUNNING;
+ private volatile int counter = 0;
/**
*
this.listener = Preconditions.checkNotNull(listener);
}
+ private void checkNotFailed() {
+ Preconditions.checkState(state != State.FAILED, "Transaction chain has failed");
+ }
+
@Override
protected Object newTransactionIdentifier() {
return "DOM-CHAIN-" + chainId + "-" + txNum.getAndIncrement();
}
@Override
- public CheckedFuture<Void,TransactionCommitFailedException> submit(
+ public CheckedFuture<Void, TransactionCommitFailedException> submit(
final DOMDataWriteTransaction transaction, final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
+ checkNotFailed();
checkNotClosed();
- return coordinator.submit(transaction, cohorts, Optional.<DOMDataCommitErrorListener> of(this));
+ final CheckedFuture<Void, TransactionCommitFailedException> ret = coordinator.submit(transaction, cohorts);
+
+ COUNTER_UPDATER.incrementAndGet(this);
+ Futures.addCallback(ret, new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(final Void result) {
+ transactionCompleted();
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ transactionFailed(transaction, t);
+ }
+ });
+
+ return ret;
}
@Override
public void close() {
- super.close();
+ final boolean success = STATE_UPDATER.compareAndSet(this, State.RUNNING, State.CLOSING);
+ if (!success) {
+ LOG.debug("Chain {} is no longer running", this);
+ return;
+ }
+ super.close();
for (DOMStoreTransactionChain subChain : getTxFactories().values()) {
subChain.close();
}
- if (!failed) {
- LOG.debug("Transaction chain {}Â successfully finished.", this);
- // FIXME: this event should be emitted once all operations complete
- listener.onTransactionChainSuccessful(this);
+ if (counter == 0) {
+ finishClose();
}
}
- @Override
- public void onCommitFailed(final DOMDataWriteTransaction tx, final Throwable cause) {
- failed = true;
+ private void finishClose() {
+ state = State.CLOSED;
+ listener.onTransactionChainSuccessful(this);
+ }
+
+ private void transactionCompleted() {
+ if (COUNTER_UPDATER.decrementAndGet(this) == 0 && state == State.CLOSING) {
+ finishClose();
+ }
+ }
+
+ private void transactionFailed(final DOMDataWriteTransaction tx, final Throwable cause) {
+ state = State.FAILED;
LOG.debug("Transaction chain {}Â failed.", this, cause);
listener.onTransactionChainFailed(this, tx, cause);
}
*/
package org.opendaylight.controller.md.sal.dom.broker.impl;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
@Override
public CheckedFuture<Void,TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
- final Iterable<DOMStoreThreePhaseCommitCohort> cohorts, final Optional<DOMDataCommitErrorListener> listener) {
+ final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
Preconditions.checkArgument(transaction != null, "Transaction must not be null.");
Preconditions.checkArgument(cohorts != null, "Cohorts must not be null.");
- Preconditions.checkArgument(listener != null, "Listener must not be null");
LOG.debug("Tx: {} is submitted for execution.", transaction.getIdentifier());
ListenableFuture<Void> commitFuture = null;
try {
commitFuture = executor.submit(new CommitCoordinationTask(transaction, cohorts,
- listener, commitStatsTracker));
+ commitStatsTracker));
} catch(RejectedExecutionException e) {
LOG.error("The commit executor's queue is full - submit task was rejected. \n" +
executor, e);
"Could not submit the commit task - the commit queue capacity has been exceeded.", e));
}
- if (listener.isPresent()) {
- Futures.addCallback(commitFuture, new DOMDataCommitErrorInvoker(transaction, listener.get()));
- }
-
return MappingCheckedFuture.create(commitFuture,
TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
}
public CommitCoordinationTask(final DOMDataWriteTransaction transaction,
final Iterable<DOMStoreThreePhaseCommitCohort> cohorts,
- final Optional<DOMDataCommitErrorListener> listener,
final DurationStatsTracker commitStatTracker) {
this.tx = Preconditions.checkNotNull(transaction, "transaction must not be null");
this.cohorts = Preconditions.checkNotNull(cohorts, "cohorts must not be null");
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.sal.dom.broker.impl;
-
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FutureCallback;
-
-/**
- *
- * Utility implemetation of {@link FutureCallback} which is responsible
- * for invoking {@link DOMDataCommitErrorListener} on TransactionCommit failed.
- *
- * When {@link #onFailure(Throwable)} is invoked, supplied {@link DOMDataCommitErrorListener}
- * callback is invoked with associated transaction and throwable is invoked on listener.
- *
- */
-class DOMDataCommitErrorInvoker implements FutureCallback<Void> {
-
- private final DOMDataWriteTransaction tx;
- private final DOMDataCommitErrorListener listener;
-
-
- /**
- *
- * Construct new DOMDataCommitErrorInvoker.
- *
- * @param transaction Transaction which should be passed as argument to {@link DOMDataCommitErrorListener#onCommitFailed(DOMDataWriteTransaction, Throwable)}
- * @param listener Listener which should be invoked on error.
- */
- public DOMDataCommitErrorInvoker(DOMDataWriteTransaction transaction, DOMDataCommitErrorListener listener) {
- this.tx = Preconditions.checkNotNull(transaction, "Transaction must not be null");
- this.listener = Preconditions.checkNotNull(listener, "Listener must not be null");
- }
-
- @Override
- public void onFailure(Throwable t) {
- listener.onCommitFailed(tx, t);
- }
-
- @Override
- public void onSuccess(Void result) {
- // NOOP
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.sal.dom.broker.impl;
-
-import java.util.EventListener;
-
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-
-/**
- *
- * Listener on transaction failure which may be passed to
- * {@link DOMDataCommitExecutor}. This listener is notified during transaction
- * processing, before result is delivered to other client code outside MD-SAL.
- * This allows implementors to update their internal state before transaction
- * failure is visible to client code.
- *
- * This is internal API for MD-SAL implementations, for consumer facing error
- * listeners see {@link org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener}.
- *
- */
-interface DOMDataCommitErrorListener extends EventListener {
-
- /**
- *
- * Callback which is invoked on transaction failure during three phase
- * commit in {@link DOMDataCommitExecutor}.
- *
- *
- * Implementation of this callback MUST NOT do any blocking calls or any
- * calls to MD-SAL, since this callback is invoked synchronously on MD-SAL
- * Broker coordination thread.
- *
- * @param tx
- * Transaction which failed
- * @param cause
- * Failure reason
- */
- void onCommitFailed(DOMDataWriteTransaction tx, Throwable cause);
-
-}
*/
package org.opendaylight.controller.md.sal.dom.broker.impl;
+import com.google.common.util.concurrent.CheckedFuture;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
/**
* Executor of Three Phase Commit coordination for
* Transaction to be used as context for reporting
* @param cohort
* DOM Store cohorts representing provided transaction, its
- * subtransactoins.
- * @param listener
- * Error listener which should be notified if transaction failed.
+ * subtransactions.
* @return a CheckedFuture. if commit coordination on cohorts finished successfully,
* nothing is returned from the Future, On failure,
* the Future fails with a {@link TransactionCommitFailedException}.
*
*/
CheckedFuture<Void,TransactionCommitFailedException> submit(DOMDataWriteTransaction tx,
- Iterable<DOMStoreThreePhaseCommitCohort> cohort, Optional<DOMDataCommitErrorListener> listener);
+ Iterable<DOMStoreThreePhaseCommitCohort> cohort);
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.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.1-SNAPSHOT</version>\r
+ <version>1.2.0-SNAPSHOT</version>\r
</parent>\r
<artifactId>sal-dom-xsql-config</artifactId>\r
<groupId>org.opendaylight.controller</groupId>\r
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-dom-xsql</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-inmemory-datastore</artifactId>
<parent>\r
<artifactId>sal-parent</artifactId>\r
<groupId>org.opendaylight.controller</groupId>\r
- <version>1.1-SNAPSHOT</version>\r
+ <version>1.2.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.1-SNAPSHOT</version>\r
+ <version>1.2.0-SNAPSHOT</version>\r
</dependency>\r
</dependencies>\r
\r
private String argument;
protected Object doExecute() throws Exception {
+ if(argument==null){
+ System.out.println("Nothing to do..., please specify a command.");
+ return null;
+ }
XSQLAdapter.getInstance().processCommand(new StringBuffer(argument),
System.out);
return null;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0">
+
+ <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+ <command>
+ <action class="org.opendaylight.controller.xsql.xsql">
+ </action>
+ </command>
+ </command-bundle>
+</blueprint>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-netconf-connector</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-remote</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-remoterpc-connector</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.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.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-rest-connector</artifactId>
<packaging>bundle</packaging>
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.rest.connector.rev140724.*,
</Private-Package>
<Import-Package>*,
- com.sun.jersey.spi.container.servlet</Import-Package>
+ com.sun.jersey.spi.container.servlet, org.eclipse.jetty.servlets</Import-Package>
<Web-ContextPath>/restconf</Web-ContextPath>
</instructions>
</configuration>
<url-pattern>/*</url-pattern>
</servlet-mapping>
+ <filter>
+ <filter-name>cross-origin-restconf</filter-name>
+ <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
+ <init-param>
+ <param-name>allowedOrigins</param-name>
+ <param-value>*</param-value>
+ </init-param>
+ <init-param>
+ <param-name>allowedMethods</param-name>
+ <param-value>GET,POST,OPTIONS,DELETE,PUT,HEAD</param-value>
+ </init-param>
+ <init-param>
+ <param-name>allowedHeaders</param-name>
+ <param-value>origin, content-type, accept, authorization</param-value>
+ </init-param>
+ </filter>
+ <filter-mapping>
+ <filter-name>cross-origin-restconf</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
<security-constraint>
<web-resource-collection>
<web-resource-name>NB api</web-resource-name>
description
"Added input parameters to rpc create-data-change-event-subscription";
- revision "2014-7-8" {
+ revision "2014-07-08" {
}
augment "/salrmt:create-data-change-event-subscription/salrmt:input" {
}
}
-}
\ No newline at end of file
+}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-rest-docgen</artifactId>
<instructions>
<Bundle-Name>MD SAL Rest Api Doc Generator</Bundle-Name>
<Import-Package>*,
- com.sun.jersey.spi.container.servlet</Import-Package>
+ com.sun.jersey.spi.container.servlet, org.eclipse.jetty.servlets</Import-Package>
<Bundle-Activator>org.opendaylight.controller.sal.rest.doc.DocProvider</Bundle-Activator>
<Web-ContextPath>/apidoc</Web-ContextPath>
</instructions>
resourcePath = getDataStorePath("/operational/", context);
addApis(node, apis, resourcePath, pathParams, schemaContext, false);
}
+ }
- Set<RpcDefinition> rpcs = m.getRpcs();
- for (RpcDefinition rpcDefinition : rpcs) {
- String resourcePath = getDataStorePath("/operations/", context);
- addRpcs(rpcDefinition, apis, resourcePath, schemaContext);
- }
+ Set<RpcDefinition> rpcs = m.getRpcs();
+ for (RpcDefinition rpcDefinition : rpcs) {
+ String resourcePath = getDataStorePath("/operations/", context);
+ addRpcs(rpcDefinition, apis, resourcePath, schemaContext);
}
_logger.debug("Number of APIs found [{}]", apis.size());
<url-pattern>/apis/*</url-pattern>
</servlet-mapping>
- <!--filter>
- <filter-name>CorsFilter</filter-name>
- <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
+ <filter>
+ <filter-name>cross-origin-api-doc</filter-name>
+ <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<init-param>
- <param-name>cors.allowed.origins</param-name>
+ <param-name>allowedOrigins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
- <param-name>cors.allowed.methods</param-name>
- <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
+ <param-name>allowedMethods</param-name>
+ <param-value>GET,POST,OPTIONS,DELETE,PUT,HEAD</param-value>
</init-param>
<init-param>
- <param-name>cors.allowed.headers</param-name>
- <param-value>Content-Type,X-Requested-With,accept,authorization,
- origin,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
- </init-param>
- <init-param>
- <param-name>cors.exposed.headers</param-name>
- <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
- </init-param>
- <init-param>
- <param-name>cors.support.credentials</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>cors.preflight.maxage</param-name>
- <param-value>10</param-value>
+ <param-name>allowedHeaders</param-name>
+ <param-value>origin, content-type, accept, authorization</param-value>
</init-param>
</filter>
<filter-mapping>
- <filter-name>CorsFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping-->
+ <filter-name>cross-origin-api-doc</filter-name>
+ <url-pattern>/apis/*</url-pattern>
+ </filter-mapping>
+
+
<security-constraint>
<web-resource-collection>
<web-resource-name>free access</web-resource-name>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sal-restconf-broker</artifactId>
<packaging>bundle</packaging>
<parent>
<artifactId>sal-parent</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>clustering-it</artifactId>
<groupId>org.opendaylight.controller.samples</groupId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.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.1-SNAPSHOT</version>
+ <version>1.2.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.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>clustering-it</artifactId>
<packaging>pom</packaging>
<parent>
<artifactId>clustering-it</artifactId>
<groupId>org.opendaylight.controller.samples</groupId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>clustering-it-provider</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.opendaylight.controller.samples.l2switch.md</groupId>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.opendaylight.controller.samples.l2switch.md</groupId>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>l2switch.aggregator</artifactId>
<groupId>org.opendaylight.controller.samples.l2switch</groupId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.samples</groupId>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.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.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sample-toaster-consumer</artifactId>
<packaging>bundle</packaging>
<properties>
- <sal-binding-api.version>1.1-SNAPSHOT</sal-binding-api.version>
+ <sal-binding-api.version>1.2.0-SNAPSHOT</sal-binding-api.version>
</properties>
<dependencies>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sample-toaster-it</artifactId>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sample-toaster-provider</artifactId>
<packaging>bundle</packaging>
<properties>
- <sal-binding-api.version>1.1-SNAPSHOT</sal-binding-api.version>
+ <sal-binding-api.version>1.2.0-SNAPSHOT</sal-binding-api.version>
</properties>
<dependencies>
<parent>
<groupId>org.opendaylight.controller.samples</groupId>
<artifactId>sal-samples</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>sample-toaster</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.md</groupId>
<artifactId>statistics-manager</artifactId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>org.eclipse.xtend.lib</artifactId>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<configuration>
<instructions>
<Bundle-Activator>org.opendaylight.controller.md.statistics.manager.StatisticsManagerActivator</Bundle-Activator>
- <Private-Package>org.opendaylight.controller.md.statistics.manager</Private-Package>
</instructions>
</configuration>
</plugin>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-abstract class AbstractListeningStatsTracker<I, K> extends AbstractStatsTracker<I, K> implements AutoCloseable, DataChangeListener {
- private static final Logger logger = LoggerFactory.getLogger(AbstractListeningStatsTracker.class);
- private ListenerRegistration<?> reg;
-
- protected AbstractListeningStatsTracker(FlowCapableContext context) {
- super(context);
- }
-
- protected abstract InstanceIdentifier<?> listenPath();
- protected abstract String statName();
-
- public void start(final DataBrokerService dbs) {
- Preconditions.checkState(reg == null);
-
- reg = dbs.registerDataChangeListener(listenPath(), this);
- logger.debug("{} Statistics tracker for node {} started", statName(), getNodeIdentifier());
- }
-
- @Override
- public final void close() {
- if (reg != null) {
- try {
- reg.close();
- } catch (Exception e) {
- logger.warn("Failed to stop {} Statistics tracker for node {}", statName(), getNodeIdentifier(), e);
- }
- reg = null;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.Future;
-
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.JdkFutureAdapters;
-
-abstract class AbstractStatsTracker<I, K> {
- private static final Logger logger = LoggerFactory.getLogger(AbstractStatsTracker.class);
-
- private static final int WAIT_FOR_REQUEST_CYCLE = 2;
-
- private final FutureCallback<RpcResult<? extends TransactionAware>> callback =
- new FutureCallback<RpcResult<? extends TransactionAware>>() {
- @Override
- public void onSuccess(RpcResult<? extends TransactionAware> result) {
- if (result.isSuccessful()) {
- final TransactionId id = result.getResult().getTransactionId();
- if (id == null) {
- final Throwable t = new UnsupportedOperationException("No protocol support");
- t.fillInStackTrace();
- onFailure(t);
- } else {
- context.registerTransaction(id);
- }
- } else {
- logger.debug("Statistics request failed: {}", result.getErrors());
-
- final Throwable t = new RPCFailedException("Failed to send statistics request", result.getErrors());
- t.fillInStackTrace();
- onFailure(t);
- }
- }
-
- @Override
- public void onFailure(Throwable t) {
- logger.debug("Failed to send statistics request", t);
- }
- };
-
- private final Map<K, Long> trackedItems = new HashMap<>();
- private final FlowCapableContext context;
- private long requestCounter;
-
- protected AbstractStatsTracker(final FlowCapableContext context) {
- this.context = Preconditions.checkNotNull(context);
- this.requestCounter = 0;
- }
-
- protected final InstanceIdentifierBuilder<Node> getNodeIdentifierBuilder() {
- return getNodeIdentifier().builder();
- }
-
- protected final NodeRef getNodeRef() {
- return context.getNodeRef();
- }
-
- protected final InstanceIdentifier<Node> getNodeIdentifier() {
- return context.getNodeIdentifier();
- }
-
- protected final <T extends TransactionAware> void requestHelper(Future<RpcResult<T>> future) {
- Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future), callback);
- }
-
- protected final DataModificationTransaction startTransaction() {
- return context.startDataModification();
- }
-
- public final synchronized void increaseRequestCounter(){
- this.requestCounter++;
- }
- protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
- protected abstract K updateSingleStat(DataModificationTransaction trans, I item);
- protected abstract K createInvariantKey(K item);
- public abstract void request();
-
- public final synchronized void updateStats(List<I> list) {
-
- final DataModificationTransaction trans = startTransaction();
- for (final I item : list) {
- K key = updateSingleStat(trans, item);
- trackedItems.put(createInvariantKey(key), requestCounter);
- }
-
- trans.commit();
- }
-
- /**
- * Statistics will be cleaned up if not update in last two request cycles.
- * @param trans
- */
- public final synchronized void cleanup(final DataModificationTransaction trans) {
- for (Iterator<Entry<K, Long>> it = trackedItems.entrySet().iterator();it.hasNext();){
- Entry<K, Long> e = it.next();
- if (requestCounter >= e.getValue()+WAIT_FOR_REQUEST_CYCLE) {
- cleanupSingleStat(trans, e.getKey());
- it.remove();
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Interface exposed to AbstractStatsTracker by its parent NodeStatisticsHandler.
- * While we could simply exist without this interface, its purpose is to document
- * the contract between the two classes.
- */
-interface FlowCapableContext {
- InstanceIdentifier<Node> getNodeIdentifier();
- NodeRef getNodeRef();
- DataModificationTransaction startDataModification();
- void registerTransaction(TransactionId id);
- void registerTableTransaction(TransactionId id, Short tableId);
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.Collection;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Sets;
-
-/**
- * There is a single instance of this class and that instance is responsible for
- * monitoring the operational data store for nodes being created/deleted and
- * notifying StatisticsProvider. These events then control the lifecycle of
- * NodeStatisticsHandler for a particular switch.
- */
-final class FlowCapableTracker implements DataChangeListener {
- private static final Logger logger = LoggerFactory.getLogger(FlowCapableTracker.class);
-
- private final InstanceIdentifier<FlowCapableNode> root;
- private final StatisticsProvider stats;
-
- private final Predicate<InstanceIdentifier<?>> filterIdentifiers = new Predicate<InstanceIdentifier<?>>() {
- @Override
- public boolean apply(final InstanceIdentifier<?> input) {
- /*
- * This notification has been triggered either by the ancestor,
- * descendant or directly for the FlowCapableNode itself. We
- * are not interested descendants, so let's prune them based
- * on the depth of their identifier.
- */
- if (root.getPath().size() < input.getPath().size()) {
- logger.debug("Ignoring notification for descendant {}", input);
- return false;
- }
-
- logger.debug("Including notification for {}", input);
- return true;
- }
- };
-
- public FlowCapableTracker(final StatisticsProvider stats, InstanceIdentifier<FlowCapableNode> root) {
- this.stats = Preconditions.checkNotNull(stats);
- this.root = Preconditions.checkNotNull(root);
- }
-
- /*
- * This method is synchronized because we want to make sure to serialize input
- * from the datastore. Competing add/remove could be problematic otherwise.
- */
- @Override
- public synchronized void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- logger.debug("Tracker at root {} processing notification", root);
-
- /*
- * First process all the identifiers which were removed, trying to figure out
- * whether they constitute removal of FlowCapableNode.
- */
- final Collection<NodeKey> removedNodes =
- Collections2.filter(Collections2.transform(
- Sets.filter(change.getRemovedOperationalData(), filterIdentifiers),
- new Function<InstanceIdentifier<?>, NodeKey>() {
- @Override
- public NodeKey apply(final InstanceIdentifier<?> input) {
- final NodeKey key = input.firstKeyOf(Node.class, NodeKey.class);
- if (key == null) {
- // FIXME: do we have a backup plan?
- logger.info("Failed to extract node key from {}", input);
- }
- return key;
- }
- }), Predicates.notNull());
- stats.stopNodeHandlers(removedNodes);
-
- final Collection<NodeKey> addedNodes =
- Collections2.filter(Collections2.transform(
- Sets.filter(change.getCreatedOperationalData().keySet(), filterIdentifiers),
- new Function<InstanceIdentifier<?>, NodeKey>() {
- @Override
- public NodeKey apply(final InstanceIdentifier<?> input) {
- final NodeKey key = input.firstKeyOf(Node.class, NodeKey.class);
- if (key == null) {
- // FIXME: do we have a backup plan?
- logger.info("Failed to extract node key from {}", input);
- }
- return key;
- }
- }), Predicates.notNull());
- stats.startNodeHandlers(addedNodes);
-
- logger.debug("Tracker at root {} finished processing notification", root);
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-
-final class FlowStatsEntry {
- private final Short tableId;
- private final Flow flow;
-
- public FlowStatsEntry(Short tableId, Flow flow){
- this.tableId = tableId;
- this.flow = flow;
- }
-
- public Short getTableId() {
- return tableId;
- }
-
- public Flow getFlow() {
- return flow;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((flow == null) ? 0 : flow.hashCode());
- result = prime * result + ((tableId == null) ? 0 : tableId.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- FlowStatsEntry other = (FlowStatsEntry) obj;
- if (flow == null) {
- if (other.flow != null)
- return false;
- } else if (!flow.equals(other.flow))
- return false;
- if (tableId == null) {
- if (other.tableId != null)
- return false;
- } else if (!tableId.equals(other.tableId))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "FlowStatsEntry [tableId=" + tableId + ", flow=" + flow + "]";
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.math.BigInteger;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map.Entry;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCookieMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.nodes.node.table.FlowCookieMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.nodes.node.table.FlowCookieMapBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.nodes.node.table.FlowCookieMapKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-
-final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatisticsMapList, FlowStatsEntry> {
- private static final Logger LOG = LoggerFactory.getLogger(FlowStatsTracker.class);
- private static final String ALIEN_SYSTEM_FLOW_ID = "#UF$TABLE*";
- private final OpendaylightFlowStatisticsService flowStatsService;
- private FlowTableStatsTracker flowTableStats;
- private int unaccountedFlowsCounter = 1;
-
-
- FlowStatsTracker(final OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context) {
- super(context);
- this.flowStatsService = flowStatsService;
- }
- FlowStatsTracker(final OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, final FlowTableStatsTracker flowTableStats) {
- this(flowStatsService, context);
- this.flowTableStats = flowTableStats;
- }
-
- @Override
- protected void cleanupSingleStat(final DataModificationTransaction trans, final FlowStatsEntry item) {
- KeyedInstanceIdentifier<Flow, FlowKey> flowRef = getNodeIdentifier()
- .augmentation(FlowCapableNode.class)
- .child(Table.class, new TableKey(item.getTableId()))
- .child(Flow.class, item.getFlow().getKey());
- trans.removeOperationalData(flowRef);
- }
-
- @Override
- protected FlowStatsEntry updateSingleStat(final DataModificationTransaction trans, final FlowAndStatisticsMapList map) {
- short tableId = map.getTableId();
-
- FlowStatisticsDataBuilder flowStatisticsData = new FlowStatisticsDataBuilder();
-
- FlowBuilder flowBuilder = new FlowBuilder(map);
- if (map.getFlowId() != null) {
- flowBuilder.setId(new FlowId(map.getFlowId().getValue()));
- }
- if (map.getFlowId() != null) {
- flowBuilder.setKey(new FlowKey(new FlowId(map.getKey().getFlowId().getValue())));
- }
-
- Flow flowRule = flowBuilder.build();
-
- FlowAndStatisticsMapListBuilder stats = new FlowAndStatisticsMapListBuilder();
- stats.setByteCount(map.getByteCount());
- stats.setPacketCount(map.getPacketCount());
- stats.setDuration(map.getDuration());
-
- GenericStatistics flowStats = stats.build();
-
- //Augment the data to the flow node
-
- FlowStatisticsBuilder flowStatistics = new FlowStatisticsBuilder();
- flowStatistics.setByteCount(flowStats.getByteCount());
- flowStatistics.setPacketCount(flowStats.getPacketCount());
- flowStatistics.setDuration(flowStats.getDuration());
-
- flowStatisticsData.setFlowStatistics(flowStatistics.build());
-
- LOG.debug("Flow : {}",flowRule.toString());
- LOG.debug("Statistics to augment : {}",flowStatistics.build().toString());
-
- InstanceIdentifier<Table> tableRef = getNodeIdentifierBuilder()
- .augmentation(FlowCapableNode.class)
- .child(Table.class, new TableKey(tableId)).toInstance();
-
- final FlowCookie flowCookie = flowRule.getCookie() != null
- ? flowRule.getCookie() : new FlowCookie(BigInteger.ZERO);
- final InstanceIdentifier<FlowCookieMap> flowCookieRef = tableRef
- .augmentation(FlowCookieMapping.class)
- .child(FlowCookieMap.class, new FlowCookieMapKey(flowCookie));
-
- FlowCookieMap cookieMap = (FlowCookieMap) trans.readOperationalData(flowCookieRef);
-
- /* find flowKey in FlowCookieMap from DataStore/OPERATIONAL */
- Optional<FlowKey> flowKey = this.getExistFlowKey(flowRule, tableRef, trans, cookieMap);
- if ( ! flowKey.isPresent()) {
- /* DataStore/CONFIG For every first statistic needs to be created */
- flowKey = this.getFlowKeyFromExistFlow(flowRule, tableRef, trans);
- if ( ! flowKey.isPresent()) {
- /* Alien flow */
- flowKey = this.makeAlienFlowKey(flowRule);
- }
- cookieMap = applyNewFlowKey(cookieMap, flowKey, flowCookie);
- trans.putOperationalData(flowCookieRef, cookieMap);
- }
-
- InstanceIdentifier<Flow> flowRef = getNodeIdentifierBuilder()
- .augmentation(FlowCapableNode.class)
- .child(Table.class, new TableKey(tableId))
- .child(Flow.class, flowKey.get()).toInstance();
- flowBuilder.setKey(flowKey.get());
- flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
-
- // Update entry with timestamp of latest response
- flowBuilder.setKey(flowKey.get());
- FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId, flowBuilder.build());
- trans.putOperationalData(flowRef, flowBuilder.build());
- return flowStatsEntry;
- }
-
- @Override
- protected InstanceIdentifier<?> listenPath() {
- return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class).build();
- }
-
- @Override
- protected String statName() {
- return "Flow";
- }
-
- @Override
- public void request() {
- // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest()
- // comes back -- we do not have any tables anyway.
- final Collection<TableKey> tables = flowTableStats.getTables();
- LOG.debug("Node {} supports {} table(s)", this.getNodeRef(), tables.size());
- for (final TableKey key : tables) {
- LOG.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), this.getNodeRef());
- this.requestAggregateFlows(key);
- }
-
- this.requestAllFlowsAllTables();
-
- }
- public void requestAllFlowsAllTables() {
- if (flowStatsService != null) {
- final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
- input.setNode(getNodeRef());
-
- requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()));
- }
- }
-
- public void requestAggregateFlows(final TableKey key) {
- if (flowStatsService != null) {
- GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
- new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
-
- input.setNode(getNodeRef());
- input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(key.getId()));
- requestHelper(flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build()));
- }
- }
-
- public void requestFlow(final Flow flow) {
- if (flowStatsService != null) {
- final GetFlowStatisticsFromFlowTableInputBuilder input =
- new GetFlowStatisticsFromFlowTableInputBuilder(flow);
- input.setNode(getNodeRef());
-
- requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build()));
- }
- }
-
- @Override
- public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- for (Entry<InstanceIdentifier<?>, DataObject> e : change.getCreatedConfigurationData().entrySet()) {
- if (Flow.class.equals(e.getKey().getTargetType())) {
- final Flow flow = (Flow) e.getValue();
- LOG.debug("Key {} triggered request for flow {}", e.getKey(), flow);
- requestFlow(flow);
- } else {
- LOG.debug("Ignoring key {}", e.getKey());
- }
- }
-
- final DataModificationTransaction trans = startTransaction();
- for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
- if (Flow.class.equals(key.getTargetType())) {
- @SuppressWarnings("unchecked")
- final InstanceIdentifier<Flow> flow = (InstanceIdentifier<Flow>)key;
- LOG.debug("Key {} triggered remove of Flow from operational space.", key);
- trans.removeOperationalData(flow);
- }
- }
- trans.commit();
- }
-
- @Override
- public void start(final DataBrokerService dbs) {
- if (flowStatsService == null) {
- LOG.debug("No Flow Statistics service, not subscribing to flows on node {}", getNodeIdentifier());
- return;
- }
-
- super.start(dbs);
- }
-
- /* Returns Exist FlowKey from exist FlowCookieMap identified by cookie
- * and by switch flow identification (priority and match)*/
- private Optional<FlowKey> getExistFlowKey(final Flow flowRule, final InstanceIdentifier<Table> tableRef,
- final DataModificationTransaction trans, final FlowCookieMap cookieMap) {
-
- if (cookieMap != null) {
- for (FlowId flowId : cookieMap.getFlowIds()) {
- InstanceIdentifier<Flow> flowIdent = tableRef.child(Flow.class, new FlowKey(flowId));
- if (flowId.getValue().startsWith(ALIEN_SYSTEM_FLOW_ID)) {
- LOG.debug("Search for flow in the operational datastore by flowID: {} ", flowIdent);
- Flow readedFlow = (Flow) trans.readOperationalData(flowIdent);
- if (FlowComparator.flowEquals(flowRule, readedFlow)) {
- return Optional.<FlowKey> of(new FlowKey(flowId));
- }
- } else {
- LOG.debug("Search for flow in the configuration datastore by flowID: {} ", flowIdent);
- Flow readedFlow = (Flow) trans.readConfigurationData(flowIdent);
- if (FlowComparator.flowEquals(flowRule, readedFlow)) {
- return Optional.<FlowKey> of(new FlowKey(flowId));
- }
- }
- }
- LOG.debug("Flow was not found in the datastore. Flow {} ", flowRule);
- }
- return Optional.absent();
- }
-
- /* Returns FlowKey from existing Flow in DataStore/CONFIGURATIONAL which is identified by cookie
- * and by switch flow identification (priority and match) */
- private Optional<FlowKey> getFlowKeyFromExistFlow(final Flow flowRule, final InstanceIdentifier<Table> tableRef,
- final DataModificationTransaction trans) {
-
- /* Try to find it in DataSotre/CONFIG */
- Table table= (Table)trans.readConfigurationData(tableRef);
- if(table != null) {
- for(Flow existingFlow : table.getFlow()) {
- LOG.debug("Existing flow in data store : {}",existingFlow.toString());
- if(FlowComparator.flowEquals(flowRule,existingFlow)){
- return Optional.<FlowKey> of(new FlowKey(existingFlow.getId()));
- }
- }
- }
- return Optional.absent();
- }
-
- /* Returns FlowKey which doesn't exist in any DataStore for now */
- private Optional<FlowKey> makeAlienFlowKey(final Flow flowRule) {
-
- StringBuilder sBuilder = new StringBuilder(ALIEN_SYSTEM_FLOW_ID)
- .append(flowRule.getTableId()).append("-").append(this.unaccountedFlowsCounter);
- this.unaccountedFlowsCounter++;
- final FlowId flowId = new FlowId(sBuilder.toString());
- return Optional.<FlowKey> of(new FlowKey(flowId));
- }
-
- /* Build new whole FlowCookieMap or add new flowKey */
- private FlowCookieMap applyNewFlowKey(FlowCookieMap flowCookieMap, final Optional<FlowKey> flowKey,
- final FlowCookie flowCookie) {
- if (flowCookieMap != null) {
- flowCookieMap.getFlowIds().add(flowKey.get().getId());
- } else {
- final FlowCookieMapBuilder flowCookieMapBuilder = new FlowCookieMapBuilder();
- flowCookieMapBuilder.setCookie(flowCookie);
- flowCookieMapBuilder.setFlowIds(Collections.singletonList(flowKey.get().getId()));
- flowCookieMap = flowCookieMapBuilder.build();
- }
- return flowCookieMap;
- }
-
- @Override
- protected FlowStatsEntry createInvariantKey(final FlowStatsEntry item) {
- FlowBuilder newFlow = new FlowBuilder();
- newFlow.setId(item.getFlow().getId());
- newFlow.setKey(item.getFlow().getKey());
- newFlow.fieldsFrom(item.getFlow());
- return new FlowStatsEntry(item.getTableId(),newFlow.build());
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListSet;
-
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-final class FlowTableStatsTracker extends AbstractStatsTracker<FlowTableAndStatisticsMap, FlowTableAndStatisticsMap> {
- private final Set<TableKey> privateTables = new ConcurrentSkipListSet<>();
- private final Set<TableKey> tables = Collections.unmodifiableSet(privateTables);
- private final OpendaylightFlowTableStatisticsService flowTableStatsService;
-
- FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context) {
- super(context);
- this.flowTableStatsService = flowTableStatsService;
- }
-
- Set<TableKey> getTables() {
- return tables;
- }
-
- @Override
- protected void cleanupSingleStat(DataModificationTransaction trans, FlowTableAndStatisticsMap item) {
- // TODO: do we want to do this?
- }
-
- @Override
- protected FlowTableAndStatisticsMap updateSingleStat(DataModificationTransaction trans, FlowTableAndStatisticsMap item) {
-
- InstanceIdentifier<Table> tableRef = getNodeIdentifierBuilder()
- .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(item.getTableId().getValue())).build();
-
- FlowTableStatisticsDataBuilder statisticsDataBuilder = new FlowTableStatisticsDataBuilder();
- final FlowTableStatistics stats = new FlowTableStatisticsBuilder(item).build();
- statisticsDataBuilder.setFlowTableStatistics(stats);
-
- TableBuilder tableBuilder = new TableBuilder();
- tableBuilder.setKey(new TableKey(item.getTableId().getValue()));
- tableBuilder.addAugmentation(FlowTableStatisticsData.class, statisticsDataBuilder.build());
- trans.putOperationalData(tableRef, tableBuilder.build());
- return item;
- }
-
- @Override
- public void request() {
- if (flowTableStatsService != null) {
- final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
- input.setNode(getNodeRef());
-
- requestHelper(flowTableStatsService.getFlowTablesStatistics(input.build()));
- }
- }
-
- @Override
- protected FlowTableAndStatisticsMap createInvariantKey(FlowTableAndStatisticsMap item) {
- FlowTableAndStatisticsMapBuilder flowTableAndStatisticsMapBuilder = new FlowTableAndStatisticsMapBuilder();
- flowTableAndStatisticsMapBuilder.setTableId(item.getTableId());
- flowTableAndStatisticsMapBuilder.setKey(item.getKey());
- return flowTableAndStatisticsMapBuilder.build();
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.desc.GroupDescBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class GroupDescStatsTracker extends AbstractListeningStatsTracker<GroupDescStats, GroupDescStats> {
- private static final Logger logger = LoggerFactory.getLogger(GroupDescStatsTracker.class);
- private final OpendaylightGroupStatisticsService groupStatsService;
-
- public GroupDescStatsTracker(OpendaylightGroupStatisticsService groupStatsService, final FlowCapableContext context) {
- super(context);
- this.groupStatsService = groupStatsService;
- }
-
- @Override
- protected GroupDescStats updateSingleStat(DataModificationTransaction trans, GroupDescStats item) {
- GroupBuilder groupBuilder = new GroupBuilder();
- GroupKey groupKey = new GroupKey(item.getGroupId());
- groupBuilder.setKey(groupKey);
-
- InstanceIdentifier<Group> groupRef = getNodeIdentifierBuilder()
- .augmentation(FlowCapableNode.class).child(Group.class,groupKey).build();
-
- NodeGroupDescStatsBuilder groupDesc= new NodeGroupDescStatsBuilder();
- groupDesc.setGroupDesc(new GroupDescBuilder(item).build());
-
- //Update augmented data
- groupBuilder.addAugmentation(NodeGroupDescStats.class, groupDesc.build());
-
- trans.putOperationalData(groupRef, groupBuilder.build());
- return item;
- }
-
- @Override
- protected void cleanupSingleStat(DataModificationTransaction trans, GroupDescStats item) {
- InstanceIdentifier<NodeGroupDescStats> groupRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class)
- .child(Group.class, new GroupKey(item.getGroupId())).augmentation(NodeGroupDescStats.class).build();
- trans.removeOperationalData(groupRef);
- }
-
- @Override
- protected InstanceIdentifier<?> listenPath() {
- return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Group.class).build();
- }
-
- @Override
- protected String statName() {
- return "Group Descriptor";
- }
-
- @Override
- public void request() {
- if (groupStatsService != null) {
- final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
- input.setNode(getNodeRef());
-
- requestHelper(groupStatsService.getGroupDescription(input.build()));
- }
- }
-
- @Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- for (InstanceIdentifier<?> key : change.getCreatedConfigurationData().keySet()) {
- if (Group.class.equals(key.getTargetType())) {
- logger.debug("Key {} triggered request", key);
- request();
- } else {
- logger.debug("Ignoring key {}", key);
- }
- }
-
- final DataModificationTransaction trans = startTransaction();
- for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
- if (Group.class.equals(key.getTargetType())) {
- @SuppressWarnings("unchecked")
- InstanceIdentifier<Group> group = (InstanceIdentifier<Group>)key;
- InstanceIdentifier<?> del = group.augmentation(NodeGroupDescStats.class);
- logger.debug("Key {} triggered remove of augmentation {}", key, del);
-
- trans.removeOperationalData(del);
- }
- }
- trans.commit();
- }
-
- @Override
- public void start(final DataBrokerService dbs) {
- if (groupStatsService == null) {
- logger.debug("No Group Statistics service, not subscribing to groups on node {}", getNodeIdentifier());
- return;
- }
-
- super.start(dbs);
- }
-
- @Override
- protected GroupDescStats createInvariantKey(GroupDescStats item) {
- // No invariant data exist in the group description stats.
- return item;
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-final class GroupStatsTracker extends AbstractListeningStatsTracker<GroupStats, GroupStats> {
- private static final Logger logger = LoggerFactory.getLogger(GroupStatsTracker.class);
- private final OpendaylightGroupStatisticsService groupStatsService;
-
- GroupStatsTracker(OpendaylightGroupStatisticsService groupStatsService, FlowCapableContext context) {
- super(context);
- this.groupStatsService = Preconditions.checkNotNull(groupStatsService);
- }
-
- @Override
- protected void cleanupSingleStat(DataModificationTransaction trans, GroupStats item) {
- InstanceIdentifier<NodeGroupStatistics> groupRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class)
- .child(Group.class, new GroupKey(item.getGroupId())).augmentation(NodeGroupStatistics.class).build();
- trans.removeOperationalData(groupRef);
- }
-
- @Override
- protected GroupStats updateSingleStat(DataModificationTransaction trans,
- GroupStats item) {
- GroupBuilder groupBuilder = new GroupBuilder();
- GroupKey groupKey = new GroupKey(item.getGroupId());
- groupBuilder.setKey(groupKey);
-
- InstanceIdentifier<Group> groupRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class)
- .child(Group.class,groupKey).build();
-
- NodeGroupStatisticsBuilder groupStatisticsBuilder= new NodeGroupStatisticsBuilder();
- groupStatisticsBuilder.setGroupStatistics(new GroupStatisticsBuilder(item).build());
-
- //Update augmented data
- groupBuilder.addAugmentation(NodeGroupStatistics.class, groupStatisticsBuilder.build());
- trans.putOperationalData(groupRef, groupBuilder.build());
- return item;
- }
-
- @Override
- protected InstanceIdentifier<?> listenPath() {
- return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Group.class).build();
- }
-
- @Override
- protected String statName() {
- return "Group";
- }
-
- @Override
- public void request() {
- final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
- input.setNode(getNodeRef());
-
- requestHelper(groupStatsService.getAllGroupStatistics(input.build()));
- }
-
- @Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- final DataModificationTransaction trans = startTransaction();
- for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
- if (Group.class.equals(key.getTargetType())) {
- @SuppressWarnings("unchecked")
- InstanceIdentifier<Group> group = (InstanceIdentifier<Group>)key;
- InstanceIdentifier<?> del = group.augmentation(NodeGroupStatistics.class);
- logger.debug("Key {} triggered remove of augmentation {}", key, del);
-
- trans.removeOperationalData(del);
- }
- }
- trans.commit();
- }
-
- @Override
- public void start(final DataBrokerService dbs) {
- if (groupStatsService == null) {
- logger.debug("No Group Statistics service, not subscribing to groups on node {}", getNodeIdentifier());
- return;
- }
-
- super.start(dbs);
- }
-
- @Override
- protected GroupStats createInvariantKey(GroupStats item) {
- GroupStatsBuilder groupStatsBuilder = new GroupStatsBuilder();
- groupStatsBuilder.setKey(item.getKey());
- groupStatsBuilder.setGroupId(item.getGroupId());
- return groupStatsBuilder.build();
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterConfigStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class MeterConfigStatsTracker extends AbstractListeningStatsTracker<MeterConfigStats, MeterConfigStats> {
- private static final Logger logger = LoggerFactory.getLogger(MeterConfigStatsTracker.class);
- private final OpendaylightMeterStatisticsService meterStatsService;
-
- protected MeterConfigStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context) {
- super(context);
- this.meterStatsService = meterStatsService;
- }
-
- @Override
- protected void cleanupSingleStat(DataModificationTransaction trans, MeterConfigStats item) {
- InstanceIdentifier<NodeMeterConfigStats> meterRef = getNodeIdentifierBuilder()
- .augmentation(FlowCapableNode.class)
- .child(Meter.class, new MeterKey(item.getMeterId()))
- .augmentation(NodeMeterConfigStats.class).build();
- trans.removeOperationalData(meterRef);
- }
-
- @Override
- protected MeterConfigStats updateSingleStat(DataModificationTransaction trans, MeterConfigStats item) {
- MeterBuilder meterBuilder = new MeterBuilder();
- MeterKey meterKey = new MeterKey(item.getMeterId());
- meterBuilder.setKey(meterKey);
-
- InstanceIdentifier<Meter> meterRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class)
- .child(Meter.class,meterKey).toInstance();
-
- NodeMeterConfigStatsBuilder meterConfig = new NodeMeterConfigStatsBuilder();
- meterConfig.setMeterConfigStats(new MeterConfigStatsBuilder(item).build());
-
- //Update augmented data
- meterBuilder.addAugmentation(NodeMeterConfigStats.class, meterConfig.build());
-
- trans.putOperationalData(meterRef, meterBuilder.build());
- return item;
- }
-
- @Override
- public void request() {
- if (meterStatsService != null) {
- GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
- input.setNode(getNodeRef());
-
- requestHelper(meterStatsService.getAllMeterConfigStatistics(input.build()));
- }
- }
-
- @Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- final DataModificationTransaction trans = startTransaction();
-
- for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
- if (Meter.class.equals(key.getTargetType())) {
- @SuppressWarnings("unchecked")
- InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>)key;
-
- InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
- meter.augmentation(NodeMeterConfigStats.class);
- trans.removeOperationalData(nodeMeterStatisticsAugmentation);
- }
- }
-
- trans.commit();
- }
-
- @Override
- protected InstanceIdentifier<?> listenPath() {
- return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Meter.class).build();
- }
-
- @Override
- protected String statName() {
- return "Meter Config";
- }
-
- @Override
- public void start(final DataBrokerService dbs) {
- if (meterStatsService == null) {
- logger.debug("No Meter Statistics service, not subscribing to meter on node {}", getNodeIdentifier());
- return;
- }
-
- super.start(dbs);
- }
-
- @Override
- protected MeterConfigStats createInvariantKey(MeterConfigStats item) {
- // No invariant data exist in the meter config stats.
- return item;
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStatsBuilder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class MeterStatsTracker extends AbstractListeningStatsTracker<MeterStats, MeterStats> {
- private static final Logger logger = LoggerFactory.getLogger(MeterStatsTracker.class);
- private final OpendaylightMeterStatisticsService meterStatsService;
-
- MeterStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context) {
- super(context);
- this.meterStatsService = meterStatsService;
- }
-
- @Override
- protected void cleanupSingleStat(DataModificationTransaction trans, MeterStats item) {
- InstanceIdentifier<NodeMeterStatistics> meterRef = getNodeIdentifierBuilder()
- .augmentation(FlowCapableNode.class)
- .child(Meter.class,new MeterKey(item.getMeterId()))
- .augmentation(NodeMeterStatistics.class).build();
- trans.removeOperationalData(meterRef);
- }
-
- @Override
- protected MeterStats updateSingleStat(DataModificationTransaction trans, MeterStats item) {
- MeterBuilder meterBuilder = new MeterBuilder();
- MeterKey meterKey = new MeterKey(item.getMeterId());
- meterBuilder.setKey(meterKey);
-
- InstanceIdentifier<Meter> meterRef = getNodeIdentifierBuilder()
- .augmentation(FlowCapableNode.class).child(Meter.class,meterKey).build();
-
- NodeMeterStatisticsBuilder meterStatsBuilder= new NodeMeterStatisticsBuilder();
- meterStatsBuilder.setMeterStatistics(new MeterStatisticsBuilder(item).build());
-
- //Update augmented data
- meterBuilder.addAugmentation(NodeMeterStatistics.class, meterStatsBuilder.build());
- trans.putOperationalData(meterRef, meterBuilder.build());
- return item;
- }
-
- @Override
- public void request() {
- if (meterStatsService != null) {
- GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
- input.setNode(getNodeRef());
-
- requestHelper(meterStatsService.getAllMeterStatistics(input.build()));
- }
- }
-
- @Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- for (InstanceIdentifier<?> key : change.getCreatedConfigurationData().keySet()) {
- if (Meter.class.equals(key.getTargetType())) {
- request();
- }
- }
-
- final DataModificationTransaction trans = startTransaction();
- for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
- if (Meter.class.equals(key.getTargetType())) {
- @SuppressWarnings("unchecked")
- InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>)key;
-
- InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
- meter.augmentation(NodeMeterStatistics.class);
- trans.removeOperationalData(nodeMeterStatisticsAugmentation);
- }
- }
- trans.commit();
- }
-
- @Override
- protected InstanceIdentifier<?> listenPath() {
- return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Meter.class).build();
- }
-
- @Override
- protected String statName() {
- return "Meter";
- }
-
- @Override
- public void start(final DataBrokerService dbs) {
- if (meterStatsService == null) {
- logger.debug("No Meter Statistics service, not subscribing to meters on node {}", getNodeIdentifier());
- return;
- }
-
- super.start(dbs);
- }
-
- @Override
- protected MeterStats createInvariantKey(MeterStats item) {
- MeterStatsBuilder meterStatsBuilder = new MeterStatsBuilder();
- meterStatsBuilder.setKey(item.getKey());
- meterStatsBuilder.setMeterId(item.getMeterId());
- return meterStatsBuilder.build();
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.MultipartTransactionAware;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Main responsibility of the class is to manage multipart response
- * for multipart request. It also handles the flow aggregate request
- * and response mapping.
- * @author avishnoi@in.ibm.com
- *
- */
-class MultipartMessageManager {
- /*
- * Map for tx id and type of request, to keep track of all the request sent
- * by Statistics Manager. Statistics Manager won't entertain any multipart
- * response for which it didn't send the request.
- */
- private final Map<TxIdEntry,Long> txIdToRequestTypeMap = new ConcurrentHashMap<>();
- /*
- * Map to keep track of the request tx id for flow table statistics request.
- * Because flow table statistics multi part response do not contains the table id.
- */
- private final Map<TxIdEntry,Short> txIdTotableIdMap = new ConcurrentHashMap<>();
- private final long lifetimeNanos;
-
- public MultipartMessageManager(long lifetimeNanos) {
- this.lifetimeNanos = lifetimeNanos;
- }
-
- private static final class TxIdEntry {
- private final TransactionId txId;
-
- public TxIdEntry(TransactionId txId) {
- this.txId = txId;
- }
- public TransactionId getTxId() {
- return txId;
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((txId == null) ? 0 : txId.hashCode());
- return result;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof TxIdEntry)) {
- return false;
- }
- TxIdEntry other = (TxIdEntry) obj;
-
- if (txId == null) {
- if (other.txId != null) {
- return false;
- }
- } else if (!txId.equals(other.txId)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "TxIdEntry [txId=" + txId + ']';
- }
- }
-
- public void recordExpectedTableTransaction(TransactionId id, Short tableId) {
- recordExpectedTransaction(id);
- txIdTotableIdMap.put(new TxIdEntry(id), Preconditions.checkNotNull(tableId));
- }
-
- public Short isExpectedTableTransaction(TransactionAware transaction) {
- Boolean more = null;
- if (transaction instanceof MultipartTransactionAware) {
- more = ((MultipartTransactionAware)transaction).isMoreReplies();
- }
-
- if (!isExpectedTransaction(transaction, more)) {
- return null;
- }
-
- final TxIdEntry key = new TxIdEntry(transaction.getTransactionId());
- if (more != null && more.booleanValue()) {
- return txIdTotableIdMap.get(key);
- } else {
- return txIdTotableIdMap.remove(key);
- }
- }
-
- public void recordExpectedTransaction(TransactionId id) {
- TxIdEntry entry = new TxIdEntry(Preconditions.checkNotNull(id));
- txIdToRequestTypeMap.put(entry, getExpiryTime());
- }
-
- private boolean isExpectedTransaction(TransactionAware transaction, Boolean more) {
- final TxIdEntry entry = new TxIdEntry(transaction.getTransactionId());
- if (more != null && more.booleanValue()) {
- return txIdToRequestTypeMap.containsKey(entry);
- } else {
- return txIdToRequestTypeMap.remove(entry) != null;
- }
- }
-
- public boolean isExpectedTransaction(TransactionAware transaction) {
- Boolean more = null;
- if (transaction instanceof MultipartTransactionAware) {
- more = ((MultipartTransactionAware)transaction).isMoreReplies();
- }
-
- return isExpectedTransaction(transaction, more);
- }
-
- private Long getExpiryTime() {
- return System.nanoTime() + lifetimeNanos;
- }
-
- public void cleanStaleTransactionIds() {
- final long now = System.nanoTime();
-
- for (Iterator<TxIdEntry> it = txIdToRequestTypeMap.keySet().iterator();it.hasNext();){
- TxIdEntry txIdEntry = it.next();
-
- Long expiryTime = txIdToRequestTypeMap.get(txIdEntry);
- if(now > expiryTime){
- it.remove();
- txIdTotableIdMap.remove(txIdEntry);
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class NodeConnectorStatsTracker extends AbstractStatsTracker<NodeConnectorStatisticsAndPortNumberMap, NodeConnectorStatisticsAndPortNumberMap> {
- private static final Logger logger = LoggerFactory.getLogger(NodeConnectorStatsTracker.class);
- private final OpendaylightPortStatisticsService portStatsService;
-
- NodeConnectorStatsTracker(final OpendaylightPortStatisticsService portStatsService, final FlowCapableContext context) {
- super(context);
- this.portStatsService = portStatsService;
- }
-
- @Override
- protected void cleanupSingleStat(final DataModificationTransaction trans, final NodeConnectorStatisticsAndPortNumberMap item) {
- // TODO Auto-generated method stub
- }
-
- @Override
- protected NodeConnectorStatisticsAndPortNumberMap updateSingleStat(final DataModificationTransaction trans, final NodeConnectorStatisticsAndPortNumberMap item) {
- FlowCapableNodeConnectorStatisticsBuilder statisticsBuilder
- = new FlowCapableNodeConnectorStatisticsBuilder();
- statisticsBuilder.setBytes(item.getBytes());
- statisticsBuilder.setCollisionCount(item.getCollisionCount());
- statisticsBuilder.setDuration(item.getDuration());
- statisticsBuilder.setPackets(item.getPackets());
- statisticsBuilder.setReceiveCrcError(item.getReceiveCrcError());
- statisticsBuilder.setReceiveDrops(item.getReceiveDrops());
- statisticsBuilder.setReceiveErrors(item.getReceiveErrors());
- statisticsBuilder.setReceiveFrameError(item.getReceiveFrameError());
- statisticsBuilder.setReceiveOverRunError(item.getReceiveOverRunError());
- statisticsBuilder.setTransmitDrops(item.getTransmitDrops());
- statisticsBuilder.setTransmitErrors(item.getTransmitErrors());
-
- //Augment data to the node-connector
- FlowCapableNodeConnectorStatisticsDataBuilder statisticsDataBuilder =
- new FlowCapableNodeConnectorStatisticsDataBuilder();
-
- statisticsDataBuilder.setFlowCapableNodeConnectorStatistics(statisticsBuilder.build());
-
- final NodeConnectorKey key = new NodeConnectorKey(item.getNodeConnectorId());
- final InstanceIdentifier<NodeConnector> nodeConnectorRef = getNodeIdentifier().child(NodeConnector.class, key);
-
- // FIXME: can we bypass this read?
- NodeConnector nodeConnector = (NodeConnector)trans.readOperationalData(nodeConnectorRef);
- if(nodeConnector != null){
- final FlowCapableNodeConnectorStatisticsData stats = statisticsDataBuilder.build();
- logger.debug("Augmenting port statistics {} to port {}",stats,nodeConnectorRef.toString());
- NodeConnectorBuilder nodeConnectorBuilder = new NodeConnectorBuilder()
- .setKey(key).setId(item.getNodeConnectorId())
- .addAugmentation(FlowCapableNodeConnectorStatisticsData.class, stats);
- trans.putOperationalData(nodeConnectorRef, nodeConnectorBuilder.build());
- }
-
- return item;
- }
-
- @Override
- public void request() {
- if (portStatsService != null) {
- final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
- input.setNode(getNodeRef());
-
- requestHelper(portStatsService.getAllNodeConnectorsStatistics(input.build()));
- }
- }
-
- @Override
- protected NodeConnectorStatisticsAndPortNumberMap createInvariantKey(NodeConnectorStatisticsAndPortNumberMap item) {
- NodeConnectorStatisticsAndPortNumberMapBuilder ncStatsBuilder = new NodeConnectorStatisticsAndPortNumberMapBuilder();
- ncStatsBuilder.setNodeConnectorId(item.getNodeConnectorId());
- ncStatsBuilder.setKey(item.getKey());
- return ncStatsBuilder.build();
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.TimeUnit;
-
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.AggregateFlowStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * This class handles the lifecycle of per-node statistics. It receives data
- * from StatisticsListener, stores it in the data store and keeps track of
- * when the data should be removed.
- *
- * @author avishnoi@in.ibm.com
- */
-public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableContext {
- private static final Logger logger = LoggerFactory.getLogger(NodeStatisticsHandler.class);
-
- private static final long STATS_COLLECTION_MILLIS = TimeUnit.SECONDS.toMillis(15);
- private static final long FIRST_COLLECTION_MILLIS = TimeUnit.SECONDS.toMillis(5);
- private static final int NUMBER_OF_WAIT_CYCLES = 2;
-
- private final MultipartMessageManager msgManager;
- private final StatisticsRequestScheduler srScheduler;
- private final InstanceIdentifier<Node> targetNodeIdentifier;
- private final FlowStatsTracker flowStats;
- private final FlowTableStatsTracker flowTableStats;
- private final GroupDescStatsTracker groupDescStats;
- private final GroupStatsTracker groupStats;
- private final MeterConfigStatsTracker meterConfigStats;
- private final MeterStatsTracker meterStats;
- private final NodeConnectorStatsTracker nodeConnectorStats;
- private final QueueStatsTracker queueStats;
- private final DataProviderService dps;
- private final NodeRef targetNodeRef;
- private final NodeKey targetNodeKey;
- private final TimerTask task = new TimerTask() {
- @Override
- public void run() {
- try{
- requestPeriodicStatistics();
- cleanStaleStatistics();
- }catch(Exception e){
- logger.warn("Exception occured while sending statistics request : {}",e);
- }
- }
- };
-
- public NodeStatisticsHandler(final DataProviderService dps, final NodeKey nodeKey,
- final OpendaylightFlowStatisticsService flowStatsService,
- final OpendaylightFlowTableStatisticsService flowTableStatsService,
- final OpendaylightGroupStatisticsService groupStatsService,
- final OpendaylightMeterStatisticsService meterStatsService,
- final OpendaylightPortStatisticsService portStatsService,
- final OpendaylightQueueStatisticsService queueStatsService,
- final StatisticsRequestScheduler srScheduler) {
- this.dps = Preconditions.checkNotNull(dps);
- this.targetNodeKey = Preconditions.checkNotNull(nodeKey);
- this.srScheduler = Preconditions.checkNotNull(srScheduler);
- this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build();
- this.targetNodeRef = new NodeRef(targetNodeIdentifier);
-
- final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
-
- msgManager = new MultipartMessageManager(lifetimeNanos);
- flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this);
- flowStats = new FlowStatsTracker(flowStatsService, this, flowTableStats);
- groupDescStats = new GroupDescStatsTracker(groupStatsService, this);
- groupStats = new GroupStatsTracker(groupStatsService, this);
- meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this);
- meterStats = new MeterStatsTracker(meterStatsService, this);
- nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this);
- queueStats = new QueueStatsTracker(queueStatsService, this);
- }
-
- public NodeKey getTargetNodeKey() {
- return targetNodeKey;
- }
-
- @Override
- public InstanceIdentifier<Node> getNodeIdentifier() {
- return targetNodeIdentifier;
- }
-
- @Override
- public NodeRef getNodeRef() {
- return targetNodeRef;
- }
-
- @Override
- public DataModificationTransaction startDataModification() {
- DataModificationTransaction dmt = dps.beginTransaction();
- dmt.registerListener(this.srScheduler);
- return dmt;
- }
-
- public synchronized void updateGroupDescStats(TransactionAware transaction, List<GroupDescStats> list) {
- if (msgManager.isExpectedTransaction(transaction)) {
- groupDescStats.updateStats(list);
- }
- }
-
- public synchronized void updateGroupStats(TransactionAware transaction, List<GroupStats> list) {
- if (msgManager.isExpectedTransaction(transaction)) {
- groupStats.updateStats(list);
- }
- }
-
- public synchronized void updateMeterConfigStats(TransactionAware transaction, List<MeterConfigStats> list) {
- if (msgManager.isExpectedTransaction(transaction)) {
- meterConfigStats.updateStats(list);
- }
- }
-
- public synchronized void updateMeterStats(TransactionAware transaction, List<MeterStats> list) {
- if (msgManager.isExpectedTransaction(transaction)) {
- meterStats.updateStats(list);
- }
- }
-
- public synchronized void updateQueueStats(TransactionAware transaction, List<QueueIdAndStatisticsMap> list) {
- if (msgManager.isExpectedTransaction(transaction)) {
- queueStats.updateStats(list);
- }
- }
-
- public synchronized void updateFlowTableStats(TransactionAware transaction, List<FlowTableAndStatisticsMap> list) {
- if (msgManager.isExpectedTransaction(transaction)) {
- flowTableStats.updateStats(list);
- }
- }
-
- public synchronized void updateNodeConnectorStats(TransactionAware transaction, List<NodeConnectorStatisticsAndPortNumberMap> list) {
- if (msgManager.isExpectedTransaction(transaction)) {
- nodeConnectorStats.updateStats(list);
- }
- }
-
- public synchronized void updateAggregateFlowStats(TransactionAware transaction, AggregateFlowStatistics flowStats) {
- final Short tableId = msgManager.isExpectedTableTransaction(transaction);
- if (tableId != null) {
- final DataModificationTransaction trans = this.startDataModification();
- InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
- .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
-
- AggregateFlowStatisticsDataBuilder aggregateFlowStatisticsDataBuilder = new AggregateFlowStatisticsDataBuilder();
- AggregateFlowStatisticsBuilder aggregateFlowStatisticsBuilder = new AggregateFlowStatisticsBuilder(flowStats);
-
- aggregateFlowStatisticsDataBuilder.setAggregateFlowStatistics(aggregateFlowStatisticsBuilder.build());
-
- logger.debug("Augment aggregate statistics: {} for table {} on Node {}",
- aggregateFlowStatisticsBuilder.build().toString(),tableId,targetNodeKey);
-
- TableBuilder tableBuilder = new TableBuilder();
- tableBuilder.setKey(new TableKey(tableId));
- tableBuilder.addAugmentation(AggregateFlowStatisticsData.class, aggregateFlowStatisticsDataBuilder.build());
- trans.putOperationalData(tableRef, tableBuilder.build());
-
- trans.commit();
- }
- }
-
- public synchronized void updateFlowStats(TransactionAware transaction, List<FlowAndStatisticsMapList> list) {
- if (msgManager.isExpectedTransaction(transaction)) {
- flowStats.updateStats(list);
- }
- }
-
- public synchronized void updateGroupFeatures(GroupFeatures notification) {
- final DataModificationTransaction trans = this.startDataModification();
-
- final NodeBuilder nodeData = new NodeBuilder();
- nodeData.setKey(targetNodeKey);
-
- NodeGroupFeaturesBuilder nodeGroupFeatures = new NodeGroupFeaturesBuilder();
- GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder(notification);
- nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
-
- //Update augmented data
- nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
- trans.putOperationalData(targetNodeIdentifier, nodeData.build());
-
- // FIXME: should we be tracking this data?
- trans.commit();
- }
-
- public synchronized void updateMeterFeatures(MeterFeatures features) {
- final DataModificationTransaction trans = this.startDataModification();
-
- final NodeBuilder nodeData = new NodeBuilder();
- nodeData.setKey(targetNodeKey);
-
- NodeMeterFeaturesBuilder nodeMeterFeatures = new NodeMeterFeaturesBuilder();
- MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder(features);
- nodeMeterFeatures.setMeterFeatures(meterFeature.build());
-
- //Update augmented data
- nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
- trans.putOperationalData(targetNodeIdentifier, nodeData.build());
-
- // FIXME: should we be tracking this data?
- trans.commit();
- }
-
- public synchronized void cleanStaleStatistics() {
- final DataModificationTransaction trans = this.startDataModification();
-
- flowStats.cleanup(trans);
- groupDescStats.cleanup(trans);
- groupStats.cleanup(trans);
- meterConfigStats.cleanup(trans);
- meterStats.cleanup(trans);
- nodeConnectorStats.cleanup(trans);
- queueStats.cleanup(trans);
- msgManager.cleanStaleTransactionIds();
-
- trans.commit();
- }
-
- public synchronized void requestPeriodicStatistics() {
- logger.debug("Send requests for statistics collection to node : {}", targetNodeKey);
-
- this.srScheduler.addRequestToSchedulerQueue(flowTableStats);
-
- this.srScheduler.addRequestToSchedulerQueue(flowStats);
-
- this.srScheduler.addRequestToSchedulerQueue(nodeConnectorStats);
-
- this.srScheduler.addRequestToSchedulerQueue(groupStats);
-
- this.srScheduler.addRequestToSchedulerQueue(groupDescStats);
-
- this.srScheduler.addRequestToSchedulerQueue(meterStats);
-
- this.srScheduler.addRequestToSchedulerQueue(meterConfigStats);
-
- this.srScheduler.addRequestToSchedulerQueue(queueStats);
- }
-
- public synchronized void start(final Timer timer) {
- flowStats.start(dps);
- groupDescStats.start(dps);
- groupStats.start(dps);
- meterConfigStats.start(dps);
- meterStats.start(dps);
- queueStats.start(dps);
-
- timer.schedule(task, (long) (Math.random() * FIRST_COLLECTION_MILLIS), STATS_COLLECTION_MILLIS);
-
- logger.debug("Statistics handler for node started with base interval {}ms", STATS_COLLECTION_MILLIS);
-
- requestPeriodicStatistics();
- }
-
- @Override
- public synchronized void close() {
- task.cancel();
- flowStats.close();
- groupDescStats.close();
- groupStats.close();
- meterConfigStats.close();
- meterStats.close();
- queueStats.close();
-
- //Clean up queued statistics request from scheduler queue
- srScheduler.removeRequestsFromSchedulerQueue(this.getNodeRef());
-
- logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
- }
-
- @Override
- public void registerTransaction(TransactionId id) {
- msgManager.recordExpectedTransaction(id);
- logger.debug("Transaction {} for node {} sent successfully", id, targetNodeKey);
- }
-
- @Override
- public void registerTableTransaction(final TransactionId id, final Short table) {
- msgManager.recordExpectedTableTransaction(id, table);
- logger.debug("Transaction {} for node {} table {} sent successfully", id, targetNodeKey, table);
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-
-final class QueueStatsEntry {
- private final NodeConnectorId nodeConnectorId;
- private final QueueId queueId;
- public QueueStatsEntry(NodeConnectorId ncId, QueueId queueId){
- this.nodeConnectorId = ncId;
- this.queueId = queueId;
- }
- public NodeConnectorId getNodeConnectorId() {
- return nodeConnectorId;
- }
- public QueueId getQueueId() {
- return queueId;
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((nodeConnectorId == null) ? 0 : nodeConnectorId.hashCode());
- result = prime * result + ((queueId == null) ? 0 : queueId.hashCode());
- return result;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof QueueStatsEntry)) {
- return false;
- }
- QueueStatsEntry other = (QueueStatsEntry) obj;
- if (nodeConnectorId == null) {
- if (other.nodeConnectorId != null) {
- return false;
- }
- } else if (!nodeConnectorId.equals(other.nodeConnectorId)) {
- return false;
- }
- if (queueId == null) {
- if (other.queueId != null) {
- return false;
- }
- } else if (!queueId.equals(other.queueId)) {
- return false;
- }
- return true;
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.Map.Entry;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class QueueStatsTracker extends AbstractListeningStatsTracker<QueueIdAndStatisticsMap, QueueStatsEntry> {
- private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class);
- private final OpendaylightQueueStatisticsService queueStatsService;
-
- QueueStatsTracker(OpendaylightQueueStatisticsService queueStatsService, final FlowCapableContext context) {
- super(context);
- this.queueStatsService = queueStatsService;
- }
-
- @Override
- protected void cleanupSingleStat(DataModificationTransaction trans, QueueStatsEntry item) {
- InstanceIdentifier<?> queueRef
- = getNodeIdentifierBuilder().child(NodeConnector.class, new NodeConnectorKey(item.getNodeConnectorId()))
- .augmentation(FlowCapableNodeConnector.class)
- .child(Queue.class, new QueueKey(item.getQueueId()))
- .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).build();
- trans.removeOperationalData(queueRef);
- }
-
- @Override
- protected QueueStatsEntry updateSingleStat(DataModificationTransaction trans, QueueIdAndStatisticsMap item) {
-
- QueueStatsEntry queueEntry = new QueueStatsEntry(item.getNodeConnectorId(), item.getQueueId());
-
- FlowCapableNodeConnectorQueueStatisticsDataBuilder queueStatisticsDataBuilder = new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
-
- FlowCapableNodeConnectorQueueStatisticsBuilder queueStatisticsBuilder = new FlowCapableNodeConnectorQueueStatisticsBuilder();
-
- queueStatisticsBuilder.fieldsFrom(item);
-
- queueStatisticsDataBuilder.setFlowCapableNodeConnectorQueueStatistics(queueStatisticsBuilder.build());
-
- InstanceIdentifier<Queue> queueRef = getNodeIdentifierBuilder().child(NodeConnector.class, new NodeConnectorKey(item.getNodeConnectorId()))
- .augmentation(FlowCapableNodeConnector.class)
- .child(Queue.class, new QueueKey(item.getQueueId())).toInstance();
-
- QueueBuilder queueBuilder = new QueueBuilder();
- FlowCapableNodeConnectorQueueStatisticsData qsd = queueStatisticsDataBuilder.build();
- queueBuilder.addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, qsd);
- queueBuilder.setKey(new QueueKey(item.getQueueId()));
-
- logger.debug("Augmenting queue statistics {} of queue {} to port {}",
- qsd,
- item.getQueueId(),
- item.getNodeConnectorId());
-
- trans.putOperationalData(queueRef, queueBuilder.build());
- return queueEntry;
- }
-
- @Override
- public void request() {
- if (queueStatsService != null) {
- GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
- input.setNode(getNodeRef());
-
- requestHelper(queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()));
- }
- }
-
- public void request(NodeConnectorId nodeConnectorId, QueueId queueId) {
- if (queueStatsService != null) {
- GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
-
- input.setNode(getNodeRef());
- input.setNodeConnectorId(nodeConnectorId);
- input.setQueueId(queueId);
-
- requestHelper(queueStatsService.getQueueStatisticsFromGivenPort(input.build()));
- }
- }
-
- @Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- for (Entry<InstanceIdentifier<?>, DataObject> e : change.getCreatedConfigurationData().entrySet()) {
- if (Queue.class.equals(e.getKey().getTargetType())) {
- final Queue queue = (Queue) e.getValue();
- final NodeConnectorKey key = e.getKey().firstKeyOf(NodeConnector.class, NodeConnectorKey.class);
- logger.debug("Key {} triggered request for connector {} queue {}", key.getId(), queue.getQueueId());
- request(key.getId(), queue.getQueueId());
- } else {
- logger.debug("Ignoring key {}", e.getKey());
- }
- }
-
- final DataModificationTransaction trans = startTransaction();
- for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
- if (Queue.class.equals(key.getTargetType())) {
- @SuppressWarnings("unchecked")
- final InstanceIdentifier<Queue> queue = (InstanceIdentifier<Queue>)key;
- final InstanceIdentifier<?> del = queue
- .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class);
- logger.debug("Key {} triggered remove of augmentation {}", key, del);
-
- trans.removeOperationalData(del);
- }
- }
- trans.commit();
- }
-
- @Override
- protected InstanceIdentifier<?> listenPath() {
- return getNodeIdentifierBuilder().child(NodeConnector.class)
- .augmentation(FlowCapableNodeConnector.class).child(Queue.class).build();
- }
-
- @Override
- protected String statName() {
- return "Queue";
- }
-
- @Override
- public void start(final DataBrokerService dbs) {
- if (queueStatsService == null) {
- logger.debug("No Queue Statistics service, not subscribing to queues on node {}", getNodeIdentifier());
- return;
- }
-
- super.start(dbs);
- }
-
- @Override
- protected QueueStatsEntry createInvariantKey(QueueStatsEntry item) {
- // No invariant data exist in the group description stats.
- return item;
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager
+ *
+ * StatListeningCommiter
+ * Definition Interface for {@link DataChangeListener} implementer class rule.
+ * Interface represent a contract between Config/DataStore changes and
+ * Operational/DataStore commits. All Operational/DataStore commit have
+ * to by represent as RPC Device response Notification processing. So
+ * Operational/DS could contains only real mirror of OF Device
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 27, 2014
+ */
+public interface StatListeningCommiter<T extends DataObject, N extends NotificationListener> extends DataChangeListener, StatNotifyCommiter<N> {
+
+
+ /**
+ * All StatListeningCommiter implementer has to clean its actual state
+ * for all cached data related to disconnected node.
+ * Method prevents unwanted dataStore changes.
+ *
+ * @param nodeIdent
+ */
+ void cleanForDisconnect(InstanceIdentifier<Node> nodeIdent);
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SwitchFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatNodeRegistration
+ * Class represents {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}
+ * {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener} in Operational/DataStore for ADD / REMOVE
+ * actions which are represented connect / disconnect OF actions. Connect functionality are expecting
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Sep 5, 2014
+ */
+public interface StatNodeRegistration extends OpendaylightInventoryListener, AutoCloseable {
+
+ /**
+ * Method contains {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode} registration to {@link StatisticsManager}
+ * for permanently collecting statistics by {@link StatPermCollector} and
+ * as a prevention to use a validation check to the Operational/DS for identify
+ * connected {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}.
+ *
+ * @param InstanceIdentifier<SwitchFeatures> keyIdent
+ * @param FlowCapableNode data
+ * @param InstanceIdentifier<Node> nodeIdent
+ */
+ void connectFlowCapableNode(InstanceIdentifier<SwitchFeatures> keyIdent,
+ SwitchFeatures data, InstanceIdentifier<Node> nodeIdent);
+
+ /**
+ * Method cut {@link Node} registration for {@link StatPermCollector}
+ *
+ * @param InstanceIdentifier<Node> keyIdent
+ */
+ void disconnectFlowCapableNode(InstanceIdentifier<Node> keyIdent);
+}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager;
+
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager
+ *
+ * StatNotifyCommiter
+ * Definition Interface for notification implementer class rule
+ * Interface represent a contract between RPC Device Notification
+ * and Operational/DataStore commits.
+ *
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 28, 2014
+ */
+public interface StatNotifyCommiter<N extends NotificationListener> extends AutoCloseable, NotificationListener {
+
+
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager
+ *
+ * StatPermCollector
+ * Class implement {@link Runnable} and inside is running statistic collecting
+ * process DataObject statistics by DataObject statistics for every {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}.
+ * Every statistics wait to finish previous statistics. Only if all statistics finish,
+ * next {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}
+ * Statistics should be collecting. We are able to set minimal time for start next round cross all Network,
+ * but all depends on network possibility.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 28, 2014
+ */
+public interface StatPermCollector extends Runnable, AutoCloseable {
+
+ /**
+ * StatCapType
+ * Enum class refers ofp_statistics capabilities fields from OF Switch
+ * capabilities specification which have to come as a post HandShake
+ * information from OF Switch and Inventory Manager adds all to the
+ * Operational/DS.
+ * If the capabilities are not add (for any reason) NodeRegistrator
+ * adds all StatCapTypes for the {@link Node}.
+ */
+ public enum StatCapabTypes {
+ /**
+ * OFPC_FLOW_STATS
+ */
+ FLOW_STATS,
+ /**
+ * OFPC_TABLE_STATS
+ */
+ TABLE_STATS,
+ /**
+ * OFPC_PORT_STATS
+ */
+ PORT_STATS,
+ /**
+ * OFPC_GROUP_STATS
+ */
+ GROUP_STATS,
+ /**
+ * OFPC_QUEUE_STATS
+ */
+ QUEUE_STATS,
+ /**
+ * Meter statistics has no support from OF Switch capabilities
+ * so we have to try get statistics for it and wait for response
+ * Error or response package with results.
+ */
+ METER_STATS
+ }
+
+ /**
+ * Add new connected node for permanent statistics collecting process
+ *
+ * @param flowNode
+ * @param statTypes
+ * @param nrOfSwitchTables
+ * @return true/false if the {@link Node} added successful
+ */
+ boolean connectedNodeRegistration(InstanceIdentifier<Node> nodeIdent,
+ List<StatCapabTypes> statTypes, Short nrOfSwitchTables);
+
+ /**
+ * All disconnected Nodes need be removed from stat list Nodes
+ * @param flowNode
+ * @return true/false if the {@link Node} removed successful
+ */
+ boolean disconnectedNodeUnregistration(InstanceIdentifier<Node> nodeIdent);
+
+ /**
+ * Method return true only and only if {@link StatPermCollector} contain
+ * valid node registration in its internal {@link Node} map.
+ * Otherwise return false.
+ *
+ * @param InstanceIdentifier<FlowCapableNode> flowNode
+ * @return
+ */
+ boolean isProvidedFlowNodeActive(InstanceIdentifier<Node> nodeIdent);
+
+ /**
+ * Object notification for continue statistics collecting process.
+ * It is call from collecting allStatistics methods as a future result for
+ * Operational/DS statistic store call (does not matter in the outcome).
+ */
+ void collectNextStatistics();
+
+ /**
+ * Method returns true if collector has registered some active nodes
+ * otherwise return false.
+ *
+ * @return
+ */
+ boolean hasActiveNodes();
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.base.Optional;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager
+ *
+ * StatRpcMsgManager
+ * It represent access point for Device statistics RPC services which are
+ * filtered for needed methods only and they are wrapped in simply way.
+ * Many statistics responses are Multipart messages, so StatRpcMsgManager
+ * provide a functionality to add all multipart msg and provides back whole
+ * stack to listener when listener catch the last Multipart msg.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 29, 2014
+ */
+public interface StatRpcMsgManager extends Runnable, AutoCloseable {
+
+ interface RpcJobsQueue extends Callable<Void> {}
+
+ /**
+ * Transaction container is definition for Multipart transaction
+ * join container for all Multipart msg with same TransactionId
+ * Input {@link DataObject} is a possible light-weight DataObject
+ * which is used for identification (e.g. Flow-> Priority,Match,Cookie,FlowId)
+ *
+ * @param <T> extends TransactionAware -
+ */
+ interface TransactionCacheContainer<T extends TransactionAware> {
+
+ void addNotif(T notification);
+
+ TransactionId getId();
+
+ NodeId getNodeId();
+
+ Optional<? extends DataObject> getConfInput();
+
+ List<T> getNotifications();
+ }
+
+ /**
+ * Method is used for check a transaction registration
+ * for multipart cache holder
+ *
+ * @param TransactionId id
+ * @return true if the transaction has been correctly registered
+ */
+ Future<Boolean> isExpectedStatistics(TransactionId id, NodeId nodeId);
+
+ /**
+ * Method converts {@link java.util.concurrent.Future} object to listenenable future which
+ * is registered for Multipart Notification Statistics Collecting processing.
+ *
+ * @param future - result every Device RPC call
+ */
+ <T extends TransactionAware, D extends DataObject> void registrationRpcFutureCallBack(Future<RpcResult<T>> future, D inputObj, NodeRef ref);
+
+ /**
+ * Method adds Notification which is marked as Multipart to the transaction cash
+ * to wait for the last one.
+ *
+ * @param notification
+ */
+ <T extends TransactionAware> void addNotification(T notification, NodeId nodeId);
+
+ /**
+ * The last Multipart should inform code about possibility to take all previous
+ * messages for next processing. The method take all msg and possible input object
+ * and build all to TransactionCacheContainer Object to return. This process clean
+ * all instances in Cache.
+ *
+ * @param TransactionId id
+ * @return TransactionCacheContainer
+ */
+ Future<Optional<TransactionCacheContainer<?>>> getTransactionCacheContainer(TransactionId id, NodeId nodeId);
+
+ /**
+ * Method wraps OpendaylightGroupStatisticsService.getAllGroupStatistics
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getAllGroupsStat(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightGroupStatisticsService.getGroupDescription
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getAllGroupsConfStats(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightMeterStatisticsService.getGroupFeatures
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getGroupFeaturesStat(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightMeterStatisticsService.getAllMeterStatistics
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getAllMetersStat(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightMeterStatisticsService.getAllMeterConfigStatistics
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getAllMeterConfigStat(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightMeterStatisticsService.getMeterFeatures
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getMeterFeaturesStat(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightFlowStatisticsService.getAllFlowsStatisticsFromAllFlowTables
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getAllFlowsStat(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightFlowStatisticsService.getAggregateFlowStatisticsFromFlowTableForAllFlows
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ * @param TableId tableId
+ */
+ void getAggregateFlowStat(NodeRef nodeRef, TableId tableId);
+
+ /**
+ * Method wraps OpendaylightPortStatisticsService.getAllNodeConnectorsStatistics
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getAllPortsStat(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightFlowTableStatisticsService.getFlowTablesStatistics
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getAllTablesStat(NodeRef nodeRef);
+
+ /**
+ * Method wraps OpendaylightQueueStatisticsService.getAllQueuesStatisticsFromAllPorts
+ * and registers to Transaction Cache
+ *
+ * @param NodeRef nodeRef
+ */
+ void getAllQueueStat(NodeRef nodeRef);
+
+}
+
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class is responsible for listening for statistics update notifications and
- * routing them to the appropriate NodeStatisticsHandler.
-
- * TODO: Need to add error message listener and clean-up the associated tx id
- * if it exists in the tx-id cache.
- * @author vishnoianil
- */
-public class StatisticsListener implements OpendaylightGroupStatisticsListener,
- OpendaylightMeterStatisticsListener,
- OpendaylightFlowStatisticsListener,
- OpendaylightPortStatisticsListener,
- OpendaylightFlowTableStatisticsListener,
- OpendaylightQueueStatisticsListener{
-
- private final static Logger sucLogger = LoggerFactory.getLogger(StatisticsListener.class);
- private final StatisticsProvider statisticsManager;
-
- /**
- * default ctor
- * @param manager
- */
- public StatisticsListener(final StatisticsProvider manager){
- this.statisticsManager = manager;
- }
-
- @Override
- public void onMeterConfigStatsUpdated(final MeterConfigStatsUpdated notification) {
- final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (handler != null) {
- handler.updateMeterConfigStats(notification, notification.getMeterConfigStats());
- }
- }
-
- @Override
- public void onMeterStatisticsUpdated(MeterStatisticsUpdated notification) {
- final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (handler != null) {
- handler.updateMeterStats(notification, notification.getMeterStats());
- }
- }
-
- @Override
- public void onGroupDescStatsUpdated(GroupDescStatsUpdated notification) {
- final NodeStatisticsHandler handler = statisticsManager.getStatisticsHandler(notification.getId());
- if (handler != null) {
- handler.updateGroupDescStats(notification, notification.getGroupDescStats());
- }
- }
-
- @Override
- public void onGroupStatisticsUpdated(GroupStatisticsUpdated notification) {
- final NodeStatisticsHandler handler = statisticsManager.getStatisticsHandler(notification.getId());
- if (handler != null) {
- handler.updateGroupStats(notification, notification.getGroupStats());
- }
- }
-
- @Override
- public void onMeterFeaturesUpdated(MeterFeaturesUpdated notification) {
- final NodeStatisticsHandler sna = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (sna != null) {
- sna.updateMeterFeatures(notification);
- }
- }
-
- @Override
- public void onGroupFeaturesUpdated(GroupFeaturesUpdated notification) {
- final NodeStatisticsHandler sna = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (sna != null) {
- sna.updateGroupFeatures(notification);
- }
- }
-
- @Override
- public void onFlowsStatisticsUpdate(final FlowsStatisticsUpdate notification) {
- sucLogger.debug("Received flow stats update : {}",notification.toString());
- final NodeStatisticsHandler sna = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (sna != null) {
- sna.updateFlowStats(notification, notification.getFlowAndStatisticsMapList());
- }
- }
-
- @Override
- public void onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
- final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (handler != null) {
- handler.updateAggregateFlowStats(notification, notification);
- }
- }
-
- @Override
- public void onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
- final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (handler != null) {
- handler.updateNodeConnectorStats(notification, notification.getNodeConnectorStatisticsAndPortNumberMap());
- }
- }
-
- @Override
- public void onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
- final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (handler != null) {
- handler.updateFlowTableStats(notification, notification.getFlowTableAndStatisticsMap());
- }
- }
-
- @Override
- public void onQueueStatisticsUpdate(QueueStatisticsUpdate notification) {
- final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
- if (handler != null) {
- handler.updateQueueStats(notification, notification.getQueueIdAndStatisticsMap());
- }
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager;
+
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.statistics.manager.StatPermCollector.StatCapabTypes;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsListener;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager
+ *
+ * StatisticsManager
+ * It represent a central point for whole module. Implementation
+ * StatisticsManager registers all Operation/DS {@link StatNotifyCommiter} and
+ * Config/DS {@StatListeningCommiter}, as well as {@link StatPermCollector}
+ * for statistic collecting and {@link StatRpcMsgManager} as Device RPCs provider.
+ * In next, StatisticsManager provides all DS contact Transaction services.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 27, 2014
+ */
+public interface StatisticsManager extends AutoCloseable, TransactionChainListener {
+
+ /**
+ * StatDataStoreOperation
+ * Interface represent functionality to submit changes to DataStore.
+ * Internal {@link TransactionChainListener} joining all DS commits
+ * to Set of chained changes for prevent often DataStore touches.
+ */
+ public interface StatDataStoreOperation {
+
+ /**
+ * Apply all read / write (put|merge) operation
+ * for DataStore
+ * @param {@link ReadWriteTransaction} tx
+ */
+ void applyOperation(ReadWriteTransaction tx);
+
+ }
+
+ /**
+ * Method starts whole StatisticManager functionality
+ *
+ * @param {@link NotificationProviderService} notifService
+ * @param {@link RpcConsumerRegistry} rpcRegistry
+ * @param minReqNetMonitInt
+ */
+ void start(final NotificationProviderService notifService,
+ final RpcConsumerRegistry rpcRegistry, final long minReqNetMonitInt);
+
+ /**
+ * Method provides read/write DataStore functionality cross applyOperation
+ * defined in {@link StatDataStoreOperation}
+ *
+ * @param inventoryOper - operation for DataStore
+ */
+ void enqueue(final StatDataStoreOperation inventoryOper);
+
+ /**
+ * Method wraps {@link StatisticCollector}.isProvidedFlowNodeActive method
+ * to provide parallel statCollection process for Set of Nodes. So it has to
+ * identify correct Node Set by NodeIdentifier
+ *
+ * @param nodeIdent
+ */
+ boolean isProvidedFlowNodeActive(InstanceIdentifier<Node> nodeIdent);
+
+ /**
+ * Method wraps {@link StatPermCollector}.collectNextStatistics to provide
+ * parallel statCollection process for Set of Nodes. So it has to
+ * identify correct Node Set by NodeIdentifier.
+ *
+ * @param nodeIdent
+ */
+ void collectNextStatistics(InstanceIdentifier<Node> nodeIdent);
+
+ /**
+ * Method wraps {@link StatPermCollector}.connectedNodeRegistration to provide
+ * parallel statCollection process for Set of Nodes. So it has to
+ * connect node to new or not full Node statCollector Set.
+ *
+ * @param nodeIdent
+ * @param statTypes
+ * @param nrOfSwitchTables
+ */
+ void connectedNodeRegistration(InstanceIdentifier<Node> nodeIdent,
+ List<StatCapabTypes> statTypes, Short nrOfSwitchTables);
+
+ /**
+ * Method wraps {@link StatPermCollector}.disconnectedNodeUnregistration to provide
+ * parallel statCollection process for Set of Nodes. So it has to identify
+ * correct collector for disconnect node.
+ *
+ * @param nodeIdent
+ */
+ void disconnectedNodeUnregistration(InstanceIdentifier<Node> nodeIdent);
+
+ /**
+ * Method provides access to Device RPC methods by wrapped
+ * internal method. In next {@link StatRpcMsgManager} is registered all
+ * Multipart device msg response and joining all to be able run all
+ * collected statistics in one time (easy identification Data for delete)
+ *
+ * @return {@link StatRpcMsgManager}
+ */
+ StatRpcMsgManager getRpcMsgManager();
+
+ /**
+ * Define Method : {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}
+ * Operational/DS data change listener -> impl. target -> register FlowCapableNode to Statistic Collecting process
+ * @return {@link StatNodeRegistration}
+ */
+ StatNodeRegistration getNodeRegistrator();
+
+ /**
+ * Define Method : Flow Config/DS data change listener -> impl. target ->
+ * -> make pair between Config/DS FlowId and Device Flow response Hash
+ * @return
+ */
+ StatListeningCommiter<Flow, OpendaylightFlowStatisticsListener> getFlowListenComit();
+
+ /**
+ * Define Method : Meter Config/DS data change listener and Operation/DS notify commit
+ * functionality
+ * @return
+ */
+ StatListeningCommiter<Meter, OpendaylightMeterStatisticsListener> getMeterListenCommit();
+
+ /**
+ * Define Method : Group Config/DS data change listener and Operation/DS notify commit
+ * functionality
+ * @return
+ */
+ StatListeningCommiter<Group, OpendaylightGroupStatisticsListener> getGroupListenCommit();
+
+ /**
+ * Define Method : Queue Config/DS change listener and Operation/DS notify commit functionality
+ * @return
+ */
+ StatListeningCommiter<Queue, OpendaylightQueueStatisticsListener> getQueueNotifyCommit();
+
+ /**
+ * Define Method : Table Operation/DS notify commit functionality
+ * @return
+ */
+ StatNotifyCommiter<OpendaylightFlowTableStatisticsListener> getTableNotifCommit();
+
+ /**
+ * Define Method : Port Operation/DS notify commit functionality
+ * @return
+ */
+ StatNotifyCommiter<OpendaylightPortStatisticsListener> getPortNotifyCommit();
+
+}
+
package org.opendaylight.controller.md.statistics.manager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.statistics.manager.impl.StatisticsManagerImpl;
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Statistics Manager Activator
+ *
+ * OSGi bundle activator
+ *
+ */
public class StatisticsManagerActivator extends AbstractBindingAwareProvider {
- private StatisticsProvider statsProvider;
+
+ private final static Logger LOG = LoggerFactory.getLogger(StatisticsManagerActivator.class);
+
+ /* TODO move it to ConfigSubsystem */
+ private static final long DEFAULT_MIN_REQUEST_NET_MONITOR_INTERVAL = 3000L;
+ private static final int MAX_NODES_FOR_COLLECTOR = 16;
+
+ private StatisticsManager statsProvider;
@Override
- public void onSessionInitiated(ProviderContext session) {
- final DataProviderService dps = session.getSALService(DataProviderService.class);
- final NotificationProviderService nps = session.getSALService(NotificationProviderService.class);
+ public void onSessionInitiated(final ProviderContext session) {
+ LOG.info("StatisticsManagerActivator initialization.");
+ try {
+ final DataBroker dataBroker = session.getSALService(DataBroker.class);
+ final NotificationProviderService notifService =
+ session.getSALService(NotificationProviderService.class);
+ statsProvider = new StatisticsManagerImpl(dataBroker, MAX_NODES_FOR_COLLECTOR);
+ statsProvider.start(notifService, session, DEFAULT_MIN_REQUEST_NET_MONITOR_INTERVAL);
+ LOG.info("StatisticsManagerActivator started successfully.");
+ }
+ catch (final Exception e) {
+ LOG.error("Unexpected error by initialization of StatisticsManagerActivator", e);
+ stopImpl(null);
+ }
+ }
- statsProvider = new StatisticsProvider(dps);
- statsProvider.start(nps, session);
+ @VisibleForTesting
+ StatisticsManager getStatisticManager() {
+ return statsProvider;
}
@Override
- protected void stopImpl(BundleContext context) {
+ protected void stopImpl(final BundleContext context) {
if (statsProvider != null) {
- statsProvider.close();
+ try {
+ statsProvider.close();
+ }
+ catch (final Exception e) {
+ LOG.error("Unexpected error by stopping StatisticsManagerActivator", e);
+ }
statsProvider = null;
}
+ LOG.info("StatisticsManagerActivator stoped.");
}
}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.Collection;
-import java.util.Timer;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Following are main responsibilities of the class:
- * 1) Invoke statistics request thread to send periodic statistics request to all the
- * flow capable switch connected to the controller. It sends statistics request for
- * Group,Meter,Table,Flow,Queue,Aggregate stats.
- *
- * 2) Invoke statistics ager thread, to clean up all the stale statistics data from
- * operational data store.
- *
- * @author avishnoi@in.ibm.com
- *
- */
-public class StatisticsProvider implements AutoCloseable {
- private static final Logger spLogger = LoggerFactory.getLogger(StatisticsProvider.class);
-
- private final ConcurrentMap<NodeId, NodeStatisticsHandler> handlers = new ConcurrentHashMap<>();
- private final Timer timer = new Timer("statistics-manager", true);
- private final DataProviderService dps;
-
- private OpendaylightGroupStatisticsService groupStatsService;
-
- private OpendaylightMeterStatisticsService meterStatsService;
-
- private OpendaylightFlowStatisticsService flowStatsService;
-
- private OpendaylightPortStatisticsService portStatsService;
-
- private OpendaylightFlowTableStatisticsService flowTableStatsService;
-
- private OpendaylightQueueStatisticsService queueStatsService;
-
- private final StatisticsRequestScheduler srScheduler;
-
- public StatisticsProvider(final DataProviderService dataService) {
- this.dps = Preconditions.checkNotNull(dataService);
- this.srScheduler = new StatisticsRequestScheduler();
- }
-
- private final StatisticsListener updateCommiter = new StatisticsListener(StatisticsProvider.this);
-
- private ListenerRegistration<NotificationListener> listenerRegistration;
-
- private ListenerRegistration<DataChangeListener> flowCapableTrackerRegistration;
-
- public void start(final NotificationProviderService nps, final RpcConsumerRegistry rpcRegistry) {
-
- // Get Group/Meter statistics service instances
- groupStatsService = rpcRegistry.getRpcService(OpendaylightGroupStatisticsService.class);
- meterStatsService = rpcRegistry.getRpcService(OpendaylightMeterStatisticsService.class);
- flowStatsService = rpcRegistry.getRpcService(OpendaylightFlowStatisticsService.class);
- portStatsService = rpcRegistry.getRpcService(OpendaylightPortStatisticsService.class);
- flowTableStatsService = rpcRegistry.getRpcService(OpendaylightFlowTableStatisticsService.class);
- queueStatsService = rpcRegistry.getRpcService(OpendaylightQueueStatisticsService.class);
- this.srScheduler.start();
-
- // Start receiving notifications
- this.listenerRegistration = nps.registerNotificationListener(this.updateCommiter);
-
- // Register for switch connect/disconnect notifications
- final InstanceIdentifier<FlowCapableNode> fcnId = InstanceIdentifier.builder(Nodes.class)
- .child(Node.class).augmentation(FlowCapableNode.class).build();
- spLogger.debug("Registering FlowCapable tracker to {}", fcnId);
- this.flowCapableTrackerRegistration = dps.registerDataChangeListener(fcnId,
- new FlowCapableTracker(this, fcnId));
-
- spLogger.info("Statistics Provider started.");
- }
-
- /**
- * Get the handler for a particular node.
- *
- * @param nodeId source node
- * @return Node statistics handler for that node. Null if the statistics should
- * not handled.
- */
- public final NodeStatisticsHandler getStatisticsHandler(final NodeId nodeId) {
- Preconditions.checkNotNull(nodeId);
- NodeStatisticsHandler handler = handlers.get(nodeId);
- if (handler == null) {
- spLogger.info("Attempted to get non-existing handler for {}", nodeId);
- }
- return handler;
- }
-
- @Override
- public void close() {
- try {
- if (this.listenerRegistration != null) {
- this.listenerRegistration.close();
- this.listenerRegistration = null;
- }
- if (this.flowCapableTrackerRegistration != null) {
- this.flowCapableTrackerRegistration.close();
- this.flowCapableTrackerRegistration = null;
- }
- timer.cancel();
- } catch (Exception e) {
- spLogger.warn("Failed to stop Statistics Provider completely", e);
- } finally {
- spLogger.info("Statistics Provider stopped.");
- }
- }
-
- void startNodeHandlers(final Collection<NodeKey> addedNodes) {
- for (NodeKey key : addedNodes) {
- if (handlers.containsKey(key.getId())) {
- spLogger.warn("Attempted to start already-existing handler for {}, very strange", key.getId());
- continue;
- }
-
- final NodeStatisticsHandler h = new NodeStatisticsHandler(dps, key,
- flowStatsService, flowTableStatsService, groupStatsService,
- meterStatsService, portStatsService, queueStatsService,srScheduler);
- final NodeStatisticsHandler old = handlers.putIfAbsent(key.getId(), h);
- if (old == null) {
- spLogger.debug("Started node handler for {}", key.getId());
- h.start(timer);
- } else {
- spLogger.debug("Prevented race on handler for {}", key.getId());
- }
- }
- }
-
- void stopNodeHandlers(final Collection<NodeKey> removedNodes) {
- for (NodeKey key : removedNodes) {
- final NodeStatisticsHandler s = handlers.remove(key.getId());
- if (s != null) {
- spLogger.debug("Stopping node handler for {}", key.getId());
- s.close();
- } else {
- spLogger.warn("Attempted to remove non-existing handler for {}, very strange", key.getId());
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.TimeUnit;
-
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Main responsibility of the class is to check the MD-SAL data store read/write
- * transaction accumulation level and send statistics request if number of pending
- * read/write transactions are zero.
- * @author avishnoi@in.ibm.com
- *
- */
-@SuppressWarnings("rawtypes")
-public class StatisticsRequestScheduler implements DataTransactionListener {
-
- private static final Logger srsLogger = LoggerFactory.getLogger(StatisticsRequestScheduler.class);
- private final Timer timer = new Timer("request-monitor", true);
-
- // We need ordered retrieval, and O(1) contains operation
- private final Map<AbstractStatsTracker,Integer> requestQueue =
- Collections.synchronizedMap(new LinkedHashMap<AbstractStatsTracker,Integer>());
-
- private Long PendingTransactions;
-
- private long lastRequestTime = System.nanoTime();
-
- private static final long REQUEST_MONITOR_INTERVAL = 1000;
-
- private final TimerTask task = new TimerTask() {
- @Override
- public void run() {
- try{
- long now = System.nanoTime();
- if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){
- requestStatistics();
- }
- }catch (IllegalArgumentException | IllegalStateException | NullPointerException e){
- srsLogger.warn("Exception occured while sending statistics request : {}",e);
- }
- }
- };
-
- public StatisticsRequestScheduler(){
- PendingTransactions = (long) 0;
- }
-
- public void addRequestToSchedulerQueue(AbstractStatsTracker statsRequest){
- requestQueue.put(statsRequest, null);
- }
-
- public void removeRequestsFromSchedulerQueue(NodeRef node){
- AbstractStatsTracker stats = null;
- synchronized(requestQueue){
- Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
- while(nodesItr.hasNext()){
- stats = nodesItr.next().getKey();
- if(stats.getNodeRef().equals(node)){
- nodesItr.remove();
- }
- }
- }
-
- }
- public AbstractStatsTracker getNextRequestFromSchedulerQueue(){
- //Remove first element
- AbstractStatsTracker stats = null;
- synchronized(requestQueue){
- Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
- if(nodesItr.hasNext()){
- stats = nodesItr.next().getKey();
- srsLogger.debug("{} chosen up for execution",stats.getNodeRef());
- nodesItr.remove();
- return stats;
- }
- }
- return stats;
- }
-
- private void requestStatistics(){
- AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue();
- sendStatsRequest(stats);
- }
- @Override
- public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) {
-
- AbstractStatsTracker stats = null;
- synchronized(PendingTransactions){
- switch(status){
- case SUBMITED:
- this.PendingTransactions++;
- break;
- case COMMITED:
- case FAILED:
- this.PendingTransactions--;
- if(PendingTransactions == 0){
- lastRequestTime = System.nanoTime();
- stats = this.getNextRequestFromSchedulerQueue();
- }
- srsLogger.debug("Pending MD-SAL transactions : {} & Scheduler queue size : {}",this.PendingTransactions,this.requestQueue.size());
- break;
- default:
- break;
- }
- }
- sendStatsRequest(stats);
- }
-
- private void sendStatsRequest(AbstractStatsTracker stats){
- if(stats != null){
- try{
- stats.request();
- stats.increaseRequestCounter();
- }catch(Exception e){
- srsLogger.warn("Statistics request was not sent successfully. Reason : {}",e.getMessage());
- }
- }
- }
- public void start(){
- timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL);
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+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.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatListeningCommiter;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatAbstractListeneningCommiter
+ * Class is abstract implementation for all Configuration/DataStore DataChange
+ * listenable DataObjects like flows, groups, meters. It is a holder for common
+ * functionality needed by construction/destruction class and for DataChange
+ * event processing.
+ *
+ */
+public abstract class StatAbstractListenCommit<T extends DataObject, N extends NotificationListener>
+ extends StatAbstractNotifyCommit<N> implements StatListeningCommiter<T,N> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StatAbstractListenCommit.class);
+
+ private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+ protected final Map<InstanceIdentifier<Node>, Map<InstanceIdentifier<T>, Integer>> mapNodesForDelete = new ConcurrentHashMap<>();
+
+ private final Class<T> clazz;
+
+ private final DataBroker dataBroker;
+
+ private volatile ReadOnlyTransaction currentReadTx;
+
+ /* Constructor has to make a registration */
+ public StatAbstractListenCommit(final StatisticsManager manager, final DataBroker db,
+ final NotificationProviderService nps, final Class<T> clazz) {
+ super(manager,nps);
+ this.clazz = Preconditions.checkNotNull(clazz, "Referenced Class can not be null");
+ Preconditions.checkArgument(db != null, "DataBroker can not be null!");
+ listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getWildCardedRegistrationPath(), this, DataChangeScope.BASE);
+ this.dataBroker = db;
+ }
+
+ /**
+ * Method returns WildCarded Path which is used for registration as a listening path changes in
+ * {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}
+ * @return
+ */
+ protected abstract InstanceIdentifier<T> getWildCardedRegistrationPath();
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+ Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
+ /*
+ * If we have opened read transaction for configuraiton data store,
+ * we will close and null it.
+ *
+ * Latest read transaction will be allocated on another read using readLatestConfiguration
+ */
+ if(currentReadTx != null) {
+ final ReadOnlyTransaction previous = currentReadTx;
+ currentReadTx = null;
+ previous.close();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void removeData(final InstanceIdentifier<?> key, final Integer value) {
+ if (clazz.equals(key.getTargetType())) {
+ final InstanceIdentifier<Node> nodeIdent = key.firstIdentifierOf(Node.class);
+ Map<InstanceIdentifier<T>, Integer> map = null;
+ if (mapNodesForDelete.containsKey(nodeIdent)) {
+ map = mapNodesForDelete.get(nodeIdent);
+ }
+ if (map == null) {
+ map = new ConcurrentHashMap<>();
+ mapNodesForDelete.put(nodeIdent, map);
+ }
+ map.put((InstanceIdentifier<T>) key, value);
+ }
+ }
+
+ @Override
+ public void cleanForDisconnect(final InstanceIdentifier<Node> nodeIdent) {
+ mapNodesForDelete.remove(nodeIdent);
+ }
+
+ @Override
+ public void close() {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.error("Error by stop {} DataChange StatListeningCommiter.", clazz.getSimpleName(), e);
+ }
+ listenerRegistration = null;
+ }
+ }
+
+ protected final <K extends DataObject> Optional<K> readLatestConfiguration(final InstanceIdentifier<K> path) {
+ if(currentReadTx == null) {
+ currentReadTx = dataBroker.newReadOnlyTransaction();
+ }
+ try {
+ return currentReadTx.read(LogicalDatastoreType.CONFIGURATION, path).checkedGet();
+ } catch (final ReadFailedException e) {
+ return Optional.absent();
+ }
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.opendaylight.controller.md.statistics.manager.StatNotifyCommiter;
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatAbstratNotifiCommiter
+ * Class is abstract implementation for all no Configuration/DataStore DataObjects
+ * and represent common functionality for all DataObject Statistics Commiters.
+ * Class defines contract between DataObject and relevant Statistics NotificationListener.
+ *
+ */
+public abstract class StatAbstractNotifyCommit<N extends NotificationListener> implements StatNotifyCommiter<N> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StatAbstractNotifyCommit.class);
+
+ protected final StatisticsManager manager;
+ private ListenerRegistration<NotificationListener> notifyListenerRegistration;
+
+ public StatAbstractNotifyCommit(final StatisticsManager manager,
+ final NotificationProviderService nps) {
+ Preconditions.checkArgument(nps != null, "NotificationProviderService can not be null!");
+ this.manager = Preconditions.checkNotNull(manager, "StatisticManager can not be null!");
+ notifyListenerRegistration = nps.registerNotificationListener(getStatNotificationListener());
+ }
+
+ @Override
+ public void close() {
+ if (notifyListenerRegistration != null) {
+ try {
+ notifyListenerRegistration.close();
+ }
+ catch (final Exception e) {
+ LOG.error("Error by stop {} StatNotificationListener.", this.getClass().getSimpleName());
+ }
+ notifyListenerRegistration = null;
+ }
+ }
+
+ /**
+ * Method returns Statistics Notification Listener for relevant DataObject implementation,
+ * which is declared for {@link StatNotifyCommiter} interface.
+ *
+ * @return
+ */
+ protected abstract N getStatNotificationListener();
+
+ /**
+ * PreConfigurationCheck - Node identified by input InstanceIdentifier<Node>
+ * has to be registered in {@link org.opendaylight.controller.md.statistics.manager.StatPermCollector}
+ *
+ * @param InstanceIdentifier<Node> nodeIdent
+ */
+ protected boolean preConfigurationCheck(final InstanceIdentifier<Node> nodeIdent) {
+ Preconditions.checkNotNull(nodeIdent, "FlowCapableNode ident can not be null!");
+ return manager.isProvidedFlowNodeActive(nodeIdent);
+ }
+
+ protected void notifyToCollectNextStatistics(final InstanceIdentifier<Node> nodeIdent) {
+ Preconditions.checkNotNull(nodeIdent, "FlowCapableNode ident can not be null!");
+ manager.collectNextStatistics(nodeIdent);
+ }
+
+ /**
+ * Wrapping Future object call for {@link org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager}
+ * getTransactionCacheContainer with 10sec TimeOut.
+ * Method has returned {@link Optional} which could contains a {@link TransactionCacheContainer}
+ *
+ * @param TransactionId transId
+ * @param NodeId nodeId
+ * @return
+ */
+ protected Optional<TransactionCacheContainer<?>> getTransactionCacheContainer(final TransactionId transId, final NodeId nodeId) {
+ Optional<TransactionCacheContainer<?>> txContainer;
+ try {
+ txContainer = manager.getRpcMsgManager().getTransactionCacheContainer(transId, nodeId).get(10, TimeUnit.SECONDS);
+ }
+ catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.warn("Get TransactionCacheContainer fail!", e);
+ txContainer = Optional.absent();
+ }
+ return txContainer;
+ }
+
+ /**
+ * Wrapping Future object call to {@link org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager}
+ * isExpectedStatistics with 10sec TimeOut.
+ * Method has checked registration for provided {@link TransactionId} and {@link NodeId}
+ *
+ * @param TransactionId transId - Transaction identification
+ * @param NodeId nodeId - Node identification
+ * @return boolean
+ */
+ protected boolean isExpectedStatistics(final TransactionId transId, final NodeId nodeId) {
+ Boolean isExpectedStat = Boolean.FALSE;
+ try {
+ isExpectedStat = manager.getRpcMsgManager().isExpectedStatistics(transId, nodeId).get(10, TimeUnit.SECONDS);
+ }
+ catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.warn("Check Transaction registraion {} fail!", transId, e);
+ return false;
+ }
+ return isExpectedStat.booleanValue();
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager.StatDataStoreOperation;
+import org.opendaylight.controller.md.statistics.manager.impl.helper.FlowComparator;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowHashIdMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowHashIdMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.nodes.node.table.FlowHashIdMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.nodes.node.table.FlowHashIdMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.nodes.node.table.FlowHashIdMapKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatListenCommitFlow
+ * Class is a NotifyListener for FlowStatistics and DataChangeListener for Config/DataStore for Flow node.
+ * All expected (registered) FlowStatistics will be builded and commit to Operational/DataStore.
+ * DataChangeEven should call create/delete Flow in Operational/DS create process needs to pair
+ * Device Flow HashCode and FlowId from Config/DS
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, OpendaylightFlowStatisticsListener>
+ implements OpendaylightFlowStatisticsListener {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(StatListenCommitFlow.class);
+
+ private static final String ALIEN_SYSTEM_FLOW_ID = "#UF$TABLE*";
+
+ private static final Integer REMOVE_AFTER_MISSING_COLLECTION = 1;
+
+ private final AtomicInteger unaccountedFlowsCounter = new AtomicInteger(0);
+
+ public StatListenCommitFlow (final StatisticsManager manager, final DataBroker db,
+ final NotificationProviderService nps){
+ super(manager, db, nps, Flow.class);
+ }
+
+ @Override
+ protected OpendaylightFlowStatisticsListener getStatNotificationListener() {
+ return this;
+ }
+
+ @Override
+ protected InstanceIdentifier<Flow> getWildCardedRegistrationPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class);
+ }
+
+ @Override
+ public void onAggregateFlowStatisticsUpdate(final AggregateFlowStatisticsUpdate notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - AggregateFlowStatisticsUpdate: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ if (notification.isMoreReplies()) {
+ return;
+ }
+ /* check flow Capable Node and write statistics */
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if (( ! txContainer.isPresent()) || txContainer.get().getNotifications() == null) {
+ return;
+ }
+ final Optional<? extends DataObject> inputObj = txContainer.get().getConfInput();
+ if (( ! inputObj.isPresent()) || ( ! (inputObj.get() instanceof Table))) {
+ return;
+ }
+ final Table table = (Table) inputObj.get();
+ final List<? extends TransactionAware> cacheNotifs = txContainer.get().getNotifications();
+ for (final TransactionAware notif : cacheNotifs) {
+ if (notif instanceof AggregateFlowStatisticsUpdate) {
+ final AggregateFlowStatisticsData stats = new AggregateFlowStatisticsDataBuilder()
+ .setAggregateFlowStatistics(new AggregateFlowStatisticsBuilder(notification).build()).build();
+ final InstanceIdentifier<FlowCapableNode> fNodeIdent = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId)).augmentation(FlowCapableNode.class);
+ final InstanceIdentifier<Table> tableRef = fNodeIdent.child(Table.class, table.getKey());
+ final InstanceIdentifier<AggregateFlowStatisticsData> tableStatRef = tableRef
+ .augmentation(AggregateFlowStatisticsData.class);
+ Optional<FlowCapableNode> fNode = Optional.absent();
+ try {
+ fNode = tx.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet();
+ } catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for FlowCapableNode fail! {}", fNodeIdent, e);
+ return;
+ }
+ if (fNode.isPresent()) {
+ ensureTable(tx, table.getId(), tableRef);
+ tx.put(LogicalDatastoreType.OPERATIONAL, tableStatRef, stats);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ public void ensureTable(final ReadWriteTransaction tx, final Short tableId, final InstanceIdentifier<Table> tableRef) {
+ final Table tableNew = new TableBuilder().setId(tableId).build();
+ tx.merge(LogicalDatastoreType.OPERATIONAL, tableRef, tableNew);
+ }
+
+ @Override
+ public void onFlowsStatisticsUpdate(final FlowsStatisticsUpdate notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - FlowsStatisticsUpdate: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ if (notification.isMoreReplies()) {
+ LOG.trace("Next notification for join txId {}", transId);
+ return;
+ }
+ /* add flow's statistics */
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if (( ! txContainer.isPresent()) || txContainer.get().getNotifications() == null) {
+ return;
+ }
+ final List<FlowAndStatisticsMapList> flowStats = new ArrayList<FlowAndStatisticsMapList>(10);
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId));
+ final List<? extends TransactionAware> cacheNotifs = txContainer.get().getNotifications();
+ for (final TransactionAware notif : cacheNotifs) {
+ if (notif instanceof FlowsStatisticsUpdate) {
+ final List<FlowAndStatisticsMapList> notifList =
+ ((FlowsStatisticsUpdate) notif).getFlowAndStatisticsMapList();
+ if (notifList != null) {
+ flowStats.addAll(notifList);
+ }
+ }
+ }
+
+ statsFlowCommitAll(flowStats, nodeIdent, tx);
+ /* cleaning all not cached hash collisions */
+ final Map<InstanceIdentifier<Flow>, Integer> listAliens = mapNodesForDelete.get(nodeIdent);
+ if (listAliens != null) {
+ for (final Entry<InstanceIdentifier<Flow>, Integer> nodeForDelete : listAliens.entrySet()) {
+ final Integer lifeIndex = nodeForDelete.getValue();
+ if (nodeForDelete.getValue() > 0) {
+ nodeForDelete.setValue(Integer.valueOf(lifeIndex.intValue() - 1));
+ } else {
+ final InstanceIdentifier<Flow> flowNodeIdent = nodeForDelete.getKey();
+ mapNodesForDelete.get(nodeIdent).remove(flowNodeIdent);
+ tx.delete(LogicalDatastoreType.OPERATIONAL, flowNodeIdent);
+ }
+ }
+ }
+ /* Notification for continue collecting statistics */
+ notifyToCollectNextStatistics(nodeIdent);
+ }
+ });
+ }
+
+ private void statsFlowCommitAll(final List<FlowAndStatisticsMapList> list,
+ final InstanceIdentifier<Node> nodeIdent, final ReadWriteTransaction tx) {
+
+ final InstanceIdentifier<FlowCapableNode> fNodeIdent = nodeIdent.augmentation(FlowCapableNode.class);
+
+ final Optional<FlowCapableNode> fNode;
+ try {
+ fNode = tx.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read FlowCapableNode {} in Operational/DS fail! Statistic scan not be updated.", nodeIdent, e);
+ return;
+ }
+ if ( ! fNode.isPresent()) {
+ LOG.trace("FlowCapableNode {} is not presented in Operational/DS. Statisticscan not be updated.", nodeIdent);
+ return;
+ }
+
+ final NodeUpdateState nodeState = new NodeUpdateState(fNodeIdent,fNode.get());
+
+ for (final FlowAndStatisticsMapList flowStat : list) {
+ final TableKey tableKey = new TableKey(flowStat.getTableId());
+ final TableFlowUpdateState tableState = nodeState.getTable(tableKey, tx);
+ tableState.reportFlow(flowStat,tx);
+ }
+
+ for (final TableFlowUpdateState table : nodeState.getTables()) {
+ table.removeUnreportedFlows(tx);
+ }
+ }
+
+ /**
+ * Method adds statistics to Flow
+ *
+ * @param flowBuilder
+ * @param deviceFlow
+ */
+ private void addStatistics(final FlowBuilder flowBuilder, final FlowAndStatisticsMapList deviceFlow) {
+ final FlowAndStatisticsMapListBuilder stats = new FlowAndStatisticsMapListBuilder(deviceFlow);
+ final FlowStatisticsBuilder flowStatisticsBuilder = new FlowStatisticsBuilder(stats.build());
+ final FlowStatisticsDataBuilder flowStatisticsData =new FlowStatisticsDataBuilder();
+ flowStatisticsData.setFlowStatistics(flowStatisticsBuilder.build());
+ flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
+ }
+
+ /**
+ * build pseudoUnique hashCode for flow in table
+ * for future easy identification
+ *
+ * FIXME: we expect same version for YANG models for all clusters and that has to be fix
+ * FIXME: CREATE BETTER KEY - for flow (MATCH is the problem)
+ */
+ static String buildFlowIdOperKey(final FlowAndStatisticsMapList deviceFlow) {
+ return new StringBuffer().append(deviceFlow.getMatch())
+ .append(deviceFlow.getPriority()).append(deviceFlow.getCookie().getValue()).toString();
+ }
+
+ private class NodeUpdateState {
+ private final InstanceIdentifier<FlowCapableNode> nodeIdentifier;
+ private final Map<TableKey,TableFlowUpdateState> tables = new HashMap<>();
+
+ public NodeUpdateState(final InstanceIdentifier<FlowCapableNode> fNodeIdent, final FlowCapableNode flowCapableNode) {
+ nodeIdentifier = fNodeIdent;
+ final List<Table> tableList = flowCapableNode.getTable();
+ if(tableList != null) {
+ for (final Table table : tableList) {
+ final TableKey tableKey = table.getKey();
+ tables.put(tableKey, new TableFlowUpdateState(nodeIdentifier.child(Table.class,tableKey),table));
+ }
+ }
+ }
+
+ public Iterable<TableFlowUpdateState> getTables() {
+ return tables.values();
+ }
+
+ TableFlowUpdateState getTable(final TableKey key,final ReadWriteTransaction tx) {
+ TableFlowUpdateState table = tables.get(key);
+ if(table == null) {
+ table = new TableFlowUpdateState(nodeIdentifier.child(Table.class, key), null);
+ tables.put(key, table);
+ }
+ return table;
+ }
+ }
+
+ private class TableFlowUpdateState {
+
+ private boolean tableEnsured = false;
+ final KeyedInstanceIdentifier<Table, TableKey> tableRef;
+ final TableKey tableKey;
+ final BiMap<FlowHashIdMapKey, FlowId> flowIdByHash;
+ List<Flow> configFlows;
+
+ public TableFlowUpdateState(final KeyedInstanceIdentifier<Table, TableKey> tablePath, final Table table) {
+ tableRef = tablePath;
+ tableKey = tablePath.getKey();
+ flowIdByHash = HashBiMap.create();
+ if(table != null) {
+ final FlowHashIdMapping flowHashMapping = table.getAugmentation(FlowHashIdMapping.class);
+ if (flowHashMapping != null) {
+ final List<FlowHashIdMap> flowHashMap = flowHashMapping.getFlowHashIdMap() != null
+ ? flowHashMapping.getFlowHashIdMap() : Collections.<FlowHashIdMap> emptyList();
+ for (final FlowHashIdMap flowHashId : flowHashMap) {
+ try {
+ flowIdByHash.put(flowHashId.getKey(), flowHashId.getFlowId());
+ } catch (final Exception e) {
+ LOG.warn("flow hashing hit a duplicate for {} -> {}", flowHashId.getKey(), flowHashId.getFlowId());
+ }
+ }
+ }
+ }
+ }
+
+ private void ensureTableFowHashIdMapping(final ReadWriteTransaction tx) {
+ if( ! tableEnsured) {
+ ensureTable(tx, tableKey.getId(), tableRef);
+ final FlowHashIdMapping emptyMapping = new FlowHashIdMappingBuilder()
+ .setFlowHashIdMap(Collections.<FlowHashIdMap> emptyList()).build();
+ tx.merge(LogicalDatastoreType.OPERATIONAL, tableRef.augmentation(FlowHashIdMapping.class), emptyMapping);
+ tableEnsured = true;
+ }
+ }
+
+ private FlowKey searchInConfiguration(final FlowAndStatisticsMapList flowStat, final ReadWriteTransaction trans) {
+ initConfigFlows(trans);
+ final Iterator<Flow> it = configFlows.iterator();
+ while(it.hasNext()) {
+ final Flow cfgFlow = it.next();
+ final FlowKey cfgKey = cfgFlow.getKey();
+ if(flowIdByHash.inverse().containsKey(cfgKey)) {
+ it.remove();
+ } else if(FlowComparator.flowEquals(flowStat, cfgFlow)) {
+ it.remove();
+ return cfgKey;
+ }
+ }
+ return null;
+ }
+
+ private void initConfigFlows(final ReadWriteTransaction trans) {
+ final Optional<Table> table = readLatestConfiguration(tableRef);
+ List<Flow> localList = null;
+ if(table.isPresent()) {
+ localList = table.get().getFlow();
+ }
+ if(localList == null) {
+ configFlows = Collections.emptyList();
+ } else {
+ configFlows = new LinkedList<>(localList);
+ }
+ }
+
+ private FlowKey getFlowKeyAndRemoveHash(final FlowHashIdMapKey key) {
+ final FlowId ret = flowIdByHash.get(key);
+ if(ret != null) {
+ flowIdByHash.remove(key);
+ return new FlowKey(ret);
+ }
+ return null;
+ }
+
+ /* Returns FlowKey which doesn't exist in any DataStore for now */
+ private FlowKey makeAlienFlowKey() {
+ final StringBuilder sBuilder = new StringBuilder(ALIEN_SYSTEM_FLOW_ID)
+ .append(tableKey.getId()).append("-").append(unaccountedFlowsCounter.incrementAndGet());
+ final FlowId flowId = new FlowId(sBuilder.toString());
+ return new FlowKey(flowId);
+ }
+
+ private Map<FlowHashIdMapKey, FlowId> getRemovalList() {
+ return flowIdByHash;
+ }
+
+ void reportFlow(final FlowAndStatisticsMapList flowStat, final ReadWriteTransaction trans) {
+ ensureTableFowHashIdMapping(trans);
+ final FlowHashIdMapKey hashingKey = new FlowHashIdMapKey(buildFlowIdOperKey(flowStat));
+ FlowKey flowKey = getFlowKeyAndRemoveHash(hashingKey);
+ if (flowKey == null) {
+ flowKey = searchInConfiguration(flowStat, trans);
+ if ( flowKey == null) {
+ flowKey = makeAlienFlowKey();
+ }
+ updateHashCache(trans,flowKey,hashingKey);
+ }
+ final FlowBuilder flowBuilder = new FlowBuilder(flowStat);
+ flowBuilder.setKey(flowKey);
+ addStatistics(flowBuilder, flowStat);
+ final InstanceIdentifier<Flow> flowIdent = tableRef.child(Flow.class, flowKey);
+ trans.put(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build());
+ /* check life for Alien flows */
+ if (flowKey.getId().getValue().startsWith(ALIEN_SYSTEM_FLOW_ID)) {
+ removeData(flowIdent, REMOVE_AFTER_MISSING_COLLECTION);
+ }
+ }
+
+ /* Build and deploy new FlowHashId map */
+ private void updateHashCache(final ReadWriteTransaction trans, final FlowKey flowKey, final FlowHashIdMapKey hashingKey) {
+ final FlowHashIdMapBuilder flHashIdMap = new FlowHashIdMapBuilder();
+ flHashIdMap.setFlowId(flowKey.getId());
+ flHashIdMap.setKey(hashingKey);
+ final KeyedInstanceIdentifier<FlowHashIdMap, FlowHashIdMapKey> flHashIdent = tableRef
+ .augmentation(FlowHashIdMapping.class).child(FlowHashIdMap.class, hashingKey);
+ /* Add new FlowHashIdMap */
+ trans.put(LogicalDatastoreType.OPERATIONAL, flHashIdent, flHashIdMap.build());
+ }
+
+ void removeUnreportedFlows(final ReadWriteTransaction tx) {
+ final InstanceIdentifier<Node> nodeIdent = tableRef.firstIdentifierOf(Node.class);
+ final List<InstanceIdentifier<Flow>> listMissingConfigFlows = notStatReportedConfigFlows();
+ final Map<InstanceIdentifier<Flow>, Integer> nodeDeleteMap = mapNodesForDelete.get(nodeIdent);
+ final Map<FlowHashIdMapKey, FlowId> listForRemove = getRemovalList();
+ for (final Entry<FlowHashIdMapKey, FlowId> entryForRemove : listForRemove.entrySet()) {
+ final FlowKey flowKey = new FlowKey(entryForRemove.getValue());
+ final InstanceIdentifier<Flow> flowRef = tableRef.child(Flow.class, flowKey);
+ if (nodeDeleteMap != null && flowKey.getId().getValue().startsWith(ALIEN_SYSTEM_FLOW_ID)) {
+ final Integer lifeIndex = nodeDeleteMap.get(flowRef);
+ if (lifeIndex > 0) {
+ break;
+ } else {
+ nodeDeleteMap.remove(flowRef);
+ }
+ } else {
+ if (listMissingConfigFlows.remove(flowRef)) {
+ break; // we probably lost some multipart msg
+ }
+ }
+ final InstanceIdentifier<FlowHashIdMap> flHashIdent =
+ tableRef.augmentation(FlowHashIdMapping.class).child(FlowHashIdMap.class, entryForRemove.getKey());
+ tx.delete(LogicalDatastoreType.OPERATIONAL, flowRef);
+ tx.delete(LogicalDatastoreType.OPERATIONAL, flHashIdent);
+ }
+ }
+
+ List<InstanceIdentifier<Flow>> notStatReportedConfigFlows() {
+ if (configFlows != null) {
+ final List<InstanceIdentifier<Flow>> returnList = new ArrayList<>(configFlows.size());
+ for (final Flow confFlow : configFlows) {
+ final InstanceIdentifier<Flow> confFlowIdent = tableRef.child(Flow.class, confFlow.getKey());
+ returnList.add(confFlowIdent);
+ }
+ return returnList;
+ }
+ return Collections.emptyList();
+ }
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager.StatDataStoreOperation;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.desc.GroupDescBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatListenCommitGroup
+ * Class is a NotifyListener for GroupStatistics and DataChangeListener for Config/DataStore for Group node.
+ * All expected (registered) GroupStatistics will be builded and commit to Operational/DataStore.
+ * DataChangeEven should call create/delete Group in Operational/DS
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class StatListenCommitGroup extends StatAbstractListenCommit<Group, OpendaylightGroupStatisticsListener>
+ implements OpendaylightGroupStatisticsListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StatListenCommitMeter.class);
+
+ public StatListenCommitGroup(final StatisticsManager manager, final DataBroker db,
+ final NotificationProviderService nps) {
+ super(manager, db, nps, Group.class);
+ }
+
+ @Override
+ protected OpendaylightGroupStatisticsListener getStatNotificationListener() {
+ return this;
+ }
+
+ @Override
+ protected InstanceIdentifier<Group> getWildCardedRegistrationPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class).child(Group.class);
+ }
+
+ @Override
+ public void onGroupDescStatsUpdated(final GroupDescStatsUpdated notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - GroupDescStatsUpdated: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ if (notification.isMoreReplies()) {
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ return;
+ }
+ final List<GroupDescStats> groupStats = notification.getGroupDescStats() != null
+ ? new ArrayList<>(notification.getGroupDescStats()) : new ArrayList<GroupDescStats>(10);
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if (txContainer.isPresent()) {
+ final List<? extends TransactionAware> cacheNotifs =
+ txContainer.get().getNotifications();
+ for (final TransactionAware notif : cacheNotifs) {
+ if (notif instanceof GroupDescStatsUpdated) {
+ groupStats.addAll(((GroupDescStatsUpdated) notif).getGroupDescStats());
+ }
+ }
+ }
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier
+ .create(Nodes.class).child(Node.class, new NodeKey(nodeId));
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+ statGroupDescCommit(groupStats, nodeIdent, tx);
+ /* Notification for continue collecting statistics */
+ notifyToCollectNextStatistics(nodeIdent);
+ }
+ });
+ }
+
+ @Override
+ public void onGroupFeaturesUpdated(final GroupFeaturesUpdated notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - MeterFeaturesUpdated: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ if (notification.isMoreReplies()) {
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ return;
+ }
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if ( ! txContainer.isPresent()) {
+ return;
+ }
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier
+ .create(Nodes.class).child(Node.class, new NodeKey(nodeId));
+
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+ notifyToCollectNextStatistics(nodeIdent);
+ final GroupFeatures stats = new GroupFeaturesBuilder(notification).build();
+ final InstanceIdentifier<GroupFeatures> groupFeatureIdent = nodeIdent
+ .augmentation(NodeGroupFeatures.class).child(GroupFeatures.class);
+ Optional<Node> node = Optional.absent();
+ try {
+ node = tx.read(LogicalDatastoreType.OPERATIONAL, nodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for Node fail! {}", nodeIdent, e);
+ }
+ if (node.isPresent()) {
+ tx.put(LogicalDatastoreType.OPERATIONAL, groupFeatureIdent, stats);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onGroupStatisticsUpdated(final GroupStatisticsUpdated notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - GroupStatisticsUpdated: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ if (notification.isMoreReplies()) {
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ return;
+ }
+ final List<GroupStats> groupStats = notification.getGroupStats() != null
+ ? new ArrayList<>(notification.getGroupStats()) : new ArrayList<GroupStats>(10);
+ Optional<Group> notifGroup = Optional.absent();
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if (txContainer.isPresent()) {
+ final Optional<? extends DataObject> inputObj = txContainer.get().getConfInput();
+ if (inputObj.isPresent() && inputObj.get() instanceof Group) {
+ notifGroup = Optional.<Group> of((Group)inputObj.get());
+ }
+ final List<? extends TransactionAware> cacheNotifs =
+ txContainer.get().getNotifications();
+ for (final TransactionAware notif : cacheNotifs) {
+ if (notif instanceof GroupStatisticsUpdated) {
+ groupStats.addAll(((GroupStatisticsUpdated) notif).getGroupStats());
+ }
+ }
+ }
+ final Optional<Group> group = notifGroup;
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier
+ .create(Nodes.class).child(Node.class, new NodeKey(nodeId));
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+ /* Notification for continue collecting statistics */
+ if ( ! group.isPresent()) {
+ notifyToCollectNextStatistics(nodeIdent);
+ }
+ statGroupCommit(groupStats, nodeIdent, group, tx);
+ }
+ });
+ }
+
+ private void statGroupCommit(final List<GroupStats> groupStats, final InstanceIdentifier<Node> nodeIdent,
+ final Optional<Group> group, final ReadWriteTransaction trans) {
+ final InstanceIdentifier<FlowCapableNode> fNodeIdent = nodeIdent.augmentation(FlowCapableNode.class);
+
+ for (final GroupStats groupStat : groupStats) {
+ final GroupStatistics stats = new GroupStatisticsBuilder(groupStat).build();
+
+ final GroupKey groupKey = new GroupKey(groupStat.getGroupId());
+ final InstanceIdentifier<GroupStatistics> gsIdent = fNodeIdent
+ .child(Group.class,groupKey).augmentation(NodeGroupStatistics.class)
+ .child(GroupStatistics.class);
+ /* Statistics Writing */
+ Optional<FlowCapableNode> fNode = Optional.absent();
+ try {
+ fNode = trans.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for FlowCapableNode fail! {}", fNodeIdent, e);
+ }
+ if (fNode.isPresent()) {
+ trans.put(LogicalDatastoreType.OPERATIONAL, gsIdent, stats);
+ }
+ }
+ }
+
+ private void statGroupDescCommit(final List<GroupDescStats> groupStats, final InstanceIdentifier<Node> nodeIdent,
+ final ReadWriteTransaction trans) {
+ final InstanceIdentifier<FlowCapableNode> fNodeIdent = nodeIdent.augmentation(FlowCapableNode.class);
+
+ final List<GroupKey> deviceGroupKeys = new ArrayList<>();
+
+ for (final GroupDescStats group : groupStats) {
+ if (group.getGroupId() != null) {
+ final GroupBuilder groupBuilder = new GroupBuilder(group);
+ final GroupKey groupKey = new GroupKey(group.getGroupId());
+ final InstanceIdentifier<Group> groupRef = fNodeIdent.child(Group.class,groupKey);
+
+ final NodeGroupDescStatsBuilder groupDesc= new NodeGroupDescStatsBuilder();
+ groupDesc.setGroupDesc(new GroupDescBuilder(group).build());
+ //Update augmented data
+ groupBuilder.addAugmentation(NodeGroupDescStats.class, groupDesc.build());
+ deviceGroupKeys.add(groupKey);
+ Optional<FlowCapableNode> hashIdUpd = Optional.absent();
+ try {
+ hashIdUpd = trans.read(LogicalDatastoreType.OPERATIONAL,fNodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for FlowCapableNode fail! {}", fNodeIdent, e);
+ }
+ if (hashIdUpd.isPresent()) {
+ trans.put(LogicalDatastoreType.OPERATIONAL, groupRef, groupBuilder.build());
+ }
+ }
+ }
+ /* Delete all not presented Group Nodes */
+ deleteAllNotPresentNode(fNodeIdent, trans, deviceGroupKeys);
+ }
+
+ private void deleteAllNotPresentNode(final InstanceIdentifier<FlowCapableNode> fNodeIdent,
+ final ReadWriteTransaction trans, final List<GroupKey> deviceGroupKeys) {
+
+ final Optional<FlowCapableNode> fNode = readLatestConfiguration(fNodeIdent);
+ if ( ! fNode.isPresent()) {
+ LOG.trace("Read Operational/DS for FlowCapableNode fail! Node {} doesn't exist.", fNodeIdent);
+ return;
+ }
+ final List<Group> existGroups = fNode.get().getGroup() != null
+ ? fNode.get().getGroup() : Collections.<Group> emptyList();
+ /* Add all existed groups paths - no updated paths has to be removed */
+ for (final Group group : existGroups) {
+ if (deviceGroupKeys.remove(group.getKey())) {
+ break; // group still exist on device
+ }
+ LOG.trace("Group {} has to removed.", group);
+ final InstanceIdentifier<Group> delGroupIdent = fNodeIdent.child(Group.class, group.getKey());
+ Optional<Group> delGroup = Optional.absent();
+ try {
+ delGroup = trans.read(LogicalDatastoreType.OPERATIONAL, delGroupIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ // NOOP - probably another transaction delete that node
+ }
+ if (delGroup.isPresent()) {
+ trans.delete(LogicalDatastoreType.OPERATIONAL, delGroupIdent);
+ }
+ }
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager.StatDataStoreOperation;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterConfigStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatListenCommitMeter
+ * Class is a NotifyListener for MeterStatistics and DataChangeListener for Config/DataStore for Meter node.
+ * All expected (registered) MeterStatistics will be builded and commit to Operational/DataStore.
+ * DataChangeEven should call create/delete Meter in Operational/DS
+ *
+ */
+public class StatListenCommitMeter extends StatAbstractListenCommit<Meter, OpendaylightMeterStatisticsListener>
+ implements OpendaylightMeterStatisticsListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StatListenCommitMeter.class);
+
+ public StatListenCommitMeter(final StatisticsManager manager, final DataBroker db,
+ final NotificationProviderService nps) {
+ super(manager, db, nps, Meter.class);
+ }
+
+ @Override
+ protected InstanceIdentifier<Meter> getWildCardedRegistrationPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class).child(Meter.class);
+ }
+
+ @Override
+ protected OpendaylightMeterStatisticsListener getStatNotificationListener() {
+ return this;
+ }
+
+ @Override
+ public void onMeterConfigStatsUpdated(final MeterConfigStatsUpdated notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - MeterConfigStatsUpdated: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ if (notification.isMoreReplies()) {
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ return;
+ }
+ final List<MeterConfigStats> meterConfStat = notification.getMeterConfigStats() != null
+ ? new ArrayList<>(notification.getMeterConfigStats()) : new ArrayList<MeterConfigStats>(10);
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if (txContainer.isPresent()) {
+ final List<? extends TransactionAware> cacheNotifs = txContainer.get().getNotifications();
+ for (final TransactionAware notif : cacheNotifs) {
+ if (notif instanceof MeterConfigStatsUpdated) {
+ meterConfStat.addAll(((MeterConfigStatsUpdated) notif).getMeterConfigStats());
+ }
+ }
+ }
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId));
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+ /* Notification for continue collecting statistics */
+ notifyToCollectNextStatistics(nodeIdent);
+ comitConfMeterStats(meterConfStat, nodeIdent, tx);
+ }
+ });
+ }
+
+ @Override
+ public void onMeterFeaturesUpdated(final MeterFeaturesUpdated notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - MeterFeaturesUpdated: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ if (notification.isMoreReplies()) {
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ return;
+ }
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if ( ! txContainer.isPresent()) {
+ return;
+ }
+ final MeterFeatures stats = new MeterFeaturesBuilder(notification).build();
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier
+ .create(Nodes.class).child(Node.class, new NodeKey(nodeId));
+ final InstanceIdentifier<MeterFeatures> meterFeatureIdent = nodeIdent
+ .augmentation(NodeMeterFeatures.class).child(MeterFeatures.class);
+
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+ /* Notification for continue collecting statistics */
+ notifyToCollectNextStatistics(nodeIdent);
+ Optional<Node> node = Optional.absent();
+ try {
+ node = tx.read(LogicalDatastoreType.OPERATIONAL, nodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for Node fail! {}", nodeIdent, e);
+ }
+ if (node.isPresent()) {
+ tx.put(LogicalDatastoreType.OPERATIONAL, meterFeatureIdent, stats);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onMeterStatisticsUpdated(final MeterStatisticsUpdated notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - MeterStatisticsUpdated: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ if (notification.isMoreReplies()) {
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ return;
+ }
+ final List<MeterStats> meterStat = notification.getMeterStats() != null
+ ? new ArrayList<>(notification.getMeterStats()) : new ArrayList<MeterStats>(10);
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if (txContainer.isPresent()) {
+ final List<? extends TransactionAware> cacheNotifs = txContainer.get().getNotifications();
+ for (final TransactionAware notif : cacheNotifs) {
+ if (notif instanceof MeterConfigStatsUpdated) {
+ meterStat.addAll(((MeterStatisticsUpdated) notif).getMeterStats());
+ }
+ }
+ }
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId));
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+ statMeterCommit(meterStat, nodeIdent, tx);
+ /* Notification for continue collecting statistics */
+ notifyToCollectNextStatistics(nodeIdent);
+ }
+ });
+ }
+
+ private void statMeterCommit(final List<MeterStats> meterStats,
+ final InstanceIdentifier<Node> nodeIdent, final ReadWriteTransaction trans) {
+
+ final InstanceIdentifier<FlowCapableNode> fNodeIdent = nodeIdent.augmentation(FlowCapableNode.class);
+ for (final MeterStats mStat : meterStats) {
+ final MeterStatistics stats = new MeterStatisticsBuilder(mStat).build();
+
+ final MeterKey mKey = new MeterKey(mStat.getMeterId());
+ final InstanceIdentifier<MeterStatistics> msIdent = fNodeIdent
+ .child(Meter.class, mKey).augmentation(NodeMeterStatistics.class)
+ .child(MeterStatistics.class);
+ /* Meter Statistics commit */
+ Optional<FlowCapableNode> fNode = Optional.absent();
+ try {
+ fNode = trans.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for FlowCapableNode fail! {}", fNodeIdent, e);
+ }
+ if (fNode.isPresent()) {
+ trans.put(LogicalDatastoreType.OPERATIONAL, msIdent, stats);
+ }
+ }
+ }
+
+ private void comitConfMeterStats(final List<MeterConfigStats> meterConfStat,
+ final InstanceIdentifier<Node> nodeIdent, final ReadWriteTransaction trans) {
+
+ final InstanceIdentifier<FlowCapableNode> fNodeIdent = nodeIdent.augmentation(FlowCapableNode.class);
+ final List<MeterKey> deviceMeterKeys = new ArrayList<>();
+
+ for (final MeterConfigStats meterConf : meterConfStat) {
+ final MeterBuilder meterBuilder = new MeterBuilder(meterConf);
+ if (meterConf.getMeterId() != null) {
+ final MeterKey meterKey = new MeterKey(meterConf.getMeterId());
+ meterBuilder.setKey(meterKey);
+ final InstanceIdentifier<Meter> meterRef = nodeIdent
+ .augmentation(FlowCapableNode.class).child(Meter.class,meterKey);
+ final NodeMeterConfigStatsBuilder meterConfig = new NodeMeterConfigStatsBuilder();
+ meterConfig.setMeterConfigStats(new MeterConfigStatsBuilder(meterConf).build());
+ //Update augmented data
+ meterBuilder.addAugmentation(NodeMeterConfigStats.class, meterConfig.build());
+ deviceMeterKeys.add(meterKey);
+ Optional<FlowCapableNode> fNode = Optional.absent();
+ try {
+ fNode = trans.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for FlowCapableNode fail! {}", fNodeIdent, e);
+ }
+ if (fNode.isPresent()) {
+ trans.put(LogicalDatastoreType.OPERATIONAL, meterRef, meterBuilder.build());
+ }
+ }
+ }
+ /* Delete all not presented Meter Nodes */
+ deleteAllNotPresentedNodes(fNodeIdent, trans, deviceMeterKeys);
+ }
+
+ private void deleteAllNotPresentedNodes(final InstanceIdentifier<FlowCapableNode> fNodeIdent,
+ final ReadWriteTransaction trans, final List<MeterKey> deviceMeterKeys) {
+ /* Delete all not presented meters */
+ final Optional<FlowCapableNode> fNode = readLatestConfiguration(fNodeIdent);
+
+ if ( ! fNode.isPresent()) {
+ LOG.trace("Read Operational/DS for FlowCapableNode fail! Node {} doesn't exist.", fNodeIdent);
+ return;
+ }
+ final List<Meter> existMeters = fNode.get().getMeter() != null
+ ? fNode.get().getMeter() : Collections.<Meter> emptyList();
+ /* Add all existed groups paths - no updated paths has to be removed */
+ for (final Meter meter : existMeters) {
+ if (deviceMeterKeys.remove(meter.getKey())) {
+ break; // Meter still exist on device
+ }
+ final InstanceIdentifier<Meter> delMeterIdent = fNodeIdent.child(Meter.class, meter.getKey());
+ Optional<Meter> delMeter = Optional.absent();
+ try {
+ delMeter = trans.read(LogicalDatastoreType.OPERATIONAL, delMeterIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ // NOOP - probably another transaction delete that node
+ }
+ if (delMeter.isPresent()) {
+ trans.delete(LogicalDatastoreType.OPERATIONAL, delMeterIdent);
+ }
+ }
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager.StatDataStoreOperation;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatNotifyCommitQueue
+ * Class is a NotifyListner for Queues Statistics
+ * All expected (registered) queueStatistics will be builded and
+ * commit to Operational/DataStore
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class StatListenCommitQueue extends StatAbstractListenCommit<Queue, OpendaylightQueueStatisticsListener>
+ implements OpendaylightQueueStatisticsListener {
+
+ private final static Logger LOG = LoggerFactory.getLogger(StatListenCommitQueue.class);
+
+ public StatListenCommitQueue(final StatisticsManager manager, final DataBroker db,
+ final NotificationProviderService nps) {
+ super(manager, db, nps, Queue.class);
+ }
+
+ @Override
+ protected OpendaylightQueueStatisticsListener getStatNotificationListener() {
+ return this;
+ }
+
+ @Override
+ protected InstanceIdentifier<Queue> getWildCardedRegistrationPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class)
+ .augmentation(FlowCapableNodeConnector.class).child(Queue.class);
+ }
+
+ @Override
+ public void onQueueStatisticsUpdate(final QueueStatisticsUpdate notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - QueueStatisticsUpdate: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ if (notification.isMoreReplies()) {
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ return;
+ }
+ final List<QueueIdAndStatisticsMap> queueStats = notification.getQueueIdAndStatisticsMap() != null
+ ? new ArrayList<>(notification.getQueueIdAndStatisticsMap()) : new ArrayList<QueueIdAndStatisticsMap>(10);
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if (txContainer.isPresent()) {
+ final List<? extends TransactionAware> cachedNotifs =
+ txContainer.get().getNotifications();
+ for (final TransactionAware notif : cachedNotifs) {
+ if (notif instanceof QueueStatisticsUpdate) {
+ queueStats.addAll(((QueueStatisticsUpdate) notif).getQueueIdAndStatisticsMap());
+ }
+ }
+ }
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId));
+ /* Queue statistics are small size and we are not able to change for OF cross controller
+ * - don't need to make are atomic */
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction trans) {
+ /* Notification for continue */
+ notifyToCollectNextStatistics(nodeIdent);
+ statQueueCommit(queueStats, nodeIdent, trans);
+ }
+ });
+ }
+
+ private void statQueueCommit(final List<QueueIdAndStatisticsMap> queueStats,
+ final InstanceIdentifier<Node> nodeIdent, final ReadWriteTransaction trans) {
+
+ /* check exist FlowCapableNode and write statistics */
+ Optional<Node> fNode = Optional.absent();
+ try {
+ fNode = trans.read(LogicalDatastoreType.OPERATIONAL, nodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for Node fail! {}", nodeIdent, e);
+ return;
+ }
+ if ( ! fNode.isPresent()) {
+ LOG.trace("Read Operational/DS for Node fail! Node {} doesn't exist.", nodeIdent);
+ return;
+ }
+
+ for (final QueueIdAndStatisticsMap queueEntry : queueStats) {
+ final FlowCapableNodeConnectorQueueStatistics statChild =
+ new FlowCapableNodeConnectorQueueStatisticsBuilder(queueEntry).build();
+ final FlowCapableNodeConnectorQueueStatisticsDataBuilder statBuild =
+ new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
+ statBuild.setFlowCapableNodeConnectorQueueStatistics(statChild);
+ final QueueKey qKey = new QueueKey(queueEntry.getQueueId());
+ final InstanceIdentifier<FlowCapableNodeConnectorQueueStatisticsData> queueStatIdent = nodeIdent
+ .child(NodeConnector.class, new NodeConnectorKey(queueEntry.getNodeConnectorId()))
+ .augmentation(FlowCapableNodeConnector.class)
+ .child(Queue.class, qKey).augmentation(FlowCapableNodeConnectorQueueStatisticsData.class);
+ trans.put(LogicalDatastoreType.OPERATIONAL, queueStatIdent, statBuild.build());
+ }
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+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.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatNodeRegistration;
+import org.opendaylight.controller.md.statistics.manager.StatPermCollector.StatCapabTypes;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager.StatDataStoreOperation;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityFlowStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityGroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityPortStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityQueueStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityTableStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SwitchFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatNodeRegistrationImpl
+ * {@link FlowCapableNode} Registration Implementation contains two method for registration/unregistration
+ * {@link FeatureCapability} for every connect/disconnect {@link FlowCapableNode}. Process of connection/disconnection
+ * is substituted by listening Operation/DS for add/delete {@link FeatureCapability}.
+ * All statistic capabilities are reading from new Node directly without contacting device or DS.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 28, 2014
+ */
+public class StatNodeRegistrationImpl implements StatNodeRegistration {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StatNodeRegistrationImpl.class);
+
+ private final StatisticsManager manager;
+ private ListenerRegistration<DataChangeListener> listenerRegistration;
+ private ListenerRegistration<?> notifListenerRegistration;
+
+ public StatNodeRegistrationImpl(final StatisticsManager manager, final DataBroker db,
+ final NotificationProviderService notificationService) {
+ this.manager = Preconditions.checkNotNull(manager, "StatisticManager can not be null!");
+ Preconditions.checkArgument(db != null, "DataBroker can not be null!");
+ Preconditions.checkArgument(notificationService != null, "NotificationProviderService can not be null!");
+ notifListenerRegistration = notificationService.registerNotificationListener(this);
+ }
+
+ @Override
+ public void close() throws Exception {
+
+ if (notifListenerRegistration != null) {
+ try {
+ notifListenerRegistration.close();
+ }
+ catch (final Exception e) {
+ LOG.warn("Error by stop FlowCapableNode Notification StatNodeRegistration.");
+ }
+ notifListenerRegistration = null;
+ }
+
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.warn("Error by stop FlowCapableNode DataChange StatListeningCommiter.", e);
+ }
+ listenerRegistration = null;
+ }
+ }
+
+ @Override
+ public void connectFlowCapableNode(final InstanceIdentifier<SwitchFeatures> keyIdent,
+ final SwitchFeatures data, final InstanceIdentifier<Node> nodeIdent) {
+ Preconditions.checkNotNull(keyIdent, "InstanceIdentifier can not be null!");
+ Preconditions.checkNotNull(data, "SwitchFeatures data for {} can not be null!", keyIdent);
+ Preconditions.checkArgument(( ! keyIdent.isWildcarded()), "InstanceIdentifier is WildCarded!");
+
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+
+ final List<StatCapabTypes> statCapabTypes = new ArrayList<>();
+ Short maxCapTables = Short.valueOf("1");
+
+ final List<Class<? extends FeatureCapability>> capabilities = data.getCapabilities() != null
+ ? data.getCapabilities() : Collections.<Class<? extends FeatureCapability>> emptyList();
+ for (final Class<? extends FeatureCapability> capability : capabilities) {
+ if (capability == FlowFeatureCapabilityTableStats.class) {
+ statCapabTypes.add(StatCapabTypes.TABLE_STATS);
+ } else if (capability == FlowFeatureCapabilityFlowStats.class) {
+ statCapabTypes.add(StatCapabTypes.FLOW_STATS);
+ } else if (capability == FlowFeatureCapabilityGroupStats.class) {
+ statCapabTypes.add(StatCapabTypes.GROUP_STATS);
+ } else if (capability == FlowFeatureCapabilityPortStats.class) {
+ statCapabTypes.add(StatCapabTypes.PORT_STATS);
+ } else if (capability == FlowFeatureCapabilityQueueStats.class) {
+ statCapabTypes.add(StatCapabTypes.QUEUE_STATS);
+ }
+ }
+ maxCapTables = data.getMaxTables();
+
+ final Optional<Short> maxTables = Optional.<Short> of(maxCapTables);
+
+ /* Meters management */
+ final InstanceIdentifier<NodeMeterFeatures> meterFeaturesIdent = nodeIdent.augmentation(NodeMeterFeatures.class);
+
+
+ Optional<NodeMeterFeatures> meterFeatures = Optional.absent();
+ try {
+ meterFeatures = tx.read(LogicalDatastoreType.OPERATIONAL, meterFeaturesIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.warn("Read NodeMeterFeatures {} fail!", meterFeaturesIdent, e);
+ }
+ if (meterFeatures.isPresent()) {
+ statCapabTypes.add(StatCapabTypes.METER_STATS);
+ }
+ manager.connectedNodeRegistration(nodeIdent,
+ Collections.unmodifiableList(statCapabTypes), maxTables.get());
+ }
+ });
+ }
+
+ @Override
+ public void disconnectFlowCapableNode(final InstanceIdentifier<Node> nodeIdent) {
+ Preconditions.checkArgument(nodeIdent != null, "InstanceIdentifier can not be NULL!");
+ Preconditions.checkArgument(( ! nodeIdent.isWildcarded()),
+ "InstanceIdentifier {} is WildCarded!", nodeIdent);
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction tx) {
+ manager.disconnectedNodeUnregistration(nodeIdent);
+ }
+ });
+ }
+
+
+ @Override
+ public void onNodeConnectorRemoved(final NodeConnectorRemoved notification) {
+ // NOOP
+ }
+
+ @Override
+ public void onNodeConnectorUpdated(final NodeConnectorUpdated notification) {
+ // NOOP
+ }
+
+ @Override
+ public void onNodeRemoved(final NodeRemoved notification) {
+ final NodeRef nodeRef = notification.getNodeRef();
+ final InstanceIdentifier<?> nodeRefIdent = nodeRef.getValue();
+ final InstanceIdentifier<Node> nodeIdent =
+ nodeRefIdent.firstIdentifierOf(Node.class);
+ if (nodeIdent != null) {
+ disconnectFlowCapableNode(nodeIdent);
+ }
+ }
+
+ @Override
+ public void onNodeUpdated(final NodeUpdated notification) {
+ final FlowCapableNodeUpdated newFlowNode =
+ notification.getAugmentation(FlowCapableNodeUpdated.class);
+ if (newFlowNode != null && newFlowNode.getSwitchFeatures() != null) {
+ final NodeRef nodeRef = notification.getNodeRef();
+ final InstanceIdentifier<?> nodeRefIdent = nodeRef.getValue();
+ final InstanceIdentifier<Node> nodeIdent =
+ nodeRefIdent.firstIdentifierOf(Node.class);
+
+ final InstanceIdentifier<SwitchFeatures> swichFeaturesIdent =
+ nodeIdent.augmentation(FlowCapableNode.class).child(SwitchFeatures.class);
+ final SwitchFeatures switchFeatures = newFlowNode.getSwitchFeatures();
+ connectFlowCapableNode(swichFeaturesIdent, switchFeatures, nodeIdent);
+ }
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager.StatDataStoreOperation;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatNotifyCommitPort
+ * Class is a NotifyListener for PortStatistics
+ * All expected (registered) portStatistics will be builded and
+ * commit to Operational/DataStore
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class StatNotifyCommitPort extends StatAbstractNotifyCommit<OpendaylightPortStatisticsListener>
+ implements OpendaylightPortStatisticsListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StatNotifyCommitPort.class);
+
+ public StatNotifyCommitPort(final StatisticsManager manager,
+ final NotificationProviderService nps) {
+ super(manager, nps);
+ }
+
+ @Override
+ protected OpendaylightPortStatisticsListener getStatNotificationListener() {
+ return this;
+ }
+
+ @Override
+ public void onNodeConnectorStatisticsUpdate(final NodeConnectorStatisticsUpdate notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - NodeConnectorStatisticsUpdate: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ if (notification.isMoreReplies()) {
+ return;
+ }
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId));
+ /* Don't block RPC Notification thread */
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction trans) {
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ if (( ! txContainer.isPresent()) || txContainer.get().getNotifications() == null) {
+ return;
+ }
+ final List<NodeConnectorStatisticsAndPortNumberMap> portStats =
+ new ArrayList<NodeConnectorStatisticsAndPortNumberMap>(10);
+ final List<? extends TransactionAware> cachedNotifs = txContainer.get().getNotifications();
+ for (final TransactionAware notif : cachedNotifs) {
+ if (notif instanceof NodeConnectorStatisticsUpdate) {
+ final List<NodeConnectorStatisticsAndPortNumberMap> notifStat =
+ ((NodeConnectorStatisticsUpdate) notif).getNodeConnectorStatisticsAndPortNumberMap();
+ if (notifStat != null) {
+ portStats.addAll(notifStat);
+ }
+ }
+ }
+ /* write stat to trans */
+ statPortCommit(portStats, nodeIdent, trans);
+ /* Notification for continue collecting statistics - Port statistics are still same size
+ * and they are small - don't need to wait for whole apply operation*/
+ notifyToCollectNextStatistics(nodeIdent);
+ }
+ });
+ }
+
+ private void statPortCommit(final List<NodeConnectorStatisticsAndPortNumberMap> portStats,
+ final InstanceIdentifier<Node> nodeIdent, final ReadWriteTransaction tx) {
+
+ /* check exist FlowCapableNode and write statistics probable with parent */
+ Optional<Node> fNode = Optional.absent();
+ try {
+ fNode = tx.read(LogicalDatastoreType.OPERATIONAL, nodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for Node fail! {}", nodeIdent, e);
+ return;
+ }
+ if ( ! fNode.isPresent()) {
+ LOG.trace("Read Operational/DS for Node fail! Node {} doesn't exist.", nodeIdent);
+ return;
+ }
+ for (final NodeConnectorStatisticsAndPortNumberMap nConnectPort : portStats) {
+ final FlowCapableNodeConnectorStatistics stats = new FlowCapableNodeConnectorStatisticsBuilder(nConnectPort).build();
+ final NodeConnectorKey key = new NodeConnectorKey(nConnectPort.getNodeConnectorId());
+ final InstanceIdentifier<NodeConnector> nodeConnectorIdent = nodeIdent.child(NodeConnector.class, key);
+ final InstanceIdentifier<FlowCapableNodeConnectorStatisticsData> nodeConnStatIdent = nodeConnectorIdent
+ .augmentation(FlowCapableNodeConnectorStatisticsData.class);
+ final InstanceIdentifier<FlowCapableNodeConnectorStatistics> flowCapNodeConnStatIdent =
+ nodeConnStatIdent.child(FlowCapableNodeConnectorStatistics.class);
+ Optional<NodeConnector> fNodeConector;
+ try {
+ fNodeConector = tx.read(LogicalDatastoreType.OPERATIONAL, nodeConnectorIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read NodeConnector {} in Operational/DS fail!", nodeConnectorIdent, e);
+ fNodeConector = Optional.absent();
+ }
+ if (fNodeConector.isPresent()) {
+ tx.merge(LogicalDatastoreType.OPERATIONAL, nodeConnectorIdent, new NodeConnectorBuilder().setId(key.getId()).build());
+ tx.merge(LogicalDatastoreType.OPERATIONAL, nodeConnStatIdent, new FlowCapableNodeConnectorStatisticsDataBuilder().build());
+ tx.put(LogicalDatastoreType.OPERATIONAL, flowCapNodeConnStatIdent, stats);
+ }
+ }
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager.StatDataStoreOperation;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatNotifyCommitTable
+ * Class is a NotifyListener for TableStatistics
+ * All expected (registered) tableStatistics will be builded and
+ * commit to Operational/DataStore
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class StatNotifyCommitTable extends StatAbstractNotifyCommit<OpendaylightFlowTableStatisticsListener>
+ implements OpendaylightFlowTableStatisticsListener {
+
+ private final static Logger LOG = LoggerFactory.getLogger(StatNotifyCommitTable.class);
+
+ public StatNotifyCommitTable(final StatisticsManager manager,
+ final NotificationProviderService nps) {
+ super(manager, nps);
+ }
+
+ @Override
+ protected OpendaylightFlowTableStatisticsListener getStatNotificationListener() {
+ return this;
+ }
+
+ @Override
+ public void onFlowTableStatisticsUpdate(final FlowTableStatisticsUpdate notification) {
+ final TransactionId transId = notification.getTransactionId();
+ final NodeId nodeId = notification.getId();
+ if ( ! isExpectedStatistics(transId, nodeId)) {
+ LOG.debug("STAT-MANAGER - FlowTableStatisticsUpdate: unregistred notification detect TransactionId {}", transId);
+ return;
+ }
+ manager.getRpcMsgManager().addNotification(notification, nodeId);
+ if (notification.isMoreReplies()) {
+ return;
+ }
+ /* Don't block RPC Notification thread */
+ manager.enqueue(new StatDataStoreOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction trans) {
+ final List<FlowTableAndStatisticsMap> tableStats = new ArrayList<FlowTableAndStatisticsMap>(10);
+ final Optional<TransactionCacheContainer<?>> txContainer = getTransactionCacheContainer(transId, nodeId);
+ final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId));
+ if (( ! txContainer.isPresent()) || txContainer.get().getNodeId() == null) {
+ return;
+ }
+ final List<? extends TransactionAware> cachedNotifs = txContainer.get().getNotifications();
+ for (final TransactionAware notif : cachedNotifs) {
+ if (notif instanceof FlowTableStatisticsUpdate) {
+ final List<FlowTableAndStatisticsMap> statNotif =
+ ((FlowTableStatisticsUpdate) notif).getFlowTableAndStatisticsMap();
+ if (statNotif != null) {
+ tableStats.addAll(statNotif);
+ }
+ }
+ }
+ /* write stat to trans */
+ statTableCommit(tableStats, nodeIdent, trans);
+ /* Notification for continue collecting statistics - Tables statistics are still same size
+ * and they are small - don't need to wait to whole apply operation */
+ notifyToCollectNextStatistics(nodeIdent);
+ }
+ });
+ }
+
+ private void statTableCommit(final List<FlowTableAndStatisticsMap> tableStats, final InstanceIdentifier<Node> nodeIdent,
+ final ReadWriteTransaction trans) {
+ final InstanceIdentifier<FlowCapableNode> fNodeIdent = nodeIdent.augmentation(FlowCapableNode.class);
+ /* check flow Capable Node and write statistics */
+ Optional<FlowCapableNode> fNode = Optional.absent();
+ try {
+ fNode = trans.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet();
+ }
+ catch (final ReadFailedException e) {
+ LOG.debug("Read Operational/DS for FlowCapableNode fail! {}", fNodeIdent, e);
+ return;
+ }
+ if ( ! fNode.isPresent()) {
+ LOG.trace("Read Operational/DS for FlowCapableNode fail! Node {} doesn't exist.", fNodeIdent);
+ return;
+ }
+ for (final FlowTableAndStatisticsMap tableStat : tableStats) {
+ final InstanceIdentifier<Table> tableIdent = fNodeIdent
+ .child(Table.class, new TableKey(tableStat.getTableId().getValue()));
+ final Table table = new TableBuilder().setId(tableStat.getTableId().getValue()).build();
+ trans.merge(LogicalDatastoreType.OPERATIONAL, tableIdent, table);
+ final InstanceIdentifier<FlowTableStatisticsData> tableStatIdent = tableIdent
+ .augmentation(FlowTableStatisticsData.class);
+ trans.merge(LogicalDatastoreType.OPERATIONAL, tableStatIdent, new FlowTableStatisticsDataBuilder().build());
+
+ final FlowTableStatistics stats = new FlowTableStatisticsBuilder(tableStat).build();
+ final InstanceIdentifier<FlowTableStatistics> tStatIdent = tableStatIdent.child(FlowTableStatistics.class);
+ trans.put(LogicalDatastoreType.OPERATIONAL, tStatIdent, stats);
+ }
+ }
+}
+
--- /dev/null
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+import org.opendaylight.controller.md.statistics.manager.StatPermCollector;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatPermCollectorImpl
+ * Thread base statistic collector. Class holds internal map for all registered
+ * (means connected) nodes with List of Switch capabilities;
+ * Statistics collecting process get cross whole Network Device by device
+ * and statistic by statistic (follow Switch capabilities to prevent unnecessary
+ * ask) Next statistic start collecting by notification or by timeout.
+ *
+ * @author @author avishnoi@in.ibm.com <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class StatPermCollectorImpl implements StatPermCollector {
+
+ private final static Logger LOG = LoggerFactory.getLogger(StatPermCollectorImpl.class);
+
+ private final static long STAT_COLLECT_TIME_OUT = 30000L;
+
+ private final ExecutorService statNetCollectorServ;
+ private final StatisticsManager manager;
+
+ private final int maxNodeForCollector;
+ private final long minReqNetInterval;
+ private final String name;
+
+ private final Object statCollectorLock = new Object();
+ private final Object statNodeHolderLock = new Object();
+
+ private Map<InstanceIdentifier<Node>, StatNodeInfoHolder> statNodeHolder =
+ Collections.<InstanceIdentifier<Node>, StatNodeInfoHolder> emptyMap();
+
+ private volatile boolean wakeMe = false;
+ private volatile boolean finishing = false;
+
+ public StatPermCollectorImpl(final StatisticsManager manager, final long minReqNetInterv, final int nr,
+ final int maxNodeForCollectors) {
+ this.manager = Preconditions.checkNotNull(manager, "StatisticsManager can not be null!");
+ name = "odl-stat-collector-" + nr;
+ minReqNetInterval = minReqNetInterv;
+ final ThreadFactory threadFact = new ThreadFactoryBuilder()
+ .setNameFormat(name + "-thread-%d").build();
+ statNetCollectorServ = Executors.newSingleThreadExecutor(threadFact);
+ maxNodeForCollector = maxNodeForCollectors;
+ LOG.trace("StatCollector {} start successfull!", name);
+ }
+
+ /**
+ * finish collecting statistics
+ */
+ @Override
+ public void close() {
+ statNodeHolder = Collections.<InstanceIdentifier<Node>, StatNodeInfoHolder> emptyMap();
+ finishing = true;
+ collectNextStatistics();
+ statNetCollectorServ.shutdown();
+ }
+
+ @Override
+ public boolean isProvidedFlowNodeActive(
+ final InstanceIdentifier<Node> flowNode) {
+ return statNodeHolder.containsKey(flowNode);
+ }
+
+ @Override
+ public boolean connectedNodeRegistration(final InstanceIdentifier<Node> ident,
+ final List<StatCapabTypes> statTypes, final Short nrOfSwitchTables) {
+ if (ident.isWildcarded()) {
+ LOG.warn("FlowCapableNode IstanceIdentifier {} registration can not be wildcarded!", ident);
+ } else {
+ if ( ! statNodeHolder.containsKey(ident)) {
+ synchronized (statNodeHolderLock) {
+ final boolean startStatCollecting = statNodeHolder.size() == 0;
+ if ( ! statNodeHolder.containsKey(ident)) {
+ if (statNodeHolder.size() >= maxNodeForCollector) {
+ return false;
+ }
+ final Map<InstanceIdentifier<Node>, StatNodeInfoHolder> statNode =
+ new HashMap<>(statNodeHolder);
+ final NodeRef nodeRef = new NodeRef(ident);
+ final StatNodeInfoHolder nodeInfoHolder = new StatNodeInfoHolder(nodeRef,
+ statTypes, nrOfSwitchTables);
+ statNode.put(ident, nodeInfoHolder);
+ statNodeHolder = Collections.unmodifiableMap(statNode);
+ }
+ if (startStatCollecting) {
+ finishing = false;
+ statNetCollectorServ.execute(this);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean disconnectedNodeUnregistration(final InstanceIdentifier<Node> ident) {
+ if (ident.isWildcarded()) {
+ LOG.warn("FlowCapableNode IstanceIdentifier {} unregistration can not be wildcarded!", ident);
+ } else {
+ if (statNodeHolder.containsKey(ident)) {
+ synchronized (statNodeHolderLock) {
+ if (statNodeHolder.containsKey(ident)) {
+ final Map<InstanceIdentifier<Node>, StatNodeInfoHolder> statNode =
+ new HashMap<>(statNodeHolder);
+ statNode.remove(ident);
+ statNodeHolder = Collections.unmodifiableMap(statNode);
+ }
+ if (statNodeHolder.isEmpty()) {
+ finishing = true;
+ collectNextStatistics();
+ statNetCollectorServ.shutdown();
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void collectNextStatistics() {
+ if (wakeMe) {
+ synchronized (statCollectorLock) {
+ if (wakeMe) {
+ LOG.trace("STAT-COLLECTOR is notified to conntinue");
+ statCollectorLock.notify();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(5000);
+ }
+ catch (final InterruptedException e1) {
+ // NOOP
+ }
+ LOG.debug("StatCollector {} Start collecting!", name);
+ /* Neverending cyle - wait for finishing */
+ while ( ! finishing) {
+ boolean collecting = false;
+ final long startTime = System.currentTimeMillis();
+
+ if ( ! statNodeHolder.isEmpty()) {
+ collecting = true;
+ collectStatCrossNetwork();
+ collecting = false;
+ }
+
+ if ( ! collecting) {
+ final long statFinalTime = System.currentTimeMillis() - startTime;
+ LOG.debug("STAT-MANAGER {}: last all NET statistics collection cost {} ms", name, statFinalTime);
+ if (statFinalTime < minReqNetInterval) {
+ LOG.trace("statCollector is about to make a collecting sleep");
+ synchronized (statCollectorLock) {
+ wakeMe = true;
+ try {
+ final long waitTime = minReqNetInterval - statFinalTime;
+ statCollectorLock.wait(waitTime);
+ LOG.trace("STAT-MANAGER : statCollector {} is waking up from a collecting sleep for {} ms", name, waitTime);
+ } catch (final InterruptedException e) {
+ LOG.warn("statCollector has been interrupted during collecting sleep", e);
+ } finally {
+ wakeMe = false;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void waitingForNotification() {
+ synchronized (statCollectorLock) {
+ wakeMe = true;
+ try {
+ statCollectorLock.wait(STAT_COLLECT_TIME_OUT);
+ LOG.trace("statCollector is waking up from a wait stat Response sleep");
+ } catch (final InterruptedException e) {
+ LOG.warn("statCollector has been interrupted waiting stat Response sleep", e);
+ } finally {
+ wakeMe = false;
+ }
+ }
+ }
+
+
+ private void collectStatCrossNetwork() {
+ for (final Entry<InstanceIdentifier<Node>, StatNodeInfoHolder> nodeEntity : statNodeHolder.entrySet()) {
+ final List<StatCapabTypes> listNeededStat = nodeEntity.getValue().getStatMarkers();
+ final NodeRef actualNodeRef = nodeEntity.getValue().getNodeRef();
+ final Short maxTables = nodeEntity.getValue().getMaxTables();
+ for (final StatCapabTypes statMarker : listNeededStat) {
+ if ( ! isProvidedFlowNodeActive(nodeEntity.getKey())) {
+ break;
+ }
+ switch (statMarker) {
+ case PORT_STATS:
+ LOG.trace("STAT-MANAGER-collecting PORT-STATS for NodeRef {}", actualNodeRef);
+ manager.getRpcMsgManager().getAllPortsStat(actualNodeRef);
+ waitingForNotification();
+ break;
+ case QUEUE_STATS:
+ LOG.trace("STAT-MANAGER-collecting QUEUE-STATS for NodeRef {}", actualNodeRef);
+ manager.getRpcMsgManager().getAllQueueStat(actualNodeRef);
+ waitingForNotification();
+ break;
+ case TABLE_STATS:
+ LOG.trace("STAT-MANAGER-collecting TABLE-STATS for NodeRef {}", actualNodeRef);
+ manager.getRpcMsgManager().getAllTablesStat(actualNodeRef);
+ waitingForNotification();
+ break;
+ case GROUP_STATS:
+ LOG.trace("STAT-MANAGER-collecting GROUP-STATS for NodeRef {}", actualNodeRef);
+ manager.getRpcMsgManager().getGroupFeaturesStat(actualNodeRef);
+ waitingForNotification();
+ manager.getRpcMsgManager().getAllGroupsConfStats(actualNodeRef);
+ waitingForNotification();
+ manager.getRpcMsgManager().getAllGroupsStat(actualNodeRef);
+ waitingForNotification();
+ break;
+ case METER_STATS:
+ LOG.trace("STAT-MANAGER-collecting METER-STATS for NodeRef {}", actualNodeRef);
+ manager.getRpcMsgManager().getMeterFeaturesStat(actualNodeRef);
+ waitingForNotification();
+ manager.getRpcMsgManager().getAllMeterConfigStat(actualNodeRef);
+ waitingForNotification();
+ manager.getRpcMsgManager().getAllMetersStat(actualNodeRef);
+ waitingForNotification();
+ break;
+ case FLOW_STATS:
+ LOG.trace("STAT-MANAGER-collecting FLOW-STATS-ALL_FLOWS for NodeRef {}", actualNodeRef);
+ manager.getRpcMsgManager().getAllFlowsStat(actualNodeRef);
+ waitingForNotification();
+ LOG.trace("STAT-MANAGER-collecting FLOW-AGGREGATE-STATS for NodeRef {}", actualNodeRef);
+ for (short i = 0; i < maxTables; i++) {
+ final TableId tableId = new TableId(i);
+ manager.getRpcMsgManager().getAggregateFlowStat(actualNodeRef, tableId);
+ }
+ break;
+ default:
+ /* Exception for programmers in implementation cycle */
+ throw new IllegalStateException("Not implemented ASK for " + statMarker);
+ }
+ }
+ }
+ }
+
+ private class StatNodeInfoHolder {
+ private final NodeRef nodeRef;
+ private final List<StatCapabTypes> statMarkers;
+ private final Short maxTables;
+
+ public StatNodeInfoHolder(final NodeRef nodeRef,
+ final List<StatCapabTypes> statMarkers, final Short maxTables) {
+ this.nodeRef = nodeRef;
+ this.maxTables = maxTables;
+ this.statMarkers = statMarkers;
+ }
+
+ public final NodeRef getNodeRef() {
+ return nodeRef;
+ }
+
+ public final List<StatCapabTypes> getStatMarkers() {
+ return statMarkers;
+ }
+
+ public final Short getMaxTables() {
+ return maxTables;
+ }
+ }
+
+ @Override
+ public boolean hasActiveNodes() {
+ return ( ! statNodeHolder.isEmpty());
+ }
+}
+
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.Collection;
+package org.opendaylight.controller.md.statistics.manager.impl;
import org.opendaylight.yangtools.yang.common.RpcError;
-final class RPCFailedException extends RuntimeException {
+import java.util.Collection;
+
+public final class StatRPCFailedException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final Collection<RpcError> errors;
- public RPCFailedException(final String message, final Collection<RpcError> errors) {
+ public StatRPCFailedException(final String message, final Collection<RpcError> errors) {
super(message);
this.errors = errors;
}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.SettableFuture;
+
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager.impl
+ *
+ * StatRpcMsgManagerImpl
+ * Class register and provide all RPC Statistics Device Services and implement pre-defined
+ * wrapped methods for prepare easy access to RPC Statistics Device Services like getAllStatisticsFor...
+ *
+ * In next Class implement process for joining multipart messages.
+ * Class internally use two WeakHashMap and GuavaCache for holding values for joining multipart msg.
+ * One Weak map is used for holding all Multipart Messages and second is used for possible input
+ * Config/DS light-weight DataObject (DataObject contains only necessary identification fields as
+ * TableId, GroupId, MeterId or for flow Match, Priority, FlowCookie, TableId and FlowId ...
+ *
+ * @author avishnoi@in.ibm.com <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
+
+ private final static Logger LOG = LoggerFactory.getLogger(StatRpcMsgManagerImpl.class);
+
+ private final Cache<String, TransactionCacheContainer<? super TransactionAware>> txCache;
+
+ private final long maxLifeForRequest = 50; /* 50 second */
+ private final int queueCapacity = 5000;
+
+ private final OpendaylightGroupStatisticsService groupStatsService;
+ private final OpendaylightMeterStatisticsService meterStatsService;
+ private final OpendaylightFlowStatisticsService flowStatsService;
+ private final OpendaylightPortStatisticsService portStatsService;
+ private final OpendaylightFlowTableStatisticsService flowTableStatsService;
+ private final OpendaylightQueueStatisticsService queueStatsService;
+
+ private BlockingQueue<RpcJobsQueue> statsRpcJobQueue;
+
+ private volatile boolean finishing = false;
+
+ public StatRpcMsgManagerImpl (final StatisticsManager manager,
+ final RpcConsumerRegistry rpcRegistry, final long minReqNetMonitInt) {
+ Preconditions.checkArgument(manager != null, "StatisticManager can not be null!");
+ Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
+ groupStatsService = Preconditions.checkNotNull(
+ rpcRegistry.getRpcService(OpendaylightGroupStatisticsService.class),
+ "OpendaylightGroupStatisticsService can not be null!");
+ meterStatsService = Preconditions.checkNotNull(
+ rpcRegistry.getRpcService(OpendaylightMeterStatisticsService.class),
+ "OpendaylightMeterStatisticsService can not be null!");
+ flowStatsService = Preconditions.checkNotNull(
+ rpcRegistry.getRpcService(OpendaylightFlowStatisticsService.class),
+ "OpendaylightFlowStatisticsService can not be null!");
+ portStatsService = Preconditions.checkNotNull(
+ rpcRegistry.getRpcService(OpendaylightPortStatisticsService.class),
+ "OpendaylightPortStatisticsService can not be null!");
+ flowTableStatsService = Preconditions.checkNotNull(
+ rpcRegistry.getRpcService(OpendaylightFlowTableStatisticsService.class),
+ "OpendaylightFlowTableStatisticsService can not be null!");
+ queueStatsService = Preconditions.checkNotNull(
+ rpcRegistry.getRpcService(OpendaylightQueueStatisticsService.class),
+ "OpendaylightQueueStatisticsService can not be null!");
+
+ statsRpcJobQueue = new LinkedBlockingQueue<>(queueCapacity);
+ txCache = CacheBuilder.newBuilder().expireAfterWrite(maxLifeForRequest, TimeUnit.SECONDS)
+ .maximumSize(10000).build();
+ }
+
+ @Override
+ public void close() {
+ finishing = true;
+ statsRpcJobQueue = null;
+ }
+
+ @Override
+ public void run() {
+ /* Neverending cyle - wait for finishing */
+ while ( ! finishing) {
+ try {
+ statsRpcJobQueue.take().call();
+ }
+ catch (final Exception e) {
+ LOG.warn("Stat Element RPC executor fail!", e);
+ }
+ }
+ // Drain all rpcCall, making sure any blocked threads are unblocked
+ while ( ! statsRpcJobQueue.isEmpty()) {
+ statsRpcJobQueue.poll();
+ }
+ }
+
+ private void addGetAllStatJob(final RpcJobsQueue getAllStatJob) {
+ final boolean success = statsRpcJobQueue.offer(getAllStatJob);
+ if ( ! success) {
+ LOG.warn("Put RPC request getAllStat fail! Queue is full.");
+ }
+ }
+
+ private void addStatJob(final RpcJobsQueue getStatJob) {
+ final boolean success = statsRpcJobQueue.offer(getStatJob);
+ if ( ! success) {
+ LOG.debug("Put RPC request for getStat fail! Queue is full.");
+ }
+ }
+
+ @Override
+ public <T extends TransactionAware, D extends DataObject> void registrationRpcFutureCallBack(
+ final Future<RpcResult<T>> future, final D inputObj, final NodeRef nodeRef) {
+
+ Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future),
+ new FutureCallback<RpcResult<? extends TransactionAware>>() {
+
+ @Override
+ public void onSuccess(final RpcResult<? extends TransactionAware> result) {
+ final TransactionId id = result.getResult().getTransactionId();
+ if (id == null) {
+ LOG.warn("No protocol support");
+ } else {
+ final NodeKey nodeKey = nodeRef.getValue().firstKeyOf(Node.class, NodeKey.class);
+ final String cacheKey = buildCacheKey(id, nodeKey.getId());
+ final TransactionCacheContainer<? super TransactionAware> container =
+ new TransactionCacheContainerImpl<>(id, inputObj, nodeKey.getId());
+ txCache.put(cacheKey, container);
+ }
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ LOG.warn("Response Registration for Statistics RPC call fail!", t);
+ }
+
+ });
+ }
+
+ private String buildCacheKey(final TransactionId id, final NodeId nodeId) {
+ return String.valueOf(id.getValue()) + "-" + nodeId.getValue();
+ }
+
+ @Override
+ public Future<Optional<TransactionCacheContainer<?>>> getTransactionCacheContainer(
+ final TransactionId id, final NodeId nodeId) {
+ Preconditions.checkArgument(id != null, "TransactionId can not be null!");
+ Preconditions.checkArgument(nodeId != null, "NodeId can not be null!");
+
+ final String key = buildCacheKey(id, nodeId);
+ final SettableFuture<Optional<TransactionCacheContainer<?>>> result = SettableFuture.create();
+
+ final RpcJobsQueue getTransactionCacheContainer = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final Optional<TransactionCacheContainer<?>> resultContainer =
+ Optional.<TransactionCacheContainer<?>> fromNullable(txCache.getIfPresent(key));
+ if (resultContainer.isPresent()) {
+ txCache.invalidate(key);
+ }
+ result.set(resultContainer);
+ return null;
+ }
+ };
+ addStatJob(getTransactionCacheContainer);
+ return result;
+ }
+
+ @Override
+ public Future<Boolean> isExpectedStatistics(final TransactionId id, final NodeId nodeId) {
+ Preconditions.checkArgument(id != null, "TransactionId can not be null!");
+ Preconditions.checkArgument(nodeId != null, "NodeId can not be null!");
+
+ final String key = buildCacheKey(id, nodeId);
+ final SettableFuture<Boolean> checkStatId = SettableFuture.create();
+
+ final RpcJobsQueue isExpecedStatistics = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final Optional<TransactionCacheContainer<?>> result =
+ Optional.<TransactionCacheContainer<?>> fromNullable(txCache.getIfPresent(key));
+ checkStatId.set(Boolean.valueOf(result.isPresent()));
+ return null;
+ }
+ };
+ addStatJob(isExpecedStatistics);
+ return checkStatId;
+ }
+
+ @Override
+ public void addNotification(final TransactionAware notification, final NodeId nodeId) {
+ Preconditions.checkArgument(notification != null, "TransactionAware can not be null!");
+ Preconditions.checkArgument(nodeId != null, "NodeId can not be null!");
+
+ final RpcJobsQueue addNotification = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final TransactionId txId = notification.getTransactionId();
+ final String key = buildCacheKey(txId, nodeId);
+ final TransactionCacheContainer<? super TransactionAware> container = (txCache.getIfPresent(key));
+ if (container != null) {
+ container.addNotif(notification);
+ }
+ return null;
+ }
+ };
+ addStatJob(addNotification);
+ }
+
+ @Override
+ public void getAllGroupsStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getAllGroupStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final GetAllGroupStatisticsInputBuilder builder =
+ new GetAllGroupStatisticsInputBuilder();
+ builder.setNode(nodeRef);
+ registrationRpcFutureCallBack(groupStatsService
+ .getAllGroupStatistics(builder.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addGetAllStatJob(getAllGroupStat);
+ }
+
+ @Override
+ public void getAllMetersStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getAllMeterStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final GetAllMeterStatisticsInputBuilder builder =
+ new GetAllMeterStatisticsInputBuilder();
+ builder.setNode(nodeRef);
+ registrationRpcFutureCallBack(meterStatsService
+ .getAllMeterStatistics(builder.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addGetAllStatJob(getAllMeterStat);
+ }
+
+ @Override
+ public void getAllFlowsStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getAllFlowStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder builder =
+ new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
+ builder.setNode(nodeRef);
+ registrationRpcFutureCallBack(flowStatsService
+ .getAllFlowsStatisticsFromAllFlowTables(builder.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addGetAllStatJob(getAllFlowStat);
+ }
+
+ @Override
+ public void getAggregateFlowStat(final NodeRef nodeRef, final TableId tableId) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ Preconditions.checkArgument(tableId != null, "TableId can not be null!");
+ final RpcJobsQueue getAggregateFlowStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder builder =
+ new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
+ builder.setNode(nodeRef);
+ builder.setTableId(tableId);
+
+ final TableBuilder tbuilder = new TableBuilder();
+ tbuilder.setId(tableId.getValue());
+ tbuilder.setKey(new TableKey(tableId.getValue()));
+ registrationRpcFutureCallBack(flowStatsService
+ .getAggregateFlowStatisticsFromFlowTableForAllFlows(builder.build()), tbuilder.build(), nodeRef);
+ return null;
+ }
+ };
+ addGetAllStatJob(getAggregateFlowStat);
+ }
+
+ @Override
+ public void getAllPortsStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getAllPortsStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final GetAllNodeConnectorsStatisticsInputBuilder builder =
+ new GetAllNodeConnectorsStatisticsInputBuilder();
+ builder.setNode(nodeRef);
+ registrationRpcFutureCallBack(portStatsService
+ .getAllNodeConnectorsStatistics(builder.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addGetAllStatJob(getAllPortsStat);
+ }
+
+ @Override
+ public void getAllTablesStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getAllTableStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final GetFlowTablesStatisticsInputBuilder builder =
+ new GetFlowTablesStatisticsInputBuilder();
+ builder.setNode(nodeRef);
+ registrationRpcFutureCallBack(flowTableStatsService
+ .getFlowTablesStatistics(builder.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addGetAllStatJob(getAllTableStat);
+ }
+
+ @Override
+ public void getAllQueueStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getAllQueueStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final GetAllQueuesStatisticsFromAllPortsInputBuilder builder =
+ new GetAllQueuesStatisticsFromAllPortsInputBuilder();
+ builder.setNode(nodeRef);
+ registrationRpcFutureCallBack(queueStatsService
+ .getAllQueuesStatisticsFromAllPorts(builder.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addGetAllStatJob(getAllQueueStat);
+ }
+
+ @Override
+ public void getAllMeterConfigStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue qetAllMeterConfStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ final GetAllMeterConfigStatisticsInputBuilder builder =
+ new GetAllMeterConfigStatisticsInputBuilder();
+ builder.setNode(nodeRef);
+ registrationRpcFutureCallBack(meterStatsService
+ .getAllMeterConfigStatistics(builder.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addGetAllStatJob(qetAllMeterConfStat);
+ }
+
+ @Override
+ public void getGroupFeaturesStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getGroupFeaturesStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ /* RPC input */
+ final GetGroupFeaturesInputBuilder input = new GetGroupFeaturesInputBuilder();
+ input.setNode(nodeRef);
+ registrationRpcFutureCallBack(groupStatsService.getGroupFeatures(input.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addStatJob(getGroupFeaturesStat);
+ }
+
+ @Override
+ public void getMeterFeaturesStat(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getMeterFeaturesStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ /* RPC input */
+ final GetMeterFeaturesInputBuilder input = new GetMeterFeaturesInputBuilder();
+ input.setNode(nodeRef);
+ registrationRpcFutureCallBack(meterStatsService.getMeterFeatures(input.build()), null, nodeRef);
+ return null;
+ }
+ };
+ addStatJob(getMeterFeaturesStat);
+ }
+
+ @Override
+ public void getAllGroupsConfStats(final NodeRef nodeRef) {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final RpcJobsQueue getAllGropConfStat = new RpcJobsQueue() {
+
+ @Override
+ public Void call() throws Exception {
+ Preconditions.checkArgument(nodeRef != null, "NodeRef can not be null!");
+ final GetGroupDescriptionInputBuilder builder =
+ new GetGroupDescriptionInputBuilder();
+ builder.setNode(nodeRef);
+ registrationRpcFutureCallBack(groupStatsService
+ .getGroupDescription(builder.build()), null, nodeRef);
+
+ return null;
+ }
+ };
+ addGetAllStatJob(getAllGropConfStat);
+ }
+
+ public class TransactionCacheContainerImpl<T extends TransactionAware> implements TransactionCacheContainer<T> {
+
+ private final TransactionId id;
+ private final NodeId nId;
+ private final List<T> notifications;
+ private final Optional<? extends DataObject> confInput;
+
+ public <D extends DataObject> TransactionCacheContainerImpl (final TransactionId id, final D input, final NodeId nodeId) {
+ this.id = Preconditions.checkNotNull(id, "TransactionId can not be null!");
+ notifications = new CopyOnWriteArrayList<T>();
+ confInput = Optional.fromNullable(input);
+ nId = nodeId;
+ }
+
+ @Override
+ public void addNotif(final T notif) {
+ notifications.add(notif);
+ }
+
+ @Override
+ public TransactionId getId() {
+ return id;
+ }
+
+ @Override
+ public NodeId getNodeId() {
+ return nId;
+ }
+
+ @Override
+ public List<T> getNotifications() {
+ return notifications;
+ }
+
+ @Override
+ public Optional<? extends DataObject> getConfInput() {
+ return confInput;
+ }
+ }
+}
+
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadFactory;
+
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.controller.md.statistics.manager.StatListeningCommiter;
+import org.opendaylight.controller.md.statistics.manager.StatNodeRegistration;
+import org.opendaylight.controller.md.statistics.manager.StatNotifyCommiter;
+import org.opendaylight.controller.md.statistics.manager.StatPermCollector;
+import org.opendaylight.controller.md.statistics.manager.StatPermCollector.StatCapabTypes;
+import org.opendaylight.controller.md.statistics.manager.StatRpcMsgManager;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsListener;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+/**
+* statistics-manager
+* org.opendaylight.controller.md.statistics.manager.impl
+*
+* StatisticsManagerImpl
+* It represent a central point for whole module. Implementation
+* {@link StatisticsManager} registers all Operation/DS {@link StatNotifyCommiter} and
+* Config/DS {@StatListeningCommiter}, as well as {@link StatPermCollector}
+* for statistic collecting and {@link StatRpcMsgManager} as Device RPCs provider.
+* In next, StatisticsManager provides all DS contact Transaction services.
+*
+* @author avishnoi@in.ibm.com <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+*
+*/
+public class StatisticsManagerImpl implements StatisticsManager, Runnable {
+
+ private final static Logger LOG = LoggerFactory.getLogger(StatisticsManagerImpl.class);
+
+ private static final int QUEUE_DEPTH = 5000;
+ private static final int MAX_BATCH = 100;
+
+ private final BlockingQueue<StatDataStoreOperation> dataStoreOperQueue = new LinkedBlockingDeque<>(QUEUE_DEPTH);
+
+ private final DataBroker dataBroker;
+ private final int maxNodesForCollectors;
+ private long minReqNetMonitInt;
+ private final ExecutorService statRpcMsgManagerExecutor;
+ private final ExecutorService statDataStoreOperationServ;
+ private StatRpcMsgManager rpcMsgManager;
+ private List<StatPermCollector> statCollectors;
+ private final Object statCollectorLock = new Object();
+ private BindingTransactionChain txChain;
+ private volatile boolean finishing = false;
+
+ private StatNodeRegistration nodeRegistrator;
+ private StatListeningCommiter<Flow, OpendaylightFlowStatisticsListener> flowListeningCommiter;
+ private StatListeningCommiter<Meter, OpendaylightMeterStatisticsListener> meterListeningCommiter;
+ private StatListeningCommiter<Group, OpendaylightGroupStatisticsListener> groupListeningCommiter;
+ private StatListeningCommiter<Queue, OpendaylightQueueStatisticsListener> queueNotifyCommiter;
+ private StatNotifyCommiter<OpendaylightFlowTableStatisticsListener> tableNotifCommiter;
+ private StatNotifyCommiter<OpendaylightPortStatisticsListener> portNotifyCommiter;
+
+ public StatisticsManagerImpl (final DataBroker dataBroker, final int maxNodesForCollector) {
+ this.dataBroker = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
+ ThreadFactory threadFact;
+ threadFact = new ThreadFactoryBuilder().setNameFormat("odl-stat-rpc-oper-thread-%d").build();
+ statRpcMsgManagerExecutor = Executors.newSingleThreadExecutor(threadFact);
+ threadFact = new ThreadFactoryBuilder().setNameFormat("odl-stat-ds-oper-thread-%d").build();
+ statDataStoreOperationServ = Executors.newSingleThreadExecutor(threadFact);
+ maxNodesForCollectors = maxNodesForCollector;
+ txChain = dataBroker.createTransactionChain(this);
+ }
+
+ @Override
+ public void start(final NotificationProviderService notifService,
+ final RpcConsumerRegistry rpcRegistry, final long minReqNetMonitInt) {
+ Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
+ this.minReqNetMonitInt = minReqNetMonitInt;
+ rpcMsgManager = new StatRpcMsgManagerImpl(this, rpcRegistry, minReqNetMonitInt);
+ statCollectors = Collections.emptyList();
+ nodeRegistrator = new StatNodeRegistrationImpl(this, dataBroker, notifService);
+ flowListeningCommiter = new StatListenCommitFlow(this, dataBroker, notifService);
+ meterListeningCommiter = new StatListenCommitMeter(this, dataBroker, notifService);
+ groupListeningCommiter = new StatListenCommitGroup(this, dataBroker, notifService);
+ tableNotifCommiter = new StatNotifyCommitTable(this, notifService);
+ portNotifyCommiter = new StatNotifyCommitPort(this, notifService);
+ queueNotifyCommiter = new StatListenCommitQueue(this, dataBroker, notifService);
+
+ statRpcMsgManagerExecutor.execute(rpcMsgManager);
+ statDataStoreOperationServ.execute(this);
+ LOG.info("Statistics Manager started successfully!");
+ }
+
+ @Override
+ public void close() throws Exception {
+ finishing = true;
+ if (nodeRegistrator != null) {
+ nodeRegistrator.close();
+ nodeRegistrator = null;
+ }
+ if (flowListeningCommiter != null) {
+ flowListeningCommiter.close();
+ flowListeningCommiter = null;
+ }
+ if (meterListeningCommiter != null) {
+ meterListeningCommiter.close();
+ meterListeningCommiter = null;
+ }
+ if (groupListeningCommiter != null) {
+ groupListeningCommiter.close();
+ groupListeningCommiter = null;
+ }
+ if (tableNotifCommiter != null) {
+ tableNotifCommiter.close();
+ tableNotifCommiter = null;
+ }
+ if (portNotifyCommiter != null) {
+ portNotifyCommiter.close();
+ portNotifyCommiter = null;
+ }
+ if (queueNotifyCommiter != null) {
+ queueNotifyCommiter.close();
+ queueNotifyCommiter = null;
+ }
+ if (statCollectors != null) {
+ for (StatPermCollector collector : statCollectors) {
+ collector.close();
+ collector = null;
+ }
+ statCollectors = null;
+ }
+ if (rpcMsgManager != null) {
+ rpcMsgManager.close();
+ rpcMsgManager = null;
+ }
+ statRpcMsgManagerExecutor.shutdown();
+ statDataStoreOperationServ.shutdown();
+ if (txChain != null) {
+ txChain.close();
+ txChain = null;
+ }
+ }
+
+ @Override
+ public void enqueue(final StatDataStoreOperation op) {
+ // we don't need to block anything - next statistics come soon
+ final boolean success = dataStoreOperQueue.offer(op);
+ if ( ! success) {
+ LOG.debug("Stat DS/Operational submiter Queue is full!");
+ }
+ }
+
+ @Override
+ public void run() {
+ /* Neverending cyle - wait for finishing */
+ while ( ! finishing) {
+ try {
+ StatDataStoreOperation op = dataStoreOperQueue.take();
+ final ReadWriteTransaction tx = txChain.newReadWriteTransaction();
+ LOG.trace("New operations available, starting transaction {}", tx.getIdentifier());
+
+ int ops = 0;
+ do {
+ op.applyOperation(tx);
+
+ ops++;
+ if (ops < MAX_BATCH) {
+ op = dataStoreOperQueue.poll();
+ } else {
+ op = null;
+ }
+ } while (op != null);
+
+ LOG.trace("Processed {} operations, submitting transaction {}", ops, tx.getIdentifier());
+
+ tx.submit().checkedGet();
+ } catch (final InterruptedException e) {
+ LOG.warn("Stat Manager DS Operation thread interupted!", e);
+ finishing = true;
+ } catch (final Exception e) {
+ LOG.warn("Unhandled exception during processing statistics. Restarting transaction chain.", e);
+ txChain.close();
+ txChain = dataBroker.createTransactionChain(StatisticsManagerImpl.this);
+ cleanDataStoreOperQueue();
+ }
+ }
+ // Drain all events, making sure any blocked threads are unblocked
+ cleanDataStoreOperQueue();
+ }
+
+ private synchronized void cleanDataStoreOperQueue() {
+ // Drain all events, making sure any blocked threads are unblocked
+ while (! dataStoreOperQueue.isEmpty()) {
+ dataStoreOperQueue.poll();
+ }
+ }
+
+ @Override
+ public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction,
+ final Throwable cause) {
+ LOG.warn("Failed to export Flow Capable Statistics, Transaction {} failed.",transaction.getIdentifier(),cause);
+ }
+
+ @Override
+ public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
+ // NOOP
+ }
+
+ @Override
+ public boolean isProvidedFlowNodeActive(final InstanceIdentifier<Node> nodeIdent) {
+ for (final StatPermCollector collector : statCollectors) {
+ if (collector.isProvidedFlowNodeActive(nodeIdent)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void collectNextStatistics(final InstanceIdentifier<Node> nodeIdent) {
+ for (final StatPermCollector collector : statCollectors) {
+ if (collector.isProvidedFlowNodeActive(nodeIdent)) {
+ collector.collectNextStatistics();
+ }
+ }
+ }
+
+ @Override
+ public void connectedNodeRegistration(final InstanceIdentifier<Node> nodeIdent,
+ final List<StatCapabTypes> statTypes, final Short nrOfSwitchTables) {
+ for (final StatPermCollector collector : statCollectors) {
+ if (collector.connectedNodeRegistration(nodeIdent, statTypes, nrOfSwitchTables)) {
+ return;
+ }
+ }
+ synchronized (statCollectorLock) {
+ for (final StatPermCollector collector : statCollectors) {
+ if (collector.connectedNodeRegistration(nodeIdent, statTypes, nrOfSwitchTables)) {
+ return;
+ }
+ }
+ final StatPermCollectorImpl newCollector = new StatPermCollectorImpl(this,
+ minReqNetMonitInt, statCollectors.size() + 1, maxNodesForCollectors);
+ final List<StatPermCollector> statCollectorsNew = new ArrayList<>(statCollectors);
+ newCollector.connectedNodeRegistration(nodeIdent, statTypes, nrOfSwitchTables);
+ statCollectorsNew.add(newCollector);
+ statCollectors = Collections.unmodifiableList(statCollectorsNew);
+ }
+ }
+
+ @Override
+ public void disconnectedNodeUnregistration(final InstanceIdentifier<Node> nodeIdent) {
+ flowListeningCommiter.cleanForDisconnect(nodeIdent);
+
+ for (final StatPermCollector collector : statCollectors) {
+ if (collector.disconnectedNodeUnregistration(nodeIdent)) {
+ if ( ! collector.hasActiveNodes()) {
+ synchronized (statCollectorLock) {
+ if (collector.hasActiveNodes()) {
+ return;
+ }
+ final List<StatPermCollector> newStatColl =
+ new ArrayList<>(statCollectors);
+ newStatColl.remove(collector);
+ statCollectors = Collections.unmodifiableList(newStatColl);
+ }
+ }
+ return;
+ }
+ }
+ LOG.debug("Node {} has not removed.", nodeIdent);
+ }
+
+ /* Getter internal Statistic Manager Job Classes */
+ @Override
+ public StatRpcMsgManager getRpcMsgManager() {
+ return rpcMsgManager;
+ }
+
+ @Override
+ public StatNodeRegistration getNodeRegistrator() {
+ return nodeRegistrator;
+ }
+
+ @Override
+ public StatListeningCommiter<Flow, OpendaylightFlowStatisticsListener> getFlowListenComit() {
+ return flowListeningCommiter;
+ }
+
+ @Override
+ public StatListeningCommiter<Meter, OpendaylightMeterStatisticsListener> getMeterListenCommit() {
+ return meterListeningCommiter;
+ }
+
+ @Override
+ public StatListeningCommiter<Group, OpendaylightGroupStatisticsListener> getGroupListenCommit() {
+ return groupListeningCommiter;
+ }
+
+ @Override
+ public StatListeningCommiter<Queue, OpendaylightQueueStatisticsListener> getQueueNotifyCommit() {
+ return queueNotifyCommiter;
+ }
+
+
+ @Override
+ public StatNotifyCommiter<OpendaylightFlowTableStatisticsListener> getTableNotifCommit() {
+ return tableNotifCommiter;
+ }
+
+ @Override
+ public StatNotifyCommiter<OpendaylightPortStatisticsListener> getPortNotifyCommit() {
+ return portNotifyCommiter;
+ }
+}
+
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.md.statistics.manager;
+package org.opendaylight.controller.md.statistics.manager.impl.helper;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.net.InetAddresses;
import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.MacAddressFilter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.annotations.VisibleForTesting;
-
/**
* Utility class for comparing flows.
*/
-final class FlowComparator {
- private final static Logger logger = LoggerFactory.getLogger(FlowComparator.class);
+public final class FlowComparator {
+ private final static Logger LOG = LoggerFactory.getLogger(FlowComparator.class);
private FlowComparator() {
-
+ throw new UnsupportedOperationException("Utilities class should not be instantiated");
}
- public static boolean flowEquals(Flow statsFlow, Flow storedFlow) {
+ public static boolean flowEquals(final Flow statsFlow, final Flow storedFlow) {
if (statsFlow == null || storedFlow == null) {
return false;
}
* @param storedFlow
* @return
*/
- public static boolean matchEquals(Match statsFlow, Match storedFlow) {
+ public static boolean matchEquals(final Match statsFlow, final Match storedFlow) {
if (statsFlow == storedFlow) {
return true;
}
* statistic data, openflow driver library returns AA:BB:CC:DD:EE:FF and default eqauls fails here.
*/
@VisibleForTesting
- static boolean ethernetMatchEquals(EthernetMatch statsEthernetMatch, EthernetMatch storedEthernetMatch){
+ static boolean ethernetMatchEquals(final EthernetMatch statsEthernetMatch, final EthernetMatch storedEthernetMatch){
boolean verdict = true;
- Boolean checkNullValues = checkNullValues(statsEthernetMatch, storedEthernetMatch);
+ final Boolean checkNullValues = checkNullValues(statsEthernetMatch, storedEthernetMatch);
if (checkNullValues != null) {
verdict = checkNullValues;
} else {
return verdict;
}
- private static boolean ethernetMatchFieldsEquals(MacAddressFilter statsEthernetMatchFields,
- MacAddressFilter storedEthernetMatchFields){
+ private static boolean ethernetMatchFieldsEquals(final MacAddressFilter statsEthernetMatchFields,
+ final MacAddressFilter storedEthernetMatchFields){
boolean verdict = true;
- Boolean checkNullValues = checkNullValues(statsEthernetMatchFields, storedEthernetMatchFields);
+ final Boolean checkNullValues = checkNullValues(statsEthernetMatchFields, storedEthernetMatchFields);
if (checkNullValues != null) {
verdict = checkNullValues;
} else {
return verdict;
}
- private static boolean macAddressEquals(MacAddress statsMacAddress, MacAddress storedMacAddress){
+ private static boolean macAddressEquals(final MacAddress statsMacAddress, final MacAddress storedMacAddress){
boolean verdict = true;
- Boolean checkNullValues = checkNullValues(statsMacAddress, storedMacAddress);
+ final Boolean checkNullValues = checkNullValues(statsMacAddress, storedMacAddress);
if (checkNullValues != null) {
verdict = checkNullValues;
} else {
}
@VisibleForTesting
- static boolean layer3MatchEquals(Layer3Match statsLayer3Match, Layer3Match storedLayer3Match){
+ static boolean layer3MatchEquals(final Layer3Match statsLayer3Match, final Layer3Match storedLayer3Match){
boolean verdict = true;
if(statsLayer3Match instanceof Ipv4Match && storedLayer3Match instanceof Ipv4Match){
- Ipv4Match statsIpv4Match = (Ipv4Match)statsLayer3Match;
- Ipv4Match storedIpv4Match = (Ipv4Match)storedLayer3Match;
+ final Ipv4Match statsIpv4Match = (Ipv4Match)statsLayer3Match;
+ final Ipv4Match storedIpv4Match = (Ipv4Match)storedLayer3Match;
if (verdict) {
verdict = compareNullSafe(
statsIpv4Match.getIpv4Source(), storedIpv4Match.getIpv4Source());
}
} else {
- Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
+ final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
if (nullCheckOut != null) {
verdict = nullCheckOut;
} else {
return verdict;
}
- private static boolean compareNullSafe(Ipv4Prefix statsIpv4, Ipv4Prefix storedIpv4) {
+ private static boolean compareNullSafe(final Ipv4Prefix statsIpv4, final Ipv4Prefix storedIpv4) {
boolean verdict = true;
- Boolean checkDestNullValuesOut = checkNullValues(storedIpv4, statsIpv4);
+ final Boolean checkDestNullValuesOut = checkNullValues(storedIpv4, statsIpv4);
if (checkDestNullValuesOut != null) {
verdict = checkDestNullValuesOut;
} else if(!IpAddressEquals(statsIpv4, storedIpv4)){
return verdict;
}
- private static Boolean checkNullValues(Object v1, Object v2) {
+ private static Boolean checkNullValues(final Object v1, final Object v2) {
Boolean verdict = null;
if (v1 == null && v2 != null) {
verdict = Boolean.FALSE;
* @param storedIpAddress
* @return true if IPv4prefixes equals
*/
- private static boolean IpAddressEquals(Ipv4Prefix statsIpAddress, Ipv4Prefix storedIpAddress) {
- IntegerIpAddress statsIpAddressInt = StrIpToIntIp(statsIpAddress.getValue());
- IntegerIpAddress storedIpAddressInt = StrIpToIntIp(storedIpAddress.getValue());
+ private static boolean IpAddressEquals(final Ipv4Prefix statsIpAddress, final Ipv4Prefix storedIpAddress) {
+ final IntegerIpAddress statsIpAddressInt = StrIpToIntIp(statsIpAddress.getValue());
+ final IntegerIpAddress storedIpAddressInt = StrIpToIntIp(storedIpAddress.getValue());
if(IpAndMaskBasedMatch(statsIpAddressInt,storedIpAddressInt)){
return true;
return false;
}
- private static boolean IpAndMaskBasedMatch(IntegerIpAddress statsIpAddressInt,IntegerIpAddress storedIpAddressInt){
+ private static boolean IpAndMaskBasedMatch(final IntegerIpAddress statsIpAddressInt,final IntegerIpAddress storedIpAddressInt){
return ((statsIpAddressInt.getIp() & statsIpAddressInt.getMask()) == (storedIpAddressInt.getIp() & storedIpAddressInt.getMask()));
}
- private static boolean IpBasedMatch(IntegerIpAddress statsIpAddressInt,IntegerIpAddress storedIpAddressInt){
+ private static boolean IpBasedMatch(final IntegerIpAddress statsIpAddressInt,final IntegerIpAddress storedIpAddressInt){
return (statsIpAddressInt.getIp() == storedIpAddressInt.getIp());
}
* Method return integer version of ip address. Converted int will be mask if
* mask specified
*/
- private static IntegerIpAddress StrIpToIntIp(String ipAddresss){
+ private static IntegerIpAddress StrIpToIntIp(final String ipAddresss){
- String[] parts = ipAddresss.split("/");
- String ip = parts[0];
+ final String[] parts = ipAddresss.split("/");
+ final String ip = parts[0];
int prefix;
if (parts.length < 2) {
}
IntegerIpAddress integerIpAddress = null;
- try {
- Inet4Address addr = (Inet4Address) InetAddress.getByName(ip);
- byte[] addrBytes = addr.getAddress();
- int ipInt = ((addrBytes[0] & 0xFF) << 24) |
+
+ final Inet4Address addr = ((Inet4Address) InetAddresses.forString(ip));
+ final byte[] addrBytes = addr.getAddress();
+ final int ipInt = ((addrBytes[0] & 0xFF) << 24) |
((addrBytes[1] & 0xFF) << 16) |
((addrBytes[2] & 0xFF) << 8) |
((addrBytes[3] & 0xFF) << 0);
- int mask = 0xffffffff << 32 - prefix;
+ // FIXME: Is this valid?
+ final int mask = 0xffffffff << 32 - prefix;
integerIpAddress = new IntegerIpAddress(ipInt, mask);
- } catch (UnknownHostException e){
- logger.error("Failed to determine host IP address by name: {}", e.getMessage(), e);
- }
+
return integerIpAddress;
}
private static class IntegerIpAddress{
int ip;
int mask;
- public IntegerIpAddress(int ip, int mask) {
+ public IntegerIpAddress(final int ip, final int mask) {
this.ip = ip;
this.mask = mask;
}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.statistics.manager;
+
+/**
+ * statistics-manager
+ * org.opendaylight.controller.md.statistics.manager
+ *
+ *
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Sep 6, 2014
+ */
+public class StatisticsManagerProvider {
+
+ private final StatisticsManagerActivator activator;
+
+ public StatisticsManagerProvider(final StatisticsManagerActivator activator) {
+ this.activator = activator;
+ }
+
+ /**
+ * Method provides Initialized {@link StatisticsManager}
+ * from {@link StatisticsManagerActivator} for all tests
+ * suites;
+ *
+ * @return
+ */
+ public StatisticsManager getStatisticsManager() {
+ return activator.getStatisticManager();
+ }
+}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.md.statistics.manager;
+package org.opendaylight.controller.md.statistics.manager.impl.helper;
import org.junit.Assert;
import org.junit.Test;
*/
@Test
public void testLayer3MatchEquals() {
- String[][][] matchSeeds = new String[][][] {
+ final String[][][] matchSeeds = new String[][][] {
{{"10.1.2.0/24", "10.1.2.0/24"}, {"10.1.2.0/24", "10.1.2.0/24"}},
{{"10.1.2.0/24", "10.1.2.0/24"}, {"10.1.2.0/24", "10.1.1.0/24"}},
{{"10.1.1.0/24", "10.1.2.0/24"}, {"10.1.2.0/24", "10.1.2.0/24"}},
{{null, null}, {null, null}},
};
- boolean[] matches = new boolean[] {
+ final boolean[] matches = new boolean[] {
true,
false,
false,
* @param matches expected match output
*
*/
- private static void checkComparisonOfL3Match(String m1Source, String m1Destination,
- String m2Source, String msDestination, boolean matches) {
- Ipv4Match m1Layer3 = prepareIPv4Match(m1Source, m1Destination);
- Ipv4Match m2Layer3 = prepareIPv4Match(m2Source, msDestination);
+ private static void checkComparisonOfL3Match(final String m1Source, final String m1Destination,
+ final String m2Source, final String msDestination, final boolean matches) {
+ final Ipv4Match m1Layer3 = prepareIPv4Match(m1Source, m1Destination);
+ final Ipv4Match m2Layer3 = prepareIPv4Match(m2Source, msDestination);
boolean comparisonResult;
try {
comparisonResult = FlowComparator.layer3MatchEquals(m1Layer3, m2Layer3);
Assert.assertEquals("failed to compare: "+m1Layer3+" vs. "+m2Layer3,
matches, comparisonResult);
- } catch (Exception e) {
+ } catch (final Exception e) {
LOG.error("failed to compare: {} vs. {}", m1Layer3, m2Layer3, e);
Assert.fail(e.getMessage());
}
}
- private static Ipv4Match prepareIPv4Match(String source, String destination) {
- Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder();
+ private static Ipv4Match prepareIPv4Match(final String source, final String destination) {
+ final Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder();
if (source != null) {
ipv4MatchBuilder.setIpv4Source(new Ipv4Prefix(source));
}
return ipv4MatchBuilder.build();
}
/**
- * Test method for {@link org.opendaylight.controller.md.statistics.manager.FlowComparator#ethernetMatchEquals(EthernetMatch, EthernetMatch)
+ * Test method for {@link org.opendaylight.controller.md.statistics.manager.impl.helper.FlowComparator#ethernetMatchEquals(EthernetMatch, EthernetMatch)
*/
@Test
public void testEthernetMatchEquals() {
- String[][][] ethernetMatchSeeds = new String[][][] {
+ final String[][][] ethernetMatchSeeds = new String[][][] {
{{"aa:bb:cc:dd:ee:ff", "ff:ff:ff:ff:ff:ff","0800"}, {"aa:bb:cc:dd:ee:ff", "ff:ff:ff:ff:ff:ff","0800"}},
{{"aa:bb:cc:dd:ee:ff", "ff:ff:ff:ff:ff:ff","0800"}, {"aa:bb:bc:cd:ee:ff", "ff:ff:ff:ff:ff:ff","0800"}},
{{"aa:bb:cc:dd:ee:ff", "ff:ff:ff:ff:ff:ff","0800"}, {"AA:BB:CC:DD:EE:FF", "ff:ff:ff:ff:ff:ff","0800"}},
{{null, null,null}, {null, null,null}},
};
- boolean[] matches = new boolean[] {
+ final boolean[] matches = new boolean[] {
true,
false,
true,
* @param ethernetMatch1
* @param ethernetMatch2
*/
- private static void checkComparisonOfEthernetMatch(String macAddress1, String macAddressMask1,String etherType1,
- String macAddress2, String macAddressMask2,String etherType2, boolean expectedResult) {
- EthernetMatch ethernetMatch1 = prepareEthernetMatch(macAddress1, macAddressMask1,etherType1);
- EthernetMatch ethernetMatch2 = prepareEthernetMatch(macAddress2, macAddressMask2,etherType2);
+ private static void checkComparisonOfEthernetMatch(final String macAddress1, final String macAddressMask1,final String etherType1,
+ final String macAddress2, final String macAddressMask2,final String etherType2, final boolean expectedResult) {
+ final EthernetMatch ethernetMatch1 = prepareEthernetMatch(macAddress1, macAddressMask1,etherType1);
+ final EthernetMatch ethernetMatch2 = prepareEthernetMatch(macAddress2, macAddressMask2,etherType2);
boolean comparisonResult;
try {
comparisonResult = FlowComparator.ethernetMatchEquals(ethernetMatch1, ethernetMatch2);
Assert.assertEquals("failed to compare: "+ethernetMatch1+" vs. "+ethernetMatch2,
expectedResult, comparisonResult);
- } catch (Exception e) {
+ } catch (final Exception e) {
LOG.error("failed to compare: {} vs. {}", ethernetMatch1, ethernetMatch2, e);
Assert.fail(e.getMessage());
}
}
- private static EthernetMatch prepareEthernetMatch(String macAddress, String macAddressMask, String etherType) {
- EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder();
- EthernetSourceBuilder ethernetSourceBuilder = new EthernetSourceBuilder();
+ private static EthernetMatch prepareEthernetMatch(final String macAddress, final String macAddressMask, final String etherType) {
+ final EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder();
+ final EthernetSourceBuilder ethernetSourceBuilder = new EthernetSourceBuilder();
if (macAddress != null) {
ethernetSourceBuilder.setAddress(new MacAddress(macAddress));
}
ethernetSourceBuilder.setMask(new MacAddress(macAddressMask));
}
if(etherType != null){
- EthernetTypeBuilder ethernetType = new EthernetTypeBuilder();
+ final EthernetTypeBuilder ethernetType = new EthernetTypeBuilder();
ethernetType.setType(new EtherType(Long.parseLong(etherType,16)));
ethernetMatchBuilder.setEthernetType(ethernetType.build());
}
--- /dev/null
+package test.mock;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManagerActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityFlowStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import test.mock.util.StatisticsManagerTest;
+
+import com.google.common.base.Optional;
+
+public class FlowStatisticsTest extends StatisticsManagerTest {
+ private final Object waitObject = new Object();
+
+// @Test(timeout = 5000)
+ public void addedFlowOnDemandStatsTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+
+ final Flow flow = getFlow();
+
+ final InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(flow.getTableId()))
+ .child(Flow.class, flow.getKey());
+ final InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(flow.getTableId()));
+ final Table table = new TableBuilder().setKey(new TableKey(flow.getTableId())).setFlow(Collections.<Flow>emptyList()).build();
+
+ final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, tableII, table);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, flowII, flow);
+ assertCommit(writeTx.submit());
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ flowII.augmentation(FlowStatisticsData.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ final ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<FlowStatisticsData> flowStatDataOptional = readTx.read(LogicalDatastoreType.OPERATIONAL, flowII.augmentation(FlowStatisticsData.class))
+ .checkedGet();
+ assertTrue(flowStatDataOptional.isPresent());
+ assertEquals(COUNTER_64_TEST_VALUE, flowStatDataOptional.get().getFlowStatistics().getByteCount());
+
+ }
+
+// @Test(timeout = 5000)
+ public void deletedFlowStatsRemovalTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+
+ final Flow flow = getFlow();
+
+ final InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(flow.getTableId()))
+ .child(Flow.class, flow.getKey());
+ final InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(flow.getTableId()));
+ final Table table = new TableBuilder().setKey(new TableKey(flow.getTableId())).setFlow(Collections.<Flow>emptyList()).build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, tableII, table);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, flowII, flow);
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ flowII.augmentation(FlowStatisticsData.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ assertCommit(writeTx.submit());
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ Optional<Flow> flowStatDataOptional = readTx.read(LogicalDatastoreType.OPERATIONAL, flowII).checkedGet();
+ assertTrue(flowStatDataOptional.isPresent());
+// assertEquals(COUNTER_64_TEST_VALUE, flowStatDataOptional.get().getFlowStatistics().getByteCount());
+
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.CONFIGURATION, flowII);
+ assertCommit(writeTx.submit());
+
+ readTx = getDataBroker().newReadOnlyTransaction();
+ flowStatDataOptional = readTx.read(LogicalDatastoreType.OPERATIONAL, flowII).checkedGet();
+ assertFalse(flowStatDataOptional.isPresent());
+ }
+
+// @Test(timeout = 23000)
+ public void getAllStatsWhenNodeIsConnectedTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNodeWithFeatures(s1Key, false, FlowFeatureCapabilityFlowStats.class);
+
+ final Flow flow = getFlow();
+
+ final InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(flow.getTableId()));
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ tableII.child(Flow.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ final ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<Table> tableOptional = readTx.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key).augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(flow.getTableId()))).checkedGet();
+ assertTrue(tableOptional.isPresent());
+ final FlowStatisticsData flowStats = tableOptional.get().getFlow().get(0).getAugmentation(FlowStatisticsData.class);
+ assertTrue(flowStats != null);
+ assertEquals(COUNTER_64_TEST_VALUE, flowStats.getFlowStatistics().getByteCount());
+ }
+
+ public class ChangeListener implements DataChangeListener {
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ synchronized (waitObject) {
+ waitObject.notify();
+ }
+ }
+ }
+}
+
--- /dev/null
+package test.mock;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManagerActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityGroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import test.mock.util.StatisticsManagerTest;
+
+import com.google.common.base.Optional;
+
+public class GroupStatisticsTest extends StatisticsManagerTest {
+ private final Object waitObject = new Object();
+
+// @Test(timeout = 5000)
+ public void addedGroupOnDemandStatsTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+
+ final Group group = getGroup();
+
+ final InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Group.class, group.getKey());
+
+ final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, groupII, group);
+ assertCommit(writeTx.submit());
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ groupII.augmentation(NodeGroupStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ final ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<NodeGroupStatistics> groupOptional = readTx.read(LogicalDatastoreType.OPERATIONAL, groupII.augmentation(NodeGroupStatistics.class)).checkedGet();
+ assertTrue(groupOptional.isPresent());
+ assertEquals(COUNTER_64_TEST_VALUE, groupOptional.get().getGroupStatistics().getByteCount());
+ }
+
+// @Test(timeout = 5000)
+ public void deletedGroupStasRemovalTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+
+ final Group group = getGroup();
+ final InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Group.class, group.getKey());
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, groupII, group);
+ assertCommit(writeTx.submit());
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ groupII.augmentation(NodeGroupStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ Optional<NodeGroupStatistics> groupOptional = readTx.read(LogicalDatastoreType.OPERATIONAL,
+ groupII.augmentation(NodeGroupStatistics.class)).checkedGet();
+ assertTrue(groupOptional.isPresent());
+ assertEquals(COUNTER_64_TEST_VALUE, groupOptional.get().getGroupStatistics().getByteCount());
+
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.CONFIGURATION, groupII);
+ assertCommit(writeTx.submit());
+
+ readTx = getDataBroker().newReadOnlyTransaction();
+ groupOptional = readTx.read(LogicalDatastoreType.OPERATIONAL,
+ groupII.augmentation(NodeGroupStatistics.class)).checkedGet();
+ assertFalse(groupOptional.isPresent());
+
+ }
+
+// @Test(timeout = 23000)
+ public void getAllStatsFromConnectedNodeTest() throws ExecutionException, InterruptedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNodeWithFeatures(s1Key, false, FlowFeatureCapabilityGroupStats.class);
+
+ final InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Group.class, getGroup().getKey());
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ groupII.augmentation(NodeGroupStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<Group> optionalGroup = readTx.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key).augmentation(FlowCapableNode.class)
+ .child(Group.class, getGroup().getKey())).get();
+
+ assertTrue(optionalGroup.isPresent());
+ assertTrue(optionalGroup.get().getAugmentation(NodeGroupDescStats.class) != null);
+ final NodeGroupStatistics groupStats = optionalGroup.get().getAugmentation(NodeGroupStatistics.class);
+ assertTrue(groupStats != null);
+ assertEquals(COUNTER_64_TEST_VALUE, groupStats.getGroupStatistics().getByteCount());
+
+ readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<GroupFeatures> optionalGroupFeatures = readTx.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key).augmentation(NodeGroupFeatures.class).child(GroupFeatures.class)).get();
+ assertTrue(optionalGroupFeatures.isPresent());
+ assertEquals(1, optionalGroupFeatures.get().getMaxGroups().size());
+ assertEquals(MAX_GROUPS_TEST_VALUE, optionalGroupFeatures.get().getMaxGroups().get(0));
+ }
+
+ private class ChangeListener implements DataChangeListener {
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ synchronized (waitObject) {
+ waitObject.notify();
+ }
+ }
+ }
+}
+
--- /dev/null
+package test.mock;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManagerActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeatures;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import test.mock.util.StatisticsManagerTest;
+
+import com.google.common.base.Optional;
+
+public class MeterStatisticsTest extends StatisticsManagerTest {
+ private final Object waitObject = new Object();
+
+// @Test(timeout = 5000)
+ public void addedMeterOnDemandStatsTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+
+ final Meter meter = getMeter();
+ final InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Meter.class, meter.getKey());
+
+ final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, meterII, meter);
+ assertCommit(writeTx.submit());
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ meterII.augmentation(NodeMeterStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ final ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<NodeMeterStatistics> meterStatsOptional = readTx.read(LogicalDatastoreType.OPERATIONAL,
+ meterII.augmentation(NodeMeterStatistics.class)).checkedGet();
+ assertTrue(meterStatsOptional.isPresent());
+ assertEquals(COUNTER_64_TEST_VALUE, meterStatsOptional.get().getMeterStatistics().getByteInCount());
+ assertEquals(COUNTER_64_TEST_VALUE, meterStatsOptional.get().getMeterStatistics().getPacketInCount());
+ }
+
+// @Test(timeout = 5000)
+ public void deletedMeterStatsRemovalTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+
+ final Meter meter = getMeter();
+ final InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Meter.class, meter.getKey());
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, meterII, meter);
+ assertCommit(writeTx.submit());
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ meterII.augmentation(NodeMeterStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<NodeMeterStatistics> meterStatsOptional = readTx.read(LogicalDatastoreType.OPERATIONAL,
+ meterII.augmentation(NodeMeterStatistics.class)).checkedGet();
+ assertTrue(meterStatsOptional.isPresent());
+ assertEquals(COUNTER_64_TEST_VALUE, meterStatsOptional.get().getMeterStatistics().getByteInCount());
+ assertEquals(COUNTER_64_TEST_VALUE, meterStatsOptional.get().getMeterStatistics().getPacketInCount());
+
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.CONFIGURATION, meterII);
+ assertCommit(writeTx.submit());
+
+ readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<Meter> meterOptional = readTx.read(LogicalDatastoreType.OPERATIONAL, meterII).checkedGet();
+ assertFalse(meterOptional.isPresent());
+ }
+
+// @Test(timeout = 23000)
+ public void getAllStatsFromConnectedNodeTest() throws ExecutionException, InterruptedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNodeWithFeatures(s1Key, true);
+
+ final InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Meter.class, getMeter().getKey());
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ meterII.augmentation(NodeMeterStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<Meter> optionalMeter = readTx.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key).augmentation(FlowCapableNode.class)
+ .child(Meter.class, getMeter().getKey())).get();
+
+ assertTrue(optionalMeter.isPresent());
+ assertTrue(optionalMeter.get().getAugmentation(NodeMeterConfigStats.class) != null);
+ final NodeMeterStatistics meterStats = optionalMeter.get().getAugmentation(NodeMeterStatistics.class);
+ assertTrue(meterStats != null);
+ assertEquals(COUNTER_64_TEST_VALUE, meterStats.getMeterStatistics().getByteInCount());
+ assertEquals(COUNTER_64_TEST_VALUE, meterStats.getMeterStatistics().getPacketInCount());
+
+ readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<MeterFeatures> optionalMeterFeautures = readTx.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key).augmentation(NodeMeterFeatures.class).child(MeterFeatures.class)).get();
+ assertTrue(optionalMeterFeautures.isPresent());
+ assertEquals(COUNTER_32_TEST_VALUE, optionalMeterFeautures.get().getMaxMeter());
+ }
+
+ private class ChangeListener implements DataChangeListener {
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ synchronized (waitObject) {
+ waitObject.notify();
+ }
+ }
+ }
+}
+
--- /dev/null
+package test.mock;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.statistics.manager.StatisticsManagerActivator;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManagerProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import test.mock.util.StatisticsManagerTest;
+
+public class NodeRegistrationTest extends StatisticsManagerTest {
+
+// @Test
+ public void nodeRegistrationTest() throws ExecutionException, InterruptedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ final StatisticsManagerProvider statisticsManagerProvider = new StatisticsManagerProvider(activator);
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+ Thread.sleep(1000);
+ final InstanceIdentifier<Node> nodeII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key);
+
+ assertTrue(statisticsManagerProvider.getStatisticsManager().isProvidedFlowNodeActive(nodeII));
+ }
+
+// @Test
+ public void nodeUnregistrationTest() throws ExecutionException, InterruptedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ final StatisticsManagerProvider statisticsManagerProvider = new StatisticsManagerProvider(activator);
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+ Thread.sleep(1000);
+ final InstanceIdentifier<Node> nodeII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key);
+
+ assertTrue(statisticsManagerProvider.getStatisticsManager().isProvidedFlowNodeActive(nodeII));
+
+ removeNode(s1Key);
+ Thread.sleep(1000);
+ assertFalse(statisticsManagerProvider.getStatisticsManager().isProvidedFlowNodeActive(nodeII));
+ }
+}
+
--- /dev/null
+package test.mock;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManagerActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityPortStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import test.mock.util.StatisticsManagerTest;
+
+import com.google.common.base.Optional;
+
+public class PortStatisticsTest extends StatisticsManagerTest {
+ private final Object waitObject = new Object();
+
+// @Test(timeout = 23000)
+ public void getPortStatisticsTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNodeWithFeatures(s1Key, false, FlowFeatureCapabilityPortStats.class);
+
+ final InstanceIdentifier<NodeConnector> nodeConnectorII = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key).child(NodeConnector.class, new NodeConnectorKey(getNodeConnectorId()));
+
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ nodeConnectorII.augmentation(FlowCapableNodeConnectorStatisticsData.class),
+ new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ final ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<FlowCapableNodeConnectorStatisticsData> flowCapableNodeConnectorStatisticsDataOptional =
+ readTx.read(LogicalDatastoreType.OPERATIONAL,
+ nodeConnectorII.augmentation(FlowCapableNodeConnectorStatisticsData.class)).checkedGet();
+ assertTrue(flowCapableNodeConnectorStatisticsDataOptional.isPresent());
+ assertEquals(BIG_INTEGER_TEST_VALUE,
+ flowCapableNodeConnectorStatisticsDataOptional.get().getFlowCapableNodeConnectorStatistics()
+ .getReceiveDrops());
+ assertEquals(BIG_INTEGER_TEST_VALUE,
+ flowCapableNodeConnectorStatisticsDataOptional.get().getFlowCapableNodeConnectorStatistics()
+ .getCollisionCount());
+ }
+
+ private class ChangeListener implements DataChangeListener {
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ synchronized (waitObject) {
+ waitObject.notify();
+ }
+ }
+ }
+}
+
--- /dev/null
+package test.mock;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManagerActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityQueueStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import test.mock.util.StatisticsManagerTest;
+
+import com.google.common.base.Optional;
+
+
+public class QueueStatisticsTest extends StatisticsManagerTest {
+ private final Object waitObject = new Object();
+
+// @Test(timeout = 5000)
+ public void addedQueueOnDemandStatsTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+
+ final Port port = getPort();
+
+ final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder();
+ final FlowCapableNodeConnectorBuilder fcncBuilder = new FlowCapableNodeConnectorBuilder();
+ fcncBuilder.setConfiguration(port.getConfiguration());
+ fcncBuilder.setPortNumber(port.getPortNumber());
+ fcncBuilder.setQueue(Collections.<Queue>emptyList());
+ ncBuilder.setKey(new NodeConnectorKey(new NodeConnectorId("connector.1")));
+ ncBuilder.addAugmentation(FlowCapableNodeConnector.class, fcncBuilder.build());
+
+
+ final Queue queue = getQueue();
+ final InstanceIdentifier<Queue> queueII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .child(NodeConnector.class, ncBuilder.getKey()).augmentation(FlowCapableNodeConnector.class)
+ .child(Queue.class, queue.getKey());
+ final InstanceIdentifier<NodeConnector> nodeConnectorII = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key).child(NodeConnector.class, ncBuilder.getKey());
+
+ final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, nodeConnectorII, ncBuilder.build());
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, queueII, queue);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, nodeConnectorII, ncBuilder.build());
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, queueII, queue);
+ assertCommit(writeTx.submit());
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ queueII.augmentation(FlowCapableNodeConnectorQueueStatisticsData.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ final ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<FlowCapableNodeConnectorQueueStatisticsData> queueStatsOptional = readTx.read(LogicalDatastoreType.OPERATIONAL,
+ queueII.augmentation(FlowCapableNodeConnectorQueueStatisticsData.class)).checkedGet();
+ assertTrue(queueStatsOptional.isPresent());
+ assertEquals(COUNTER_64_TEST_VALUE,
+ queueStatsOptional.get().getFlowCapableNodeConnectorQueueStatistics().getTransmittedBytes());
+ }
+
+// @Test(timeout = 5000)
+ public void deletedQueueStatsRemovalTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNode(s1Key);
+
+ final Port port = getPort();
+
+ final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder();
+ final FlowCapableNodeConnectorBuilder fcncBuilder = new FlowCapableNodeConnectorBuilder();
+ fcncBuilder.setConfiguration(port.getConfiguration());
+ fcncBuilder.setPortNumber(port.getPortNumber());
+ fcncBuilder.setQueue(Collections.<Queue>emptyList());
+ ncBuilder.setKey(new NodeConnectorKey(new NodeConnectorId("connector.1")));
+ ncBuilder.addAugmentation(FlowCapableNodeConnector.class, fcncBuilder.build());
+
+
+ final Queue queue = getQueue();
+ final InstanceIdentifier<Queue> queueII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .child(NodeConnector.class, ncBuilder.getKey()).augmentation(FlowCapableNodeConnector.class)
+ .child(Queue.class, queue.getKey());
+ final InstanceIdentifier<NodeConnector> nodeConnectorII = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key).child(NodeConnector.class, ncBuilder.getKey());
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, nodeConnectorII, ncBuilder.build());
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, queueII, queue);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, nodeConnectorII, ncBuilder.build());
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, queueII, queue);
+ assertCommit(writeTx.submit());
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ queueII.augmentation(FlowCapableNodeConnectorQueueStatisticsData.class),
+ new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ Optional<FlowCapableNodeConnectorQueueStatisticsData> queueStatsOptional = readTx.read(LogicalDatastoreType.OPERATIONAL,
+ queueII.augmentation(FlowCapableNodeConnectorQueueStatisticsData.class)).checkedGet();
+ assertTrue(queueStatsOptional.isPresent());
+ assertEquals(COUNTER_64_TEST_VALUE,
+ queueStatsOptional.get().getFlowCapableNodeConnectorQueueStatistics().getTransmittedBytes());
+
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.CONFIGURATION, queueII);
+ assertCommit(writeTx.submit());
+
+ readTx = getDataBroker().newReadOnlyTransaction();
+ queueStatsOptional = readTx.read(LogicalDatastoreType.OPERATIONAL,
+ queueII.augmentation(FlowCapableNodeConnectorQueueStatisticsData.class)).checkedGet();
+ assertFalse(queueStatsOptional.isPresent());
+ }
+
+// @Test(timeout = 23000)
+ public void getAllStatsFromConnectedNodeTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNodeWithFeatures(s1Key, false, FlowFeatureCapabilityQueueStats.class);
+
+ final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder();
+ final FlowCapableNodeConnectorBuilder fcncBuilder = new FlowCapableNodeConnectorBuilder();
+ ncBuilder.setKey(new NodeConnectorKey(getNodeConnectorId()));
+ ncBuilder.addAugmentation(FlowCapableNodeConnector.class, fcncBuilder.build());
+
+ final InstanceIdentifier<NodeConnector> nodeConnectorII = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, s1Key)
+ .child(NodeConnector.class, ncBuilder.getKey());
+
+ final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, nodeConnectorII, ncBuilder.build());
+ final InstanceIdentifier<Queue> queueII = nodeConnectorII.augmentation(FlowCapableNodeConnector.class)
+ .child(Queue.class, getQueue().getKey());
+ final QueueBuilder qBuilder = new QueueBuilder(getQueue());
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, queueII, qBuilder.build());
+ assertCommit(writeTx.submit());
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ queueII.augmentation(FlowCapableNodeConnectorQueueStatisticsData.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ final ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<Queue> queueOptional = readTx.read(LogicalDatastoreType.OPERATIONAL, queueII).checkedGet();
+ assertTrue(queueOptional.isPresent());
+ final FlowCapableNodeConnectorQueueStatisticsData queueStats =
+ queueOptional.get().getAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class);
+ assertTrue(queueStats != null);
+ assertEquals(COUNTER_64_TEST_VALUE,
+ queueStats.getFlowCapableNodeConnectorQueueStatistics().getTransmittedBytes());
+ }
+
+ private class ChangeListener implements DataChangeListener {
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ synchronized (waitObject) {
+ waitObject.notify();
+ }
+ }
+ }
+}
+
--- /dev/null
+package test.mock;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.statistics.manager.StatisticsManagerActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityTableStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import test.mock.util.StatisticsManagerTest;
+
+import com.google.common.base.Optional;
+
+public class TableStatisticsTest extends StatisticsManagerTest {
+ private final Object waitObject = new Object();
+
+// @Test(timeout = 23000)
+ public void getTableStatisticsTest() throws ExecutionException, InterruptedException, ReadFailedException {
+ final StatisticsManagerActivator activator = new StatisticsManagerActivator();
+ activator.onSessionInitiated(providerContext);
+
+ addFlowCapableNodeWithFeatures(s1Key, false, FlowFeatureCapabilityTableStats.class);
+
+ final TableId tableId = getTableId();
+ final InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId.getValue()));
+
+ getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ tableII.augmentation(FlowTableStatisticsData.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+
+ synchronized (waitObject) {
+ waitObject.wait();
+ }
+
+ final ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ final Optional<FlowTableStatisticsData> flowTableStatisticsDataOptional = readTx.read(
+ LogicalDatastoreType.OPERATIONAL, tableII.augmentation(FlowTableStatisticsData.class)).checkedGet();
+ assertTrue(flowTableStatisticsDataOptional.isPresent());
+ assertEquals(COUNTER_32_TEST_VALUE,
+ flowTableStatisticsDataOptional.get().getFlowTableStatistics().getActiveFlows());
+ assertEquals(COUNTER_64_TEST_VALUE,
+ flowTableStatisticsDataOptional.get().getFlowTableStatistics().getPacketsLookedUp());
+ }
+
+ private class ChangeListener implements DataChangeListener {
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ synchronized (waitObject) {
+ waitObject.notify();
+ }
+ }
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package test.mock.util;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class AbstractDataBrokerTest extends AbstractSchemaAwareTest {
+
+ private DataBrokerTestCustomizer testCustomizer;
+ private DataBroker dataBroker;
+ private DOMDataBroker domBroker;
+
+
+ @Override
+ protected void setupWithSchema(final SchemaContext context) {
+ testCustomizer = createDataBrokerTestCustomizer();
+ dataBroker = testCustomizer.createDataBroker();
+ domBroker = testCustomizer.createDOMDataBroker();
+ testCustomizer.updateSchema(context);
+ setupWithDataBroker(dataBroker);
+ }
+
+ protected void setupWithDataBroker(final DataBroker dataBroker) {
+ // Intentionally left No-op, subclasses may customize it
+ }
+
+ protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() {
+ return new DataBrokerTestCustomizer();
+ }
+
+ public DataBroker getDataBroker() {
+ return dataBroker;
+ }
+
+ public DOMDataBroker getDomBroker() {
+ return domBroker;
+ }
+
+ protected static final void assertCommit(final ListenableFuture<Void> commit) {
+ try {
+ commit.get(500, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package test.mock.util;
+
+import org.junit.Before;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public abstract class AbstractSchemaAwareTest {
+
+ private Iterable<YangModuleInfo> moduleInfos;
+ private SchemaContext schemaContext;
+
+
+ protected Iterable<YangModuleInfo> getModuleInfos() {
+ return BindingReflections.loadModuleInfos();
+ }
+
+
+ @Before
+ public final void setup() {
+ moduleInfos = getModuleInfos();
+ ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
+ moduleContext.addModuleInfos(moduleInfos);
+ schemaContext = moduleContext.tryToCreateSchemaContext().get();
+ setupWithSchema(schemaContext);
+ }
+
+ /**
+ * Setups test with Schema context.
+ * This method is called before {@link #setupWithSchemaService(SchemaService)}
+ *
+ * @param context
+ */
+ protected abstract void setupWithSchema(SchemaContext context);
+
+}
--- /dev/null
+package test.mock.util;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Dictionary;
+
+public class BundleContextMock implements BundleContext {
+ @Override
+ public String getProperty(String s) {
+ return null;
+ }
+
+ @Override
+ public Bundle getBundle() {
+ return null;
+ }
+
+ @Override
+ public Bundle installBundle(String s, InputStream inputStream) throws BundleException {
+ return null;
+ }
+
+ @Override
+ public Bundle installBundle(String s) throws BundleException {
+ return null;
+ }
+
+ @Override
+ public Bundle getBundle(long l) {
+ return null;
+ }
+
+ @Override
+ public Bundle[] getBundles() {
+ return new Bundle[0];
+ }
+
+ @Override
+ public void addServiceListener(ServiceListener serviceListener, String s) throws InvalidSyntaxException {
+
+ }
+
+ @Override
+ public void addServiceListener(ServiceListener serviceListener) {
+
+ }
+
+ @Override
+ public void removeServiceListener(ServiceListener serviceListener) {
+
+ }
+
+ @Override
+ public void addBundleListener(BundleListener bundleListener) {
+
+ }
+
+ @Override
+ public void removeBundleListener(BundleListener bundleListener) {
+
+ }
+
+ @Override
+ public void addFrameworkListener(FrameworkListener frameworkListener) {
+
+ }
+
+ @Override
+ public void removeFrameworkListener(FrameworkListener frameworkListener) {
+
+ }
+
+ @Override
+ public ServiceRegistration<?> registerService(String[] strings, Object o, Dictionary<String, ?> stringDictionary) {
+ return null;
+ }
+
+ @Override
+ public ServiceRegistration<?> registerService(String s, Object o, Dictionary<String, ?> stringDictionary) {
+ return null;
+ }
+
+ @Override
+ public <S> ServiceRegistration<S> registerService(Class<S> sClass, S s, Dictionary<String, ?> stringDictionary) {
+ return null;
+ }
+
+ @Override
+ public ServiceReference<?>[] getServiceReferences(String s, String s2) throws InvalidSyntaxException {
+ return new ServiceReference<?>[0];
+ }
+
+ @Override
+ public ServiceReference<?>[] getAllServiceReferences(String s, String s2) throws InvalidSyntaxException {
+ return new ServiceReference<?>[0];
+ }
+
+ @Override
+ public ServiceReference<?> getServiceReference(String s) {
+ return null;
+ }
+
+ @Override
+ public <S> ServiceReference<S> getServiceReference(Class<S> sClass) {
+ return null;
+ }
+
+ @Override
+ public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> sClass, String s) throws InvalidSyntaxException {
+ return null;
+ }
+
+ @Override
+ public <S> S getService(ServiceReference<S> sServiceReference) {
+ return null;
+ }
+
+ @Override
+ public boolean ungetService(ServiceReference<?> serviceReference) {
+ return false;
+ }
+
+ @Override
+ public File getDataFile(String s) {
+ return null;
+ }
+
+ @Override
+ public Filter createFilter(String s) throws InvalidSyntaxException {
+ return null;
+ }
+
+ @Override
+ public Bundle getBundle(String s) {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package test.mock.util;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import javassist.ClassPool;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class DataBrokerTestCustomizer {
+
+ private DOMDataBroker domDataBroker;
+ private final RuntimeGeneratedMappingServiceImpl mappingService;
+ private final MockSchemaService schemaService;
+ private ImmutableMap<LogicalDatastoreType, DOMStore> datastores;
+ private final BindingToNormalizedNodeCodec bindingToNormalized ;
+
+ public ImmutableMap<LogicalDatastoreType, DOMStore> createDatastores() {
+ return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
+ .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
+ .put(LogicalDatastoreType.CONFIGURATION,createConfigurationDatastore())
+ .build();
+ }
+
+ public DataBrokerTestCustomizer() {
+ schemaService = new MockSchemaService();
+ ClassPool pool = ClassPool.getDefault();
+ mappingService = new RuntimeGeneratedMappingServiceImpl(pool);
+ DataObjectSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(pool));
+ BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
+ GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
+ bindingToNormalized = new BindingToNormalizedNodeCodec(loading, mappingService, codecRegistry);
+ schemaService.registerSchemaContextListener(bindingToNormalized);
+ }
+
+ public DOMStore createConfigurationDatastore() {
+ InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG",
+ MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor());
+ schemaService.registerSchemaContextListener(store);
+ return store;
+ }
+
+ public DOMStore createOperationalDatastore() {
+ InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER",
+ MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor());
+ schemaService.registerSchemaContextListener(store);
+ return store;
+ }
+
+ public DOMDataBroker createDOMDataBroker() {
+ return new DOMDataBrokerImpl(getDatastores(), getCommitCoordinatorExecutor());
+ }
+
+ public ListeningExecutorService getCommitCoordinatorExecutor() {
+ return MoreExecutors.sameThreadExecutor();
+ }
+
+ public DataBroker createDataBroker() {
+ return new ForwardedBindingDataBroker(getDOMDataBroker(), bindingToNormalized, schemaService );
+ }
+
+ public ForwardedBackwardsCompatibleDataBroker createBackwardsCompatibleDataBroker() {
+ return new ForwardedBackwardsCompatibleDataBroker(getDOMDataBroker(), bindingToNormalized, getSchemaService(), MoreExecutors.sameThreadExecutor());
+ }
+
+ private SchemaService getSchemaService() {
+ return schemaService;
+ }
+
+ private DOMDataBroker getDOMDataBroker() {
+ if(domDataBroker == null) {
+ domDataBroker = createDOMDataBroker();
+ }
+ return domDataBroker;
+ }
+
+ private synchronized ImmutableMap<LogicalDatastoreType, DOMStore> getDatastores() {
+ if (datastores == null) {
+ datastores = createDatastores();
+ }
+ return datastores;
+ }
+
+ public void updateSchema(final SchemaContext ctx) {
+ schemaService.changeSchema(ctx);
+ mappingService.onGlobalContextUpdated(ctx);
+ }
+
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+public class FlowMockGenerator {
+ private static final Random rnd = new Random();
+ private static final FlowBuilder flowBuilder = new FlowBuilder();
+
+ public static Flow getRandomFlow() {
+ flowBuilder.setKey(new FlowKey(new FlowId("flow." + rnd.nextInt(1000))));
+ flowBuilder.setOutGroup(TestUtils.nextLong(0, 4294967296L));
+ flowBuilder.setTableId((short) rnd.nextInt(256));
+ flowBuilder.setOutPort(BigInteger.valueOf(TestUtils.nextLong(0, Long.MAX_VALUE)));
+ flowBuilder.setStrict(rnd.nextBoolean());
+ flowBuilder.setContainerName("container." + rnd.nextInt(1000));
+ flowBuilder.setBarrier(rnd.nextBoolean());
+ flowBuilder.setMatch(MatchMockGenerator.getRandomMatch());
+ flowBuilder.setPriority(rnd.nextInt(65535));
+ flowBuilder.setCookie(new FlowCookie(BigInteger.valueOf(TestUtils.nextLong(0, Long.MAX_VALUE))));
+ flowBuilder.setCookieMask(flowBuilder.getCookie());
+ return flowBuilder.build();
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+
+import java.util.Random;
+
+public class GroupMockGenerator {
+ private static final Random rnd = new Random();
+ private static final GroupBuilder groupBuilder = new GroupBuilder();
+
+ public static Group getRandomGroup() {
+ groupBuilder.setKey(new GroupKey(new GroupId(TestUtils.nextLong(0, 4294967295L))));
+ groupBuilder.setContainerName("container." + rnd.nextInt(1000));
+ groupBuilder.setBarrier(rnd.nextBoolean());
+ groupBuilder.setGroupName("group." + rnd.nextInt(1000));
+ groupBuilder.setGroupType(GroupTypes.forValue(rnd.nextInt(4)));
+ return groupBuilder.build();
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.MetadataBuilder;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+public class MatchMockGenerator {
+ private static final Random rnd = new Random();
+ private static final MatchBuilder matchBuilder = new MatchBuilder();
+ private static final IpMatchBuilder ipMatchBuilder = new IpMatchBuilder();
+ private static final MetadataBuilder metadataBuilder = new MetadataBuilder();
+
+ public static Match getRandomMatch() {
+ matchBuilder.setInPort(new NodeConnectorId("port." + rnd.nextInt(500)));
+ ipMatchBuilder.setIpDscp(new Dscp((short) rnd.nextInt(64))).build();
+ ipMatchBuilder.setIpEcn((short) rnd.nextInt(256));
+ ipMatchBuilder.setIpProtocol((short) rnd.nextInt(256));
+ matchBuilder.setIpMatch(ipMatchBuilder.build());
+ metadataBuilder.setMetadata(BigInteger.valueOf(TestUtils.nextLong(0, Long.MAX_VALUE)));
+ metadataBuilder.setMetadataMask(BigInteger.valueOf(TestUtils.nextLong(0, Long.MAX_VALUE)));
+ matchBuilder.setMetadata(metadataBuilder.build());
+ return matchBuilder.build();
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.BandId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.MeterBandHeadersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderKey;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+public class MeterMockGenerator {
+ private static final Random rnd = new Random();
+ private static final MeterBuilder meterBuilder = new MeterBuilder();
+ private static final MeterBandHeaderBuilder meterBandHeaderBuilder = new MeterBandHeaderBuilder();
+ private static final MeterBandHeadersBuilder meterBandHeadersBuilder = new MeterBandHeadersBuilder();
+
+ public static Meter getRandomMeter() {
+ meterBandHeaderBuilder.setKey(new MeterBandHeaderKey(new BandId(TestUtils.nextLong(0, 4294967295L))));
+ meterBandHeaderBuilder.setBandBurstSize(TestUtils.nextLong(0, 4294967295L));
+ meterBandHeaderBuilder.setBandRate(TestUtils.nextLong(0, 4294967295L));
+ List<MeterBandHeader> meterBandHeaders = new ArrayList<>();
+ meterBuilder.setKey(new MeterKey(new MeterId(TestUtils.nextLong(0, 4294967295L))));
+ meterBuilder.setBarrier(rnd.nextBoolean());
+ meterBuilder.setContainerName("container." + rnd.nextInt(1000));
+ meterBuilder.setMeterName("meter." + rnd.nextInt(1000));
+ meterBuilder.setMeterBandHeaders(meterBandHeadersBuilder.setMeterBandHeader(meterBandHeaders).build());
+ return meterBuilder.build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package test.mock.util;
+
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+
+@SuppressWarnings("deprecation")
+public final class MockSchemaService implements SchemaService, SchemaContextProvider {
+
+ private SchemaContext schemaContext;
+
+ ListenerRegistry<SchemaContextListener> listeners = ListenerRegistry.create();
+
+ @Override
+ public void addModule(final Module module) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public synchronized SchemaContext getGlobalContext() {
+ return schemaContext;
+ }
+
+ @Override
+ public synchronized SchemaContext getSessionContext() {
+ return schemaContext;
+ }
+
+ @Override
+ public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
+ final SchemaContextListener listener) {
+ return listeners.register(listener);
+ }
+
+ @Override
+ public void removeModule(final Module module) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public synchronized SchemaContext getSchemaContext() {
+ return schemaContext;
+ }
+
+ public synchronized void changeSchema(final SchemaContext newContext) {
+ schemaContext = newContext;
+ for (ListenerRegistration<SchemaContextListener> listener : listeners) {
+ listener.getInstance().onGlobalContextUpdated(schemaContext);
+ }
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
+import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class NotificationProviderServiceHelper {
+ private NotificationBrokerImpl notifBroker = new NotificationBrokerImpl(SingletonHolder.getDefaultNotificationExecutor());
+
+ public NotificationBrokerImpl getNotifBroker() {
+ return notifBroker;
+ }
+
+ public void pushDelayedNotification(final Notification notification, int delay) {
+ new Timer().schedule(new TimerTask() {
+ @Override
+ public void run() {
+ notifBroker.publish(notification);
+ }
+ }, delay);
+ }
+
+ public void pushNotification(final Notification notification) {
+ notifBroker.publish(notification);
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class OpendaylightFlowStatisticsServiceMock implements OpendaylightFlowStatisticsService {
+ NotificationProviderServiceHelper notifService;
+ AtomicLong transNum = new AtomicLong();
+
+ public OpendaylightFlowStatisticsServiceMock(NotificationProviderServiceHelper notifService) {
+ this.notifService = notifService;
+ }
+
+ @Override
+ public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
+ GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder builder = new GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
+ GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder builder = new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ AggregateFlowStatisticsUpdateBuilder afsuBuilder = new AggregateFlowStatisticsUpdateBuilder();
+ afsuBuilder.setMoreReplies(false);
+ afsuBuilder.setTransactionId(transId);
+ afsuBuilder.setByteCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ afsuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ notifService.pushDelayedNotification(afsuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(GetAllFlowStatisticsFromFlowTableInput input) {
+ GetAllFlowStatisticsFromFlowTableOutputBuilder builder = new GetAllFlowStatisticsFromFlowTableOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(GetAllFlowsStatisticsFromAllFlowTablesInput input) {
+ GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder builder = new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ List<FlowAndStatisticsMapList> flowAndStatisticsMapLists = new ArrayList<>();
+ FlowsStatisticsUpdateBuilder flowsStatisticsUpdateBuilder = new FlowsStatisticsUpdateBuilder();
+ flowsStatisticsUpdateBuilder.setTransactionId(transId);
+ flowsStatisticsUpdateBuilder.setMoreReplies(false);
+ flowsStatisticsUpdateBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ FlowAndStatisticsMapListBuilder flowAndStatisticsMapListBuilder = new FlowAndStatisticsMapListBuilder(StatisticsManagerTest.getFlow());
+ flowAndStatisticsMapListBuilder.setTableId(StatisticsManagerTest.getFlow().getTableId());
+ flowAndStatisticsMapListBuilder.setContainerName(StatisticsManagerTest.getFlow().getContainerName());
+ flowAndStatisticsMapListBuilder.setBarrier(StatisticsManagerTest.getFlow().isBarrier());
+ flowAndStatisticsMapListBuilder.setByteCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ flowAndStatisticsMapLists.add(flowAndStatisticsMapListBuilder.build());
+ flowsStatisticsUpdateBuilder.setFlowAndStatisticsMapList(flowAndStatisticsMapLists);
+ notifService.pushDelayedNotification(flowsStatisticsUpdateBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(GetFlowStatisticsFromFlowTableInput input) {
+ GetFlowStatisticsFromFlowTableOutputBuilder builder = new GetFlowStatisticsFromFlowTableOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ List<FlowAndStatisticsMapList> flowAndStatisticsMapLists = new ArrayList<>();
+ FlowsStatisticsUpdateBuilder flowsStatisticsUpdateBuilder = new FlowsStatisticsUpdateBuilder();
+ flowsStatisticsUpdateBuilder.setTransactionId(transId);
+ flowsStatisticsUpdateBuilder.setMoreReplies(false);
+ flowsStatisticsUpdateBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ FlowAndStatisticsMapListBuilder flowAndStatisticsMapListBuilder = new FlowAndStatisticsMapListBuilder(input);
+ flowAndStatisticsMapListBuilder.setTableId(input.getTableId());
+ flowAndStatisticsMapListBuilder.setContainerName(input.getContainerName());
+ flowAndStatisticsMapListBuilder.setBarrier(input.isBarrier());
+ flowAndStatisticsMapListBuilder.setByteCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ flowAndStatisticsMapLists.add(flowAndStatisticsMapListBuilder.build());
+ flowsStatisticsUpdateBuilder.setFlowAndStatisticsMapList(flowAndStatisticsMapLists);
+ notifService.pushDelayedNotification(flowsStatisticsUpdateBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+}
--- /dev/null
+package test.mock.util;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class OpendaylightFlowTableStatisticsServiceMock implements OpendaylightFlowTableStatisticsService {
+ NotificationProviderServiceHelper notifService;
+ AtomicLong transNum = new AtomicLong();
+
+ public OpendaylightFlowTableStatisticsServiceMock(NotificationProviderServiceHelper notifService) {
+ this.notifService = notifService;
+ }
+
+ @Override
+ public Future<RpcResult<GetFlowTablesStatisticsOutput>> getFlowTablesStatistics(GetFlowTablesStatisticsInput input) {
+ GetFlowTablesStatisticsOutputBuilder builder = new GetFlowTablesStatisticsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ FlowTableStatisticsUpdateBuilder ftsBuilder = new FlowTableStatisticsUpdateBuilder();
+ FlowTableAndStatisticsMapBuilder ftasmBuilder = new FlowTableAndStatisticsMapBuilder();
+ List<FlowTableAndStatisticsMap> tableAndStatisticsMaps = new ArrayList<>();
+ ftasmBuilder.setKey(new FlowTableAndStatisticsMapKey(StatisticsManagerTest.getTableId()));
+ ftasmBuilder.setActiveFlows(StatisticsManagerTest.COUNTER_32_TEST_VALUE);
+ tableAndStatisticsMaps.add(ftasmBuilder.build());
+ ftsBuilder.setTransactionId(transId);
+ ftsBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ ftsBuilder.setFlowTableAndStatisticsMap(tableAndStatisticsMaps);
+ ftsBuilder.setMoreReplies(true);
+ notifService.pushDelayedNotification(ftsBuilder.build(), 0); // 1st notification
+ ftsBuilder.setMoreReplies(false);
+ ftasmBuilder.setPacketsLookedUp(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ tableAndStatisticsMaps.clear();
+ tableAndStatisticsMaps.add(ftasmBuilder.build());
+ ftsBuilder.setFlowTableAndStatisticsMap(tableAndStatisticsMaps);
+ notifService.pushDelayedNotification(ftsBuilder.build(), 0); // 2nd notification
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+}
--- /dev/null
+package test.mock.util;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStatsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStatsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class OpendaylightGroupStatisticsServiceMock implements OpendaylightGroupStatisticsService {
+ NotificationProviderServiceHelper notifService;
+ AtomicLong transNum = new AtomicLong();
+
+ public OpendaylightGroupStatisticsServiceMock(NotificationProviderServiceHelper notifService) {
+ this.notifService = notifService;
+ }
+
+ @Override
+ public Future<RpcResult<GetAllGroupStatisticsOutput>> getAllGroupStatistics(GetAllGroupStatisticsInput input) {
+ GetAllGroupStatisticsOutputBuilder builder = new GetAllGroupStatisticsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ List<GroupStats> groupStats = new ArrayList<>();
+ GroupStatsBuilder gsBuilder = new GroupStatsBuilder();
+ GroupStatisticsUpdatedBuilder gsuBuilder = new GroupStatisticsUpdatedBuilder();
+ gsBuilder.setKey(new GroupStatsKey(StatisticsManagerTest.getGroup().getGroupId()));
+ gsBuilder.setByteCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ groupStats.add(gsBuilder.build());
+ builder.setGroupStats(groupStats);
+ gsuBuilder.setTransactionId(transId);
+ gsuBuilder.setMoreReplies(false);
+ gsuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ gsuBuilder.setGroupStats(groupStats);
+ notifService.pushDelayedNotification(gsuBuilder.build(), 500);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetGroupDescriptionOutput>> getGroupDescription(GetGroupDescriptionInput input) {
+ GetGroupDescriptionOutputBuilder builder = new GetGroupDescriptionOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ List<GroupDescStats> groupDescStats = new ArrayList<>();
+ GroupDescStatsUpdatedBuilder gdsuBuilder = new GroupDescStatsUpdatedBuilder();
+ GroupDescStatsBuilder gdsBuilder = new GroupDescStatsBuilder();
+ gdsBuilder.setKey(new GroupDescStatsKey(StatisticsManagerTest.getGroup().getGroupId()));
+ gdsBuilder.setBuckets(StatisticsManagerTest.getGroup().getBuckets());
+ gdsBuilder.setContainerName(StatisticsManagerTest.getGroup().getContainerName());
+ gdsBuilder.setGroupName(StatisticsManagerTest.getGroup().getGroupName());
+ gdsBuilder.setGroupType(StatisticsManagerTest.getGroup().getGroupType());
+ groupDescStats.add(gdsBuilder.build());
+ builder.setGroupDescStats(groupDescStats);
+ gdsuBuilder.setTransactionId(transId);
+ gdsuBuilder.setMoreReplies(false);
+ gdsuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ gdsuBuilder.setGroupDescStats(groupDescStats);
+ notifService.pushDelayedNotification(gdsuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetGroupFeaturesOutput>> getGroupFeatures(GetGroupFeaturesInput input) {
+ GetGroupFeaturesOutputBuilder builder = new GetGroupFeaturesOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ GroupFeaturesUpdatedBuilder gfuBuilder = new GroupFeaturesUpdatedBuilder();
+ gfuBuilder.setTransactionId(transId);
+ gfuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ gfuBuilder.setMoreReplies(false);
+ List<Long> maxGroups = new ArrayList<>();
+ maxGroups.add(StatisticsManagerTest.MAX_GROUPS_TEST_VALUE);
+ gfuBuilder.setMaxGroups(maxGroups);
+ notifService.pushDelayedNotification(gfuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetGroupStatisticsOutput>> getGroupStatistics(GetGroupStatisticsInput input) {
+ GetGroupStatisticsOutputBuilder builder = new GetGroupStatisticsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ GroupStatsBuilder gsBuilder = new GroupStatsBuilder();
+ List<GroupStats> groupStats = new ArrayList<>();
+ gsBuilder.setKey(new GroupStatsKey(input.getGroupId()));
+ gsBuilder.setByteCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ groupStats.add(gsBuilder.build());
+ GroupStatisticsUpdatedBuilder gsuBuilder = new GroupStatisticsUpdatedBuilder();
+ gsuBuilder.setTransactionId(transId);
+ gsuBuilder.setMoreReplies(false);
+ gsuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ gsuBuilder.setGroupStats(groupStats);
+ notifService.pushDelayedNotification(gsuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStatsKey;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class OpendaylightMeterStatisticsServiceMock implements OpendaylightMeterStatisticsService {
+ NotificationProviderServiceHelper notifService;
+ AtomicLong transNum = new AtomicLong();
+
+ public OpendaylightMeterStatisticsServiceMock(NotificationProviderServiceHelper notifService) {
+ this.notifService = notifService;
+ }
+
+ @Override
+ public Future<RpcResult<GetAllMeterConfigStatisticsOutput>> getAllMeterConfigStatistics(GetAllMeterConfigStatisticsInput input) {
+ GetAllMeterConfigStatisticsOutputBuilder builder = new GetAllMeterConfigStatisticsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ List<MeterConfigStats> meterConfigStats = new ArrayList<>();
+ MeterConfigStatsBuilder mcsBuilder = new MeterConfigStatsBuilder();
+ mcsBuilder.setMeterId(StatisticsManagerTest.getMeter().getMeterId());
+ mcsBuilder.setMeterName(StatisticsManagerTest.getMeter().getMeterName());
+ mcsBuilder.setContainerName(StatisticsManagerTest.getMeter().getContainerName());
+ meterConfigStats.add(mcsBuilder.build());
+ builder.setMeterConfigStats(meterConfigStats);
+ MeterConfigStatsUpdatedBuilder mscuBuilder = new MeterConfigStatsUpdatedBuilder();
+ mscuBuilder.setTransactionId(transId);
+ mscuBuilder.setMoreReplies(false);
+ mscuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ mscuBuilder.setMeterConfigStats(meterConfigStats);
+ notifService.pushDelayedNotification(mscuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetAllMeterStatisticsOutput>> getAllMeterStatistics(GetAllMeterStatisticsInput input) {
+ GetAllMeterStatisticsOutputBuilder builder = new GetAllMeterStatisticsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ MeterStatsBuilder msBuilder = new MeterStatsBuilder();
+ msBuilder.setByteInCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ msBuilder.setPacketInCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ msBuilder.setKey(new MeterStatsKey(StatisticsManagerTest.getMeter().getMeterId()));
+ List<MeterStats> meterStats = new ArrayList<>();
+ meterStats.add(msBuilder.build());
+ MeterStatisticsUpdatedBuilder msuBuilder = new MeterStatisticsUpdatedBuilder();
+ msuBuilder.setTransactionId(transId);
+ msuBuilder.setMoreReplies(false);
+ msuBuilder.setMeterStats(meterStats);
+ msuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ notifService.pushDelayedNotification(msuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetMeterFeaturesOutput>> getMeterFeatures(GetMeterFeaturesInput input) {
+ GetMeterFeaturesOutputBuilder builder = new GetMeterFeaturesOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ MeterFeaturesUpdatedBuilder mfuBuilder = new MeterFeaturesUpdatedBuilder();
+ mfuBuilder.setTransactionId(transId);
+ mfuBuilder.setMoreReplies(false);
+ mfuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ mfuBuilder.setMaxMeter(StatisticsManagerTest.COUNTER_32_TEST_VALUE);
+ notifService.pushDelayedNotification(mfuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetMeterStatisticsOutput>> getMeterStatistics(GetMeterStatisticsInput input) {
+ GetMeterStatisticsOutputBuilder builder = new GetMeterStatisticsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ MeterStatsBuilder msBuilder = new MeterStatsBuilder();
+ msBuilder.setKey(new MeterStatsKey(input.getMeterId()));
+ msBuilder.setByteInCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ msBuilder.setPacketInCount(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ List<MeterStats> meterStats = new ArrayList<>();
+ meterStats.add(msBuilder.build());
+ MeterStatisticsUpdatedBuilder msuBuilder = new MeterStatisticsUpdatedBuilder();
+ msuBuilder.setTransactionId(transId);
+ msuBuilder.setMoreReplies(false);
+ msuBuilder.setMeterStats(meterStats);
+ msuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ notifService.pushDelayedNotification(msuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class OpendaylightPortStatisticsServiceMock implements OpendaylightPortStatisticsService {
+ NotificationProviderServiceHelper notifService;
+ AtomicLong transNum = new AtomicLong();
+
+ public OpendaylightPortStatisticsServiceMock(NotificationProviderServiceHelper notifService) {
+ this.notifService = notifService;
+ }
+
+ @Override
+ public Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> getAllNodeConnectorsStatistics(GetAllNodeConnectorsStatisticsInput input) {
+ GetAllNodeConnectorsStatisticsOutputBuilder builder = new GetAllNodeConnectorsStatisticsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ NodeConnectorStatisticsUpdateBuilder ncsuBuilder = new NodeConnectorStatisticsUpdateBuilder();
+ NodeConnectorStatisticsAndPortNumberMapBuilder ncsapnmBuilder = new NodeConnectorStatisticsAndPortNumberMapBuilder();
+ List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsAndPortNumberMaps = new ArrayList<>();
+ ncsapnmBuilder.setKey(new NodeConnectorStatisticsAndPortNumberMapKey(StatisticsManagerTest.getNodeConnectorId()));
+ ncsapnmBuilder.setReceiveDrops(StatisticsManagerTest.BIG_INTEGER_TEST_VALUE);
+ nodeConnectorStatisticsAndPortNumberMaps.add(ncsapnmBuilder.build());
+ ncsuBuilder.setTransactionId(new TransactionId(BigInteger.valueOf(1)));
+ ncsuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ ncsuBuilder.setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatisticsAndPortNumberMaps);
+ ncsuBuilder.setMoreReplies(true);
+ notifService.pushDelayedNotification(ncsuBuilder.build(), 0); // 1st notification
+ ncsuBuilder.setMoreReplies(false);
+ ncsapnmBuilder.setCollisionCount(StatisticsManagerTest.BIG_INTEGER_TEST_VALUE);
+ nodeConnectorStatisticsAndPortNumberMaps.clear();
+ nodeConnectorStatisticsAndPortNumberMaps.add(ncsapnmBuilder.build());
+ ncsuBuilder.setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatisticsAndPortNumberMaps);
+ notifService.pushDelayedNotification(ncsuBuilder.build(), 10); // 2nd notification
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetNodeConnectorStatisticsOutput>> getNodeConnectorStatistics(GetNodeConnectorStatisticsInput input) {
+ GetNodeConnectorStatisticsOutputBuilder builder = new GetNodeConnectorStatisticsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapKey;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class OpendaylightQueueStatisticsServiceMock implements OpendaylightQueueStatisticsService {
+ NotificationProviderServiceHelper notifService;
+ AtomicLong transNum = new AtomicLong();
+
+ public OpendaylightQueueStatisticsServiceMock(NotificationProviderServiceHelper notifService) {
+ this.notifService = notifService;
+ }
+
+ @Override
+ public Future<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> getAllQueuesStatisticsFromAllPorts(GetAllQueuesStatisticsFromAllPortsInput input) {
+ GetAllQueuesStatisticsFromAllPortsOutputBuilder builder = new GetAllQueuesStatisticsFromAllPortsOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ QueueStatisticsUpdateBuilder qsuBuilder = new QueueStatisticsUpdateBuilder();
+ QueueIdAndStatisticsMapBuilder qiasmBuilder = new QueueIdAndStatisticsMapBuilder();
+ List<QueueIdAndStatisticsMap> queueIdAndStatisticsMaps = new ArrayList<>();
+ qsuBuilder.setMoreReplies(false);
+ qsuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ qsuBuilder.setTransactionId(transId);
+ qiasmBuilder.setTransmittedBytes(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ qiasmBuilder.setKey(new QueueIdAndStatisticsMapKey(StatisticsManagerTest.getNodeConnectorId(), StatisticsManagerTest.getQueue().getQueueId()));
+ queueIdAndStatisticsMaps.add(qiasmBuilder.build());
+ qsuBuilder.setQueueIdAndStatisticsMap(queueIdAndStatisticsMaps);
+ notifService.pushDelayedNotification(qsuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> getAllQueuesStatisticsFromGivenPort(GetAllQueuesStatisticsFromGivenPortInput input) {
+ GetAllQueuesStatisticsFromGivenPortOutputBuilder builder = new GetAllQueuesStatisticsFromGivenPortOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+
+ @Override
+ public Future<RpcResult<GetQueueStatisticsFromGivenPortOutput>> getQueueStatisticsFromGivenPort(GetQueueStatisticsFromGivenPortInput input) {
+ GetQueueStatisticsFromGivenPortOutputBuilder builder = new GetQueueStatisticsFromGivenPortOutputBuilder();
+ TransactionId transId = new TransactionId(BigInteger.valueOf(transNum.incrementAndGet()));
+ builder.setTransactionId(transId);
+ QueueIdAndStatisticsMapBuilder qiasmBuilder = new QueueIdAndStatisticsMapBuilder();
+ List<QueueIdAndStatisticsMap> queueIdAndStatisticsMaps = new ArrayList<>();
+ qiasmBuilder.setKey(new QueueIdAndStatisticsMapKey(input.getNodeConnectorId(), input.getQueueId()));
+ qiasmBuilder.setTransmittedBytes(StatisticsManagerTest.COUNTER_64_TEST_VALUE);
+ queueIdAndStatisticsMaps.add(qiasmBuilder.build());
+ QueueStatisticsUpdateBuilder qsuBuilder = new QueueStatisticsUpdateBuilder();
+ qsuBuilder.setMoreReplies(false);
+ qsuBuilder.setTransactionId(transId);
+ qsuBuilder.setId(input.getNode().getValue().firstKeyOf(Node.class, NodeKey.class).getId());
+ qsuBuilder.setQueueIdAndStatisticsMap(queueIdAndStatisticsMaps);
+ notifService.pushDelayedNotification(qsuBuilder.build(), 100);
+ return Futures.immediateFuture(RpcResultBuilder.success(builder.build()).build());
+ }
+}
--- /dev/null
+package test.mock.util;
+
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.CommonPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.PortBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.PortKey;
+
+import java.util.Random;
+
+public class PortMockGenerator {
+ private static final Random rnd = new Random();
+ private static final PortBuilder portBuilder = new PortBuilder();
+
+ public static Port getRandomPort() {
+ portBuilder.setKey(new PortKey(TestUtils.nextLong(0, 4294967295L)));
+ portBuilder.setBarrier(rnd.nextBoolean());
+ portBuilder.setPortNumber(new CommonPort.PortNumber(TestUtils.nextLong(0, 4294967295L)));
+ portBuilder.setConfiguration(new PortConfig(rnd.nextBoolean(), rnd.nextBoolean(), rnd.nextBoolean(), rnd.nextBoolean()));
+ return portBuilder.build();
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public class ProviderContextMock implements BindingAwareBroker.ProviderContext {
+
+ RpcProviderRegistry rpcProviderMock;
+ NotificationProviderService notificationProviderService;
+ DataBroker dataBroker;
+
+ public ProviderContextMock(RpcProviderRegistry rpcProviderMock, DataBroker dataBroker,
+ NotificationProviderService notificationProviderServiceMock) {
+ this.rpcProviderMock = rpcProviderMock;
+ this.dataBroker = dataBroker;
+ this.notificationProviderService = notificationProviderServiceMock;
+ }
+
+ @Override
+ public void registerFunctionality(BindingAwareProvider.ProviderFunctionality functionality) {
+
+ }
+
+ @Override
+ public void unregisterFunctionality(BindingAwareProvider.ProviderFunctionality functionality) {
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T extends BindingAwareService> T getSALService(Class<T> service) {
+ if (service.equals(DataBroker.class)) {
+ return (T) dataBroker;
+ }
+ else if (service.equals(NotificationProviderService.class)) {
+ return (T) notificationProviderService;
+ }
+ return null;
+ }
+
+ @Override
+ public <T extends RpcService> BindingAwareBroker.RpcRegistration<T> addRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public <T extends RpcService> BindingAwareBroker.RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(L listener) {
+ return null;
+ }
+
+ @Override
+ public <T extends RpcService> T getRpcService(Class<T> serviceInterface) {
+ return rpcProviderMock.getRpcService(serviceInterface);
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
+
+import java.util.Random;
+
+public class QueueMockGenerator {
+ private static final Random rnd = new Random();
+ private static final QueueBuilder queueBuilder = new QueueBuilder();
+
+ public static Queue getRandomQueue() {
+ queueBuilder.setKey(new QueueKey(new QueueId(TestUtils.nextLong(0, 4294967295L))));
+ queueBuilder.setPort(TestUtils.nextLong(0, 4294967295L));
+ queueBuilder.setProperty(rnd.nextInt(65535));
+ return queueBuilder.build();
+ }
+
+ public static Queue getRandomQueueWithPortNum(long portNum) {
+ queueBuilder.setKey(new QueueKey(new QueueId(TestUtils.nextLong(0, 4294967295L))));
+ queueBuilder.setPort(portNum);
+ queueBuilder.setProperty(rnd.nextInt(65535));
+ return queueBuilder.build();
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public class RpcProviderRegistryMock implements RpcProviderRegistry {
+
+ OpendaylightFlowStatisticsServiceMock flowStatisticsServiceMock;
+ OpendaylightFlowTableStatisticsServiceMock flowTableStatisticsServiceMock;
+ OpendaylightGroupStatisticsServiceMock groupStatisticsServiceMock;
+ OpendaylightMeterStatisticsServiceMock meterStatisticsServiceMock;
+ OpendaylightPortStatisticsServiceMock portStatisticsServiceMock;
+ OpendaylightQueueStatisticsServiceMock queueStatisticsServiceMock;
+
+ public RpcProviderRegistryMock(NotificationProviderServiceHelper notificationProviderService) {
+ this.flowStatisticsServiceMock = new OpendaylightFlowStatisticsServiceMock(notificationProviderService);
+ this.flowTableStatisticsServiceMock = new OpendaylightFlowTableStatisticsServiceMock(notificationProviderService);
+ this.groupStatisticsServiceMock = new OpendaylightGroupStatisticsServiceMock(notificationProviderService);
+ this.meterStatisticsServiceMock = new OpendaylightMeterStatisticsServiceMock(notificationProviderService);
+ this.portStatisticsServiceMock = new OpendaylightPortStatisticsServiceMock(notificationProviderService);
+ this.queueStatisticsServiceMock = new OpendaylightQueueStatisticsServiceMock(notificationProviderService);
+ }
+
+ @Override
+ public <T extends RpcService> BindingAwareBroker.RpcRegistration<T> addRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public <T extends RpcService> BindingAwareBroker.RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(L listener) {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T extends RpcService> T getRpcService(Class<T> serviceInterface) {
+ if (serviceInterface.equals(OpendaylightFlowStatisticsService.class)) {
+ return (T)flowStatisticsServiceMock;
+ } else if (serviceInterface.equals(OpendaylightFlowTableStatisticsService.class)) {
+ return (T) flowTableStatisticsServiceMock;
+ } else if (serviceInterface.equals(OpendaylightGroupStatisticsService.class)) {
+ return (T) groupStatisticsServiceMock;
+ } else if (serviceInterface.equals(OpendaylightMeterStatisticsService.class)) {
+ return (T) meterStatisticsServiceMock;
+ } else if (serviceInterface.equals(OpendaylightPortStatisticsService.class)) {
+ return (T) portStatisticsServiceMock;
+ } else if (serviceInterface.equals(OpendaylightQueueStatisticsService.class)) {
+ return (T) queueStatisticsServiceMock;
+ } else {
+ return null;
+ }
+ }
+
+ public OpendaylightFlowStatisticsServiceMock getFlowStatisticsServiceMock() {
+ return flowStatisticsServiceMock;
+ }
+
+ public OpendaylightFlowTableStatisticsServiceMock getFlowTableStatisticsServiceMock() {
+ return flowTableStatisticsServiceMock;
+ }
+
+ public OpendaylightGroupStatisticsServiceMock getGroupStatisticsServiceMock() {
+ return groupStatisticsServiceMock;
+ }
+
+ public OpendaylightMeterStatisticsServiceMock getMeterStatisticsServiceMock() {
+ return meterStatisticsServiceMock;
+ }
+
+ public OpendaylightPortStatisticsServiceMock getPortStatisticsServiceMock() {
+ return portStatisticsServiceMock;
+ }
+
+ public OpendaylightQueueStatisticsServiceMock getQueueStatisticsServiceMock() {
+ return queueStatisticsServiceMock;
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter64;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SwitchFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+public abstract class StatisticsManagerTest extends AbstractDataBrokerTest {
+
+ public static final Counter64 COUNTER_64_TEST_VALUE = new Counter64(BigInteger.valueOf(128));
+ public static final Counter32 COUNTER_32_TEST_VALUE = new Counter32(64L);
+ public static final Long MAX_GROUPS_TEST_VALUE = 2000L;
+ public static final BigInteger BIG_INTEGER_TEST_VALUE = BigInteger.valueOf(1000);
+
+ private static Flow flow;
+ private static Group group;
+ private static Meter meter;
+ private static Port port;
+ private static Queue queue;
+ private static TableId tableId;
+ private static NodeConnectorId nodeConnectorId;
+
+ private final NotificationProviderServiceHelper notificationMock = new NotificationProviderServiceHelper();
+ protected final NodeKey s1Key = new NodeKey(new NodeId("S1"));
+ protected RpcProviderRegistryMock rpcRegistry;
+ protected ProviderContextMock providerContext;
+
+ @BeforeClass
+ public static void setupTests() {
+ flow = FlowMockGenerator.getRandomFlow();
+ group = GroupMockGenerator.getRandomGroup();
+ meter = MeterMockGenerator.getRandomMeter();
+ port = PortMockGenerator.getRandomPort();
+ queue = QueueMockGenerator.getRandomQueueWithPortNum(port.getPortNumber().getUint32());
+ tableId = new TableId((short) 2);
+ nodeConnectorId = new NodeConnectorId("connector.1");
+ }
+
+ @Before
+ public void init() {
+ rpcRegistry = new RpcProviderRegistryMock(notificationMock);
+ providerContext = new ProviderContextMock(rpcRegistry, getDataBroker(), notificationMock.getNotifBroker());
+ }
+
+ // node with statistics capabilities will enable cyclic statistics collection
+ @SafeVarargs
+ protected final void addFlowCapableNodeWithFeatures(final NodeKey nodeKey, final Boolean hasMeterCapabilities,
+ final Class<? extends FeatureCapability>... capabilities)
+ throws ExecutionException, InterruptedException {
+ final Nodes nodes = new NodesBuilder().setNode(Collections.<Node>emptyList()).build();
+ final InstanceIdentifier<Node> flowNodeIdentifier = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, nodeKey);
+
+ final FlowCapableNodeBuilder fcnBuilder = new FlowCapableNodeBuilder();
+ final SwitchFeaturesBuilder sfBuilder = new SwitchFeaturesBuilder();
+ final List<Class<? extends FeatureCapability>> capabilitiyList = new ArrayList<>();
+ for (final Class<? extends FeatureCapability> capability : capabilities) {
+ capabilitiyList.add(capability);
+ }
+ sfBuilder.setCapabilities(capabilitiyList);
+ sfBuilder.setMaxTables((short) 2);
+ final NodeBuilder nodeBuilder = new NodeBuilder();
+ nodeBuilder.setKey(nodeKey);
+ fcnBuilder.setSwitchFeatures(sfBuilder.build());
+ final List<Table> tables = new ArrayList<>();
+ final TableBuilder tBuilder = new TableBuilder();
+ tBuilder.setId(getFlow().getTableId());
+ tables.add(tBuilder.build());
+ fcnBuilder.setTable(tables);
+ final FlowCapableNode flowCapableNode = fcnBuilder.build();
+ nodeBuilder.addAugmentation(FlowCapableNode.class, flowCapableNode);
+ final Node node = nodeBuilder.build();
+
+ final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodes);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, flowNodeIdentifier, nodeBuilder.build());
+ if (hasMeterCapabilities) {
+ final NodeMeterFeaturesBuilder nmfBuilder = new NodeMeterFeaturesBuilder();
+ final MeterFeaturesBuilder mfBuilder = new MeterFeaturesBuilder();
+ mfBuilder.setMaxBands((short) 4);
+ nmfBuilder.setMeterFeatures(mfBuilder.build());
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, flowNodeIdentifier.augmentation(NodeMeterFeatures.class),
+ nmfBuilder.build());
+ }
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Nodes.class), nodes);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowNodeIdentifier, node);
+ assertCommit(writeTx.submit());
+
+ final NodeUpdatedBuilder nuBuilder = new NodeUpdatedBuilder(node);
+ final FlowCapableNodeUpdatedBuilder fcnuBuilder = new FlowCapableNodeUpdatedBuilder(flowCapableNode);
+ nuBuilder.setNodeRef(new NodeRef(flowNodeIdentifier));
+ nuBuilder.addAugmentation(FlowCapableNodeUpdated.class, fcnuBuilder.build());
+ notificationMock.pushNotification(nuBuilder.build());
+ }
+
+ public void addFlowCapableNode(final NodeKey nodeKey) throws ExecutionException, InterruptedException {
+ final Nodes nodes = new NodesBuilder().setNode(Collections.<Node>emptyList()).build();
+ final InstanceIdentifier<Node> flowNodeIdentifier = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, nodeKey);
+
+ final FlowCapableNodeBuilder fcnBuilder = new FlowCapableNodeBuilder();
+ final NodeBuilder nodeBuilder = new NodeBuilder();
+ nodeBuilder.setKey(nodeKey);
+ final FlowCapableNode flowCapableNode = fcnBuilder.build();
+ nodeBuilder.addAugmentation(FlowCapableNode.class, flowCapableNode);
+ final Node node = nodeBuilder.build();
+
+ final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodes);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, flowNodeIdentifier, node);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Nodes.class), nodes);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowNodeIdentifier, node);
+ assertCommit(writeTx.submit());
+
+ final NodeUpdatedBuilder nuBuilder = new NodeUpdatedBuilder(node);
+ final FlowCapableNodeUpdatedBuilder fcnuBuilder = new FlowCapableNodeUpdatedBuilder(flowCapableNode);
+ nuBuilder.setNodeRef(new NodeRef(flowNodeIdentifier));
+ nuBuilder.addAugmentation(FlowCapableNodeUpdated.class, fcnuBuilder.build());
+ notificationMock.pushNotification(nuBuilder.build());
+ }
+
+ protected void removeNode(final NodeKey nodeKey) throws ExecutionException, InterruptedException {
+ final InstanceIdentifier<Node> nodeII = InstanceIdentifier.create(Nodes.class).child(Node.class, nodeKey);
+
+ final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.OPERATIONAL, nodeII);
+ writeTx.submit().get();
+
+ final NodeRemovedBuilder nrBuilder = new NodeRemovedBuilder();
+ nrBuilder.setNodeRef(new NodeRef(nodeII));
+ notificationMock.pushNotification(nrBuilder.build());
+ }
+
+ public static Flow getFlow() {
+ return flow;
+ }
+
+ public static Group getGroup() {
+ return group;
+ }
+
+ public static Meter getMeter() {
+ return meter;
+ }
+
+ public static Port getPort() {
+ return port;
+ }
+
+ public static Queue getQueue() {
+ return queue;
+ }
+
+ public static TableId getTableId() {
+ return tableId;
+ }
+
+ public static NodeConnectorId getNodeConnectorId() {
+ return nodeConnectorId;
+ }
+}
+
--- /dev/null
+package test.mock.util;
+
+import java.util.Random;
+
+public class TestUtils {
+ private static Random rnd = new Random();
+
+ public static long nextLong(long RangeBottom, long rangeTop) {
+ return RangeBottom + ((long)(rnd.nextDouble()*(rangeTop - RangeBottom)));
+ }
+}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.controller.md</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.md</groupId>
<artifactId>topology-manager</artifactId>
*/
package org.opendaylight.md.controller.topology.manager;
-import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.getNodeConnectorKey;
-import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.getNodeKey;
-import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTerminationPoint;
-import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTerminationPointId;
-import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyLink;
-import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNode;
-import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNodeId;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import java.util.List;
+
+import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.getNodeConnectorKey;
+import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.getNodeKey;
+import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTerminationPoint;
+import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTerminationPointId;
+import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyLink;
+import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNode;
+import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNodeId;
class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, OpendaylightInventoryListener {
processor.enqueueOperation(new TopologyOperation() {
@Override
public void applyOperation(ReadWriteTransaction transaction) {
- removeAffectedLinks(nodeId, transaction);
- transaction.delete(LogicalDatastoreType.OPERATIONAL, nodeInstance);
+ removeAffectedLinks(nodeId, transaction);
+ transaction.delete(LogicalDatastoreType.OPERATIONAL, nodeInstance);
}
@Override
final InstanceIdentifier<TerminationPoint> tpInstance = toTerminationPointIdentifier(
notification.getNodeConnectorRef());
+ final InstanceIdentifier<Node> node = tpInstance.firstIdentifierOf(Node.class);
+
final TpId tpId = toTerminationPointId(getNodeConnectorKey(
notification.getNodeConnectorRef()).getId());
processor.enqueueOperation(new TopologyOperation() {
@Override
public void applyOperation(ReadWriteTransaction transaction) {
- removeAffectedLinks(tpId, transaction);
- transaction.delete(LogicalDatastoreType.OPERATIONAL, tpInstance);
+ Optional<Node> nodeOptional = Optional.absent();
+ try {
+ nodeOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, node).checkedGet();
+ } catch (ReadFailedException e) {
+ LOG.error("Error occured when trying to read NodeConnector ", e);
+ }
+ if (nodeOptional.isPresent()) {
+ removeAffectedLinks(tpId, transaction);
+ transaction.delete(LogicalDatastoreType.OPERATIONAL, tpInstance);
+ }
}
@Override
public void applyOperation(final ReadWriteTransaction transaction) {
final Link link = toTopologyLink(notification);
final InstanceIdentifier<Link> path = linkPath(link);
- transaction.merge(LogicalDatastoreType.OPERATIONAL, path, link, true);
+ transaction.put(LogicalDatastoreType.OPERATIONAL, path, link, true);
}
@Override
processor.enqueueOperation(new TopologyOperation() {
@Override
public void applyOperation(final ReadWriteTransaction transaction) {
- transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(toTopologyLink(notification)));
+ Optional<Link> linkOptional = Optional.absent();
+ try {
+ // read that checks if link exists (if we do not do this we might get an exception on delete)
+ linkOptional = transaction.read(LogicalDatastoreType.OPERATIONAL,
+ linkPath(toTopologyLink(notification))).checkedGet();
+ } catch (ReadFailedException e) {
+ LOG.error("Error occured when trying to read Link ", e);
+ }
+ if (linkOptional.isPresent()) {
+ transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(toTopologyLink(notification)));
+ }
}
@Override
}
private void removeAffectedLinks(final NodeId id, final ReadWriteTransaction transaction) {
- CheckedFuture<Optional<Topology>, ReadFailedException> topologyDataFuture =
- transaction.read(LogicalDatastoreType.OPERATIONAL, topology);
- Futures.addCallback(topologyDataFuture, new FutureCallback<Optional<Topology>>() {
- @Override
- public void onSuccess(Optional<Topology> topologyOptional) {
- removeAffectedLinks(id, topologyOptional);
- }
-
- @Override
- public void onFailure(Throwable throwable) {
- LOG.error("Error reading topology data for topology {}", topology, throwable);
- }
- });
+ Optional<Topology> topologyOptional = Optional.absent();
+ try {
+ topologyOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, topology).checkedGet();
+ } catch (ReadFailedException e) {
+ LOG.error("Error reading topology data for topology {}", topology, e);
+ }
+ if (topologyOptional.isPresent()) {
+ removeAffectedLinks(id, topologyOptional, transaction);
+ }
}
- private void removeAffectedLinks(final NodeId id, Optional<Topology> topologyOptional) {
+ private void removeAffectedLinks(final NodeId id, Optional<Topology> topologyOptional, ReadWriteTransaction transaction) {
if (!topologyOptional.isPresent()) {
return;
}
List<Link> linkList = topologyOptional.get().getLink() != null ?
topologyOptional.get().getLink() : Collections.<Link> emptyList();
- final List<InstanceIdentifier<Link>> linkIDsToDelete = Lists.newArrayList();
for (Link link : linkList) {
if (id.equals(link.getSource().getSourceNode()) ||
id.equals(link.getDestination().getDestNode())) {
- linkIDsToDelete.add(linkPath(link));
+ transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(link));
}
}
-
- enqueueLinkDeletes(linkIDsToDelete);
- }
-
- private void enqueueLinkDeletes(final Collection<InstanceIdentifier<Link>> linkIDsToDelete) {
- if(!linkIDsToDelete.isEmpty()) {
- processor.enqueueOperation(new TopologyOperation() {
- @Override
- public void applyOperation(ReadWriteTransaction transaction) {
- for(InstanceIdentifier<Link> linkID: linkIDsToDelete) {
- transaction.delete(LogicalDatastoreType.OPERATIONAL, linkID);
- }
- }
-
- @Override
- public String toString() {
- return "Delete Links " + linkIDsToDelete.size();
- }
- });
- }
}
private void removeAffectedLinks(final TpId id, final ReadWriteTransaction transaction) {
- CheckedFuture<Optional<Topology>, ReadFailedException> topologyDataFuture =
- transaction.read(LogicalDatastoreType.OPERATIONAL, topology);
- Futures.addCallback(topologyDataFuture, new FutureCallback<Optional<Topology>>() {
- @Override
- public void onSuccess(Optional<Topology> topologyOptional) {
- removeAffectedLinks(id, topologyOptional);
- }
-
- @Override
- public void onFailure(Throwable throwable) {
- LOG.error("Error reading topology data for topology {}", topology, throwable);
- }
- });
+ Optional<Topology> topologyOptional = Optional.absent();
+ try {
+ topologyOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, topology).checkedGet();
+ } catch (ReadFailedException e) {
+ LOG.error("Error reading topology data for topology {}", topology, e);
+ }
+ if (topologyOptional.isPresent()) {
+ removeAffectedLinks(id, topologyOptional, transaction);
+ }
}
- private void removeAffectedLinks(final TpId id, Optional<Topology> topologyOptional) {
+ private void removeAffectedLinks(final TpId id, Optional<Topology> topologyOptional, ReadWriteTransaction transaction) {
if (!topologyOptional.isPresent()) {
return;
}
List<Link> linkList = topologyOptional.get().getLink() != null
? topologyOptional.get().getLink() : Collections.<Link> emptyList();
- final List<InstanceIdentifier<Link>> linkIDsToDelete = Lists.newArrayList();
for (Link link : linkList) {
if (id.equals(link.getSource().getSourceTp()) ||
id.equals(link.getDestination().getDestTp())) {
- linkIDsToDelete.add(linkPath(link));
+ transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(link));
}
}
-
- enqueueLinkDeletes(linkIDsToDelete);
}
private InstanceIdentifier<Node> getNodePath(final NodeId nodeId) {
package org.opendaylight.md.controller.topology.manager;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
final class OperationProcessor implements AutoCloseable, Runnable, TransactionChainListener {
private static final Logger LOG = LoggerFactory.getLogger(OperationProcessor.class);
private static final int MAX_TRANSACTION_OPERATIONS = 100;
private final BlockingQueue<TopologyOperation> queue = new LinkedBlockingQueue<>(OPERATION_QUEUE_DEPTH);
private final DataBroker dataBroker;
- private final BindingTransactionChain transactionChain;
+ private BindingTransactionChain transactionChain;
+ private volatile boolean finishing = false;
OperationProcessor(final DataBroker dataBroker) {
this.dataBroker = Preconditions.checkNotNull(dataBroker);
@Override
public void run() {
- try {
- for (; ; ) {
- TopologyOperation op = queue.take();
+ while (!finishing) {
+ try {
+ TopologyOperation op = queue.take();
- LOG.debug("New {} operation available, starting transaction", op);
+ LOG.debug("New {} operation available, starting transaction", op);
- final ReadWriteTransaction tx = transactionChain.newReadWriteTransaction();
+ final ReadWriteTransaction tx = transactionChain.newReadWriteTransaction();
- int ops = 0;
- do {
- op.applyOperation(tx);
+ int ops = 0;
+ do {
+ op.applyOperation(tx);
- ops++;
- if (ops < MAX_TRANSACTION_OPERATIONS) {
- op = queue.poll();
- } else {
- op = null;
- }
+ ops++;
+ if (ops < MAX_TRANSACTION_OPERATIONS) {
+ op = queue.poll();
+ } else {
+ op = null;
+ }
- LOG.debug("Next operation {}", op);
- } while (op != null);
+ LOG.debug("Next operation {}", op);
+ } while (op != null);
- LOG.debug("Processed {} operations, submitting transaction", ops);
+ LOG.debug("Processed {} operations, submitting transaction", ops);
- CheckedFuture<Void, TransactionCommitFailedException> txResultFuture = tx.submit();
- Futures.addCallback(txResultFuture, new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void notUsed) {
- LOG.debug("Topology export successful for tx :{}", tx.getIdentifier());
+ try {
+ tx.submit().checkedGet();
+ } catch (final TransactionCommitFailedException e) {
+ LOG.warn("Stat DataStoreOperation unexpected State!", e);
+ transactionChain.close();
+ transactionChain = dataBroker.createTransactionChain(this);
+ cleanDataStoreOperQueue();
}
- @Override
- public void onFailure(Throwable throwable) {
- LOG.error("Topology export transaction {} failed", tx.getIdentifier(), throwable.getCause());
- }
- });
+ } catch (final IllegalStateException e) {
+ LOG.warn("Stat DataStoreOperation unexpected State!", e);
+ transactionChain.close();
+ transactionChain = dataBroker.createTransactionChain(this);
+ cleanDataStoreOperQueue();
+ } catch (final InterruptedException e) {
+ LOG.warn("Stat Manager DS Operation thread interupted!", e);
+ finishing = true;
+ } catch (final Exception e) {
+ LOG.warn("Stat DataStore Operation executor fail!", e);
+ }
}
- } catch (InterruptedException e) {
- LOG.info("Interrupted processing, terminating", e);
- }
-
// Drain all events, making sure any blocked threads are unblocked
+ cleanDataStoreOperQueue();
+ }
+
+ private void cleanDataStoreOperQueue() {
while (!queue.isEmpty()) {
queue.poll();
}
@Override
public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
LOG.error("Failed to export Topology manager operations, Transaction {} failed.", transaction.getIdentifier(), cause);
+ transactionChain.close();
+ transactionChain = dataBroker.createTransactionChain(this);
+ cleanDataStoreOperQueue();
}
@Override
package org.opendaylight.md.controller.topology.manager;
-import static org.junit.Assert.fail;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.SettableFuture;
+import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.SettableFuture;
-import com.google.common.util.concurrent.Uninterruptibles;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
public class FlowCapableTopologyExporterTest {
@Test
public void testOnNodeRemoved() {
+ NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
+ InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
+ Node topoNode = new NodeBuilder().setKey(topoNodeKey).build();
+
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
- nodeKey = newInvNodeKey("node1");
+ nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
InstanceIdentifier<?> invNodeID = InstanceIdentifier.create(Nodes.class).child(
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
nodeKey);
};
SettableFuture<Optional<Topology>> readFuture = SettableFuture.create();
+ readFuture.set(Optional.of(topology));
ReadWriteTransaction mockTx1 = mock(ReadWriteTransaction.class);
doReturn(Futures.makeChecked(readFuture, ReadFailedException.MAPPER)).when(mockTx1)
.read(LogicalDatastoreType.OPERATIONAL, topologyIID);
+ SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
+ readFutureNode.set(Optional.of(topoNode));
+ doReturn(Futures.makeChecked(readFutureNode, ReadFailedException.MAPPER)).when(mockTx1)
+ .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
+
CountDownLatch submitLatch1 = setupStubbedSubmit(mockTx1);
int expDeleteCalls = expDeletedIIDs.length;
ArgumentCaptor.forClass(InstanceIdentifier.class);
setupStubbedDeletes(mockTx1, deletedLinkIDs, deleteLatch);
- ReadWriteTransaction mockTx2 = mock(ReadWriteTransaction.class);
- setupStubbedDeletes(mockTx2, deletedLinkIDs, deleteLatch);
- CountDownLatch submitLatch2 = setupStubbedSubmit(mockTx2);
-
- doReturn(mockTx1).doReturn(mockTx2).when(mockTxChain).newReadWriteTransaction();
+ doReturn(mockTx1).when(mockTxChain).newReadWriteTransaction();
exporter.onNodeRemoved(new NodeRemovedBuilder().setNodeRef(new NodeRef(invNodeID)).build());
waitForDeletes(expDeleteCalls, deleteLatch);
- waitForSubmit(submitLatch2);
-
assertDeletedIDs(expDeletedIIDs, deletedLinkIDs);
verifyMockTx(mockTx1);
- verifyMockTx(mockTx2);
}
@SuppressWarnings({ "rawtypes" })
@Test
public void testOnNodeRemovedWithNoTopology() {
+ NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
+ InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
+ Node topoNode = new NodeBuilder().setKey(topoNodeKey).build();
+
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
- nodeKey = newInvNodeKey("node1");
+ nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
InstanceIdentifier<?> invNodeID = InstanceIdentifier.create(Nodes.class).child(
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
nodeKey);
.read(LogicalDatastoreType.OPERATIONAL, topologyIID);
CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
+ SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
+ readFutureNode.set(Optional.of(topoNode));
+ doReturn(Futures.makeChecked(readFutureNode, ReadFailedException.MAPPER)).when(mockTx)
+ .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
+
CountDownLatch deleteLatch = new CountDownLatch(1);
ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
ArgumentCaptor.forClass(InstanceIdentifier.class);
@Test
public void testOnNodeConnectorRemoved() {
+ NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
+ TerminationPointKey terminationPointKey = new TerminationPointKey(new TpId("tp1"));
+
+ InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
+ Node topoNode = new NodeBuilder().setKey(topoNodeKey).build();
+
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
- nodeKey = newInvNodeKey("node1");
+ nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
- newInvNodeConnKey("tp1");
+ newInvNodeConnKey(terminationPointKey.getTpId().getValue());
InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
};
final SettableFuture<Optional<Topology>> readFuture = SettableFuture.create();
+ readFuture.set(Optional.of(topology));
ReadWriteTransaction mockTx1 = mock(ReadWriteTransaction.class);
doReturn(Futures.makeChecked(readFuture, ReadFailedException.MAPPER)).when(mockTx1)
.read(LogicalDatastoreType.OPERATIONAL, topologyIID);
+ SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
+ readFutureNode.set(Optional.of(topoNode));
+ doReturn(Futures.makeChecked(readFutureNode, ReadFailedException.MAPPER)).when(mockTx1)
+ .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
+
CountDownLatch submitLatch1 = setupStubbedSubmit(mockTx1);
int expDeleteCalls = expDeletedIIDs.length;
ArgumentCaptor.forClass(InstanceIdentifier.class);
setupStubbedDeletes(mockTx1, deletedLinkIDs, deleteLatch);
- ReadWriteTransaction mockTx2 = mock(ReadWriteTransaction.class);
- setupStubbedDeletes(mockTx2, deletedLinkIDs, deleteLatch);
- CountDownLatch submitLatch2 = setupStubbedSubmit(mockTx2);
-
- doReturn(mockTx1).doReturn(mockTx2).when(mockTxChain).newReadWriteTransaction();
+ doReturn(mockTx1).when(mockTxChain).newReadWriteTransaction();
exporter.onNodeConnectorRemoved(new NodeConnectorRemovedBuilder().setNodeConnectorRef(
new NodeConnectorRef(invNodeConnID)).build());
waitForDeletes(expDeleteCalls, deleteLatch);
- waitForSubmit(submitLatch2);
-
assertDeletedIDs(expDeletedIIDs, deletedLinkIDs);
verifyMockTx(mockTx1);
- verifyMockTx(mockTx2);
}
@SuppressWarnings("rawtypes")
@Test
public void testOnNodeConnectorRemovedWithNoTopology() {
+ NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
+ TerminationPointKey terminationPointKey = new TerminationPointKey(new TpId("tp1"));
+
+ InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
+ Node topoNode = new NodeBuilder().setKey(topoNodeKey).build();
+
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
- nodeKey = newInvNodeKey("node1");
+ nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
- newInvNodeConnKey("tp1");
+ newInvNodeConnKey(terminationPointKey.getTpId().getValue());
InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
.read(LogicalDatastoreType.OPERATIONAL, topologyIID);
CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
+ SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
+ readFutureNode.set(Optional.of(topoNode));
+ doReturn(Futures.makeChecked(readFutureNode, ReadFailedException.MAPPER)).when(mockTx)
+ .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
+
CountDownLatch deleteLatch = new CountDownLatch(1);
ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
ArgumentCaptor.forClass(InstanceIdentifier.class);
waitForSubmit(submitLatch);
ArgumentCaptor<Link> mergedNode = ArgumentCaptor.forClass(Link.class);
- verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(topologyIID.child(
- Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId())))),
+ verify(mockTx).put(eq(LogicalDatastoreType.OPERATIONAL), eq(topologyIID.child(
+ Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId())))),
mergedNode.capture(), eq(true));
assertEquals("Source node ID", "sourceNode",
mergedNode.getValue().getSource().getSourceNode().getValue());
destNodeConnKey = newInvNodeConnKey("destTP");
InstanceIdentifier<?> destConnID = newNodeConnID(destNodeKey, destNodeConnKey);
+ Link link = newLink(sourceNodeConnKey.getId().getValue(), newSourceTp(sourceNodeConnKey.getId().getValue()),
+ newDestTp(destNodeConnKey.getId().getValue()));
+
ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
+ doReturn(Futures.immediateCheckedFuture(Optional.of(link))).when(mockTx).read(LogicalDatastoreType.OPERATIONAL, topologyIID.child(
+ Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId()))));
exporter.onLinkRemoved(new LinkRemovedBuilder().setSource(
new NodeConnectorRef(sourceConnID)).setDestination(
- new NodeConnectorRef(destConnID)).build());
+ new NodeConnectorRef(destConnID)).build());
waitForSubmit(submitLatch);
Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId()))));
}
+ @Test
+ public void testOnLinkRemovedLinkDoesNotExist() {
+
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+ sourceNodeKey = newInvNodeKey("sourceNode");
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+ sourceNodeConnKey = newInvNodeConnKey("sourceTP");
+ InstanceIdentifier<?> sourceConnID = newNodeConnID(sourceNodeKey, sourceNodeConnKey);
+
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+ destNodeKey = newInvNodeKey("destNode");
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+ destNodeConnKey = newInvNodeConnKey("destTP");
+ InstanceIdentifier<?> destConnID = newNodeConnID(destNodeKey, destNodeConnKey);
+
+ ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
+ CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
+ doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
+ doReturn(Futures.immediateCheckedFuture(Optional.<Link>absent())).when(mockTx).read(LogicalDatastoreType.OPERATIONAL, topologyIID.child(
+ Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId()))));
+
+ exporter.onLinkRemoved(new LinkRemovedBuilder().setSource(
+ new NodeConnectorRef(sourceConnID)).setDestination(
+ new NodeConnectorRef(destConnID)).build());
+
+ waitForSubmit(submitLatch);
+
+ verify(mockTx, never()).delete(LogicalDatastoreType.OPERATIONAL, topologyIID.child(
+ Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId()))));
+ }
+
private void verifyMockTx(ReadWriteTransaction mockTx) {
InOrder inOrder = inOrder(mockTx);
inOrder.verify(mockTx, atLeast(0)).submit();
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>config-netconf-connector</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>config-persister-impl</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>ietf-netconf-monitoring</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-api</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>netconf-auth</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-cli</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-client</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.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.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-impl</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-it</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-mapping-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-monitoring</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-netty-util</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>netconf-ssh</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>netconf-tcp</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-testtool</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>netconf-usermanager</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>netconf-util</artifactId>
<packaging>bundle</packaging>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>netconf-subsystem</artifactId>
- <version>0.2.5-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<prerequisites>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>networkconfig.neutron.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<enunciate.version>1.26.2</enunciate.version>
portDB.putIfAbsent(input.getID(), input);
// if there are no fixed IPs, allocate one for each subnet in the network
INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (input.getFixedIPs() == null){
+ input.setFixedIPs(new ArrayList<Neutron_IPs>());
+ }
if (input.getFixedIPs().size() == 0) {
List<Neutron_IPs> list = input.getFixedIPs();
Iterator<NeutronSubnet> subnetIterator = systemCRUD.getAllSubnets().iterator();
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>networkconfig.neutron</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<enunciate.version>1.26.2</enunciate.version>
<groupId>org.opendaylight.controller</groupId>
<artifactId>app-northbound</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>maven-archetype</packaging>
<name>app-northbound</name>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.1-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>bundlescanner</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>bundlescanner.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>commons.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>connectionmanager.northbound</artifactId>
- <version>0.1.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>containermanager.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>controllermanager.northbound</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>flowprogrammer.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>httpservice-bridge</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<description>HttpService bridge web application</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>northbound.integrationtest</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>northbound.client</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>jolokia-bridge</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<description>Jolokia bridge web application</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>networkconfig.bridgedomain.northbound</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>networkconfig.neutron.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
org.eclipse.persistence.jaxb.rs,
com.sun.jersey.spi.container.servlet,
javax.ws.rs,
+ javax.ws.rs.ext,
javax.ws.rs.core,
javax.xml.bind.annotation,
javax.xml.bind,
import org.codehaus.enunciate.jaxrs.StatusCodes;
import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
-import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
/**
* For now, the LB pool member data is maintained with the INeutronLoadBalancerPoolCRUD,
- * although there may be an overlap with INeutronLoadBalancerPoolMemberCRUD's cache.
- * TODO: Consolidate and maintain a single copy
+ * and not duplicated within the INeutronLoadBalancerPoolMemberCRUD's cache.
*/
@Path("/pools")
service.neutronLoadBalancerPoolDeleted(singleton);
}
}
-
- /*
- * remove corresponding members from the member cache too
- */
- INeutronLoadBalancerPoolMemberCRUD loadBalancerPoolMemberInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolMemberCRUD(this);
- if (loadBalancerPoolMemberInterface != null) {
- List<NeutronLoadBalancerPoolMember> allLoadBalancerPoolMembers = new
- ArrayList<NeutronLoadBalancerPoolMember>(loadBalancerPoolMemberInterface.getAllNeutronLoadBalancerPoolMembers());
- Iterator<NeutronLoadBalancerPoolMember> i = allLoadBalancerPoolMembers.iterator();
- while (i.hasNext()) {
- NeutronLoadBalancerPoolMember member = i.next();
- if (member.getPoolID() == loadBalancerPoolUUID)
- loadBalancerPoolMemberInterface.removeNeutronLoadBalancerPoolMember(member.getPoolMemberID());
- }
- }
return Response.status(204).build();
}
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>forwarding.staticrouting.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>statistics.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>subnets.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>swagger-ui</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>switchmanager.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>topology.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>usermanager.northbound</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.0-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../opendaylight/commons/opendaylight</relativePath>
</parent>
<scm>
<groupId>org.opendaylight.controller</groupId>
<artifactId>northboundtest</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>protocol_plugins.openflow</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>protocol_plugins.stub</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>routing.dijkstra_implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal</artifactId>
- <version>0.8.1-SNAPSHOT</version>
+ <version>0.9.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.connection</artifactId>
- <version>0.1.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.connection.implementation</artifactId>
- <version>0.1.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.networkconfiguration</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>sal.networkconfiguration.implementation</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustersession</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>samples.loadbalancer</artifactId>
- <version>0.5.2-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../../commons/opendaylight</relativePath>
</parent>
<artifactId>samples.loadbalancer.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>samples.simpleforwarding</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../commons/opendaylight</relativePath>
</parent>
<artifactId>security</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>statisticsmanager</artifactId>
- <version>0.5.1-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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.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.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>statisticsmanager.integrationtest</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>switchmanager</artifactId>
- <version>0.7.1-SNAPSHOT</version>
+ <version>0.8.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>switchmanager.integrationtest</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>topologymanager</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.integrationtest</artifactId>
- <version>0.5.2-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<relativePath>../../commons/integrationtest</relativePath>
</parent>
<artifactId>topologymanager.integrationtest</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>topologymanager.shell</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>usermanager</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>usermanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.0-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<scm>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web.brandfragment</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>devices.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>flows.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>osgi-brandfragment.web</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>0.1.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.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>topology.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
- <version>1.4.2-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>troubleshoot.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<relativePath>opendaylight/commons/parent</relativePath>
</parent>
<artifactId>releasepom</artifactId>
- <version>0.1.2-SNAPSHOT</version>
+ <version>0.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<prerequisites>
<maven>3.0</maven>
</prerequisites>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.thirdparty</artifactId>
- <version>1.1.2-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.thirdparty</artifactId>
- <version>1.1.2-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../commons/thirdparty</relativePath>
</parent>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>ganymed</artifactId>
- <version>1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.thirdparty</artifactId>
- <version>1.1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../commons/thirdparty</relativePath>
</parent>
<scm>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>com.sun.jersey.jersey-servlet</artifactId>
- <version>1.18-SNAPSHOT</version>
+ <version>1.19.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<plugins>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.thirdparty</artifactId>
- <version>1.1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../commons/thirdparty</relativePath>
</parent>
<scm>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>net.sf.jung2</artifactId>
- <version>2.0.2-SNAPSHOT</version>
+ <version>2.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<plugins>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.openflow.openflowj</artifactId>
- <version>1.0.3-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<name>OpenFlow Java</name>
<description>A Java implemention of the OpenFlow v1.0 protocol</description>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.thirdparty</artifactId>
- <version>1.1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../commons/thirdparty</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.thirdparty</artifactId>
- <version>1.1.1-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<relativePath>../commons/thirdparty</relativePath>
</parent>
<scm>
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
- <version>7.0.43-SNAPSHOT</version>
+ <version>7.1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<plugins>