</prerequisites>
<properties>
+ <aopalliance.version>1.0.0</aopalliance.version>
+ <appauth.version>0.4.2-SNAPSHOT</appauth.version>
+ <!-- Controller Modules Versions -->
<arphandler.version>0.5.2-SNAPSHOT</arphandler.version>
+ <!-- Plugin Versions -->
+ <bouncycastle.version>1.50</bouncycastle.version>
<bundle.plugin.version>2.3.7</bundle.plugin.version>
<bundlescanner.version>0.4.2-SNAPSHOT</bundlescanner.version>
<checkstyle.version>2.10</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>
+ <!-- Third Party Versions -->
+ <commons.codec.version>1.7</commons.codec.version>
+ <commons.fileupload.version>1.2.2</commons.fileupload.version>
<commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
<commons.io.version>2.4</commons.io.version>
<commons.lang.version>3.1</commons.lang.version>
+ <commons.net.version>3.0.1</commons.net.version>
<compiler.version>2.3.2</compiler.version>
<concepts.version>0.5.2-SNAPSHOT</concepts.version>
<config.version>0.2.5-SNAPSHOT</config.version>
+ <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.version>0.5.2-SNAPSHOT</containermanager.version>
- <!--versions for bits of the controller -->
+ <controllermanager.northbound.version>0.0.2-SNAPSHOT</controllermanager.northbound.version>
<corsfilter.version>7.0.42</corsfilter.version>
+ <devices.web.version>0.4.2-SNAPSHOT</devices.web.version>
+ <eclipse.persistence.version>2.5.0</eclipse.persistence.version>
<!-- enforcer version -->
<enforcer.version>1.3.1</enforcer.version>
<enunciate.version>1.26.2</enunciate.version>
<exam.version>3.0.0</exam.version>
<!-- OpenEXI third party lib for netconf-->
- <exi.nagasena.version>0000.0002.0035.0-SNAPSHOT</exi.nagasena.version>
+ <exi.nagasena.version>0000.0002.0038.0-SNAPSHOT</exi.nagasena.version>
<failsafe.version>2.15</failsafe.version>
+ <felix.dependencymanager.shell.version>3.0.1</felix.dependencymanager.shell.version>
+ <felix.dependencymanager.version>3.1.0</felix.dependencymanager.version>
+ <felix.fileinstall.version>3.1.6</felix.fileinstall.version>
+ <felix.webconsole.version>4.2.0</felix.webconsole.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>
<geminiweb.version>2.2.0.RELEASE</geminiweb.version>
+ <gson.version>2.2.4</gson.version>
<guava.version>14.0.1</guava.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_new.api.version>0.4.2-SNAPSHOT</hosttracker_new.api.version>
<ietf-inet-types.version>2010.09.24.4-SNAPSHOT</ietf-inet-types.version>
<ietf-topology.version>2013.10.21.2-SNAPSHOT</ietf-topology.version>
<!-- Third party version -->
<jersey-servlet.version>1.17</jersey-servlet.version>
<jersey.version>1.17</jersey.version>
+ <jettison.version>1.3.3</jettison.version>
<jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
<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>
<junit.version>4.8.1</junit.version>
<logback.version>1.0.9</logback.version>
<logging.bridge.version>0.4.2-SNAPSHOT</logging.bridge.version>
<netconf.version>0.2.5-SNAPSHOT</netconf.version>
<netty.version>4.0.17.Final</netty.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>
<!-- ODL repository / plugin repository -->
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
<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>
+ <osgi.compendium.version>5.0.0</osgi.compendium.version>
<osgi.core.version>5.0.0</osgi.core.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<projectinfo>2.6</projectinfo>
-
<propertymavenplugin.version>1.0-alpha-2</propertymavenplugin.version>
<protocol-framework.version>0.5.0-SNAPSHOT</protocol-framework.version>
- <protocol_plugin.stub.version>0.4.2-SNAPSHOT</protocol_plugin.stub.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>
<releaseplugin.version>2.3.2</releaseplugin.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>
<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>
+ <security.version>0.4.2-SNAPSHOT</security.version>
<sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
<siteplugin>3.2</siteplugin>
<slf4j.version>1.7.2</slf4j.version>
<spring-osgi.version>1.2.1</spring-osgi.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>
<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>
<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>
+ <troubleshoot.web.version>0.4.2-SNAPSHOT</troubleshoot.web.version>
<url.version>1.5.0</url.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>
<virgo.version>3.6.0.RELEASE</virgo.version>
+ <web.version>0.4.2-SNAPSHOT</web.version>
<xtend.dstdir>src/main/xtend-gen</xtend.dstdir>
<xtend.version>2.4.3</xtend.version>
<yang-ext.version>2013.09.07.4-SNAPSHOT</yang-ext.version>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
- <version>2.0.1</version>
+ <version>${jsr305.api.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>2.2.4</version>
+ <version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>jersey-core</artifactId>
<version>${jersey.version}</version>
</dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>${jsr311.api.version}</version>
+ </dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
- <version>1.7</version>
+ <version>${commons.codec.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
- <version>1.2.2</version>
+ <version>${commons.fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
- <version>3.0.1</version>
+ <version>${commons.net.version}</version>
</dependency>
<dependency>
<groupId>eclipselink</groupId>
<artifactId>netty-common</artifactId>
<version>${netty.version}</version>
</dependency>
-
- <!--Netty-->
+ <!-- Netty -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
<dependency>
<groupId>org.aopalliance</groupId>
<artifactId>com.springsource.org.aopalliance</artifactId>
- <version>1.0.0</version>
+ <version>${aopalliance.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.dependencymanager</artifactId>
- <version>3.1.0</version>
+ <version>${felix.dependencymanager.version}</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.dependencymanager.shell</artifactId>
- <version>3.0.1</version>
+ <version>${felix.dependencymanager.shell.version}</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.fileinstall</artifactId>
- <version>3.1.6</version>
+ <version>${felix.fileinstall.version}</version>
</dependency>
<!-- felix webconsole -->
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.webconsole</artifactId>
- <version>4.2.0</version>
+ <version>${felix.webconsole.version}</version>
<!-- the all bundle includes all the necessary plugins -->
<classifier>all</classifier>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
- <version>1.50</version>
+ <version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
- <version>1.50</version>
+ <version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
<version>${enunciate.version}</version>
</dependency>
-
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
- <version>1.3.3</version>
+ <version>${jettison.version}</version>
</dependency>
<!-- equinox http service bridge -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.antlr</artifactId>
- <version>2.5.0</version>
+ <version>${eclipse.persistence.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
- <version>2.5.0</version>
+ <version>${eclipse.persistence.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
- <version>2.5.0</version>
+ <version>${eclipse.persistence.version}</version>
</dependency>
<!-- md-sal -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>appauth</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${appauth.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.test</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${clustering.test.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${commmons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.3-SNAPSHOT</version>
+ <version>${configuration.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${containermanager.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>controllermanager.northbound</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>${controllermanager.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>devices.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${devices.web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>flowprogrammer.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${flowprogrammer.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>flows.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${flows.web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${forwarding.staticrouting.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${forwardingrulesmanager.implementation.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${hosttracker.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${networkconfig.neutron.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${networkconfig.neutron.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${networkconfig.neutron.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>osgi-brandfragment.web</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>${osgi-brandfragment.web.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.openflow</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${protocol_plugins.openflow.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.stub</artifactId>
- <version>${protocol_plugin.stub.version}</version>
+ <version>${protocol_plugins.stub.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>routing.dijkstra_implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${routing.dijkstra_implementation.version}</version>
</dependency>
<!-- SAL bundles -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${sal.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.loadbalancer.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${samples.loadbalancer.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.simpleforwarding</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${samples.simpleforwarding.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>security</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${security.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statistics.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${statistics.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${statisticsmanager.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>subnets.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${subnets.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${switchmanager.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${switchmanager.northbound.version}</version>
</dependency>
<!-- threadpool -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topology.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${topology.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topology.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${topology.web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>troubleshoot.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${troubleshoot.web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager.implementation</artifactId>
- <version>${usermanager.version}</version>
+ <version>${usermanager.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager.northbound</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>${usermanager.northbound.version}</version>
</dependency>
<!-- Web bundles -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
- <version>${osgi.core.version}</version>
+ <version>${osgi.compendium.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
*/
package org.opendaylight.controller.config.yang.protocol.framework;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
public class NeverReconnectStrategyModuleTest extends AbstractConfigTest {
private static final String INSTANCE_NAME = "never-reconect-strategy-factory-impl";
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new NeverReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new ReconnectImmediatelyStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
*/
package org.opendaylight.controller.config.yang.protocol.framework;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.math.BigDecimal;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.math.BigDecimal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
public class TimedReconnectStrategyModuleTest extends AbstractConfigTest {
private static final String INSTANCE_NAME = "timed-reconect-stategy-facotry-impl";
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TimedReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+/**
+ * Interface exposing some internal state on top of ServiceReferenceReadableRegistry. This will
+ * not be exposed via JMX.
+ */
public interface CloseableServiceReferenceReadableRegistry extends AutoCloseable, ServiceReferenceReadableRegistry {
-
void close();
}
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.dependencyresolver.DestroyedModule;
}
};
- Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(
+ Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = new HashMap<>(
resolver.getAllFactories());
+ // add all factories that disappeared from SR but are still committed
+ for (ModuleInternalInfo moduleInternalInfo : currentConfig.getEntries()) {
+ String name = moduleInternalInfo.getModuleFactory().getImplementationName();
+ if (allCurrentFactories.containsKey(name) == false) {
+ logger.trace("Factory {} not found in SR, using reference from previous commit", name);
+ allCurrentFactories.put(name,
+ Maps.immutableEntry(moduleInternalInfo.getModuleFactory(), moduleInternalInfo.getBundleContext()));
+ }
+ }
+ allCurrentFactories = Collections.unmodifiableMap(allCurrentFactories);
+
// closed by transaction controller
ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier(
transactionName), factory, allCurrentFactories);
- ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+ SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
readableSRRegistry, txLookupRegistry, allCurrentFactories);
ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
// non recoverable from here:
try {
return secondPhaseCommit(configTransactionController, commitInfo, configTransactionControllerEntry.getValue());
- } catch (Throwable t) { // some libs throw Errors: e.g.
+ } catch (Error | RuntimeException t) { // some libs throw Errors: e.g.
// javax.xml.ws.spi.FactoryFinder$ConfigurationError
isHealthy = false;
logger.error("Configuration Transaction failed on 2PC, server is unhealthy", t);
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
- } else if (t instanceof Error) {
- throw (Error) t;
} else {
- throw new RuntimeException(t);
+ throw (Error) t;
}
}
}
// register to JMX
try {
- newModuleJMXRegistrator.registerMBean(newReadableConfigBean,
- primaryReadOnlyON);
+ newModuleJMXRegistrator.registerMBean(newReadableConfigBean, primaryReadOnlyON);
} catch (InstanceAlreadyExistsException e) {
- throw new IllegalStateException(e);
+ throw new IllegalStateException("Possible code error, already registered:" + primaryReadOnlyON,e);
}
- // register to OSGi
+ // register services to OSGi
+ Map<String, ServiceInterfaceAnnotation> annotationMapping = configTransactionController.getWritableRegistry().findServiceInterfaces(moduleIdentifier);
+ BundleContext bc = configTransactionController.getModuleFactoryBundleContext(
+ entry.getModuleFactory().getImplementationName());
if (osgiRegistration == null) {
- ModuleFactory moduleFactory = entry.getModuleFactory();
- if (moduleFactory != null) {
- BundleContext bc = configTransactionController.
- getModuleFactoryBundleContext(moduleFactory.getImplementationName());
- osgiRegistration = beanToOsgiServiceManager.registerToOsgi(realModule.getClass(),
- newReadableConfigBean.getInstance(), entry.getIdentifier(), bc);
- } else {
- throw new NullPointerException(entry.getIdentifier().getFactoryName() + " ModuleFactory not found.");
- }
-
+ osgiRegistration = beanToOsgiServiceManager.registerToOsgi(
+ newReadableConfigBean.getInstance(), moduleIdentifier, bc, annotationMapping);
+ } else {
+ osgiRegistration.updateRegistrations(annotationMapping, bc, instance);
}
RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator = runtimeRegistrators
ModuleInternalInfo newInfo = new ModuleInternalInfo(
entry.getIdentifier(), newReadableConfigBean, osgiRegistration,
runtimeBeanRegistrator, newModuleJMXRegistrator,
- orderingIdx, entry.isDefaultBean());
+ orderingIdx, entry.isDefaultBean(), entry.getModuleFactory(), entry.getBundleContext());
newConfigEntries.put(realModule, newInfo);
orderingIdx++;
*/
package org.opendaylight.controller.config.manager.impl;
+import static java.lang.String.format;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import javax.management.DynamicMBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
-import javax.management.DynamicMBean;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.String.format;
-
/**
* This is a JMX bean representing current transaction. It contains
* transaction identifier, unique version and parent version for
private final boolean blankTransaction;
@GuardedBy("this")
- private final ServiceReferenceWritableRegistry writableSRRegistry;
+ private final SearchableServiceReferenceWritableRegistry writableSRRegistry;
public ConfigTransactionControllerImpl(ConfigTransactionLookupRegistry txLookupRegistry,
long parentVersion, CodecRegistry codecRegistry, long currentVersion,
Map<String, Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer,
- boolean blankTransaction, ServiceReferenceWritableRegistry writableSRRegistry) {
+ boolean blankTransaction, SearchableServiceReferenceWritableRegistry writableSRRegistry) {
this.txLookupRegistry = txLookupRegistry;
String transactionName = txLookupRegistry.getTransactionIdentifier().getName();
this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName);
}
// add default modules
for (ModuleFactory moduleFactory : toBeAdded) {
+ BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager,
- getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+ bundleContext);
for (Module module : defaultModules) {
// ensure default module to be registered to jmx even if its module factory does not use dependencyResolverFactory
DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier());
try {
boolean defaultBean = true;
- putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, dependencyResolver, defaultBean);
+ putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null,
+ dependencyResolver, defaultBean, bundleContext);
} catch (InstanceAlreadyExistsException e) {
throw new IllegalStateException(e);
}
}
- private synchronized void copyExistingModule(
- ModuleInternalInfo oldConfigBeanInfo)
- throws InstanceAlreadyExistsException {
+ private synchronized void copyExistingModule(ModuleInternalInfo oldConfigBeanInfo) throws InstanceAlreadyExistsException {
+
transactionStatus.checkNotCommitStarted();
transactionStatus.checkNotAborted();
ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
dependencyResolverManager.assertNotExists(moduleIdentifier);
- ModuleFactory moduleFactory = factoriesHolder
- .findByModuleName(moduleIdentifier.getFactoryName());
+ ModuleFactory moduleFactory;
+ BundleContext bc;
+ try {
+ moduleFactory = factoriesHolder.findByModuleName(moduleIdentifier.getFactoryName());
+ bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalStateException(e);
+ }
Module module;
DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
try {
- BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
+
module = moduleFactory.createModule(
moduleIdentifier.getInstanceName(), dependencyResolver,
oldConfigBeanInfo.getReadableModule(), bc);
oldConfigBeanInfo, moduleFactory), e);
}
putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver,
- oldConfigBeanInfo.isDefaultBean());
+ oldConfigBeanInfo.isDefaultBean(), bc);
}
@Override
dependencyResolverManager.assertNotExists(moduleIdentifier);
// find factory
- ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
+ ModuleFactory moduleFactory;
+ try {
+ moduleFactory = factoriesHolder.findByModuleName(factoryName);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalArgumentException(e);
+ }
DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
+ BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
Module module = moduleFactory.createModule(instanceName, dependencyResolver,
- getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+ bundleContext);
boolean defaultBean = false;
return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module,
- moduleFactory, null, dependencyResolver, defaultBean);
+ moduleFactory, null, dependencyResolver, defaultBean, bundleContext);
}
private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(
ModuleIdentifier moduleIdentifier, Module module,
ModuleFactory moduleFactory,
- @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver, boolean isDefaultBean)
+ @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver,
+ boolean isDefaultBean, BundleContext bundleContext)
throws InstanceAlreadyExistsException {
logger.debug("Adding module {} to transaction {}", moduleIdentifier, this);
dependencyResolverManager.put(
moduleIdentifier, module, moduleFactory,
- maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean);
+ maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean, bundleContext);
return writableON;
}
logger.debug("Destroying module {} in transaction {}", moduleIdentifier, this);
transactionStatus.checkNotAborted();
+ ModuleInternalTransactionalInfo found = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
if (blankTransaction == false) {
- ModuleInternalTransactionalInfo found =
- dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
+
if (found.isDefaultBean()) {
logger.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
}
}
// first remove refNames, it checks for objectname existence
+
try {
writableSRRegistry.removeServiceReferences(
ObjectNameUtil.createTransactionModuleON(getTransactionName(), moduleIdentifier));
}
@Override
- public ServiceReferenceWritableRegistry getWritableRegistry() {
+ public SearchableServiceReferenceWritableRegistry getWritableRegistry() {
return writableSRRegistry;
}
*/
package org.opendaylight.controller.config.manager.impl;
-import java.util.Collection;
-import java.util.List;
-
-import javax.management.ObjectName;
-
import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.osgi.framework.BundleContext;
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.List;
+
/**
* Defines contract between {@link ConfigTransactionControllerImpl} (producer)
* and {@link ConfigRegistryImpl} (consumer).
BundleContext getModuleFactoryBundleContext(String factoryName);
- ServiceReferenceWritableRegistry getWritableRegistry();
+ SearchableServiceReferenceWritableRegistry getWritableRegistry();
TransactionIdentifier getTransactionIdentifier();
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
+import java.util.Deque;
+import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
public class DeadlockMonitor implements AutoCloseable {
private final TransactionIdentifier transactionIdentifier;
private final DeadlockMonitorRunnable thread;
@GuardedBy("this")
- private ModuleIdentifierWithNanos moduleIdentifierWithNanos = new ModuleIdentifierWithNanos();
+ private final Deque<ModuleIdentifierWithNanos> moduleIdentifierWithNanosStack = new LinkedList<>();
+ @GuardedBy("this")
+ private ModuleIdentifierWithNanos top = ModuleIdentifierWithNanos.EMPTY;
public DeadlockMonitor(TransactionIdentifier transactionIdentifier) {
this.transactionIdentifier = transactionIdentifier;
}
public synchronized void setCurrentlyInstantiatedModule(ModuleIdentifier currentlyInstantiatedModule) {
- this.moduleIdentifierWithNanos = new ModuleIdentifierWithNanos(currentlyInstantiatedModule);
+
+ boolean popping = currentlyInstantiatedModule == null;
+ if (popping) {
+ moduleIdentifierWithNanosStack.pop();
+ if (moduleIdentifierWithNanosStack.isEmpty()) {
+ top = ModuleIdentifierWithNanos.EMPTY;
+ } else {
+ top = moduleIdentifierWithNanosStack.peekLast();
+ }
+ } else {
+ ModuleIdentifierWithNanos current = new ModuleIdentifierWithNanos(currentlyInstantiatedModule);
+ moduleIdentifierWithNanosStack.push(current);
+ top = current;
+ }
+ logger.trace("setCurrentlyInstantiatedModule {}, top {}", currentlyInstantiatedModule, top);
}
public boolean isAlive() {
public void run() {
ModuleIdentifierWithNanos old = new ModuleIdentifierWithNanos(); // null moduleId
while (this.isInterrupted() == false) {
- ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.moduleIdentifierWithNanos);
- if (old.moduleIdentifier == null) {
+ ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.top);
+ if (old.moduleIdentifier == null || old.equals(copy) == false) {
// started
old = copy;
- } else if (old.moduleIdentifier != null && old.equals(copy)) {
+ } else {
// is the getInstance() running longer than WARN_AFTER_MILLIS ?
long runningTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - copy.nanoTime);
if (runningTime > WARN_AFTER_MILLIS) {
}
}
- private class ModuleIdentifierWithNanos {
+
+
+
+ private static class ModuleIdentifierWithNanos {
+ private static ModuleIdentifierWithNanos EMPTY = new ModuleIdentifierWithNanos();
@Nullable
private final ModuleIdentifier moduleIdentifier;
+
private final long nanoTime;
private ModuleIdentifierWithNanos() {
- moduleIdentifier = null;
- nanoTime = System.nanoTime();
+ this((ModuleIdentifier)null);
}
private ModuleIdentifierWithNanos(ModuleIdentifier moduleIdentifier) {
result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32));
return result;
}
+
+ @Override
+ public String toString() {
+ return "ModuleIdentifierWithNanos{" +
+ moduleIdentifier +
+ '}';
+ }
}
}
import org.opendaylight.controller.config.manager.impl.jmx.ModuleJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegistratorImpl;
import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager.OsgiRegistration;
+import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.yangtools.concepts.Identifiable;
+import org.osgi.framework.BundleContext;
/**
* Provides metadata about Module from controller to registry.
private final ModuleJMXRegistrator moduleJMXRegistrator;
private final int orderingIdx;
private final boolean isDefaultBean;
+ private final ModuleFactory moduleFactory;
+ private final BundleContext bundleContext;
public ModuleInternalInfo(ModuleIdentifier name,
@Nullable DynamicReadableWrapper readableModule,
OsgiRegistration osgiRegistration,
RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator,
ModuleJMXRegistrator moduleJMXRegistrator, int orderingIdx,
- boolean isDefaultBean) {
+ boolean isDefaultBean, ModuleFactory moduleFactory, BundleContext bundleContext) {
if (osgiRegistration == null) {
throw new IllegalArgumentException(
this.moduleJMXRegistrator = moduleJMXRegistrator;
this.orderingIdx = orderingIdx;
this.isDefaultBean = isDefaultBean;
+ this.moduleFactory = moduleFactory;
+ this.bundleContext = bundleContext;
}
public DynamicReadableWrapper getReadableModule() {
public boolean isDefaultBean() {
return isDefaultBean;
}
+
+ public ModuleFactory getModuleFactory() {
+ return moduleFactory;
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.manager.impl;
+
+import java.util.Map;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+
+public interface SearchableServiceReferenceWritableRegistry extends ServiceReferenceWritableRegistry {
+ /**
+ * Return mapping between service ref names and service interface annotation for given
+ * module.
+ *
+ * @throws java.lang.IllegalArgumentException if any of service qNames is not found
+ * @throws java.lang.NullPointerException if parameter is null
+ */
+ Map<String /* service ref */, ServiceInterfaceAnnotation> findServiceInterfaces(ModuleIdentifier moduleIdentifier);
+
+}
*/
package org.opendaylight.controller.config.manager.impl;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
import org.opendaylight.controller.config.api.LookupRegistry;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, SearchableServiceReferenceWritableRegistry {
private static final Logger logger = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class);
private final Map<String, ModuleFactory> factories;
private final ServiceReferenceRegistrator serviceReferenceRegistrator;
// helper method for getting QName of SI from namespace + local name
private final Map<String /* namespace */, Map<String /* local name */, ServiceInterfaceAnnotation>> namespacesToAnnotations;
+ private final Map<String /* service qName */, ServiceInterfaceAnnotation> serviceQNamesToAnnotations;
// all Service Interface qNames for sanity checking
private final Set<String /* qName */> allQNames;
+ Map<ModuleIdentifier, Map<String /* service ref name */, ServiceInterfaceAnnotation >> modulesToServiceRef = new HashMap<>();
+
// actual reference database
private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
/**
* Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data.
*/
- public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
+ public static SearchableServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
ConfigTransactionLookupRegistry txLookupRegistry,
Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
Map<String, Set<String /* QName */>> modifiableFactoryNamesToQNames = new HashMap<>();
Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
Set<String /* qName */> allQNames = new HashSet<>();
+
+
for (Entry<String, ModuleFactory> entry : factories.entrySet()) {
if (entry.getKey().equals(entry.getValue().getImplementationName()) == false) {
logger.error("Possible error in code: Mismatch between supplied and actual name of {}", entry);
throw new IllegalArgumentException("Possible error in code: Mismatch between supplied and actual name of " + entry);
}
Set<ServiceInterfaceAnnotation> siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue());
- Set<String> qNames = new HashSet<>();
- for (ServiceInterfaceAnnotation sia: siAnnotations) {
- qNames.add(sia.value());
- }
+ Set<String> qNames = InterfacesHelper.getQNames(siAnnotations);
allAnnotations.addAll(siAnnotations);
allQNames.addAll(qNames);
modifiableFactoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames));
// fill namespacesToAnnotations
Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> modifiableNamespacesToAnnotations =
new HashMap<>();
+ Map<String /* service qName*/, ServiceInterfaceAnnotation> modifiableServiceQNamesToAnnotations = new HashMap<>();
for (ServiceInterfaceAnnotation sia : allAnnotations) {
Map<String, ServiceInterfaceAnnotation> ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace());
if (ofNamespace == null) {
throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName());
}
ofNamespace.put(sia.localName(), sia);
+ modifiableServiceQNamesToAnnotations.put(sia.value(), sia);
}
this.namespacesToAnnotations = Collections.unmodifiableMap(modifiableNamespacesToAnnotations);
- // copy refNames
+ this.serviceQNamesToAnnotations = Collections.unmodifiableMap(modifiableServiceQNamesToAnnotations);
logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
}
+ @Override
+ public Map<String /* service ref */, ServiceInterfaceAnnotation> findServiceInterfaces(ModuleIdentifier moduleIdentifier) {
+ Map<String, ServiceInterfaceAnnotation> result = modulesToServiceRef.get(moduleIdentifier);
+ if (result == null) {
+ return Collections.emptyMap();
+ }
+ return Collections.unmodifiableMap(result);
+ }
@Override
public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
- String qName = entry.getKey().getServiceInterfaceName();
+ String qName = entry.getKey().getServiceInterfaceQName();
Map<String /* refName */, ObjectName> innerMap = result.get(qName);
if (innerMap == null) {
innerMap = new HashMap<>();
throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + moduleIdentifier.getFactoryName());
}
// supplied serviceInterfaceName must exist in this collection
- if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceName()) == false) {
- logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
- throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName() + " within factory " + moduleIdentifier.getFactoryName());
+ if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
+ logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceQName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
+ throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName() + " within factory " + moduleIdentifier.getFactoryName());
}
}
// save to refNames
refNames.put(serviceReference, moduleIdentifier);
+ Map<String, ServiceInterfaceAnnotation> refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier);
+ if (refNamesToAnnotations == null){
+ refNamesToAnnotations = new HashMap<>();
+ modulesToServiceRef.put(moduleIdentifier, refNamesToAnnotations);
+ }
+
+ ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations.get(serviceReference.getServiceInterfaceQName());
+ checkNotNull(annotation, "Possible error in code, cannot find annotation for " + serviceReference);
+ refNamesToAnnotations.put(serviceReference.getRefName(), annotation);
return result;
}
private ObjectName getServiceON(ServiceReference serviceReference) {
if (writable) {
return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(),
- serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+ serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
} else {
- return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+ return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
}
}
logger.debug("Removing service reference {} from {}", serviceReference, this);
assertWritable();
// is the qName known?
- if (allQNames.contains(serviceReference.getServiceInterfaceName()) == false) {
- logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceName(), allQNames);
- throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName());
+ if (allQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
+ logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceQName(), allQNames);
+ throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName());
}
ModuleIdentifier removed = refNames.remove(serviceReference);
if (removed == null){
- throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceName());
+ throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceQName());
}
Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
if (entry == null) {
@Override
public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException {
+ lookupRegistry.checkConfigBeanExists(moduleObjectName);
+ String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
+ // check that service interface name exist
+ Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
+ return removeServiceReferences(moduleObjectName, serviceInterfaceQNames);
+ }
+
+
+ private boolean removeServiceReferences(ObjectName moduleObjectName, Set<String> qNames) throws InstanceNotFoundException {
+ ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE);
assertWritable();
- Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName);
+ Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, qNames);
for (ServiceReference sr : serviceReferencesLinkingTo) {
removeServiceReference(sr);
}
return serviceReferencesLinkingTo.isEmpty() == false;
}
- private synchronized Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName) throws InstanceNotFoundException {
- lookupRegistry.checkConfigBeanExists(moduleObjectName);
+ private Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName, Set<String> serviceInterfaceQNames) {
String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
- // check that service interface name exist
- Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
if (serviceInterfaceQNames == null) {
- logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
+ logger.warn("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
}
String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName);
return result;
}
-
@Override
public String toString() {
return "ServiceReferenceRegistryImpl{" +
*/
package org.opendaylight.controller.config.manager.impl.dependencyresolver;
+import static com.google.common.base.Preconditions.checkState;
+
import com.google.common.reflect.AbstractInvocationHandler;
import com.google.common.reflect.Reflection;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.concurrent.GuardedBy;
+import javax.management.InstanceAlreadyExistsException;
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.DependencyResolverFactory;
import org.opendaylight.controller.config.api.JmxAttribute;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.management.InstanceAlreadyExistsException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkState;
+import org.osgi.framework.BundleContext;
/**
* Holds information about modules being created and destroyed within this
ModuleFactory moduleFactory,
ModuleInternalInfo maybeOldInternalInfo,
TransactionModuleJMXRegistration transactionModuleJMXRegistration,
- boolean isDefaultBean) {
+ boolean isDefaultBean, BundleContext bundleContext) {
transactionStatus.checkNotCommitted();
Class<? extends Module> moduleClass = Module.class;
ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
moduleIdentifier, proxiedModule, moduleFactory,
- maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module);
+ maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module, bundleContext);
modulesHolder.put(moduleInternalTransactionalInfo);
}
import org.opendaylight.yangtools.concepts.Identifiable;
import javax.annotation.Nullable;
+import org.osgi.framework.BundleContext;
public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdentifier> {
private final ModuleIdentifier name;
private final ModuleInternalInfo maybeOldInternalInfo;
private final TransactionModuleJMXRegistration transactionModuleJMXRegistration;
private final boolean isDefaultBean;
+ private final BundleContext bundleContext;
public ModuleInternalTransactionalInfo(ModuleIdentifier name, Module proxiedModule,
ModuleFactory moduleFactory,
ModuleInternalInfo maybeOldInternalInfo,
TransactionModuleJMXRegistration transactionModuleJMXRegistration,
- boolean isDefaultBean, Module realModule) {
+ boolean isDefaultBean, Module realModule, BundleContext bundleContext) {
this.name = name;
this.proxiedModule = proxiedModule;
this.moduleFactory = moduleFactory;
this.transactionModuleJMXRegistration = transactionModuleJMXRegistration;
this.isDefaultBean = isDefaultBean;
this.realModule = realModule;
+ this.bundleContext = bundleContext;
}
public Module getRealModule() {
return realModule;
}
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
}
package org.opendaylight.controller.config.manager.impl.factoriesresolver;
-import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.osgi.framework.BundleContext;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
+import javax.management.InstanceNotFoundException;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.osgi.framework.BundleContext;
/**
* Hold sorted ConfigMBeanFactories by their module names. Check that module
* @throws IllegalArgumentException
* if factory is not found
*/
- public ModuleFactory findByModuleName(String moduleName) {
+ public ModuleFactory findByModuleName(String moduleName) throws InstanceNotFoundException {
Map.Entry<ModuleFactory, BundleContext> result = moduleNamesToConfigBeanFactories.get(moduleName);
if (result == null) {
- throw new IllegalArgumentException(
+ throw new InstanceNotFoundException(
"ModuleFactory not found with module name: " + moduleName);
}
return result.getKey();
return moduleFactories;
}
- public Map<String, Entry<ModuleFactory, BundleContext>> getModuleNamesToConfigBeanFactories() {
- return moduleNamesToConfigBeanFactories;
- }
}
this.refName = refName;
}
- public String getServiceInterfaceName() {
+ public String getServiceInterfaceQName() {
return serviceInterfaceName;
}
result = 31 * result + refName.hashCode();
return result;
}
+
+ @Override
+ public String toString() {
+ return "ServiceReference{" +
+ "serviceInterfaceName='" + serviceInterfaceName + '\'' +
+ ", refName='" + refName + '\'' +
+ '}';
+ }
}
*/
package org.opendaylight.controller.config.manager.impl.osgi;
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
-import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
+import static com.google.common.base.Preconditions.checkState;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Registers instantiated beans as OSGi services and unregisters these services
* if beans are destroyed.
*/
public class BeanToOsgiServiceManager {
- // name of properties submitted to osgi
- static final String INSTANCE_NAME_OSGI_PROP = "instanceName";
- static final String IMPLEMENTATION_NAME_OSGI_PROP = "implementationName";
+ private static final String SERVICE_NAME_OSGI_PROP = "name";
/**
* To be called for every created, reconfigured and recreated config bean.
* It is expected that before using this method OSGi service registry will
* be cleaned from previous registrations.
*/
- public OsgiRegistration registerToOsgi(
- Class<? extends Module> configBeanClass, AutoCloseable instance,
- ModuleIdentifier moduleIdentifier, BundleContext bundleContext) {
- try {
- final Set<Class<?>> configuresInterfaces = InterfacesHelper
- .getOsgiRegistrationTypes(configBeanClass);
- checkInstanceImplementing(instance, configuresInterfaces);
-
- // bundleContext.registerService blows up with empty 'clazzes'
- if (configuresInterfaces.isEmpty() == false) {
- final Dictionary<String, ?> propertiesForOsgi = getPropertiesForOsgi(moduleIdentifier);
- final ServiceRegistration<?> serviceRegistration = bundleContext
- .registerService(classesToNames(configuresInterfaces), instance, propertiesForOsgi);
- return new OsgiRegistration(serviceRegistration);
- } else {
- return new OsgiRegistration();
- }
- } catch (IllegalStateException e) {
- throw new IllegalStateException(
- "Error while registering instance into OSGi Service Registry: "
- + moduleIdentifier, e);
- }
+ public OsgiRegistration registerToOsgi(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
+ BundleContext bundleContext,
+ Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ return new OsgiRegistration(instance, moduleIdentifier, bundleContext, serviceNamesToAnnotations);
}
- private static String[] classesToNames(Set<Class<?>> cfgs) {
- String[] result = new String[cfgs.size()];
- int i = 0;
- for (Class<?> cfg : cfgs) {
- result[i] = cfg.getName();
- i++;
- }
+ private static Dictionary<String, String> createProps(String serviceName) {
+ Hashtable<String, String> result = new Hashtable<>();
+ result.put(SERVICE_NAME_OSGI_PROP, serviceName);
return result;
}
- private void checkInstanceImplementing(AutoCloseable instance,
- Set<Class<?>> configures) {
- Set<Class<?>> missing = new HashSet<>();
- for (Class<?> requiredIfc : configures) {
- if (requiredIfc.isInstance(instance) == false) {
- missing.add(requiredIfc);
- }
- }
- if (missing.isEmpty() == false) {
- throw new IllegalStateException(
- instance.getClass()
- + " does not implement following interfaces as announced by "
- + ServiceInterfaceAnnotation.class.getName()
- + " annotation :" + missing);
- }
- }
-
- private static Dictionary<String, ?> getPropertiesForOsgi(
- ModuleIdentifier moduleIdentifier) {
- Hashtable<String, String> table = new Hashtable<>();
- table.put(IMPLEMENTATION_NAME_OSGI_PROP,
- moduleIdentifier.getFactoryName());
- table.put(INSTANCE_NAME_OSGI_PROP, moduleIdentifier.getInstanceName());
- return table;
- }
public static class OsgiRegistration implements AutoCloseable {
- private final ServiceRegistration<?> serviceRegistration;
+ private static final Logger logger = LoggerFactory.getLogger(OsgiRegistration.class);
- public OsgiRegistration(ServiceRegistration<?> serviceRegistration) {
- this.serviceRegistration = serviceRegistration;
+ @GuardedBy("this")
+ private AutoCloseable instance;
+ private final ModuleIdentifier moduleIdentifier;
+ @GuardedBy("this")
+ private final Set<ServiceRegistration<?>> serviceRegistrations;
+ @GuardedBy("this")
+ private final Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations;
+
+ public OsgiRegistration(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
+ BundleContext bundleContext,
+ Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ this.instance = instance;
+ this.moduleIdentifier = moduleIdentifier;
+ this.serviceNamesToAnnotations = serviceNamesToAnnotations;
+ this.serviceRegistrations = registerToSR(instance, bundleContext, serviceNamesToAnnotations);
}
- public OsgiRegistration() {
- this.serviceRegistration = null;
+ private static Set<ServiceRegistration<?>> registerToSR(AutoCloseable instance, BundleContext bundleContext,
+ Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ Set<ServiceRegistration<?>> serviceRegistrations = new HashSet<>();
+ for (Entry<String, ServiceInterfaceAnnotation> entry : serviceNamesToAnnotations.entrySet()) {
+ Class<?> requiredInterface = entry.getValue().osgiRegistrationType();
+ checkState(requiredInterface.isInstance(instance), instance.getClass().getName() +
+ " instance should implement " + requiredInterface.getName());
+ Dictionary<String, String> propertiesForOsgi = createProps(entry.getKey());
+ ServiceRegistration<?> serviceRegistration = bundleContext
+ .registerService(requiredInterface.getName(), instance, propertiesForOsgi);
+ serviceRegistrations.add(serviceRegistration);
+ }
+ return serviceRegistrations;
}
@Override
- public void close() {
- if (serviceRegistration != null) {
- serviceRegistration.unregister();
+ public synchronized void close() {
+ for (ServiceRegistration<?> serviceRegistration : serviceRegistrations) {
+ try {
+ serviceRegistration.unregister();
+ } catch(IllegalStateException e) {
+ logger.trace("Cannot unregister {}", serviceRegistration, e);
+ }
}
+ serviceRegistrations.clear();
}
- }
+ public synchronized void updateRegistrations(Map<String, ServiceInterfaceAnnotation> newAnnotationMapping,
+ BundleContext bundleContext, AutoCloseable newInstance) {
+ boolean notEquals = this.instance != newInstance;
+ notEquals |= newAnnotationMapping.equals(serviceNamesToAnnotations) == false;
+ if (notEquals) {
+ // FIXME: changing from old state to new state can be improved by computing the diff
+ logger.debug("Detected change in service registrations for {}: old: {}, new: {}", moduleIdentifier,
+ serviceNamesToAnnotations, newAnnotationMapping);
+ close();
+ this.instance = newInstance;
+ Set<ServiceRegistration<?>> newRegs = registerToSR(instance, bundleContext, newAnnotationMapping);
+ serviceRegistrations.clear();
+ serviceRegistrations.addAll(newRegs);
+ }
+ }
+ }
}
return result;
}
+ public static Set<String> getQNames(Set<ServiceInterfaceAnnotation> siAnnotations) {
+ Set<String> qNames = new HashSet<>();
+ for (ServiceInterfaceAnnotation sia: siAnnotations) {
+ qNames.add(sia.value());
+ }
+ return Collections.unmodifiableSet(qNames);
+ }
public static Set<ServiceInterfaceAnnotation> getServiceInterfaceAnnotations(ModuleFactory factory) {
Set<Class<? extends AbstractServiceInterface>> implementedServiceIntefaces = Collections.unmodifiableSet(factory.getImplementedServiceIntefaces());
result.add(annotation);
}
}
- return result;
+ return Collections.unmodifiableSet(result);
}
static Set<Class<? extends AbstractServiceInterface>> getAllAbstractServiceInterfaceClasses(
*/
package org.opendaylight.controller.config.manager;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import java.lang.management.ManagementFactory;
-
import org.junit.Test;
import org.opendaylight.controller.config.manager.impl.AbstractLockedPlatformMBeanServerTest;
import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.lang.management.ManagementFactory;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
public class ConfigRegistryImplTest extends
AbstractLockedPlatformMBeanServerTest {
private static final Logger logger = LoggerFactory
BundleContext context = mock(BundleContext.class);
ConfigRegistryImpl configRegistry = null;
try {
- ModuleFactoriesResolver resolver = new HardcodedModuleFactoriesResolver(
+ ModuleFactoriesResolver resolver = new HardcodedModuleFactoriesResolver(mock(BundleContext.class),
factory, factory);
configRegistry = new ConfigRegistryImpl(resolver,
package org.opendaylight.controller.config.manager.impl;
import com.google.common.base.Preconditions;
-import junit.framework.Assert;
import org.junit.After;
+import org.junit.Before;
import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.RuntimeMBeanException;
-import java.io.Closeable;
-import java.io.InputStream;
import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Dictionary;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
protected ConfigRegistryJMXClient configRegistryClient;
protected BaseJMXRegistrator baseJmxRegistrator;
protected InternalJMXRegistrator internalJmxRegistrator;
- protected BundleContext mockedContext = mock(BundleContext.class);
+ @Mock
+ protected BundleContext mockedContext;
+ @Mock
protected ServiceRegistration<?> mockedServiceRegistration;
- private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class);
+ @Before
+ public void setUpMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
// Default handler for OSGi service registration
- private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() {
+ protected static class RecordingBundleContextServiceRegistrationHandler implements BundleContextServiceRegistrationHandler {
+ private final List<RegistrationHolder> registrations = new LinkedList<>();
@Override
- public void handleServiceRegistration(Object serviceInstance) {}
- };
+ public void handleServiceRegistration(Class<?> clazz, Object serviceInstance, Dictionary<String, ?> props) {
+
+ registrations.add(new RegistrationHolder(clazz, serviceInstance, props));
+ }
+
+ public List<RegistrationHolder> getRegistrations() {
+ return registrations;
+ }
+
+ protected static class RegistrationHolder {
+ protected final Class<?> clazz;
+ protected final Object instance;
+ protected final Dictionary<String, ?> props;
+
+ public RegistrationHolder(Class<?> clazz, Object instance, Dictionary<String, ?> props) {
+ this.clazz = clazz;
+ this.instance = instance;
+ this.props = props;
+ }
+ }
+
+ }
+
+ protected BundleContextServiceRegistrationHandler currentBundleContextServiceRegistrationHandler;
protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class<?> serviceType) {
- return noopServiceRegHandler;
+ return currentBundleContextServiceRegistrationHandler;
}
// this method should be called in @Before
protected void initConfigTransactionManagerImpl(
ModuleFactoriesResolver resolver) {
+
final MBeanServer platformMBeanServer = ManagementFactory
.getPlatformMBeanServer();
- configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(
- platformMBeanServer);
+ configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(platformMBeanServer);
initBundleContext();
internalJmxRegistrator = new InternalJMXRegistrator(platformMBeanServer);
throw new RuntimeException(e);
}
configRegistryClient = new ConfigRegistryJMXClient(platformMBeanServer);
+ currentBundleContextServiceRegistrationHandler = new RecordingBundleContextServiceRegistrationHandler();
}
private void initBundleContext() {
- this.mockedServiceRegistration = mock(ServiceRegistration.class);
doNothing().when(mockedServiceRegistration).unregister();
-
RegisterServiceAnswer answer = new RegisterServiceAnswer();
-
- doAnswer(answer).when(mockedContext).registerService(Matchers.any(String[].class),
- any(Closeable.class), Matchers.<Dictionary<String, ?>>any());
- doAnswer(answer).when(mockedContext).registerService(Matchers.<Class<Closeable>>any(), any(Closeable.class),
- Matchers.<Dictionary<String, ?>>any());
- }
-
-
- public Collection<InputStream> getFilesAsInputStreams(List<String> paths) {
- final Collection<InputStream> resources = new ArrayList<>();
- List<String> failedToFind = new ArrayList<>();
- for (String path : paths) {
- InputStream resourceAsStream = getClass().getResourceAsStream(path);
- if (resourceAsStream == null) {
- failedToFind.add(path);
- } else {
- resources.add(resourceAsStream);
- }
- }
- Assert.assertEquals("Some files were not found", Collections.<String>emptyList(), failedToFind);
-
- return resources;
+ doAnswer(answer).when(mockedContext).registerService(Matchers.<String>any(), any(), Matchers.<Dictionary<String, ?>>any());
+ doAnswer(answer).when(mockedContext).registerService(Matchers.<Class>any(), any(), Matchers.<Dictionary<String, ?>>any());
}
@After
transaction.commit();
}
- protected void assertSame(ObjectName oN1, ObjectName oN2) {
- assertEquals(oN1.getKeyProperty("instanceName"),
- oN2.getKeyProperty("instanceName"));
- assertEquals(oN1.getKeyProperty("interfaceName"),
- oN2.getKeyProperty("interfaceName"));
- }
-
protected void assertStatus(CommitStatus status, int expectedNewInstances,
int expectedRecreatedInstances, int expectedReusedInstances) {
assertEquals("New instances mismatch in " + status, expectedNewInstances, status.getNewInstances().size());
.size());
}
- protected ObjectName createTestConfigBean(
- ConfigTransactionJMXClient transaction, String implementationName,
- String name) throws InstanceAlreadyExistsException {
- return transaction.createModule(implementationName,
- name);
- }
protected void assertBeanCount(int i, String configMXBeanName) {
assertEquals(i, configRegistry.lookupConfigBeans(configMXBeanName)
.size());
}
- protected void assertBeanExists(int count, String moduleName,
- String instanceName) {
- assertEquals(1,
- configRegistry.lookupConfigBeans(moduleName, instanceName)
- .size());
- }
-
/**
*
* @param configBeanClass
public static interface BundleContextServiceRegistrationHandler {
- void handleServiceRegistration(Object serviceInstance);
+ void handleServiceRegistration(Class<?> clazz, Object serviceInstance, Dictionary<String, ?> props);
}
Object serviceTypeRaw = args[0];
Object serviceInstance = args[1];
+ Dictionary<String, ?> props = (Dictionary) args[2];
if (serviceTypeRaw instanceof Class) {
Class<?> serviceType = (Class<?>) serviceTypeRaw;
- invokeServiceHandler(serviceInstance, serviceType);
+ invokeServiceHandler(serviceInstance, serviceType, props);
} else if(serviceTypeRaw instanceof String[]) {
for (String className : (String[]) serviceTypeRaw) {
- try {
- Class<?> serviceType = Class.forName(className);
- invokeServiceHandler(serviceInstance, serviceType);
- } catch (ClassNotFoundException e) {
- logger.warn("Not handling service registration of type {} ", className, e);
- }
+ invokeServiceHandler(serviceInstance, className, props);
}
+ } else if (serviceTypeRaw instanceof String) {
+ invokeServiceHandler(serviceInstance, (String) serviceTypeRaw, props);
+ } else {
+ throw new IllegalStateException("Not handling service registration of type, Unknown type" + serviceTypeRaw);
+ }
- } else
- logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw);
return mockedServiceRegistration;
}
- private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType) {
+ public void invokeServiceHandler(Object serviceInstance, String className, Dictionary<String, ?> props) {
+ try {
+ Class<?> serviceType = Class.forName(className);
+ invokeServiceHandler(serviceInstance, serviceType, props);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException("Not handling service registration of type " + className, e);
+ }
+ }
+
+ private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType, Dictionary<String, ?> props) {
BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType);
if (serviceRegistrationHandler != null) {
- serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance));
+ serviceRegistrationHandler.handleServiceRegistration(serviceType, serviceInstance, props);
}
}
}
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
}
}, currentlyRegisteredFactories);
- ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+ SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(), txLookupRegistry, currentlyRegisteredFactories);
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver());
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext));
}
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest.RecordingBundleContextServiceRegistrationHandler.RegistrationHolder;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBean;
import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory;
import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface;
import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import javax.management.Attribute;
import javax.management.MBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
-
+import java.util.List;
import java.util.Map;
import java.util.Set;
@Before
public void setUp() {
super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ mockedContext,
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory(),
new TestingScheduledThreadPoolModuleFactory()));
// create apsp-parallel
createParallelAPSP(transaction1, serviceReference);
transaction1.commit();
+
// check fixed1 is used
ServiceReferenceMXBean serviceReferenceMXBean = JMX.newMXBeanProxy(platformMBeanServer,
withoutTransactionName(serviceReference), ServiceReferenceMXBean.class);
assertEquals(withoutTransactionName(fixedTPTransactionON), serviceReferenceMXBean.getCurrentImplementation());
checkApspThreadCount(fixedNrOfThreads);
+ // check OSGi SR
+ List<RegistrationHolder> registrations =
+ ((RecordingBundleContextServiceRegistrationHandler) currentBundleContextServiceRegistrationHandler).getRegistrations();
+ assertEquals(1, registrations.size());
+ RegistrationHolder record = registrations.get(0);
+ assertEquals(TestingThreadPoolIfc.class, record.clazz);
+ assertEquals(ImmutableMap.of("name","ref"), (Map<String, String>) record.props);
// switch reference to scheduled
ConfigTransactionJMXClient transaction2 = configRegistryClient.createTransaction();
*/
package org.opendaylight.controller.config.manager.impl.dependencyresolver;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+
+import java.util.Arrays;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.JmxAttribute;
import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.spi.ModuleFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
+import org.osgi.framework.BundleContext;
public class DependencyResolverManagerTest {
moduleFactory,
maybeOldInternalInfo,
transactionModuleJMXRegistration,
- isDefaultBean);
+ isDefaultBean, mock(BundleContext.class));
}
private static Module mockedModule() {
}
}
- public HardcodedModuleFactoriesResolver(ModuleFactory... list) {
- this(mockBundleContext(),list);
- }
-
private static BundleContext mockBundleContext() {
BundleContext bundleContext = Mockito.mock(BundleContext.class);
ServiceRegistration<ModuleFactory> serviceRegistration = mock(ServiceRegistration.class);
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory()));
}
*/
package org.opendaylight.controller.config.manager.testingservices.parallelapsp.test;
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.concurrent.Executor;
-
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import javax.management.ObjectName;
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.Executor;
+
public class MockedDependenciesTest extends AbstractParallelAPSPTest {
private final String threadPoolImplementationName = "mockedthreadpool";
ClassBasedModuleFactory mockedThreadPoolConfigFactory = new ClassBasedModuleFactory(
threadPoolImplementationName, MockedThreadPoolModule.class);
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingParallelAPSPModuleFactory(),
mockedThreadPoolConfigFactory));
}
*/
package org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.test;
-import static org.junit.Assert.assertEquals;
-
import org.junit.After;
import org.junit.Before;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolImpl;
-import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool
- .TestingScheduledThreadPoolModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory;
import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import static org.junit.Assert.assertEquals;
+
public abstract class AbstractScheduledTest extends AbstractConfigTest {
protected static final String scheduled1 = "scheduled1";
public final void setUp() {
assertEquals(0,
TestingScheduledThreadPoolImpl.getNumberOfCloseMethodCalls());
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingScheduledThreadPoolModuleFactory(),
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory()));
@Override
public void close() throws IOException {
executorService.shutdown();
+ allExecutors.remove(executorService);
}
--- /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.config.manager.testingservices.threadpool.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.osgi.framework.BundleContext;
+
+public class ShutdownTest extends AbstractConfigTest {
+ private final TestingFixedThreadPoolModuleFactory testingFixedThreadPoolModuleFactory = new TestingFixedThreadPoolModuleFactory();
+
+ @Mock
+ ModuleFactoriesResolver mockedResolver;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ Map<String, Entry<ModuleFactory, BundleContext>> allFactories = ImmutableMap.of(
+ testingFixedThreadPoolModuleFactory.getImplementationName(),
+ Maps.<ModuleFactory, BundleContext>immutableEntry(testingFixedThreadPoolModuleFactory, mockedContext));
+ doReturn(allFactories).when(mockedResolver).getAllFactories();
+ super.initConfigTransactionManagerImpl(mockedResolver);
+ }
+
+
+ @Test
+ public void testCreateAndDestroyBeanInSameTransaction() throws Exception {
+ {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+ SimpleConfigurationTest.createFixedThreadPool(transaction);
+ transaction.commit();
+ }
+ assertEquals(1, TestingFixedThreadPool.allExecutors.size());
+ doReturn(Collections.emptyMap()).when(mockedResolver).getAllFactories();
+ {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+ transaction.commit();
+ }
+ assertEquals(1, TestingFixedThreadPool.allExecutors.size());
+ }
+}
* dependencies.
*/
public class SimpleConfigurationTest extends AbstractConfigTest {
- private final int numberOfThreads = 5;
+ private static final int numberOfThreads = 5;
private final int numberOfThreads2 = 10;
private static final String fixed1 = "fixed1";
private static final List<ObjectName> emptyONs = Collections
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingFixedThreadPoolModuleFactory()));
}
return fixed1names;
}
- private ObjectName createFixedThreadPool(
+ static ObjectName createFixedThreadPool(
ConfigTransactionJMXClient transaction)
throws InstanceAlreadyExistsException, InstanceNotFoundException {
transaction.assertVersion(0, 1);
// 4, check
assertEquals(2, configRegistryClient.getVersion());
- assertEquals(1, TestingFixedThreadPool.allExecutors.size());
- assertTrue(TestingFixedThreadPool.allExecutors.get(0).isShutdown());
+ assertEquals(0, TestingFixedThreadPool.allExecutors.size());
// dynamic config should be removed from platform
try {
// commit
transaction.commit();
// check that first threadpool is closed
- checkThreadPools(2, numberOfThreads2);
+ checkThreadPools(1, numberOfThreads2);
}
private void checkThreadPools(int expectedTotalNumberOfExecutors,
// commit
CommitStatus commitStatus = transaction.commit();
// check that new threadpool is created and old one is closed
- checkThreadPools(2, numberOfThreads);
+ checkThreadPools(1, numberOfThreads);
CommitStatus expected = new CommitStatus(emptyONs, emptyONs, fixed1List);
assertEquals(expected, commitStatus);
}
platformMBeanServer.getMBeanInfo(transaction.getObjectName());
fail();
}catch(InstanceNotFoundException e){
+ assertEquals("org.opendaylight.controller:TransactionName=ConfigTransaction-0-1,type=ConfigTransaction", e.getMessage());
}
}
* @return prefix + key as used in getProperty method.
*/
String getFullKeyForReporting(String key);
+
+ String getPrefix();
+ String getPropertyWithoutPrefix(String fullKey);
}
public String getFullKeyForReporting(String key) {
return null;
}
+
+ @Override
+ public String getPrefix() {
+ return null;
+ }
+
+ @Override
+ public String getPropertyWithoutPrefix(String fullKey) {
+ return null;
+ }
}
public void setUp() throws Exception {
factory = new LogbackModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
public void setUp() throws IOException, ClassNotFoundException {
factory = new LogbackModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
/**
public void setUp() throws JoranException, IOException {
factory = new LogbackModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
lc = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
@Before
public void setUp() {
factory = new GlobalEventExecutorModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
@Before
public void setUp() {
factory = new NettyThreadgroupModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
class StopSystemBundleThread extends Thread {
private static final Logger logger = LoggerFactory.getLogger(StopSystemBundleThread.class);
- public static final String CONFIG_MANAGER_SYMBOLIC_NAME = "org.opendaylight.controller.config-manager";
private final Bundle systemBundle;
StopSystemBundleThread(Bundle systemBundle) {
try {
// wait so that JMX response is received
Thread.sleep(1000);
- // first try to stop config-manager
- Bundle configManager = findConfigManager();
- if (configManager != null){
- logger.debug("Stopping config-manager");
- configManager.stop();
- Thread.sleep(1000);
- }
logger.debug("Stopping system bundle");
systemBundle.stop();
} catch (BundleException e) {
logger.warn("Shutdown process interrupted", e);
}
}
-
- private Bundle findConfigManager() {
- for(Bundle bundle: systemBundle.getBundleContext().getBundles()){
- if (CONFIG_MANAGER_SYMBOLIC_NAME.equals(bundle.getSymbolicName())) {
- return bundle;
- }
- }
- return null;
- }
-
}
class CallSystemExitThread extends Thread {
*/
package org.opendaylight.controller.config.yang.shutdown.impl;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME;
+
+import java.util.Collections;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.ObjectName;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.osgi.framework.Bundle;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.ObjectName;
-import java.util.Collections;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME;
-
public class ShutdownTest extends AbstractConfigTest {
private final ShutdownModuleFactory factory = new ShutdownModuleFactory();
@Mock
- private Bundle mockedSysBundle, mockedConfigManager;
+ private Bundle mockedSysBundle;
@Before
doReturn(mockedSysBundle).when(mockedContext).getBundle(0);
mockedContext.getBundle(0);
doNothing().when(mockedSysBundle).stop();
- doNothing().when(mockedConfigManager).stop();
doReturn(mockedContext).when(mockedSysBundle).getBundleContext();
- doReturn(new Bundle[]{mockedSysBundle, mockedConfigManager}).when(mockedContext).getBundles();
+ doReturn(new Bundle[]{mockedSysBundle}).when(mockedContext).getBundles();
doReturn("system bundle").when(mockedSysBundle).getSymbolicName();
- doReturn(StopSystemBundleThread.CONFIG_MANAGER_SYMBOLIC_NAME).when(mockedConfigManager).getSymbolicName();
+
ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
private void assertStopped() throws Exception {
Thread.sleep(3000); // happens on another thread
- verify(mockedConfigManager).stop();
verify(mockedSysBundle).stop();
}
}
TestingScheduledThreadPoolModule.class, poolImplName);
factory = new AsyncEventBusModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
scheduledThreadPoolConfigFactory));
}
*/
package org.opendaylight.controller.config.threadpool.eventbus;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.containsString;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.config.yang.threadpool.impl.EventBusModuleFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
public class SyncEventBusConfigBeanTest extends AbstractConfigTest {
private EventBusModuleFactory factory;
public void setUp() {
factory = new EventBusModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
@Before
public void setUp() {
factory = new FixedThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
new NamingThreadFactoryModuleFactory()));
}
public void setUp() {
flexibleFactory = new FlexibleThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(flexibleFactory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,flexibleFactory,
new NamingThreadFactoryModuleFactory()));
}
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
public void setUp() {
factory = new NamingThreadFactoryModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory));
}
@Test
public void setUp() {
factory = new ScheduledThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory,
new NamingThreadFactoryModuleFactory()));
}
*/
package org.opendaylight.controller.config.yangjmxgenerator.it;
-import static org.junit.Assert.fail;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.TestImplModuleMXBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.fail;
+
@Ignore
// ietf beans are not JMX compliant beans:
// Do not know how to make a
public void setUp() {
factory = new TestImplModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
factory));
}
--- /dev/null
+/*
+* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v1.0 which accompanies this distribution,
+* and is available at http://www.eclipse.org/legal/epl-v10.html
+*/
+/*
+* Generated file
+*
+* Generated from: yang module name: config-test-impl yang module local name: impl-dep
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Apr 25 11:50:32 CEST 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.test.impl;
+public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory {
+
+}
--- /dev/null
+/*
+* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v1.0 which accompanies this distribution,
+* and is available at http://www.eclipse.org/legal/epl-v10.html
+*/
+/*
+* Generated file
+*
+* Generated from: yang module name: config-test-impl yang module local name: impl-identity-test
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Apr 25 11:50:32 CEST 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.test.impl;
+public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory {
+
+}
--- /dev/null
+/*
+* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v1.0 which accompanies this distribution,
+* and is available at http://www.eclipse.org/legal/epl-v10.html
+*/
+/*
+* Generated file
+*
+* Generated from: yang module name: config-test-impl yang module local name: impl-netconf
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Apr 25 11:50:32 CEST 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.test.impl;
+public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory {
+
+}
--- /dev/null
+/*
+* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v1.0 which accompanies this distribution,
+* and is available at http://www.eclipse.org/legal/epl-v10.html
+*/
+/*
+* Generated file
+*
+* Generated from: yang module name: config-test-impl yang module local name: impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Apr 25 11:50:32 CEST 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.test.impl;
+public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory {
+
+}
public void setUp() {
factory = new NetconfTestImplModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
new DepTestImplModuleFactory(), new IdentityTestModuleFactory()));
}
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
<snapshot>
<required-capabilities>
<capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&revision=2013-11-19</capability>
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
<snapshot>
<configuration>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
<snapshot>
<configuration>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+ <configuration>
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
+ <name>controller-config</name>
+ <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1830</port>
+ <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
+ <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
+ <name>global-worker-group</name>
+ </worker-thread-group>
+ <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
+ <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
+ <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
+ <name>global-event-executor</name>
+ </event-executor>
+ <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
+ <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
+ <name>global-boss-group</name>
+ </boss-thread-group>
+ <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
+ <name>dom-broker</name>
+ </dom-registry>
+ </module>
+ </modules>
+ </data>
+ </configuration>
+ <required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&revision=2013-10-28</capability>
+ </required-capabilities>
+</snapshot>
}
if (!d.isPresent() && iterator.hasNext()) {
- writeTransaction.put(store, currentPath, currentOp.createDefault(currentArg));
+ writeTransaction.merge(store, currentPath, currentOp.createDefault(currentArg));
}
}
//LOG .info("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
--- /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.binding.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+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.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class ConcurrentImplicitCreateTest extends AbstractDataServiceTest {
+
+ private static final NodeKey NODE_FOO_KEY = new NodeKey(new NodeId("foo"));
+ private static final NodeKey NODE_BAR_KEY = new NodeKey(new NodeId("foo"));
+ private static InstanceIdentifier<Nodes> NODES_PATH = InstanceIdentifier.builder(Nodes.class).build();
+ private static InstanceIdentifier<Node> NODE_FOO_PATH = InstanceIdentifier.builder(NODES_PATH)
+ .child(Node.class, NODE_FOO_KEY).build();
+ private static InstanceIdentifier<Node> NODE_BAR_PATH = InstanceIdentifier.builder(NODES_PATH)
+ .child(Node.class, NODE_FOO_KEY).build();
+
+ @Test
+ public void testConcurrentCreate() throws InterruptedException, ExecutionException {
+
+ DataModificationTransaction fooTx = baDataService.beginTransaction();
+ DataModificationTransaction barTx = baDataService.beginTransaction();
+
+ fooTx.putOperationalData(NODE_FOO_PATH, new NodeBuilder().setKey(NODE_FOO_KEY).build());
+ barTx.putOperationalData(NODE_BAR_PATH, new NodeBuilder().setKey(NODE_BAR_KEY).build());
+
+ Future<RpcResult<TransactionStatus>> fooFuture = fooTx.commit();
+ Future<RpcResult<TransactionStatus>> barFuture = barTx.commit();
+
+ RpcResult<TransactionStatus> fooResult = fooFuture.get();
+ RpcResult<TransactionStatus> barResult = barFuture.get();
+
+ assertTrue(fooResult.isSuccessful());
+ assertTrue(barResult.isSuccessful());
+
+ assertEquals(TransactionStatus.COMMITED, fooResult.getResult());
+ assertEquals(TransactionStatus.COMMITED, barResult.getResult());
+
+ }
+}
</provider>
</instance>
</service>
+
<service>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
binding:binding-broker-osgi-registry
</provider>
</instance>
</service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <instance>
+ <name>binding-rpc-broker</name>
+ <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+ </instance>
+ </service>
<service>
<type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
binding-impl:binding-dom-mapping-service
@Override
public void merge(final LogicalDatastoreType store, final InstanceIdentifier path,
final NormalizedNode<?, ?> data) {
- // TODO Auto-generated method stub
- throw new UnsupportedOperationException("Not implemented yet.");
+ getSubtransaction(store).merge(path,data);
}
@Override
final InstanceIdentifier path) {
return getSubtransaction(store).read(path);
}
-
- @Override
- public void merge(final LogicalDatastoreType store, final InstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
-
- }
}
private final class CommitCoordination implements Callable<RpcResult<TransactionStatus>> {
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.ListenableFuture;
public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransaction> implements
InstanceIdentifier currentPath = new InstanceIdentifier(currentArguments);
boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
if(isPresent == false && iterator.hasNext()) {
- getDelegate().put(store, currentPath, currentOp.createDefault(currentArg));
+ getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
}
}
} catch (InterruptedException | ExecutionException e) {
getDelegate().put(store, normalizedPath, normalizedData);
}
- private boolean isAugmentationChild(final InstanceIdentifier normalizedPath) {
- List<PathArgument> parentArgs = parentPath(normalizedPath).getPath();
- if(parentArgs.isEmpty()) {
- return false;
- }
- return Iterables.getLast(parentArgs) instanceof AugmentationIdentifier;
- }
-
- private void ensureParentNode(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath,
- final NormalizedNode<?, ?> normalizedData) {
- InstanceIdentifier parentPath = parentPath(normalizedPath);
- PathArgument parentType = Iterables.getLast(parentPath.getPath());
- if(parentType instanceof AugmentationIdentifier) {
- AugmentationNode node = Builders.augmentationBuilder()
- .withNodeIdentifier((AugmentationIdentifier) parentType)
- .build();
- getDelegate().put(store, parentPath, node);
- }
- if(normalizedData instanceof MapEntryNode) {
- MapNode mapNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(normalizedData.getNodeType())).build();
- getDelegate().put(store, parentPath, mapNode);
- } else if (normalizedData instanceof LeafSetNode<?>){
- LeafSetNode<Object> leafNode = Builders.leafSetBuilder().withNodeIdentifier(new NodeIdentifier(normalizedData.getNodeType())).build();
- getDelegate().put(store, parentPath, leafNode);
- }
-
-
- }
-
- private InstanceIdentifier parentPath(final InstanceIdentifier normalizedPath) {
- List<PathArgument> childArgs = normalizedPath.getPath();
- return new InstanceIdentifier(childArgs.subList(0, childArgs.size() -1));
- }
-
- private boolean parentNodeDoesNotExists(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath) {
- try {
- return !getDelegate().read(store, parentPath(normalizedPath)).get().isPresent();
- } catch (InterruptedException | ExecutionException e) {
- throw new IllegalStateException(e);
- }
- }
-
@Override
public void removeConfigurationData(final InstanceIdentifier legacyPath) {
checkNotNull(legacyPath, "Path MUST NOT be null.");
}
}
+ @Override
+ public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+ checkNotReady();
+ try {
+ LOG.trace("Tx: {} Merge: {}:{}",getIdentifier(),path,data);
+ mutableTree.merge(path, data);
+ // FIXME: Add checked exception
+ } catch (Exception e) {
+ LOG.error("Tx: {}, failed to write {}:{} in {}",getIdentifier(),path,data,mutableTree,e);
+ }
+ }
+
@Override
public void delete(final InstanceIdentifier path) {
checkNotReady();
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
resolveModificationFor(path).write(value);
}
+ public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+ checkSealed();
+ mergeImpl(resolveModificationFor(path),data);
+ }
+
+ private void mergeImpl(final OperationWithModification op,final NormalizedNode<?,?> data) {
+
+ if(data instanceof NormalizedNodeContainer<?,?,?>) {
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ NormalizedNodeContainer<?,?,NormalizedNode<PathArgument, ?>> dataContainer = (NormalizedNodeContainer) data;
+ for(NormalizedNode<PathArgument, ?> child : dataContainer.getValue()) {
+ PathArgument childId = child.getIdentifier();
+ mergeImpl(op.forChild(childId), child);
+ }
+ }
+ op.merge(data);
+ }
+
public void delete(final InstanceIdentifier path) {
checkSealed();
resolveModificationFor(path).delete();
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import com.google.common.base.Optional;
public class OperationWithModification {
private final NodeModification modification;
+
private final ModificationApplyOperation applyOperation;
private OperationWithModification(final ModificationApplyOperation op, final NodeModification mod) {
return this;
}
+ public NodeModification getModification() {
+ return modification;
+ }
+
+ public ModificationApplyOperation getApplyOperation() {
+ return applyOperation;
+ }
+
public boolean isApplicable(final Optional<StoreMetadataNode> data) {
return applyOperation.isApplicable(modification, data);
}
return new OperationWithModification(operation, modification);
}
+
+ public void merge(final NormalizedNode<?, ?> data) {
+ modification.merge(data);
+ applyOperation.verifyStructure(modification);
+
+ }
+
+ public OperationWithModification forChild(final PathArgument childId) {
+ NodeModification childMod = modification.modifyChild(childId);
+ Optional<ModificationApplyOperation> childOp = applyOperation.getChild(childId);
+ return from(childOp.get(),childMod);
+ }
}
\ No newline at end of file
switch (modification.getModificationType()) {
case SUBTREE_MODIFIED:
return resolveSubtreeChangeEvent(path, listeners, modification, before.get(), after.get());
+ case MERGE:
case WRITE:
if (before.isPresent()) {
return resolveReplacedEvent(path, listeners, before.get().getData(), after.get().getData());
switch (childMod.getModificationType()) {
case WRITE:
+ case MERGE:
case DELETE:
one.merge(resolveAnyChangeEvent(childPath, childListeners, childMod, childBefore, childAfter));
break;
return isSubtreeModificationApplicable(modification, current);
case WRITE:
return isWriteApplicable(modification, current);
+ case MERGE:
+ return isMergeApplicable(modification,current);
case UNMODIFIED:
return true;
default:
}
}
+ private boolean isMergeApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
+ Optional<StoreMetadataNode> original = modification.getOriginal();
+ if (original.isPresent() && current.isPresent()) {
+ return isNotConflicting(original.get(), current.get());
+ } else if (current.isPresent()) {
+ return true;
+ }
+ return true;
+ }
+
protected boolean isWriteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
Optional<StoreMetadataNode> original = modification.getOriginal();
if (original.isPresent() && current.isPresent()) {
modification);
return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(),
subtreeVersion)));
+ case MERGE:
+ if(currentMeta.isPresent()) {
+ return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(),subtreeVersion)));
+ } // Fallback to write is intentional - if node is not preexisting merge is same as write
case WRITE:
return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion)));
case UNMODIFIED:
}
}
+ protected abstract StoreMetadataNode applyMerge(NodeModification modification,
+ StoreMetadataNode currentMeta, UnsignedLong subtreeVersion);
+
protected abstract StoreMetadataNode applyWrite(NodeModification modification,
Optional<StoreMetadataNode> currentMeta, UnsignedLong subtreeVersion);
+ "is leaf type node. Subtree change is not allowed.");
}
+ @Override
+ protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta,
+ final UnsignedLong subtreeVersion) {
+ return applyWrite(modification, Optional.of(currentMeta), subtreeVersion);
+ }
+
@Override
protected StoreMetadataNode applyWrite(final NodeModification modification,
final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
UnsignedLong nodeVersion = subtreeVersion;
- if (currentMeta.isPresent()) {
- nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion());
- }
-
return StoreMetadataNode.builder().setNodeVersion(nodeVersion).setSubtreeVersion(subtreeVersion)
.setData(modification.getWritenValue()).build();
}
}
+ @Override
+ protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta,
+ final UnsignedLong subtreeVersion) {
+ // For Node Containers - merge is same as subtree change - we only replace children.
+ return applySubtreeChange(modification, currentMeta, subtreeVersion);
+ }
+
@Override
public StoreMetadataNode applySubtreeChange(final NodeModification modification,
final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
entryStrategy = Optional.<ModificationApplyOperation> of(new UnkeyedListItemModificationStrategy(schema));
}
-
+ @Override
+ protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta,
+ final UnsignedLong subtreeVersion) {
+ return applyWrite(modification, Optional.of(currentMeta), subtreeVersion);
+ }
@Override
protected StoreMetadataNode applySubtreeChange(final NodeModification modification,
* Tree node is to be deleted.
*
*/
- DELETE
+ DELETE,
+
+ /**
+ *
+ * Tree node is to be merged with existing one.
+ *
+ */
+ MERGE
}
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
-import com.google.common.primitives.UnsignedLong;
/**
* Node Modification Node and Tree
public static final Predicate<NodeModification> IS_TERMINAL_PREDICATE = new Predicate<NodeModification>() {
@Override
public boolean apply(final NodeModification input) {
- return input.getModificationType() == ModificationType.WRITE || input.getModificationType() == ModificationType.DELETE;
+ return input.getModificationType() == ModificationType.WRITE //
+ || input.getModificationType() == ModificationType.DELETE //
+ || input.getModificationType() == ModificationType.MERGE;
}
};
private final PathArgument identifier;
private NormalizedNode<?, ?> value;
- private UnsignedLong subtreeVersion;
private Optional<StoreMetadataNode> snapshotCache;
private final Map<PathArgument, NodeModification> childModification;
this.value = value;
}
+ public synchronized void merge(final NormalizedNode<?, ?> data) {
+ checkSealed();
+ clearSnapshot();
+ updateModificationType(ModificationType.MERGE);
+ // FIXME: Probably merge with previous value.
+ this.value = data;
+ }
+
@GuardedBy("this")
private void checkSealed() {
checkState(!sealed, "Node Modification is sealed. No further changes allowed.");
*/
void write(InstanceIdentifier path, NormalizedNode<?, ?> data);
+ /**
+ * Store a provided data at specified path. This acts as a add / replace
+ * operation, which is to say that whole subtree will be replaced by
+ * specified path.
+ *
+ * If you need add or merge of current object with specified use
+ * {@link #merge(LogicalDatastoreType, Path, Object)}
+ *
+ *
+ * @param path
+ * @param data
+ * Data object to be written
+ *
+ * @throws IllegalStateException
+ * if the client code already sealed transaction and invoked
+ * {@link #ready()}
+ */
+ void merge(InstanceIdentifier path, NormalizedNode<?, ?> data);
+
/**
*
* Deletes data and whole subtree located at provided path.
@Override
public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
- return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext()));
+ return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext()), rpc);
}
@Override
import java.util.Queue;
import java.util.Set;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
import org.opendaylight.controller.netconf.client.NetconfClientSession;
import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.controller.sal.common.util.Rpcs;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
import org.opendaylight.yangtools.yang.common.QName;
private static final class Request {
final UncancellableFuture<RpcResult<CompositeNode>> future;
final NetconfMessage request;
+ final QName rpc;
- private Request(UncancellableFuture<RpcResult<CompositeNode>> future, NetconfMessage request) {
+ private Request(UncancellableFuture<RpcResult<CompositeNode>> future, NetconfMessage request, final QName rpc) {
this.future = future;
this.request = request;
+ this.rpc = rpc;
}
}
try {
NetconfMapping.checkSuccessReply(message);
- } catch (IllegalStateException e) {
+ } catch (NetconfDocumentedException | IllegalStateException e) {
LOG.warn("Error reply from remote device", e);
r.future.setException(e);
return;
}
- r.future.set(Rpcs.getRpcResult(true, NetconfMapping.toNotificationNode(message, device.getSchemaContext()),
- Collections.<RpcError>emptyList()));
+ r.future.set(NetconfMapping.toRpcResult(message, r.rpc, device.getSchemaContext()));
} else {
LOG.warn("Ignoring unsolicited message", message);
}
}
- synchronized ListenableFuture<RpcResult<CompositeNode>> sendRequest(final NetconfMessage message) {
+ synchronized ListenableFuture<RpcResult<CompositeNode>> sendRequest(final NetconfMessage message, final QName rpc) {
if (session == null) {
LOG.debug("Session to {} is disconnected, failing RPC request {}", device.getName(), message);
return Futures.<RpcResult<CompositeNode>>immediateFuture(new RpcResult<CompositeNode>() {
});
}
- final Request req = new Request(new UncancellableFuture<RpcResult<CompositeNode>>(true), message);
+ final Request req = new Request(new UncancellableFuture<RpcResult<CompositeNode>>(true), message, rpc);
requests.add(req);
session.sendMessage(req.request).addListener(new FutureListener<Void>() {
public void operationComplete(final Future<Void> future) throws Exception {
if (!future.isSuccess()) {
// We expect that a session down will occur at this point
- LOG.debug("Failed to send request {}", req.request, future.cause());
+ LOG.debug("Failed to send request {}", XmlUtil.toString(req.request.getDocument()), future.cause());
req.future.setException(future.cause());
} else {
LOG.trace("Finished sending request {}", req.request);
*/
package org.opendaylight.controller.sal.connect.netconf;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
-
import javax.activation.UnsupportedDataTypeException;
import javax.annotation.Nullable;
-
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
public class NetconfMapping {
public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0");
rawRpc = it.toInstance();
// sys(xmlData)
} else {
- RpcDefinition rpcSchema = Iterables.find(context.get().getOperations(), new Predicate<RpcDefinition>() {
- @Override
- public boolean apply(final RpcDefinition input) {
- return rpc == input.getQName();
- }
- });
rawRpc = (CompositeNode) toCompositeNode(message.getDocument());
}
else {
}
}
- public static void checkSuccessReply(NetconfMessage output) {
+ public static void checkSuccessReply(NetconfMessage output) throws NetconfDocumentedException {
if(NetconfMessageUtil.isErrorMessage(output)) {
throw new IllegalStateException(String.format("Response contains error: %s", XmlUtil.toString(output.getDocument())));
}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String> {
private final NetconfDevice device;
+ private final Logger logger;
+
public NetconfRemoteSchemaSourceProvider(NetconfDevice device) {
this.device = Preconditions.checkNotNull(device);
+ logger = LoggerFactory.getLogger(NetconfDevice.class + "#" + device.getName());
}
@Override
request.addLeaf("version", revision.get());
}
- device.logger.trace("Loading YANG schema source for {}:{}", moduleName, revision);
+ logger.trace("Loading YANG schema source for {}:{}", moduleName, revision);
try {
RpcResult<CompositeNode> schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance()).get();
if (schemaReply.isSuccessful()) {
return Optional.of(schemaBody);
}
}
- device.logger.warn("YANG shcema was not successfully retrieved.");
+ logger.warn("YANG shcema was not successfully retrieved.");
} catch (InterruptedException | ExecutionException e) {
- device.logger.warn("YANG shcema was not successfully retrieved.", e);
+ logger.warn("YANG shcema was not successfully retrieved.", e);
}
return Optional.absent();
}
// it could be identityref Built-In Type
URI namespace = getNamespaceFor(value);
if (namespace != null) {
- return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null);
+ return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null,value);
}
// it is not "prefix:value" but just "value"
return value;
if (xPathParts.length < 2) { // must be at least "/pr:node"
return null;
}
- IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO();
+ IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(value);
for (int i = 1; i < xPathParts.length; i++) {
String xPathPartTrimmed = xPathParts[i].trim();
if (namespaceAndValue.length == 2) {
String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
if (namespace != null && !namespace.isEmpty()) {
- return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0]);
+ return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0],value);
}
}
// it is not "prefix:value" but just "value"
public final class IdentityValuesDTO {
private final List<IdentityValue> elementData = new ArrayList<>();
+ private final String originValue;
- public IdentityValuesDTO(String namespace, String value, String prefix) {
+ public IdentityValuesDTO(String namespace, String value, String prefix,String originValue) {
elementData.add(new IdentityValue(namespace, value, prefix));
+ this.originValue = originValue;
+ }
+
+ public IdentityValuesDTO(String originValue) {
+ this.originValue = originValue;
}
public IdentityValuesDTO() {
-
+ originValue = null;
}
public void add(String namespace, String value, String prefix) {
public String toString() {
return elementData.toString();
}
+
+ public String getOriginValue() {
+ return originValue;
+ }
public static final class IdentityValue {
input == null ? "null" : input.getClass(), String.valueOf(input));
return null;
} else if (type instanceof LeafrefTypeDefinition) {
+ if (input instanceof IdentityValuesDTO) {
+ return LEAFREF_DEFAULT_CODEC.deserialize(((IdentityValuesDTO)input).getOriginValue());
+ }
return LEAFREF_DEFAULT_CODEC.deserialize(input);
} else if (type instanceof InstanceIdentifierTypeDefinition) {
if (input instanceof IdentityValuesDTO) {
TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
.from(type);
if (typeAwarecodec != null) {
+ if (input instanceof IdentityValuesDTO) {
+ return typeAwarecodec.deserialize(((IdentityValuesDTO)input).getOriginValue());
+ }
return typeAwarecodec.deserialize(String.valueOf(input));
} else {
logger.debug("Codec for type \"" + type.getQName().getLocalName()
@Override
public IdentityValuesDTO serialize(QName data) {
- return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix());
+ return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix(),null);
}
@Override
if (schema.typeDefinition instanceof IdentityrefTypeDefinition) {
if (value instanceof String) {
- inputValue = new IdentityValuesDTO(nodeBuilder.namespace.toString, value as String, null)
+ inputValue = new IdentityValuesDTO(nodeBuilder.namespace.toString, value as String, null,value as String);
} // else value is already instance of IdentityValuesDTO
}
--- /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.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+
+public class XmlAndJsonToCnSnLeafRefTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/leafref/yang", 2, "leafref-module", "cont");
+ }
+
+ @Test
+ public void loadXmlToCnSn() throws WebApplicationException, IOException, URISyntaxException {
+ CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/xml/xmldata.xml", XmlToCompositeNodeProvider.INSTANCE);
+ TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
+ verifyContPredicate(cnSn, "/ns:cont/ns:lf1", "/cont/lf1", "/ns:cont/ns:lf1", "../lf1");
+ }
+
+ @Test
+ public void loadJsonToCnSn() throws WebApplicationException, IOException, URISyntaxException {
+ CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/json/jsondata.json",
+ JsonToCompositeNodeProvider.INSTANCE);
+ TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
+ verifyContPredicate(cnSn, "/leafref-module:cont/leafref-module:lf1", "/leafref-module:cont/leafref-module:lf1",
+ "/referenced-module:cont/referenced-module:lf1", "/leafref-module:cont/leafref-module:lf1");
+ }
+
+ private void verifyContPredicate(CompositeNode cnSn, String... values) throws URISyntaxException {
+ Object lf2Value = null;
+ Object lf3Value = null;
+ Object lf4Value = null;
+ Object lf5Value = null;
+
+ for (Node<?> node : cnSn.getValue()) {
+ if (node.getNodeType().getLocalName().equals("lf2")) {
+ lf2Value = ((SimpleNode<?>) node).getValue();
+ } else if (node.getNodeType().getLocalName().equals("lf3")) {
+ lf3Value = ((SimpleNode<?>) node).getValue();
+ } else if (node.getNodeType().getLocalName().equals("lf4")) {
+ lf4Value = ((SimpleNode<?>) node).getValue();
+ } else if (node.getNodeType().getLocalName().equals("lf5")) {
+ lf5Value = ((SimpleNode<?>) node).getValue();
+ }
+ }
+ assertEquals(values[0], lf2Value);
+ assertEquals(values[1], lf3Value);
+ assertEquals(values[2], lf4Value);
+ assertEquals(values[3], lf5Value);
+ }
+
+}
--- /dev/null
+{
+ "leafref-module:cont" : {
+ "lf4" : "/referenced-module:cont/referenced-module:lf1",
+ "lf2" : "/leafref-module:cont/leafref-module:lf1",
+ "lf3" : "/leafref-module:cont/leafref-module:lf1",
+ "lf5" : "/leafref-module:cont/leafref-module:lf1"
+ }
+}
\ No newline at end of file
--- /dev/null
+<cont xmlns="leafref:module">
+ <lf4 xmlns:ns="referenced:module">/ns:cont/ns:lf1</lf4>
+ <lf2 xmlns:ns="leafref:module">/ns:cont/ns:lf1</lf2>
+ <lf3 xmlns:ns="leafref:module">/cont/lf1</lf3>
+ <lf5 xmlns:ns="leafref:module">../lf1</lf5>
+</cont>
--- /dev/null
+module leafref-module {
+ namespace "leafref:module";
+
+
+ prefix "lfrfmodule";
+
+ import referenced-module { prefix refmod; revision-date 2014-04-17;}
+
+
+ revision 2014-04-17 {
+ }
+
+
+ container cont {
+ leaf lf1 {
+ type instance-identifier;
+ }
+
+ leaf lf2 {
+ type leafref {
+ path "../lf1";
+ }
+ }
+
+ leaf lf3 {
+ type leafref {
+ path "/refmod:cont/refmod:lf1";
+ }
+ }
+
+ leaf lf4 {
+ type leafref {
+ path "/cont/lf1";
+ }
+ }
+
+ leaf lf5 {
+ type leafref {
+ path "../lf1";
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+module referenced-module {
+ namespace "referenced:module";
+
+ prefix "refmodule";
+ revision 2014-04-17 {
+ }
+
+ container cont {
+ leaf lf1 {
+ type instance-identifier;
+ }
+ }
+}
\ No newline at end of file
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.osgi</artifactId>
</dependency>
- <dependency>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>org.eclipse.xtend.lib</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
<manifestLocation>${project.basedir}/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>xtend-maven-plugin</artifactId>
- </plugin>
</plugins>
</build>
<scm>
--- /dev/null
+/**
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.md.controller.topology.lldp;
+
+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;
+
+public class LLDPActivator extends AbstractBindingAwareProvider {
+ private static LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider();
+
+ public void onSessionInitiated(final ProviderContext session) {
+ DataProviderService dataService = session.<DataProviderService>getSALService(DataProviderService.class);
+ provider.setDataService(dataService);
+ NotificationProviderService notificationService = session.<NotificationProviderService>getSALService(NotificationProviderService.class);
+ provider.setNotificationService(notificationService);
+ provider.start();
+ }
+
+ protected void stopImpl(final BundleContext context) {
+ provider.close();
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.md.controller.topology.lldp
-
-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
-
-class LLDPActivator extends AbstractBindingAwareProvider {
-
- static var LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider();
-
- override onSessionInitiated(ProviderContext session) {
- provider.dataService = session.getSALService(DataProviderService)
- provider.notificationService = session.getSALService(NotificationProviderService)
- provider.start();
- }
-
- override protected stopImpl(BundleContext context) {
- provider.close();
- }
-
-}
--- /dev/null
+/**
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.md.controller.topology.lldp;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LLDPDiscoveryProvider implements AutoCloseable {
+ private final static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider.class);
+ private DataProviderService dataService;
+ private NotificationProviderService notificationService;
+ private final LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(LLDPDiscoveryProvider.this);
+ private Registration<NotificationListener> listenerRegistration;
+
+ public DataProviderService getDataService() {
+ return this.dataService;
+ }
+
+ public void setDataService(final DataProviderService dataService) {
+ this.dataService = dataService;
+ }
+
+ public NotificationProviderService getNotificationService() {
+ return this.notificationService;
+ }
+
+ public void setNotificationService(final NotificationProviderService notificationService) {
+ this.notificationService = notificationService;
+ }
+
+ public void start() {
+ Registration<NotificationListener> registerNotificationListener = this.getNotificationService().registerNotificationListener(this.commiter);
+ this.listenerRegistration = registerNotificationListener;
+ LLDPLinkAger.getInstance().setManager(this);
+ LOG.info("LLDPDiscoveryListener Started.");
+ }
+
+ public void close() {
+ try {
+ LOG.info("LLDPDiscoveryListener stopped.");
+ if (this.listenerRegistration!=null) {
+ this.listenerRegistration.close();
+ }
+ LLDPLinkAger.getInstance().close();
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.md.controller.topology.lldp
-
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.NotificationListener
-import org.slf4j.LoggerFactory
-
-class LLDPDiscoveryProvider implements AutoCloseable {
-
-
- static val LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider);
-
- @Property
- DataProviderService dataService;
-
- @Property
- NotificationProviderService notificationService;
-
- val LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(this);
-
- Registration<NotificationListener> listenerRegistration
-
- def void start() {
- listenerRegistration = notificationService.registerNotificationListener(commiter);
- LLDPLinkAger.instance.manager = this;
- LOG.info("LLDPDiscoveryListener Started.");
-
- }
-
- override close() {
- LOG.info("LLDPDiscoveryListener stopped.");
- listenerRegistration?.close();
- LLDPLinkAger.instance.close();
- }
-
-}
-
-
org.opendaylight.controller.netconf.confignetconfconnector.transactions,
org.opendaylight.controller.netconf.confignetconfconnector.util,
org.opendaylight.controller.netconf.confignetconfconnector.osgi,
- org.opendaylight.controller.config.util,</Private-Package>
+ org.opendaylight.controller.config.util,
+ org.opendaylight.controller.netconf.confignetconfconnector.exception,</Private-Package>
<Import-Package>com.google.common.base,
com.google.common.collect,
javax.annotation,
org.opendaylight.controller.netconf.mapping.api,
org.opendaylight.controller.netconf.util.mapping,
org.opendaylight.controller.netconf.util.xml,
+ org.opendaylight.controller.netconf.util.exception,
org.opendaylight.yangtools.yang.common,
org.opendaylight.yangtools.yang.model.api,
org.osgi.framework,
com.google.common.io,
org.opendaylight.yangtools.yang.model.api.type,
org.opendaylight.yangtools.sal.binding.generator.spi,
- org.opendaylight.yangtools.sal.binding.yang.types</Import-Package>
+ org.opendaylight.yangtools.sal.binding.yang.types,</Import-Package>
<Export-Package></Export-Package>
</instructions>
</configuration>
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.confignetconfconnector.exception;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class NetconfConfigHandlingException extends NetconfDocumentedException {
+
+ public NetconfConfigHandlingException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity) {
+ this(message, errorType, errorTag, errorSeverity, Collections.<String, String>emptyMap());
+ }
+
+ public NetconfConfigHandlingException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
+ super(message,errorType,errorTag,errorSeverity,errorInfo);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.confignetconfconnector.exception;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class NoTransactionFoundException extends NetconfDocumentedException {
+
+ public NoTransactionFoundException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity) {
+ this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
+ }
+
+ public NoTransactionFoundException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
+ super(message,errorType,errorTag,errorSeverity,errorInfo);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.confignetconfconnector.exception;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class OperationNotPermittedException extends NetconfDocumentedException {
+
+ public OperationNotPermittedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity) {
+ this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
+ }
+
+ public OperationNotPermittedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
+ super(message,errorType,errorTag,errorSeverity,errorInfo);
+ }
+}
public abstract class AttributeIfcSwitchStatement<T> {
- protected AttributeIfc lastAttribute;
+ private AttributeIfc lastAttribute;
public T switchAttribute(AttributeIfc attributeIfc) {
return caseJavaUnionAttribute(openType);
} else if(((JavaAttribute)attributeIfc).isIdentityRef()) {
return caseJavaIdentityRefAttribute(openType);
- } else
+ } else {
return caseJavaAttribute(openType);
+ }
} catch (UnknownOpenTypeException e) {
throw getIllegalArgumentException(attributeIfc);
}
throw getIllegalArgumentException(attributeIfc);
}
+ public AttributeIfc getLastAttribute() {
+ return lastAttribute;
+ }
+
protected T caseJavaIdentityRefAttribute(OpenType<?> openType) {
return caseJavaAttribute(openType);
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import java.util.List;
}
@Override
- public AttributeConfigElement readElement(List<XmlElement> configNodes) {
- if (configNodes.size() == 0)
+ public AttributeConfigElement readElement(List<XmlElement> configNodes) throws NetconfDocumentedException {
+ if (configNodes.size() == 0){
return AttributeConfigElement.createNullValue(postprocessNullableDefault(nullableDefault));
-
+ }
return readElementHook(configNodes);
}
- abstract AttributeConfigElement readElementHook(List<XmlElement> configNodes);
+ abstract AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException;
protected Object postprocessNullableDefault(String nullableDefault) {
return nullableDefault;
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
import com.google.common.collect.Lists;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import java.util.List;
}
@Override
- AttributeConfigElement readElementHook(List<XmlElement> configNodes) {
+ AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
List<Object> innerList = Lists.newArrayList();
for (int i = 0; i < configNodes.size(); i++) {
innerList.add(innerStrategy.readElement(Lists.newArrayList(configNodes.get(i))).getValue());
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
import com.google.common.base.Optional;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
import javax.management.openmbean.OpenType;
}
public void resolveValue(AttributeResolvingStrategy<?, ? extends OpenType<?>> attributeResolvingStrategy,
- String attrName) {
+ String attrName) throws NetconfDocumentedException {
resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value);
Optional<?> resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue);
resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null;
import java.util.List;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
public interface AttributeReadingStrategy {
- public abstract AttributeConfigElement readElement(List<XmlElement> element);
+ public abstract AttributeConfigElement readElement(List<XmlElement> element) throws NetconfDocumentedException;
}
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import java.util.List;
}
@Override
- AttributeConfigElement readElementHook(List<XmlElement> configNodes) {
+ AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
Preconditions.checkState(configNodes.size() == 1, "This element should be present only once %s", configNodes);
List<XmlElement> recognisedChildren = Lists.newArrayList();
for (Entry<String, AttributeReadingStrategy> innerAttrEntry : innerStrategies.entrySet()) {
- List<XmlElement> childItem = complexElement.getChildElementsWithSameNamespace(innerAttrEntry.getKey());
+ List<XmlElement> childItem = null;
+ childItem = complexElement.getChildElementsWithSameNamespace(innerAttrEntry.getKey());
recognisedChildren.addAll(childItem);
AttributeConfigElement resolvedInner = innerAttrEntry.getValue().readElement(childItem);
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
import com.google.common.base.Preconditions;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
private static final Object PREFIX_SEPARATOR = ":";
+ private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeReadingStrategy.class);
public ObjectNameAttributeReadingStrategy(String nullableDefault) {
super(nullableDefault);
}
@Override
- AttributeConfigElement readElementHook(List<XmlElement> configNodes) {
+ AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
XmlElement firstChild = configNodes.get(0);
Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + firstChild
return AttributeConfigElement.create(getNullableDefault(), resolve(firstChild));
}
- private ObjectNameAttributeMappingStrategy.MappedDependency resolve(XmlElement firstChild) {
- XmlElement typeElement = firstChild.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
+ private ObjectNameAttributeMappingStrategy.MappedDependency resolve(XmlElement firstChild) throws NetconfDocumentedException{
+ XmlElement typeElement = null;
+ typeElement = firstChild.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
Map.Entry<String, String> prefixNamespace = typeElement.findNamespaceOfTextContent();
String serviceName = checkPrefixAndExtractServiceName(typeElement, prefixNamespace);
dependencyName);
}
- public static String checkPrefixAndExtractServiceName(XmlElement typeElement, Map.Entry<String, String> prefixNamespace) {
+ public static String checkPrefixAndExtractServiceName(XmlElement typeElement, Map.Entry<String, String> prefixNamespace) throws NetconfDocumentedException {
String serviceName = typeElement.getTextContent();
- Preconditions.checkState(prefixNamespace.equals("") == false, "Service %s value not prefixed with namespace",
+ Preconditions.checkState(!prefixNamespace.equals(""), "Service %s value not prefixed with namespace",
XmlNetconfConstants.TYPE_KEY);
String prefix = prefixNamespace.getKey() + PREFIX_SEPARATOR;
Preconditions.checkState(serviceName.startsWith(prefix),
@Override
protected AttributeReadingStrategy caseJavaBinaryAttribute(OpenType<?> openType) {
- return new SimpleBinaryAttributeReadingStrategy(lastAttribute.getNullableDefault());
+ return new SimpleBinaryAttributeReadingStrategy(getLastAttribute().getNullableDefault());
}
@Override
protected AttributeReadingStrategy caseJavaUnionAttribute(OpenType<?> openType) {
String mappingKey = JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION;
- return new SimpleUnionAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey);
+ return new SimpleUnionAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey);
}
@Override
public AttributeReadingStrategy caseJavaSimpleAttribute(SimpleType<?> openType) {
- return new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault());
+ return new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault());
}
@Override
public AttributeReadingStrategy caseJavaArrayAttribute(ArrayType<?> openType) {
- SimpleAttributeReadingStrategy innerStrategy = new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault());
- return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
+ SimpleAttributeReadingStrategy innerStrategy = new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault());
+ return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy);
}
@Override
public AttributeReadingStrategy caseJavaCompositeAttribute(CompositeType openType) {
Preconditions.checkState(openType.keySet().size() == 1, "Unexpected number of elements for open type %s, should be 1", openType);
String mappingKey = openType.keySet().iterator().next();
- return new SimpleCompositeAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey);
+ return new SimpleCompositeAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey);
}
@Override
Set<String> keys = ((CompositeType) openType).keySet();
Preconditions.checkState(keys.size() == 1, "Unexpected number of elements for open type %s, should be 1", openType);
String mappingKey = keys.iterator().next();
- return new SimpleIdentityRefAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey, identityMap);
+ return new SimpleIdentityRefAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey, identityMap);
}
@Override
protected AttributeReadingStrategy caseDependencyAttribute(SimpleType<?> openType) {
- return new ObjectNameAttributeReadingStrategy(lastAttribute.getNullableDefault());
+ return new ObjectNameAttributeReadingStrategy(getLastAttribute().getNullableDefault());
}
@Override
protected AttributeReadingStrategy caseTOAttribute(CompositeType openType) {
- Preconditions.checkState(lastAttribute instanceof TOAttribute);
- Map<String, AttributeIfc> inner = ((TOAttribute)lastAttribute).getYangPropertiesToTypesMap();
+ Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
+ Map<String, AttributeIfc> inner = ((TOAttribute)getLastAttribute()).getYangPropertiesToTypesMap();
Map<String, AttributeReadingStrategy> innerStrategies = Maps.newHashMap();
innerStrategies.put(innerAttrEntry.getKey(), innerStrat);
}
- return new CompositeAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategies);
+ return new CompositeAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategies);
}
@Override
protected AttributeReadingStrategy caseListAttribute(ArrayType<?> openType) {
- Preconditions.checkState(lastAttribute instanceof ListAttribute);
- AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) lastAttribute).getInnerAttribute());
- return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
+ Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
+ AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) getLastAttribute()).getInnerAttribute());
+ return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy);
}
@Override
protected AttributeReadingStrategy caseListDependeciesAttribute(ArrayType<?> openType) {
- Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+ Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
AttributeReadingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME);
- return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
+ return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy);
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
import com.google.common.base.Preconditions;
+import java.util.List;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
-
public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
private static final Logger logger = LoggerFactory.getLogger(SimpleAttributeReadingStrategy.class);
}
@Override
- AttributeConfigElement readElementHook(List<XmlElement> configNodes) {
+ AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
XmlElement xmlElement = configNodes.get(0);
Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + xmlElement
+ " but was " + configNodes.size());
logger.warn("Ignoring exception caused by failure to read text element", e);
}
- Preconditions.checkNotNull(textContent, "This element should contain text %s", xmlElement);
+ if (null == textContent){
+ throw new NetconfDocumentedException(String.format("This element should contain text %s", xmlElement),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
return AttributeConfigElement.create(postprocessNullableDefault(getNullableDefault()),
postprocessParsedValue(textContent));
}
- protected String readElementContent(XmlElement xmlElement) {
+ protected String readElementContent(XmlElement xmlElement) throws NetconfDocumentedException {
return xmlElement.getTextContent();
}
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.yangtools.yang.common.QName;
}
@Override
- protected String readElementContent(XmlElement xmlElement) {
+ protected String readElementContent(XmlElement xmlElement) throws NetconfDocumentedException {
// TODO test
Map.Entry<String, String> namespaceOfTextContent = xmlElement.findNamespaceOfTextContent();
String content = xmlElement.getTextContent();
revision = date;
}
}
- } else
+ } else {
revision = revisions.keySet().iterator().next();
-
+ }
return QName.create(URI.create(namespace), revision, localName).toString();
}
@Override
public Optional<List<Object>> mapAttribute(Object value) {
- if (value == null)
+ if (value == null){
return Optional.absent();
+ }
Preconditions.checkArgument(value.getClass().isArray(), "Value has to be instanceof Array ");
for (int i = 0; i < Array.getLength(value); i++) {
Object innerValue = Array.get(value, i);
- // String expectedClassName =
- // getOpenType().getElementOpenType().getClassName();
- // String realClassName = value.getClass().getName();
-
- // Preconditions.checkState(realClassName.contains(expectedClassName),
- // "Element in collection/array should be of type " +
- // expectedClassName + " but was "
- // + realClassName + " for attribute: " + getOpenType());
-
Optional<?> mapAttribute = innerElementStrategy.mapAttribute(innerValue);
- if (mapAttribute.isPresent())
+ if (mapAttribute.isPresent()){
retVal.add(mapAttribute.get());
+ }
}
return Optional.of(retVal);
@Override
public Optional<Map<String, Object>> mapAttribute(Object value) {
- if (value == null)
+ if (value == null){
return Optional.absent();
+ }
Util.checkType(value, CompositeDataSupport.class);
for (String jmxName : jmxToJavaNameMapping.keySet()) {
Optional<?> mapped = mapInnerAttribute(compositeData, jmxName, expectedType.getDescription(jmxName));
- if(mapped.isPresent())
+ if(mapped.isPresent()){
retVal.put(jmxToJavaNameMapping.get(jmxName), mapped.get());
+ }
}
return Optional.of(retVal);
AttributeMappingStrategy<?, ? extends OpenType<?>> attributeMappingStrategy = innerStrategies
.get(jmxName);
- Optional<?> mapAttribute = attributeMappingStrategy.mapAttribute(innerValue);
- return mapAttribute;
+ return attributeMappingStrategy.mapAttribute(innerValue);
}
}
@Override
protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseDependencyAttribute(
SimpleType<?> openType) {
- return new ObjectNameAttributeMappingStrategy(openType, dependencyTracker,
+ return new ObjectNameAttributeMappingStrategy(openType,
serviceNameOfDepAttr, namespaceOfDepAttr);
}
protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseTOAttribute(CompositeType openType) {
Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies = Maps.newHashMap();
- Preconditions.checkState(lastAttribute instanceof TOAttribute);
- TOAttribute lastTO = (TOAttribute) lastAttribute;
+ Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
+ TOAttribute lastTO = (TOAttribute) getLastAttribute();
- for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute)lastAttribute).getJmxPropertiesToTypesMap().entrySet()) {
+ for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute)getLastAttribute()).getJmxPropertiesToTypesMap().entrySet()) {
innerStrategies.put(innerAttrEntry.getKey(), prepareStrategy(innerAttrEntry.getValue()));
}
@Override
protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseListAttribute(ArrayType<?> openType) {
- Preconditions.checkState(lastAttribute instanceof ListAttribute);
+ Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
return new ArrayAttributeMappingStrategy(openType,
- prepareStrategy(((ListAttribute) lastAttribute).getInnerAttribute()));
+ prepareStrategy(((ListAttribute) getLastAttribute()).getInnerAttribute()));
}
@Override
protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseListDependeciesAttribute(ArrayType<?> openType) {
- Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+ Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
return new ArrayAttributeMappingStrategy(openType, caseDependencyAttribute(SimpleType.OBJECTNAME));
}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-
import javax.management.ObjectName;
import javax.management.openmbean.SimpleType;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
public class ObjectNameAttributeMappingStrategy extends
AbstractAttributeMappingStrategy<ObjectNameAttributeMappingStrategy.MappedDependency, SimpleType<?>> {
- private final ServiceRegistryWrapper tracker;
private final String serviceName;
private final String namespace;
- public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) {
+ public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, String serviceName, String namespace) {
super(openType);
- this.tracker = dependencyTracker;
this.serviceName = serviceName;
this.namespace = namespace;
}
@Override
public Optional<MappedDependency> mapAttribute(Object value) {
- if (value == null)
+ if (value == null){
return Optional.absent();
+ }
String expectedClass = getOpenType().getClassName();
String realClass = value.getClass().getName();
@Override
public Optional<String> mapAttribute(Object value) {
- if (value == null)
+ if (value == null){
return Optional.absent();
+ }
String expectedClass = getOpenType().getClassName();
String realClass = value.getClass().getName();
@Override
protected Optional<?> mapInnerAttribute(CompositeDataSupport compositeData, String jmxName, String description) {
- if(description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION) == false)
+ if(!description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){
return Optional.absent();
-
+ }
return super.mapInnerAttribute(compositeData, jmxName, description);
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
import com.google.common.base.Optional;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
@Override
- public Optional<Object> parseAttribute(String attrName, Object value) {
+ public Optional<Object> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
if (value == null) {
return Optional.absent();
}
if (innerTypeResolvingStrategy.getOpenType() instanceof CompositeType) {
innerTypeClass = CompositeDataSupport.class;
- } else
+ } else {
try {
innerTypeClass = Class.forName(getOpenType().getElementOpenType().getClassName());
} catch (ClassNotFoundException e) {
- throw new RuntimeException("Unable to locate class for "
+ throw new IllegalStateException("Unable to locate class for "
+ getOpenType().getElementOpenType().getClassName(), e);
}
+ }
Object parsedArray = null;
if (getOpenType().isPrimitiveArray()) {
Class<?> primitiveType = getPrimitiveType(innerTypeClass);
parsedArray = Array.newInstance(primitiveType, valueList.size());
- } else
+ } else {
parsedArray = Array.newInstance(innerTypeClass, valueList.size());
+ }
int i = 0;
for (Object innerValue : valueList) {
Optional<?> parsedElement = innerTypeResolvingStrategy.parseAttribute(attrName + "_" + i, innerValue);
-
- if (!parsedElement.isPresent())
+ if (!parsedElement.isPresent()){
continue;
-
+ }
Array.set(parsedArray, i, parsedElement.get());
- // parsedArray[i] = parsedElement.get();
i++;
}
try {
return (Class<?>) innerTypeClass.getField("TYPE").get(null);
} catch (Exception e) {
- throw new RuntimeException("Unable to determine primitive type to " + innerTypeClass);
+ throw new IllegalStateException("Unable to determine primitive type to " + innerTypeClass);
}
}
import com.google.common.base.Optional;
import javax.management.openmbean.OpenType;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
/**
* Create real object from String or Map that corresponds to given opentype.
public interface AttributeResolvingStrategy<T, O extends OpenType<?>> {
O getOpenType();
- Optional<T> parseAttribute(String attrName, Object value);
+ Optional<T> parseAttribute(String attrName, Object value) throws NetconfDocumentedException;
}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
@Override
- public Optional<CompositeDataSupport> parseAttribute(String attrName, Object value) {
+ public Optional<CompositeDataSupport> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
if (value == null) {
return Optional.absent();
try {
parsedValue = new CompositeDataSupport(getOpenType(), items);
} catch (OpenDataException e) {
- throw new RuntimeException("An error occured during restoration of composite type " + this
+ throw new IllegalStateException("An error occured during restoration of composite type " + this
+ " for attribute " + attrName + " from value " + value, e);
}
@Override
protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseTOAttribute(CompositeType openType) {
- Preconditions.checkState(lastAttribute instanceof TOAttribute);
- TOAttribute toAttribute = (TOAttribute) lastAttribute;
+ Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
+ TOAttribute toAttribute = (TOAttribute) getLastAttribute();
Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap = Maps.newHashMap();
@Override
protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseListAttribute(ArrayType<?> openType) {
- Preconditions.checkState(lastAttribute instanceof ListAttribute);
- AttributeIfc innerAttribute = ((ListAttribute) lastAttribute).getInnerAttribute();
+ Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
+ AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute();
return new ArrayAttributeResolvingStrategy(prepareStrategy(innerAttribute), openType);
}
@Override
protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseListDependeciesAttribute(ArrayType<?> openType) {
- Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+ Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
return new ArrayAttributeResolvingStrategy(caseDependencyAttribute(SimpleType.OBJECTNAME), openType);
}
import com.google.common.base.Optional;
import com.google.common.collect.Maps;
+import java.lang.reflect.InvocationTargetException;
+import java.text.ParseException;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
@Override
- public Optional<Object> parseAttribute(String attrName, Object value) {
+ public Optional<Object> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
if (value == null) {
return Optional.absent();
}
}
static interface Resolver {
- Object resolveObject(Class<?> type, String attrName, String value);
+ Object resolveObject(Class<?> type, String attrName, String value) throws NetconfDocumentedException;
}
static class DefaultResolver implements Resolver {
@Override
- public Object resolveObject(Class<?> type, String attrName, String value) {
+ public Object resolveObject(Class<?> type, String attrName, String value) throws NetconfDocumentedException {
try {
- Object parsedValue = parseObject(type, value);
- return parsedValue;
+ return parseObject(type, value);
} catch (Exception e) {
- throw new RuntimeException("Unable to resolve attribute " + attrName + " from " + value, e);
+ throw new NetconfDocumentedException("Unable to resolve attribute " + attrName + " from " + value,
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
}
- protected Object parseObject(Class<?> type, String value) throws Exception {
- Method method = type.getMethod("valueOf", String.class);
- Object parsedValue = method.invoke(null, value);
- return parsedValue;
+ protected Object parseObject(Class<?> type, String value) throws NetconfDocumentedException {
+ Method method = null;
+ try {
+ method = type.getMethod("valueOf", String.class);
+ return method.invoke(null, value);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ logger.trace("Error parsing object {}",e);
+ throw new NetconfDocumentedException("Error parsing object.",
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
}
}
static class StringResolver extends DefaultResolver {
@Override
- protected Object parseObject(Class<?> type, String value) throws Exception {
+ protected Object parseObject(Class<?> type, String value) {
return value;
}
}
static class BigIntegerResolver extends DefaultResolver {
@Override
- protected Object parseObject(Class<?> type, String value) throws Exception {
+ protected Object parseObject(Class<?> type, String value) {
return new BigInteger(value);
}
}
static class BigDecimalResolver extends DefaultResolver {
@Override
- protected Object parseObject(Class<?> type, String value) throws Exception {
+ protected Object parseObject(Class<?> type, String value) {
return new BigDecimal(value);
}
}
static class CharResolver extends DefaultResolver {
@Override
- protected Object parseObject(Class<?> type, String value) throws Exception {
+ protected Object parseObject(Class<?> type, String value) {
return new Character(value.charAt(0));
}
}
static class DateResolver extends DefaultResolver {
-
@Override
- protected Object parseObject(Class<?> type, String value) throws Exception {
- return Util.readDate(value);
+ protected Object parseObject(Class<?> type, String value) throws NetconfDocumentedException {
+ try {
+ return Util.readDate(value);
+ } catch (ParseException e) {
+ logger.trace("Unable parse value {} due to {}",value, e);
+ throw new NetconfDocumentedException("Unable to parse value "+value+" as date.",
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
}
}
Map<String, Object> newMap = Maps.newHashMap();
for (String key : openType.keySet()) {
- if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION))
+ if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){
newMap.put(key, valueMap.get(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION));
- else
+ } else {
newMap.put(key, null);
+ }
}
return newMap;
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
+
+public abstract class AbstractAttributeWritingStrategy {
+ protected Object preprocess(Object value) {
+ return value;
+ }
+}
public class CompositeAttributeWritingStrategy implements AttributeWritingStrategy {
- protected final String key;
- protected final Document document;
- protected final Map<String, AttributeWritingStrategy> innerStrats;
+ private final String key;
+ private final Document document;
+ private final Map<String, AttributeWritingStrategy> innerStrats;
public CompositeAttributeWritingStrategy(Document document, String key,
Map<String, AttributeWritingStrategy> innerStrats) {
}
parentElement.appendChild(innerNode);
}
+
+ public String getKey() {
+ return key;
+ }
+
+ public Document getDocument() {
+ return document;
+ }
+
+ public Map<String, AttributeWritingStrategy> getInnerStrats() {
+ return innerStrats;
+ }
}
@Override
protected AttributeWritingStrategy caseTOAttribute(CompositeType openType) {
- Preconditions.checkState(lastAttribute instanceof TOAttribute);
+ Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
Map<String, AttributeWritingStrategy> innerStrats = Maps.newHashMap();
String currentKey = key;
- for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute) lastAttribute).getYangPropertiesToTypesMap().entrySet()) {
+ for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute) getLastAttribute()).getYangPropertiesToTypesMap().entrySet()) {
AttributeWritingStrategy innerStrategy = prepareWritingStrategy(innerAttrEntry.getKey(),
innerAttrEntry.getValue(), document);
@Override
protected AttributeWritingStrategy caseListAttribute(ArrayType<?> openType) {
- Preconditions.checkState(lastAttribute instanceof ListAttribute);
- AttributeIfc innerAttribute = ((ListAttribute) lastAttribute).getInnerAttribute();
+ Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
+ AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute();
AttributeWritingStrategy innerStrategy = prepareWritingStrategy(key, innerAttribute, document);
return new ArrayAttributeWritingStrategy(innerStrategy);
@Override
protected AttributeWritingStrategy caseListDependeciesAttribute(ArrayType<?> openType) {
- Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+ Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
AttributeWritingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME);
return new ArrayAttributeWritingStrategy(innerStrategy);
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-import java.util.Map;
-import java.util.Map.Entry;
-
+import com.google.common.base.Optional;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
+import java.util.Map;
+import java.util.Map.Entry;
public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingStrategy {
public void writeElement(Element parentElement, String namespace, Object value) {
Util.checkType(value, Map.class);
- Element innerNode = XmlUtil.createElement(document, key, Optional.<String>absent());
+ Element innerNode = XmlUtil.createElement(getDocument(), getKey(), Optional.<String>absent());
Map<?, ?> map = (Map<?, ?>) value;
// bean
Util.checkType(runtimeBeanInstanceMappingEntry.getValue(), Map.class);
Map<?, ?> innerMap = (Map<?, ?>) runtimeBeanInstanceMappingEntry.getValue();
- Element runtimeInstanceNode = XmlUtil.createElement(document, "_"
+ Element runtimeInstanceNode = XmlUtil.createElement(getDocument(), "_"
+ (String) runtimeBeanInstanceMappingEntry.getKey(), Optional.<String>absent());
innerNode.appendChild(runtimeInstanceNode);
String innerKey = (String) innerObjectEntry.getKey();
Object innerValue = innerObjectEntry.getValue();
- innerStrats.get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue);
+ getInnerStrats().get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue);
}
}
parentElement.appendChild(innerNode);
typeElement.appendChild(document.createTextNode(value));
return typeElement;
}
-
protected Object preprocess(Object value) {
return value;
}
super(document, key);
}
+ @Override
protected Object preprocess(Object value) {
Util.checkType(value, List.class);
BaseEncoding en = BaseEncoding.base64();
public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWritingStrategy {
- private static final char QNAME_SEPARATOR = ':';
private static final String PREFIX = "prefix";
/**
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-
import javax.management.ObjectName;
-
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import static com.google.common.base.Preconditions.checkState;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
public class Config {
- private final Logger logger = LoggerFactory.getLogger(Config.class);
private final Map<String/* Namespace from yang file */,
Map<String /* Name of module entry from yang file */, ModuleConfig>> moduleConfigs;
- private final Map<String, ModuleConfig> moduleNamesToConfigs;
private final Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
this.moduleConfigs = moduleConfigs;
- Map<String, ModuleConfig> moduleNamesToConfigs = new HashMap<>();
- for (Entry<String, Map<String, ModuleConfig>> entry : moduleConfigs.entrySet()) {
- moduleNamesToConfigs.putAll(entry.getValue());
- }
- this.moduleNamesToConfigs = Collections.unmodifiableMap(moduleNamesToConfigs);
this.identityMap = identityMap;
}
// TODO, this code does not support same module names from different namespaces
// Namespace should be present in ObjectName
- if (instances == null)
+ if (instances == null){
continue;
+ }
innerRetVal.put(moduleName, instances);
return retVal;
}
- // public Element toXml(Set<ObjectName> instancesToMap, String namespace,
- // Document document) {
- // return toXml(instancesToMap, Optional.of(namespace), document);
- // }
-
public Element toXml(Set<ObjectName> instancesToMap, Optional<String> maybeNamespace, Document document,
Element dataElement, ServiceRegistryWrapper serviceTracker) {
// TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
// class
- public Map<String, Multimap<String, ModuleElementResolved>> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+ public Map<String, Multimap<String, ModuleElementResolved>> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) throws NetconfDocumentedException {
Optional<XmlElement> modulesElement = getModulesElement(xml);
List<XmlElement> moduleElements = getModulesElementList(modulesElement);
for (XmlElement moduleElement : moduleElements) {
ResolvingStrategy<ModuleElementResolved> resolvingStrategy = new ResolvingStrategy<ModuleElementResolved>() {
@Override
- public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) {
+ public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) throws NetconfDocumentedException {
return moduleMapping.fromXml(moduleElement, serviceTracker,
instanceName, moduleNamespace, defaultStrategy, identityMap);
}
* return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted.
*/
public Map<String, Multimap<String, ModuleElementDefinition>> fromXmlModulesMap(XmlElement xml,
- EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+ EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) throws NetconfDocumentedException {
Optional<XmlElement> modulesElement = getModulesElement(xml);
List<XmlElement> moduleElements = getModulesElementList(modulesElement);
XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
}
- private List<XmlElement> getModulesElementList(Optional<XmlElement> modulesElement) {
+ private List<XmlElement> getModulesElementList(Optional<XmlElement> modulesElement) throws NetconfDocumentedException {
List<XmlElement> moduleElements;
if (modulesElement.isPresent()) {
}
private <T> void resolveModule(Map<String, Multimap<String, T>> retVal, ServiceRegistryWrapper serviceTracker,
- XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy<T> resolvingStrategy) {
- XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
+ XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy<T> resolvingStrategy) throws NetconfDocumentedException {
+ XmlElement typeElement = null;
+ typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
String moduleNamespace = prefixToNamespace.getValue();
- XmlElement nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY);
+ XmlElement nameElement = null;
+ nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY);
String instanceName = nameElement.getTextContent();
String factoryNameWithPrefix = typeElement.getTextContent();
String prefixOrEmptyString = prefixToNamespace.getKey();
innerMap.put(factoryName, resolvedElement);
}
- public Services fromXmlServices(XmlElement xml) {
+ public Services fromXmlServices(XmlElement xml) throws NetconfDocumentedException {
Optional<XmlElement> servicesElement = getServicesElement(xml);
Services services;
XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
}
- public static void checkUnrecognisedChildren(XmlElement parent) {
+ public static void checkUnrecognisedChildren(XmlElement parent) throws NetconfDocumentedException {
Optional<XmlElement> servicesOpt = getServicesElement(parent);
Optional<XmlElement> modulesOpt = getModulesElement(parent);
List<XmlElement> recognised = Lists.newArrayList();
- if(servicesOpt.isPresent())
+ if(servicesOpt.isPresent()){
recognised.add(servicesOpt.get());
- if(modulesOpt.isPresent())
+ }
+ if(modulesOpt.isPresent()){
recognised.add(modulesOpt.get());
+ }
parent.checkUnrecognisedElements(recognised);
}
private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) {
checkState(
factoryNameWithPrefix.startsWith(prefixOrEmptyString),
- format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'",
+ String.format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'",
factoryNameWithPrefix, prefixOrEmptyString));
int factoryNameAfterPrefixIndex;
private interface ResolvingStrategy<T> {
public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker,
- String instanceName, String moduleNamespace, EditStrategyType defaultStrategy);
+ String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) throws NetconfDocumentedException;
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeReadingStrategy;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectXmlReader;
Map<String, Object> toXml = Maps.newHashMap();
for (Entry<String, AttributeIfc> configDefEntry : jmxToAttrConfig.entrySet()) {
-
// Skip children runtime beans as they are mapped by InstanceRuntime
- if (configDefEntry.getValue() instanceof RuntimeBeanEntry)
+ if (configDefEntry.getValue() instanceof RuntimeBeanEntry){
continue;
-
+ }
Object value = configRegistryClient.getAttributeCurrentValue(on, configDefEntry.getKey());
try {
AttributeMappingStrategy<?, ? extends OpenType<?>> attributeMappingStrategy = mappingStrategies
.get(configDefEntry.getKey());
Optional<?> a = attributeMappingStrategy.mapAttribute(value);
- if (a.isPresent() == false)
+ if (!a.isPresent()){
continue;
-
+ }
toXml.put(configDefEntry.getValue().getAttributeYangName(), a.get());
} catch (Exception e) {
throw new IllegalStateException("Unable to map value " + value + " to attribute "
+ configDefEntry.getKey(), e);
}
}
-
return toXml;
}
}
public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace,
- EditStrategyType defaultStrategy, Multimap<String, String> providedServices, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
+ EditStrategyType defaultStrategy, Multimap<String, String> providedServices, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) throws NetconfDocumentedException {
Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap);
List<XmlElement> recognisedChildren = Lists.newArrayList();
- XmlElement type = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
- XmlElement name = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY);
+ XmlElement type = null;
+ XmlElement name = null;
+ type = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
+ name = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY);
List<XmlElement> typeAndName = Lists.newArrayList(type, name);
for (Entry<String, AttributeReadingStrategy> readStratEntry : strats.entrySet()) {
}
private List<XmlElement> getConfigNodes(XmlElement moduleElement, String moduleNamespace, String name,
- List<XmlElement> recognisedChildren, List<XmlElement> typeAndName) {
+ List<XmlElement> recognisedChildren, List<XmlElement> typeAndName) throws NetconfDocumentedException {
List<XmlElement> foundConfigNodes = moduleElement.getChildElementsWithinNamespace(name, moduleNamespace);
if (foundConfigNodes.isEmpty()) {
logger.debug("No config nodes {}:{} found in {}", moduleNamespace, name, moduleElement);
List<XmlElement> foundWithoutNamespaceNodes = moduleElement.getChildElementsWithinNamespace(name,
XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
foundWithoutNamespaceNodes.removeAll(typeAndName);
- Preconditions.checkState(foundWithoutNamespaceNodes.isEmpty(),
- "Element %s present multiple times with different namespaces: %s, %s", name, foundConfigNodes,
- foundWithoutNamespaceNodes);
+ if (!foundWithoutNamespaceNodes.isEmpty()){
+ throw new NetconfDocumentedException(String.format("Element %s present multiple times with different namespaces: %s, %s", name, foundConfigNodes,
+ foundWithoutNamespaceNodes),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
}
recognisedChildren.addAll(foundConfigNodes);
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-import com.google.common.base.Preconditions;
import com.google.common.collect.Multimap;
+import java.util.Map;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-import java.util.Map;
-
/**
* Parsed xml element containing whole configuration for an instance of some
* module. Contains preferred edit strategy type.
private final Map<String, AttributeConfigElement> configuration;
private final Multimap<String, String> providedServices;
- public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
- EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy);
+ public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy, Multimap<String, String> providedServices) throws NetconfDocumentedException {
+ EditStrategyType valueOf = null;
+ valueOf = parseStrategy(currentStrategy, defaultStrategy);
this.editStrategy = valueOf;
this.configuration = configuration;
this.providedServices = providedServices;
}
- static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
+ static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) throws OperationNotPermittedException {
EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy);
- if (defaultStrategy.isEnforcing()) {
- Preconditions
- .checkArgument(
- parsedStrategy == defaultStrategy,
- "With "
- + defaultStrategy
- + " as "
- + EditConfigXmlParser.DEFAULT_OPERATION_KEY
- + " operations on module elements are not permitted since the default option is restrictive");
- }
+ EditStrategyType.compareParsedStrategyToDefaultEnforcing(parsedStrategy,defaultStrategy);
return parsedStrategy;
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Map;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
public class ModuleConfig {
Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.<String>absent());
// Xml.addNamespaceAttr(document, root, namespace);
- final String prefix = getPrefix(namespace);
+ final String prefix = getPrefix();
Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(prefix, XmlNetconfConstants.TYPE_KEY), prefix,
moduleName, Optional.<String>of(namespace));
// Xml.addNamespaceAttr(document, typeElement,
return root;
}
- private String getPrefix(String namespace) {
- // if(namespace.contains(":")==false)
+ private String getPrefix() {
return XmlNetconfConstants.PREFIX;
- // return namespace.substring(namespace.lastIndexOf(':') + 1,
- // namespace.length());
-
}
public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
- String moduleNamespace, EditStrategyType defaultStrategy, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
+ String moduleNamespace, EditStrategyType defaultStrategy, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) throws NetconfDocumentedException {
InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices, identityMap);
return new ModuleElementResolved(instanceName, ice);
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ModuleElementDefinition {
private final String instanceName;
private final EditStrategyType editStrategy;
+ private static final Logger logger = LoggerFactory.getLogger(ModuleElementDefinition.class);
public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) {
this.instanceName = instanceName;
- if (currentStrategy == null || currentStrategy.isEmpty())
+ if (currentStrategy == null || currentStrategy.isEmpty()) {
this.editStrategy = defaultStrategy;
- else
- this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy);
+ } else {
+ EditStrategyType _edStrategy = null;
+ try {
+ _edStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy);
+ } catch (OperationNotPermittedException e) {
+ _edStrategy = defaultStrategy;
+ logger.warn("Operation not permitted on current strategy {} while default strategy is {}. Element definition strategy set to default.",
+ currentStrategy,
+ defaultStrategy,
+ e);
+ }
+ this.editStrategy = _edStrategy;
+ }
+
}
public String getInstanceName() {
public boolean hasRefName(String namespace, String serviceName, ObjectName on) {
String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
Map<String, ObjectName> forQName = configServiceRefRegistry.getServiceMapping().get(qname);
- if(forQName==null) return false;
+ if(forQName==null){
+ return false;
+ }
return forQName.values().contains(on);
}
Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
- for (String serviceQName : serviceMapping.keySet())
+ for (String serviceQName : serviceMapping.keySet()){
for (String refName : serviceMapping.get(serviceQName).keySet()) {
ObjectName on = serviceMapping.get(serviceQName).get(refName);
serviceToRefs.put(localName, refsToSis);
}
- Preconditions.checkState(refsToSis.containsKey(refName) == false,
+ Preconditions.checkState(!refsToSis.containsKey(refName),
"Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
localName, on);
refsToSis.put(refName, si.toString());
}
+ }
return retVal;
}
Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
Map<String, String> refNameToInstance;
- if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
+ if(serviceNameToRefNameToInstance == null || !serviceNameToRefNameToInstance.containsKey(serviceName)) {
refNameToInstance = Collections.emptyMap();
- } else
+ } else {
refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+ }
final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
if (refNamesAsSet.contains(refName)) {
}
private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
- String intitialRefName = refName;
+ String availableRefName = "";
while (true) {
- refName = intitialRefName + "_" + suffix++;
- if (refNamesAsSet.contains(refName) == false)
- return refName;
+ availableRefName = refName + "_" + suffix++;
+ if (!refNamesAsSet.contains(availableRefName)){
+ return availableRefName;
+ }
}
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
+import javax.management.ObjectName;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public final class Services {
- private static final Logger logger = LoggerFactory.getLogger(Services.class);
-
private static final String PROVIDER_KEY = "provider";
private static final String NAME_KEY = "name";
public static final String TYPE_KEY = "type";
// TODO support edit strategies on services
- public static Services fromXml(XmlElement xml) {
+ public static Services fromXml(XmlElement xml) throws NetconfDocumentedException {
Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
List<XmlElement> services = xml.getChildElements(SERVICE_KEY);
XmlElement typeElement = service.getOnlyChildElement(TYPE_KEY);
Entry<String, String> prefixNamespace = typeElement.findNamespaceOfTextContent();
- Preconditions.checkState(prefixNamespace.getKey()!=null && prefixNamespace.getKey().equals("") == false, "Type attribute was not prefixed");
+ Preconditions.checkState(prefixNamespace.getKey()!=null && !prefixNamespace.getKey().equals(""), "Type attribute was not prefixed");
Map<String, Map<String, String>> namespaceToServices = retVal.get(prefixNamespace.getValue());
if(namespaceToServices == null) {
public static ServiceInstance fromString(String instanceId) {
instanceId = instanceId.trim();
Matcher matcher = p.matcher(instanceId);
- if(matcher.matches() == false) {
+ if(!matcher.matches()) {
matcher = pDeprecated.matcher(instanceId);
}
@Override
public boolean equals(Object obj) {
- if (this == obj)
+ if (this == obj){
return true;
- if (obj == null)
+ }
+ if (obj == null){
return false;
- if (getClass() != obj.getClass())
+ }
+ if (getClass() != obj.getClass()){
return false;
+ }
ServiceInstance other = (ServiceInstance) obj;
if (instanceName == null) {
- if (other.instanceName != null)
+ if (other.instanceName != null){
return false;
- } else if (!instanceName.equals(other.instanceName))
+ }
+ } else if (!instanceName.equals(other.instanceName)){
return false;
+ }
if (moduleName == null) {
- if (other.moduleName != null)
+ if (other.moduleName != null){
return false;
- } else if (!moduleName.equals(other.moduleName))
+ }
+ } else if (!moduleName.equals(other.moduleName)){
return false;
+ }
return true;
}
import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeReadingStrategy;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectXmlReader;
}
}
- public Map<String, AttributeConfigElement> fromXml(XmlElement configRootNode) {
+ public Map<String, AttributeConfigElement> fromXml(XmlElement configRootNode) throws NetconfDocumentedException {
Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
// FIXME add identity map to runtime data
public final class ModuleRpcs {
- Map<String, String> yangToJavaNames = Maps.newHashMap();
- Map<String, Map<String, InstanceRuntimeRpc>> rpcMapping = Maps.newHashMap();
+ private final Map<String, String> yangToJavaNames = Maps.newHashMap();
+ private final Map<String, Map<String, InstanceRuntimeRpc>> rpcMapping = Maps.newHashMap();
public void addNameMapping(RuntimeBeanEntry runtimeEntry) {
String yangName = runtimeEntry.getYangName();
- Preconditions.checkState(yangToJavaNames.containsKey(yangName) == false,
+ Preconditions.checkState(!yangToJavaNames.containsKey(yangName),
"RuntimeBean %s found twice in same namespace", yangName);
yangToJavaNames.put(yangName, runtimeEntry.getJavaNamePrefix());
}
rpcMapping.put(yangName, map);
}
- Preconditions.checkState(map.containsKey(rpc.getYangName()) == false, "Rpc %s for runtime bean %s added twice",
+ Preconditions.checkState(!map.containsKey(rpc.getYangName()), "Rpc %s for runtime bean %s added twice",
rpc.getYangName(), yangName);
map.put(rpc.getYangName(), new InstanceRuntimeRpc(rpc));
}
Preconditions.checkState(rpc != null, "No rpc found for runtime bean %s with name %s", rbeName, rpcName);
return rpc;
}
+
+ public Map<String, String> getYangToJavaNames() {
+ return yangToJavaNames;
+ }
+
+ public Map<String, Map<String, InstanceRuntimeRpc>> getRpcMapping() {
+ return rpcMapping;
+ }
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Sets;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Sets;
+import javax.management.ObjectName;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
public class InstanceRuntime {
* root + any number of additional properties
*/
private Set<ObjectName> findChildren(ObjectName innerRootBean, Set<ObjectName> childRbeOns) {
- final Hashtable<String, String> wantedProperties = innerRootBean.getKeyPropertyList();
+ final Map<String, String> wantedProperties = innerRootBean.getKeyPropertyList();
return Sets.newHashSet(Collections2.filter(childRbeOns, new Predicate<ObjectName>() {
@Override
public boolean apply(ObjectName on) {
- Hashtable<String, String> localProperties = on.getKeyPropertyList();
+ Map<String, String> localProperties = on.getKeyPropertyList();
for (Entry<String, String> propertyEntry : wantedProperties.entrySet()) {
- if (!localProperties.containsKey(propertyEntry.getKey()))
+ if (!localProperties.containsKey(propertyEntry.getKey())){
return false;
- if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue()))
+ }
+ if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue())){
return false;
- if (localProperties.size() <= wantedProperties.size())
+ }
+ if (localProperties.size() <= wantedProperties.size()){
return false;
+ }
}
return true;
}
@Override
public boolean apply(ObjectName on) {
- if (on.getKeyPropertyList().size() != keyListSize + 1)
+ if (on.getKeyPropertyList().size() != keyListSize + 1){
return false;
- if (!on.getKeyPropertyList().containsKey(string))
+ }
+ if (!on.getKeyPropertyList().containsKey(string)){
return false;
+ }
return true;
}
}));
public class ModuleRuntime {
- private final String moduleName;
private final InstanceRuntime instanceRuntime;
public ModuleRuntime(String moduleName, InstanceRuntime instanceRuntime) {
- this.moduleName = moduleName;
this.instanceRuntime = instanceRuntime;
}
private ObjectName findRoot(Collection<ObjectName> runtimeBeanOns) {
for (ObjectName objectName : runtimeBeanOns) {
- if (objectName.getKeyPropertyList().size() == 3)
+ if (objectName.getKeyPropertyList().size() == 3){
return objectName;
+ }
}
throw new IllegalStateException("Root runtime bean not found among " + runtimeBeanOns);
}
Element runtimeXml;
ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName);
- if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) {
+ if(instanceToRbe==null || !instanceToRbe.containsKey(instanceName)) {
runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace);
} else {
ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
return root;
}
- private ObjectName findInstance(Collection<ObjectName> objectNames, String instanceName) {
- for (ObjectName objectName : objectNames) {
- String name = ObjectNameUtil.getInstanceName(objectName);
- if(name.equals(instanceName))
- return objectName;
- }
-
- throw new UnsupportedOperationException("Unable to find config bean instance under name " + instanceName + " among " + objectNames);
- }
-
}
public abstract class AbstractConfigNetconfOperation extends AbstractLastNetconfOperation {
- protected final ConfigRegistryClient configRegistryClient;
+ private final ConfigRegistryClient configRegistryClient;
protected AbstractConfigNetconfOperation(ConfigRegistryClient configRegistryClient,
String netconfSessionIdForReporting) {
super(netconfSessionIdForReporting);
this.configRegistryClient = configRegistryClient;
}
+
+ public ConfigRegistryClient getConfigRegistryClient() {
+ return configRegistryClient;
+ }
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-import java.util.HashMap;
-import java.util.Map;
-
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
this.transactionProvider = transactionProvider;
}
- private static void checkXml(XmlElement xml) {
+ private static void checkXml(XmlElement xml) throws NetconfDocumentedException {
xml.checkName(XmlNetconfConstants.COMMIT);
xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
}
@Override
protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
- checkXml(xml);
+ checkXml(xml);
CommitStatus status;
try {
status = this.transactionProvider.commitTransaction();
- } catch (final IllegalStateException e) {
- // TODO Illegal state thrown when no transaction yet for user
- // Throw other exception type, or create transaction automatically
- logger.warn("Commit failed: ", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.operation_failed.name(),
- "Operation failed. Use 'get-config' or 'edit-config' before triggering 'commit' operation");
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
- ErrorSeverity.error, errorInfo);
- } catch (ValidationException e) {
+ logger.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
+ } catch (ConflictingVersionException | ValidationException e) {
throw NetconfDocumentedException.wrap(e);
- } catch (ConflictingVersionException e) {
- throw NetconfDocumentedException.wrap(e);
-
}
logger.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import java.util.HashMap;
-import java.util.Map;
+ package org.opendaylight.controller.netconf.confignetconfconnector.operations;
+import com.google.common.base.Optional;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
+import java.util.HashMap;
+import java.util.Map;
+
public class DiscardChanges extends AbstractConfigNetconfOperation {
this.transactionProvider = transactionProvider;
}
- private static void fromXml(XmlElement xml) {
+ private static void fromXml(XmlElement xml) throws NetconfDocumentedException {
xml.checkName(DISCARD);
xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
}
@Override
protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
- try {
- fromXml(xml);
- } catch (final IllegalArgumentException e) {
- //FIXME where can IllegalStateException be thrown?
- logger.warn("Rpc error: {}", ErrorTag.bad_attribute, e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage());
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.bad_attribute,
- ErrorSeverity.error, errorInfo);
- }
-
+ fromXml(xml);
try {
this.transactionProvider.abortTransaction();
} catch (final IllegalStateException e) {
- //FIXME where can IllegalStateException be thrown?
logger.warn("Abort failed: ", e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo
}
logger.trace("Changes discarded successfully from datastore {}", Datastore.candidate);
+
return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-import java.util.HashMap;
-import java.util.Map;
-
+import com.google.common.base.Optional;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+import java.util.HashMap;
+import java.util.Map;
public class Validate extends AbstractConfigNetconfOperation {
this.transactionProvider = transactionProvider;
}
- private void checkXml(XmlElement xml) {
+ private void checkXml(XmlElement xml) throws NetconfDocumentedException {
xml.checkName(VALIDATE);
xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
String datastoreValue = sourceChildNode.getName();
Datastore sourceDatastore = Datastore.valueOf(datastoreValue);
- Preconditions.checkState(sourceDatastore == Datastore.candidate, "Only " + Datastore.candidate
- + " is supported as source for " + VALIDATE + " but was " + datastoreValue);
+ if (sourceDatastore != Datastore.candidate){
+ throw new NetconfDocumentedException( "Only " + Datastore.candidate
+ + " is supported as source for " + VALIDATE + " but was " + datastoreValue,ErrorType.application,ErrorTag.data_missing,ErrorSeverity.error);
+ }
}
@Override
@Override
protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
- try {
- checkXml(xml);
- } catch (IllegalStateException e) {
- //FIXME where can IllegalStateException be thrown? I see precondition that guards for programming bugs..
- logger.warn("Rpc error: {}", ErrorTag.missing_attribute, e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.missing_attribute.name(), "Missing value of datastore attribute");
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.missing_attribute,
- ErrorSeverity.error, errorInfo);
- } catch (final IllegalArgumentException e) {
- // FIXME use checked exception if it has domain meaning
- logger.warn("Rpc error: {}", ErrorTag.bad_attribute, e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage());
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.bad_attribute,
- ErrorSeverity.error, errorInfo);
- }
-
+ checkXml(xml);
try {
transactionProvider.validateTransaction();
} catch (ValidationException e) {
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
@Override
public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, ServiceRegistryWrapper services) {
+ ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
try {
ObjectName on = ta.lookupConfigBean(module, instance);
// edit configs should not handle missing
abstract void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, ServiceRegistryWrapper services);
+ String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException;
abstract void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- ObjectName objectName, ServiceRegistryWrapper services);
+ ObjectName objectName, ServiceRegistryWrapper services) throws NetconfConfigHandlingException;
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import java.util.Map;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import java.util.Map;
-
public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy {
private static final Logger logger = LoggerFactory.getLogger(DeleteEditConfigStrategy.class);
- private final Multimap<String, String> providedServices;
-
- public DeleteEditConfigStrategy() {
- this.providedServices = HashMultimap.create();
- }
-
- public DeleteEditConfigStrategy(Multimap<String, String> providedServices) {
- this.providedServices = providedServices;
- }
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, ServiceRegistryWrapper services) {
- throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found");
+ String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
+ throw new NetconfConfigHandlingException(String.format("Unable to delete %s : %s , ServiceInstance not found", module ,instance),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
try {
ta.destroyModule(on);
logger.debug("ServiceInstance {} deleted successfully", on);
} catch (InstanceNotFoundException e) {
- throw new IllegalStateException("Unable to delete " + on, e);
+ throw new NetconfConfigHandlingException(
+ String.format("Unable to delete %s because of exception %s" + on, e.getMessage()),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
public class EditConfig extends AbstractConfigNetconfOperation {
@VisibleForTesting
Element getResponseInternal(final Document document,
- final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
+ final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException, NetconfConfigHandlingException {
if (editConfigExecution.shouldTest()) {
- executeTests(configRegistryClient, editConfigExecution);
+ executeTests(getConfigRegistryClient(), editConfigExecution);
}
if (editConfigExecution.shouldSet()) {
- executeSet(configRegistryClient, editConfigExecution);
+ executeSet(getConfigRegistryClient(), editConfigExecution);
}
logger.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
private void executeSet(ConfigRegistryClient configRegistryClient,
EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
- try {
- set(configRegistryClient, editConfigExecution);
-
- } catch (IllegalStateException e) {
- //FIXME: when can IllegalStateException be thrown?
- // JmxAttributeValidationException is wrapped in DynamicWritableWrapper with ValidationException
- // ValidationException is not thrown until validate or commit is issued
- logger.warn("Set phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage());
- throw new NetconfDocumentedException("Test phase: " + e.getMessage(), e, ErrorType.application,
- ErrorTag.operation_failed, ErrorSeverity.error, errorInfo);
- }
+ set(configRegistryClient, editConfigExecution);
logger.debug("Set phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG);
}
EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
try {
test(configRegistryClient, editConfigExecution, editConfigExecution.getDefaultStrategy());
- } catch (IllegalStateException | ValidationException e) {
- //FIXME: when can IllegalStateException be thrown?
+ } catch (final ValidationException e) {
logger.warn("Test phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage());
}
private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution,
- EditStrategyType editStrategyType) throws ValidationException {
+ EditStrategyType editStrategyType) throws ValidationException, NetconfDocumentedException {
ObjectName taON = transactionProvider.getTestTransaction();
try {
-
// default strategy = replace wipes config
if (editStrategyType == EditStrategyType.replace) {
transactionProvider.wipeTestTransaction(taON);
}
private void set(ConfigRegistryClient configRegistryClient,
- EditConfigXmlParser.EditConfigExecution editConfigExecution) {
+ EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
ObjectName taON = transactionProvider.getOrCreateTransaction();
// default strategy = replace wipes config
setOnTransaction(ta, editConfigExecution);
}
- private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+ private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) throws NetconfDocumentedException {
Services services = execution.getServices();
logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService,
on, refName, saved);
} catch (InstanceNotFoundException e) {
- throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e);
+ throw new NetconfDocumentedException(String.format("Unable to save ref name " + refName + " for instance " + on, e),
+ ErrorType.application,
+ ErrorTag.operation_failed,
+ ErrorSeverity.error);
}
}
}
return ta.getServiceInterfaceName(namespace, serviceName);
}
- private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+ private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) throws NetconfDocumentedException {
for (Multimap<String, ModuleElementResolved> modulesToResolved : execution.getResolvedXmlElements(ta).values()) {
- for (Entry<String, ModuleElementResolved> moduleToResolved : modulesToResolved.entries()) {
+ for (Map.Entry<String, ModuleElementResolved> moduleToResolved : modulesToResolved.entries()) {
String moduleName = moduleToResolved.getKey();
ModuleElementResolved moduleElementResolved = moduleToResolved.getValue();
}
private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta,
- EditConfigExecution execution) {
+ EditConfigExecution execution) throws NetconfDocumentedException {
for (Multimap<String,ModuleElementDefinition> modulesToResolved : execution.getModulesDefinition(ta).values()) {
- for (Entry<String, ModuleElementDefinition> moduleToResolved : modulesToResolved.entries()) {
+ for (Map.Entry<String, ModuleElementDefinition> moduleToResolved : modulesToResolved.entries()) {
String moduleName = moduleToResolved.getKey();
ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue();
void addIdSchemaNode(IdentitySchemaNode node) {
String name = node.getQName().getLocalName();
- Preconditions.checkState(identityNameToSchemaNode.containsKey(name) == false);
+ Preconditions.checkState(!identityNameToSchemaNode.containsKey(name));
identityNameToSchemaNode.put(name, node);
}
}
Date revision = module.getRevision();
- Preconditions.checkState(revisionsByNamespace.containsKey(revision) == false,
+ Preconditions.checkState(!revisionsByNamespace.containsKey(revision),
"Duplicate revision %s for namespace %s", revision, namespace);
IdentityMapping identityMapping = revisionsByNamespace.get(revision);
Map<String, Map<String, ModuleConfig>> namespaceToModuleNameToModuleConfig = Maps.newHashMap();
for (String namespace : mBeanEntries.keySet()) {
- for (Entry<String, ModuleMXBeanEntry> moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) {
+ for (Map.Entry<String, ModuleMXBeanEntry> moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) {
String moduleName = moduleNameToMbe.getKey();
ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue();
protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
EditConfigXmlParser.EditConfigExecution editConfigExecution;
- Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot);
- try {
- editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, configRegistryClient);
- } catch (IllegalStateException e) {
- logger.warn("Error parsing xml", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.missing_attribute.name(), "Error parsing xml: " + e.getMessage());
- throw new NetconfDocumentedException(e.getMessage(), ErrorType.rpc, ErrorTag.missing_attribute,
- ErrorSeverity.error, errorInfo);
- } catch (final IllegalArgumentException e) {
- logger.warn("Error parsing xml", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage());
- throw new NetconfDocumentedException(e.getMessage(), ErrorType.rpc, ErrorTag.bad_attribute,
- ErrorSeverity.error, errorInfo);
- } catch (final UnsupportedOperationException e) {
- logger.warn("Unsupported", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.operation_not_supported.name(), "Unsupported option for 'edit-config'");
- throw new NetconfDocumentedException(e.getMessage(), ErrorType.application,
- ErrorTag.operation_not_supported, ErrorSeverity.error, errorInfo);
- }
+ Config cfg = getConfigMapping(getConfigRegistryClient(), yangStoreSnapshot);
+ editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, getConfigRegistryClient());
- return getResponseInternal(document, editConfigExecution);
+ Element responseInternal;
+ responseInternal = getResponseInternal(document, editConfigExecution);
+ return responseInternal;
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
public interface EditConfigStrategy {
void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, ServiceRegistryWrapper services);
+ ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException;
}
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
+import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
+import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.slf4j.Logger;
xml.checkName(EditConfigXmlParser.EDIT_CONFIG);
xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- XmlElement targetElement = xml.getOnlyChildElementWithSameNamespace(EditConfigXmlParser.TARGET_KEY);
- XmlElement targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
+
+ XmlElement targetElement = null;
+ XmlElement targetChildNode = null;
+ try {
+ targetElement = xml.getOnlyChildElementWithSameNamespace(EditConfigXmlParser.TARGET_KEY);
+ targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
+ } catch (final MissingNameSpaceException | UnexpectedNamespaceException e) {
+ logger.trace("Can't get only child element with same namespace due to {}",e);
+ throw NetconfDocumentedException.wrap(e);
+ }
String datastoreValue = targetChildNode.getName();
Datastore targetDatastore = Datastore.valueOf(datastoreValue);
logger.debug("Setting {} to '{}'", EditConfigXmlParser.TARGET_KEY, targetDatastore);
// check target
- Preconditions.checkArgument(targetDatastore == Datastore.candidate,
- "Only %s datastore supported for edit config but was: %s", Datastore.candidate, targetDatastore);
+ if (targetDatastore != Datastore.candidate){
+ throw new NetconfDocumentedException(String.format(
+ "Only %s datastore supported for edit config but was: %s",
+ Datastore.candidate,
+ targetDatastore),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
// Test option
TestOption testOption;
.getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.ERROR_OPTION_KEY);
if (errorOptionElement.isPresent()) {
String errorOptionParsed = errorOptionElement.get().getTextContent();
- if (false == errorOptionParsed.equals(EditConfigXmlParser.DEFAULT_ERROR_OPTION))
+ if (!errorOptionParsed.equals(EditConfigXmlParser.DEFAULT_ERROR_OPTION)){
throw new UnsupportedOperationException("Only " + EditConfigXmlParser.DEFAULT_ERROR_OPTION
+ " supported for " + EditConfigXmlParser.ERROR_OPTION_KEY + ", was " + errorOptionParsed);
+ }
}
// Default op
editStrategyType = EditStrategyType.valueOf(mergeStrategyString);
}
- XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
+ XmlElement configElement = null;
+ try {
+ configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
+ } catch (MissingNameSpaceException e) {
+ logger.trace("Can't get only child element with same namespace due to {}",e);
+ throw NetconfDocumentedException.wrap(e);
+ }
return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType);
}
private final Config configResolver;
private final XmlElement configElement;
- EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) {
+ EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) throws NetconfDocumentedException {
Config.checkUnrecognisedChildren(configElement);
this.configResolver = configResolver;
this.configElement = configElement;
return testOption == TestOption.set || testOption == TestOption.testThenSet;
}
- Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) {
+ Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) throws NetconfDocumentedException {
return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
}
return new ServiceRegistryWrapper(serviceRegistry);
}
- Map<String, Multimap<String,ModuleElementDefinition>> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) {
+ Map<String, Multimap<String,ModuleElementDefinition>> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) throws NetconfDocumentedException {
return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
import com.google.common.collect.Multimap;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException;
import java.util.EnumSet;
import java.util.Set;
+ this);
}
}
+ public static void compareParsedStrategyToDefaultEnforcing(EditStrategyType parsedStrategy,
+ EditStrategyType defaultStrategy) throws OperationNotPermittedException {
+ if (defaultStrategy.isEnforcing()) {
+ if (parsedStrategy != defaultStrategy){
+ throw new OperationNotPermittedException(String.format("With "
+ + defaultStrategy
+ + " as "
+ + EditConfigXmlParser.DEFAULT_OPERATION_KEY
+ + " operations on module elements are not permitted since the default option is restrictive"),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
+ }
+ }
public EditConfigStrategy getFittingStrategy(Multimap<String, String> providedServices) {
switch (this) {
case merge:
case replace:
return new ReplaceEditConfigStrategy(providedServices);
case delete:
- return new DeleteEditConfigStrategy(providedServices);
+ return new DeleteEditConfigStrategy();
case remove:
return new RemoveEditConfigStrategy();
case none:
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, ServiceRegistryWrapper services) {
- throw new IllegalStateException(
- "Unable to handle missing instance, no missing instances should appear at this point, missing: "
- + module + ":" + instance);
+ String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
+ throw new NetconfConfigHandlingException(
+ String.format("Unable to handle missing instance, no missing instances should appear at this point, missing: %s : %s ",
+ module,
+ instance),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
for (Entry<String, String> namespaceToService : providedServices.entries()) {
if(services.hasRefName(namespaceToService.getKey(),
- namespaceToService.getValue(), on))
+ namespaceToService.getValue(), on)){
continue;
+ }
String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
}
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
try {
addRefNames(services, providedServices, ta, on);
} catch (InstanceNotFoundException e) {
- throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+ throw new NetconfConfigHandlingException(String.format("Unable to save default ref name for instance %s. Instance was not found.",e),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
ta.setAttribute(on, ace.getJmxName(), new Attribute(ace.getJmxName(), value));
logger.debug("Attribute {} set to {} for {}", configAttributeEntry.getKey(), value, on);
} catch (Exception e) {
- throw new IllegalStateException("Unable to set attributes for " + on + ", Error with attribute "
- + configAttributeEntry.getKey() + ":" + configAttributeEntry.getValue(), e);
+ throw new NetconfConfigHandlingException(String.format("Unable to set attributes for %s, Error with attribute %s : %s ",
+ on,
+ configAttributeEntry.getKey(),
+ configAttributeEntry.getValue()),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, ServiceRegistryWrapper services) {
+ String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
ObjectName on = null;
try {
on = ta.createModule(module, instance);
logger.trace("New instance for {} {} created under name {}", module, instance, on);
} catch (InstanceAlreadyExistsException e1) {
- throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
+ throw new NetconfConfigHandlingException(String.format("Unable to create instance for %s : %s.", module, instance),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
}
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, ServiceRegistryWrapper services) {
- throw new IllegalStateException(
- "Unable to handle missing instance, no missing instances should appear at this point, missing: "
- + module + ":" + instance);
+ String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
+ throw new NetconfConfigHandlingException(
+ String.format("Unable to handle missing instance, no missing instances should appear at this point, missing: %s : %s ",
+ module,
+ instance),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
for (Entry<String, String> namespaceToService : providedServices.entries()) {
if(services.hasRefName(namespaceToService.getKey(),
- namespaceToService.getValue(), on))
+ namespaceToService.getValue(), on)){
continue;
+ }
String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
}
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
try {
addRefNames(services, providedServices, ta, on);
} catch (InstanceNotFoundException e) {
- throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+ throw new NetconfConfigHandlingException(String.format("Unable to save default ref name for instance %s. Instance not found. ",on),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
}
for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
package org.opendaylight.controller.netconf.confignetconfconnector.operations.get;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+import com.google.common.collect.Maps;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
+import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
+import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException;
+import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.slf4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.collect.Maps;
+import javax.management.ObjectName;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class Get extends AbstractConfigNetconfOperation {
RuntimeBeanEntry root = null;
for (RuntimeBeanEntry rbe : mbe.getRuntimeBeans()) {
cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap()));
- if (rbe.isRoot())
+ if (rbe.isRoot()){
root = rbe;
+ }
}
- if (root == null)
+ if (root == null){
continue;
+ }
InstanceRuntime rootInstanceRuntime = createInstanceRuntime(root, cache);
ModuleRuntime moduleRuntime = new ModuleRuntime(module, rootInstanceRuntime);
return jmxToYangNamesForChildRbe;
}
- private static void checkXml(XmlElement xml) {
+ private static void checkXml(XmlElement xml) throws UnexpectedElementException, UnexpectedNamespaceException, MissingNameSpaceException {
xml.checkName(XmlNetconfConstants.GET);
xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
// Filter option - unsupported
- if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0)
+ if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){
throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for " + XmlNetconfConstants.GET);
+ }
}
@Override
@Override
protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
- try {
- checkXml(xml);
- } catch (final IllegalArgumentException e) {
- logger.warn("Error parsing xml", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage());
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.bad_attribute,
- ErrorSeverity.error, errorInfo);
- } catch (final UnsupportedOperationException e) {
- logger.warn("Unsupported", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.operation_not_supported.name(), "Unsupported option for 'get'");
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application,
- ErrorTag.operation_not_supported, ErrorSeverity.error, errorInfo);
- }
+ checkXml(xml);
- final Set<ObjectName> runtimeBeans = configRegistryClient.lookupRuntimeBeans();
+ final Set<ObjectName> runtimeBeans = getConfigRegistryClient().lookupRuntimeBeans();
//Transaction provider required only for candidate datastore
final Set<ObjectName> configBeans = Datastore.getInstanceQueryStrategy(Datastore.running, null)
- .queryInstances(configRegistryClient);
+ .queryInstances(getConfigRegistryClient());
- final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(configRegistryClient,
+ final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(getConfigRegistryClient(),
yangStoreSnapshot.getModuleMXBeanEntryMap());
final Map<String, Map<String, ModuleConfig>> moduleConfigs = EditConfig.transformMbeToModuleConfigs(
- configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
+ getConfigRegistryClient(), yangStoreSnapshot.getModuleMXBeanEntryMap());
final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
ObjectName txOn = transactionProvider.getOrCreateTransaction();
- ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn);
+ ConfigTransactionClient ta = getConfigRegistryClient().getConfigTransactionClient(txOn);
final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta));
logger.trace("{} operation successful", XmlNetconfConstants.GET);
package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Optional;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
+import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
+import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException;
+import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
+import javax.management.ObjectName;
+import java.util.Set;
public class GetConfig extends AbstractConfigNetconfOperation {
this.transactionProvider = transactionProvider;
}
- public static Datastore fromXml(XmlElement xml) {
+ public static Datastore fromXml(XmlElement xml) throws UnexpectedNamespaceException, UnexpectedElementException, MissingNameSpaceException, NetconfDocumentedException {
+
xml.checkName(GET_CONFIG);
xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
Datastore sourceDatastore = Datastore.valueOf(sourceParsed);
// Filter option - unsupported
- if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0)
+ if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){
throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for "
+ GET_CONFIG);
+ }
return sourceDatastore;
@Override
public Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
Datastore source;
- try {
- source = fromXml(xml);
- } catch (final IllegalArgumentException e) {
- logger.warn("Rpc error: {}", ErrorTag.bad_attribute, e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage());
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.bad_attribute,
- ErrorSeverity.error, errorInfo);
- } catch (final IllegalStateException e) {
- logger.warn("Rpc error: {}", ErrorTag.missing_attribute, e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.missing_attribute.name(), "Missing datasource attribute value");
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.missing_attribute,
- ErrorSeverity.error, errorInfo);
- } catch (final UnsupportedOperationException e) {
- logger.warn("Unsupported", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.operation_not_supported.name(), "Unsupported option for get");
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application,
- ErrorTag.operation_not_supported, ErrorSeverity.error, errorInfo);
- }
- return getResponseInternal(document, configRegistryClient, source);
+ source = fromXml(xml);
+ return getResponseInternal(document, getConfigRegistryClient(), source);
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
-import java.util.Map;
-
-import javax.management.ObjectName;
-import javax.management.openmbean.OpenType;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
+import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
+import javax.management.ObjectName;
+import javax.management.openmbean.OpenType;
+import java.util.Map;
public class RuntimeRpc extends AbstractConfigNetconfOperation {
this.yangStoreSnapshot = yangStoreSnapshot;
}
- private Element toXml(Document doc, Object result, AttributeIfc returnType, String namespace, String elementName) {
+ private Element toXml(Document doc, Object result, AttributeIfc returnType, String namespace, String elementName) throws NetconfDocumentedException {
AttributeMappingStrategy<?, ? extends OpenType<?>> mappingStrategy = new ObjectMapper(null).prepareStrategy(returnType);
Optional<?> mappedAttributeOpt = mappingStrategy.mapAttribute(result);
Preconditions.checkState(mappedAttributeOpt.isPresent(), "Unable to map return value %s as %s", result, returnType.getOpenType());
}
public NetconfOperationExecution fromXml(final XmlElement xml) throws NetconfDocumentedException {
- final String namespace = xml.getNamespace();
+ final String namespace;
+ try {
+ namespace = xml.getNamespace();
+ } catch (MissingNameSpaceException e) {
+ logger.trace("Can't get namespace from xml element due to {}",e);
+ throw NetconfDocumentedException.wrap(e);
+ }
final XmlElement contextInstanceElement = xml.getOnlyChildElement(CONTEXT_INSTANCE);
final String operationName = xml.getName();
}
@Override
- public HandlingPriority canHandle(Document message) {
- XmlElement requestElement = getRequestElementWithCheck(message);
+ public HandlingPriority canHandle(Document message) throws NetconfDocumentedException {
+ XmlElement requestElement = null;
+ requestElement = getRequestElementWithCheck(message);
XmlElement operationElement = requestElement.getOnlyChildElement();
final String netconfOperationName = operationElement.getName();
- final String netconfOperationNamespace = operationElement.getNamespace();
+ final String netconfOperationNamespace;
+ try {
+ netconfOperationNamespace = operationElement.getNamespace();
+ } catch (MissingNameSpaceException e) {
+ logger.debug("Cannot retrieve netconf operation namespace from message due to {}", e);
+ return HandlingPriority.CANNOT_HANDLE;
+ }
final Optional<XmlElement> contextInstanceElement = operationElement
.getOnlyChildElementOptionally(CONTEXT_INSTANCE);
- if (contextInstanceElement.isPresent() == false)
+ if (!contextInstanceElement.isPresent()){
return HandlingPriority.CANNOT_HANDLE;
+ }
final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get()
.getTextContent(), netconfOperationName, netconfOperationNamespace);
@Override
protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
-
- // TODO exception handling
// TODO check for namespaces and unknown elements
-
final NetconfOperationExecution execution = fromXml(xml);
logger.debug("Invoking operation {} on {} with arguments {}", execution.operationName, execution.on,
execution.attributes);
- final Object result = executeOperation(configRegistryClient, execution.on, execution.operationName,
+ final Object result = executeOperation(getConfigRegistryClient(), execution.on, execution.operationName,
execution.attributes);
logger.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName,
for (XmlElement xmlElement : xml.getChildElements()) {
final String name = xmlElement.getName();
- if (CONTEXT_INSTANCE.equals(name) == false) { // skip context
+ if (!CONTEXT_INSTANCE.equals(name)) { // skip context
// instance child node
// because it
// specifies
RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint);
PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"),
- matcher.group("key2"), matcher.group("value2"), matcher.group("additional"));
+ matcher.group("value2"), matcher.group("additional"));
String moduleName = groups.getModuleName();
String instanceName = groups.getInstanceName();
- HashMap<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
+ Map<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(),
additionalAttributes);
private static final class PatternGroupResolver {
- private final String key1, key2, value1, value2;
+ private final String key1, value1, value2;
private final String additional;
private String runtimeBeanYangName;
- PatternGroupResolver(String key1, String value1, String key2, String value2, String additional) {
+ PatternGroupResolver(String key1, String value1, String value2, String additional) {
this.key1 = Preconditions.checkNotNull(key1);
this.value1 = Preconditions.checkNotNull(value1);
- this.key2 = Preconditions.checkNotNull(key2);
this.value2 = Preconditions.checkNotNull(value2);
this.additional = Preconditions.checkNotNull(additional);
return key1.equals(XmlNetconfConstants.NAME_KEY) ? value1 : value2;
}
- HashMap<String, String> getAdditionalKeys(String elementName, String moduleName) {
+ Map<String, String> getAdditionalKeys(String elementName, String moduleName) {
HashMap<String, String> additionalAttributes = Maps.newHashMap();
runtimeBeanYangName = moduleName;
for (String additionalKeyValue : additional.split("/")) {
- if (Strings.isNullOrEmpty(additionalKeyValue))
+ if (Strings.isNullOrEmpty(additionalKeyValue)){
continue;
+ }
Matcher matcher = additionalPattern.matcher(additionalKeyValue);
Preconditions
.checkState(
}
@Override
- public void stop(BundleContext context) throws Exception {
+ public void stop(BundleContext context) {
if (configRegistryLookup != null) {
configRegistryLookup.interrupt();
}
import java.util.Set;
final class NetconfOperationProvider {
- private final YangStoreSnapshot yangStoreSnapshot;
private final Set<NetconfOperation> operations;
- private final ConfigRegistryClient configRegistryClient;
- private final TransactionProvider transactionProvider;
NetconfOperationProvider(YangStoreSnapshot yangStoreSnapshot, ConfigRegistryClient configRegistryClient,
TransactionProvider transactionProvider, String netconfSessionIdForReporting) {
- this.yangStoreSnapshot = yangStoreSnapshot;
- this.configRegistryClient = configRegistryClient;
- this.transactionProvider = transactionProvider;
operations = setUpOperations(yangStoreSnapshot, configRegistryClient, transactionProvider,
netconfSessionIdForReporting);
}
Thread.sleep(ATTEMPT_TIMEOUT_MS);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
- throw new RuntimeException("Interrupted while reattempting connection", e1);
+ throw new IllegalStateException("Interrupted while reattempting connection", e1);
}
}
}
for (Map<String, ModuleMXBeanEntry> moduleNameToMBE : moduleMXBeanEntryMap.values()) {
for (ModuleMXBeanEntry moduleMXBeanEntry : moduleNameToMBE.values()) {
String moduleSeenByYangStore = moduleMXBeanEntry.getYangModuleQName().toString();
- if(modulesSeenByConfig.contains(moduleSeenByYangStore) == false)
+ if(!modulesSeenByConfig.contains(moduleSeenByYangStore)){
missingModulesFromConfig.add(moduleSeenByYangStore);
+ }
}
}
}
}
- private static class YangStoreCapability extends BasicCapability {
+ private static final class YangStoreCapability extends BasicCapability {
private final String content;
private final String revision;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NoTransactionFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final String netconfSessionIdForReporting;
private ObjectName transaction;
private final List<ObjectName> allOpenedTransactions = new ArrayList<>();
+ private static final String NO_TRANSACTION_FOUND_FOR_SESSION = "No transaction found for session ";
public TransactionProvider(ConfigRegistryClient configRegistryClient, String netconfSessionIdForReporting) {
this.configRegistryClient = configRegistryClient;
public Optional<ObjectName> getTransaction() {
- if (transaction == null)
+ if (transaction == null){
return Optional.absent();
+ }
// Transaction was already closed somehow
- if (isStillOpenTransaction(transaction) == false) {
+ if (!isStillOpenTransaction(transaction)) {
logger.warn("Fixing illegal state: transaction {} was closed in {}", transaction,
netconfSessionIdForReporting);
transaction = null;
}
private boolean isStillOpenTransaction(ObjectName transaction) {
- boolean isStillOpenTransaction = configRegistryClient.getOpenConfigs().contains(transaction);
- return isStillOpenTransaction;
+ return configRegistryClient.getOpenConfigs().contains(transaction);
}
public synchronized ObjectName getOrCreateTransaction() {
/**
* Commit and notification send must be atomic
*/
- public synchronized CommitStatus commitTransaction() throws ValidationException, ConflictingVersionException {
+ public synchronized CommitStatus commitTransaction() throws ValidationException, ConflictingVersionException, NoTransactionFoundException {
+ if (!getTransaction().isPresent()){
+ throw new NoTransactionFoundException("No transaction found for session " + netconfSessionIdForReporting,
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
final Optional<ObjectName> maybeTaON = getTransaction();
- Preconditions.checkState(maybeTaON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
ObjectName taON = maybeTaON.get();
try {
CommitStatus status = configRegistryClient.commitConfig(taON);
public synchronized void abortTransaction() {
logger.debug("Aborting current transaction");
Optional<ObjectName> taON = getTransaction();
- Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
+ Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
transactionClient.abortConfig();
public void validateTransaction() throws ValidationException {
Optional<ObjectName> taON = getTransaction();
- Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
+ Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
transactionClient.validateConfig();
try {
transactionClient.destroyModule(instance);
} catch (InstanceNotFoundException e) {
- if (isTest)
+ if (isTest){
logger.debug("Unable to clean configuration in transactiom {}", taON, e);
- else
+ } else {
logger.warn("Unable to clean configuration in transactiom {}", taON, e);
+ }
throw new IllegalStateException("Unable to clean configuration in transactiom " + taON, e);
}
public void wipeTransaction() {
Optional<ObjectName> taON = getTransaction();
- Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
+ Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
wipeInternal(taON.get(), false, null);
}
package org.opendaylight.controller.netconf.confignetconfconnector;
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement;
-import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText;
-import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import org.custommonkey.xmlunit.AbstractNodeTester;
import org.custommonkey.xmlunit.NodeTest;
import org.custommonkey.xmlunit.NodeTestException;
import org.opendaylight.controller.config.yang.test.impl.Peers;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl;
import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
import org.w3c.dom.traversal.DocumentTraversal;
import org.xml.sax.SAXException;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement;
+import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText;
+import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement;
public class NetconfMappingTest extends AbstractConfigTest {
this.factory = new NetconfTestImplModuleFactory();
this.factory2 = new DepTestImplModuleFactory();
this.factory3 = new IdentityTestModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.factory, this.factory2,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, this.factory, this.factory2,
this.factory3));
transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID);
assertThat(string, JUnitMatchers.containsString(substring));
}
- private void checkEnum(final Document response) {
+ private void checkEnum(final Document response) throws NetconfDocumentedException {
XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data")
.getOnlyChildElement("modules");
assertEquals(2, testingDepsSize);
}
- private void checkTypeConfigAttribute(Document response) {
+ private void checkTypeConfigAttribute(Document response) throws NetconfDocumentedException {
XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data")
.getOnlyChildElement("modules");
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
}
- private EditConfigExecution mockExecution(EditConfigStrategy editStrat) {
+ private EditConfigExecution mockExecution(EditConfigStrategy editStrat) throws NetconfDocumentedException {
EditConfigExecution mock = mock(EditConfigExecution.class);
doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class));
doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class));
try {
mBeanServerConnection.addNotificationListener(DefaultCommitOperationMXBean.OBJECT_NAME, listener, null, null);
} catch (InstanceNotFoundException | IOException e) {
- throw new RuntimeException("Cannot register as JMX listener to netconf", e);
+ throw new IllegalStateException("Cannot register as JMX listener to netconf", e);
}
}
@Override
public void handleNotification(Notification notification, Object handback) {
- if (notification instanceof NetconfJMXNotification == false) {
+ if (!(notification instanceof NetconfJMXNotification))
return;
- }
// Socket should not be closed at this point
// Activator unregisters this as JMX listener before close is called
this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis;
}
- public synchronized LinkedHashMap<ConfigSnapshotHolder, EditAndCommitResponse> pushConfigs(List<ConfigSnapshotHolder> configs) {
+ public synchronized LinkedHashMap<ConfigSnapshotHolder, EditAndCommitResponse> pushConfigs(List<ConfigSnapshotHolder> configs) throws NetconfDocumentedException {
logger.debug("Last config snapshots to be pushed to netconf: {}", configs);
LinkedHashMap<ConfigSnapshotHolder, EditAndCommitResponse> result = new LinkedHashMap<>();
// start pushing snapshots:
* is caught, whole process is retried - new service instance need to be obtained from the factory. Closes
* {@link NetconfOperationService} after each use.
*/
- private synchronized EditAndCommitResponse pushConfigWithConflictingVersionRetries(ConfigSnapshotHolder configSnapshotHolder) {
+ private synchronized EditAndCommitResponse pushConfigWithConflictingVersionRetries(ConfigSnapshotHolder configSnapshotHolder) throws NetconfDocumentedException {
ConflictingVersionException lastException;
Stopwatch stopwatch = new Stopwatch().start();
do {
} else {
serviceCandidate.close();
logger.trace("Netconf server did not provide required capabilities for {} " +
- "Expected but not found: {}, all expected {}, current {}",
+ "Expected but not found: {}, all expected {}, current {}",
idForReporting, notFoundDiff, expectedCapabilities, serviceCandidate.getCapabilities()
);
throw new NotEnoughCapabilitiesException("Not enough capabilities for " + idForReporting + ". Expected but not found: " + notFoundDiff);
* @throws java.lang.RuntimeException if edit-config or commit fails otherwise
*/
private synchronized EditAndCommitResponse pushConfig(ConfigSnapshotHolder configSnapshotHolder, NetconfOperationService operationService)
- throws ConflictingVersionException {
+ throws ConflictingVersionException, NetconfDocumentedException {
Element xmlToBePersisted;
try {
return new EditAndCommitResponse(editResponseMessage, commitResponseMessage);
}
- private NetconfOperation findOperation(NetconfMessage request, NetconfOperationService operationService) {
+ private NetconfOperation findOperation(NetconfMessage request, NetconfOperationService operationService) throws NetconfDocumentedException {
TreeMap<HandlingPriority, NetconfOperation> allOperations = new TreeMap<>();
Set<NetconfOperation> netconfOperations = operationService.getNetconfOperations();
if (netconfOperations.isEmpty()) {
private Document sendRequestGetResponseCheckIsOK(NetconfMessage request, NetconfOperationService operationService,
String operationNameForReporting, String configIdForReporting)
- throws ConflictingVersionException {
+ throws ConflictingVersionException, NetconfDocumentedException {
NetconfOperation operation = findOperation(request, operationService);
Document response;
}
// load editConfig.xml template, populate /rpc/edit-config/config with parameter
- private static NetconfMessage createEditConfigMessage(Element dataElement) {
+ private static NetconfMessage createEditConfigMessage(Element dataElement) throws NetconfDocumentedException {
String editConfigResourcePath = "/netconfOp/editConfig.xml";
try (InputStream stream = ConfigPersisterNotificationHandler.class.getResourceAsStream(editConfigResourcePath)) {
Preconditions.checkNotNull(stream, "Unable to load resource " + editConfigResourcePath);
package org.opendaylight.controller.netconf.persist.impl;
import com.google.common.annotations.VisibleForTesting;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.api.PropertiesProvider;
import org.opendaylight.controller.config.persist.api.StorageAdapter;
import org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator;
-import org.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
-
/**
* {@link Persister} implementation that delegates persisting functionality to
* underlying {@link Persister} storages. Each storage has unique id, class, readonly value.
}
}
- private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProviderBaseImpl propertiesProvider) {
+ private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProvider propertiesProvider) {
String classKey = index + "." + ConfigPersisterActivator.STORAGE_ADAPTER_CLASS_PROP_SUFFIX;
String storageAdapterClass = propertiesProvider.getProperty(classKey);
try {
Class<?> clazz = Class.forName(storageAdapterClass);
boolean implementsCorrectIfc = StorageAdapter.class.isAssignableFrom(clazz);
- if (implementsCorrectIfc == false) {
+ if (!implementsCorrectIfc) {
throw new IllegalArgumentException("Storage adapter " + clazz + " does not implement " + StorageAdapter.class);
}
storageAdapter = StorageAdapter.class.cast(clazz.newInstance());
}
- public static PersisterAggregator createFromProperties(PropertiesProviderBaseImpl propertiesProvider) {
+ public static PersisterAggregator createFromProperties(PropertiesProvider propertiesProvider) {
List<PersisterWithConfiguration> persisterWithConfigurations = new ArrayList<>();
String prefixes = propertiesProvider.getProperty("active");
- if (prefixes!=null && prefixes.isEmpty() == false) {
+ if (prefixes!=null && !prefixes.isEmpty()) {
String [] keys = prefixes.split(",");
for (String index: keys) {
persisterWithConfigurations.add(PersisterAggregator.loadConfiguration(index, propertiesProvider));
} catch (IOException e) {
throw new RuntimeException("Error while calling loadLastConfig on " + persisterWithConfiguration, e);
}
- if (configs.isEmpty() == false) {
+ if (!configs.isEmpty()) {
logger.debug("Found non empty configs using {}:{}", persisterWithConfiguration, configs);
return configs;
}
package org.opendaylight.controller.netconf.persist.impl;
import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl;
public class PropertiesProviderAdapterImpl implements PropertiesProvider {
- private final PropertiesProviderBaseImpl inner;
+ private final PropertiesProvider inner;
private final String index;
- public PropertiesProviderAdapterImpl(PropertiesProviderBaseImpl inner, String index) {
+ public PropertiesProviderAdapterImpl(PropertiesProvider inner, String index) {
this.inner = inner;
this.index = index;
}
return inner.getPrefix() + "." + index + ".properties";
}
+ @Override
+ public String getPropertyWithoutPrefix(String fullKey) {
+ return inner.getPropertyWithoutPrefix(fullKey);
+ }
+
+
@Override
public String getFullKeyForReporting(String key) {
return getPrefix() + "." + key;
import com.google.common.annotations.VisibleForTesting;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider);
List<ConfigSnapshotHolder> configs = persisterAggregator.loadLastConfigs();
long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider);
- logger.trace("Following configs will be pushed: {}", configs);
+ logger.debug("Following configs will be pushed: {}", configs);
InnerCustomizer innerCustomizer = new InnerCustomizer(configs, maxWaitForCapabilitiesMillis,
conflictingVersionTimeoutMillis, persisterAggregator);
final Thread pushingThread = new Thread(new Runnable() {
@Override
public void run() {
- configPusher.pushConfigs(configs);
+ try {
+ configPusher.pushConfigs(configs);
+ } catch (NetconfDocumentedException e) {
+ logger.error("Error pushing configs {}",configs);
+ throw new IllegalStateException(e);
+ }
logger.info("Configuration Persister initialization completed.");
ConfigPersisterNotificationHandler jmxNotificationHandler = new ConfigPersisterNotificationHandler(platformMBeanServer, persisterAggregator);
synchronized (ConfigPersisterActivator.this) {
// this means pushing of config was successful
public void assertCannotRegisterAsJMXListener_pushWasSuccessful() {
- handler.assertException(RuntimeException.class, "Cannot register as JMX listener to netconf");
+ handler.assertException(IllegalStateException.class, "Cannot register as JMX listener to netconf");
}
public NetconfOperationService getWorkingService(Document document) throws SAXException, IOException, NetconfDocumentedException {
/**
**/
-public class LocationBuilder {
+public final class LocationBuilder {
public static Location getDefaultInstance(String defaultValue) {
return defaultValue.equals("NETCONF") ? new Location(Location.Enumeration.NETCONF) : new Location(new Uri(
this.errorInfo = errorInfo;
}
+ public static <E extends Exception> NetconfDocumentedException wrap(E exception) throws NetconfDocumentedException {
+ final Map<String, String> errorInfo = new HashMap<>();
+ errorInfo.put(ErrorTag.operation_failed.name(), "Exception thrown");
+ throw new NetconfDocumentedException(exception.getMessage(), exception, ErrorType.application, ErrorTag.operation_failed,
+ ErrorSeverity.error, errorInfo);
+ }
public static NetconfDocumentedException wrap(ValidationException e) throws NetconfDocumentedException {
final Map<String, String> errorInfo = new HashMap<>();
errorInfo.put(ErrorTag.operation_failed.name(), "Validation failed");
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GlobalEventExecutor;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.Set;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Sets;
+
+/**
+ * @deprecated Use {@link NetconfClientDispatcher.createClient()} or {@link NetconfClientDispatcher.createReconnectingClient()} instead.
+ */
+@Deprecated
+public class NetconfClient implements Closeable {
+
+ private static final Logger logger = LoggerFactory.getLogger(NetconfClient.class);
+
+ public static final int DEFAULT_CONNECT_TIMEOUT = 5000;
+ private final NetconfClientDispatcher dispatch;
+ private final String label;
+ private final NetconfClientSession clientSession;
+ private final NetconfClientSessionListener sessionListener;
+ private final long sessionId;
+ private final InetSocketAddress address;
+
+ // TODO test reconnecting constructor
+ public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectionAttempts,
+ int attemptMsTimeout, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+ this(clientLabelForLogging, address, getReconnectStrategy(connectionAttempts, attemptMsTimeout),
+ netconfClientDispatcher);
+ }
+
+ private NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+ this.label = clientLabelForLogging;
+ dispatch = netconfClientDispatcher;
+ sessionListener = new SimpleNetconfClientSessionListener();
+ Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strat);
+ this.address = address;
+ clientSession = get(clientFuture);
+ this.sessionId = clientSession.getSessionId();
+ }
+
+ private NetconfClientSession get(Future<NetconfClientSession> clientFuture) throws InterruptedException {
+ try {
+ return clientFuture.get();
+ } catch (CancellationException e) {
+ throw new RuntimeException("Cancelling " + this, e);
+ } catch (ExecutionException e) {
+ throw new IllegalStateException("Unable to create " + this, e);
+ }
+ }
+
+ public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+ return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher);
+ }
+
+ public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address,
+ ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException {
+ return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher,listener);
+ }
+
+ public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs,
+ NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+ this(clientLabelForLogging, address,
+ new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, connectTimeoutMs), netconfClientDispatcher);
+ }
+
+ public NetconfClient(String clientLabelForLogging, InetSocketAddress address,
+ NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+ this(clientLabelForLogging, address, new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
+ DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher);
+ }
+
+ public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy,
+ NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{
+ this.label = clientLabelForLogging;
+ dispatch = netconfClientDispatcher;
+ sessionListener = listener;
+ Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strategy);
+ this.address = address;
+ clientSession = get(clientFuture);
+ this.sessionId = clientSession.getSessionId();
+ }
+
+ public Future<NetconfMessage> sendRequest(NetconfMessage message) {
+ return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message);
+ }
+
+ /**
+ * @deprecated Use {@link sendRequest} instead
+ */
+ @Deprecated
+ public NetconfMessage sendMessage(NetconfMessage message) throws ExecutionException, InterruptedException, TimeoutException {
+ return sendMessage(message, 5, 1000);
+ }
+
+ /**
+ * @deprecated Use {@link sendRequest} instead
+ */
+ @Deprecated
+ public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) throws ExecutionException, InterruptedException, TimeoutException {
+ final Stopwatch stopwatch = new Stopwatch().start();
+
+ try {
+ return sendRequest(message).get(attempts * attemptMsDelay, TimeUnit.MILLISECONDS);
+ } finally {
+ stopwatch.stop();
+ logger.debug("Total time spent waiting for response from {}: {} ms", address, stopwatch.elapsed(TimeUnit.MILLISECONDS));
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ clientSession.close();
+ }
+
+ public NetconfClientDispatcher getNetconfClientDispatcher() {
+ return dispatch;
+ }
+
+ private static ReconnectStrategy getReconnectStrategy(int connectionAttempts, int attemptMsTimeout) {
+ return new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null,
+ Long.valueOf(connectionAttempts), null);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("NetconfClient{");
+ sb.append("label=").append(label);
+ sb.append(", sessionId=").append(sessionId);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public long getSessionId() {
+ return sessionId;
+ }
+
+ public Set<String> getCapabilities() {
+ Preconditions.checkState(clientSession != null, "Client was not initialized successfully");
+ return Sets.newHashSet(clientSession.getServerCapabilities());
+ }
+
+ public NetconfClientSession getClientSession() {
+ return clientSession;
+ }
+}
});
}
- private static class ClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
+ private static final class ClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
private final NetconfClientSessionListener sessionListener;
package org.opendaylight.controller.netconf.client;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.Promise;
import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
import org.opendaylight.controller.netconf.util.AbstractNetconfSessionNegotiator;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
public class NetconfClientSessionNegotiator extends
AbstractNetconfSessionNegotiator<NetconfClientSessionPreferences, NetconfClientSession, NetconfClientSessionListener>
}
@Override
- protected void handleMessage(NetconfHelloMessage netconfMessage) {
+ protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
NetconfClientSession session = super.getSessionForHelloMessage(netconfMessage);
if (shouldUseExi(netconfMessage.getDocument())){
- logger.info("Netconf session: {} should use exi.", session);
+ logger.debug("Netconf session: {} should use exi.", session);
tryToStartExi(session);
} else {
- logger.info("Netconf session {} isn't capable using exi.", session);
+ logger.debug("Netconf session {} isn't capable using exi.", session);
negotiationSuccessful(session);
}
}
}
@Override
- protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel, NetconfHelloMessage message) {
+ protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException {
return new NetconfClientSession(sessionListener, channel, extractSessionId(message.getDocument()),
NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument()));
}
package org.opendaylight.controller.netconf.client;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+import io.netty.channel.Channel;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.Promise;
import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
import org.openexi.proc.common.AlignmentType;
import org.openexi.proc.common.EXIOptions;
import org.openexi.proc.common.EXIOptionsException;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-
-import io.netty.channel.Channel;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfMessage, NetconfClientSession, NetconfClientSessionListener> {
public static final java.util.Set<String> CLIENT_CAPABILITIES = Sets.newHashSet(
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1,
+ XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
+ XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1,
XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0);
private static final String START_EXI_MESSAGE_ID = "default-start-exi";
private final long connectionTimeoutMillis;
private final Timer timer;
private final EXIOptions options;
+ private static final Logger logger = LoggerFactory.getLogger(NetconfClientSessionNegotiatorFactory.class);
public NetconfClientSessionNegotiatorFactory(Timer timer,
Optional<NetconfHelloMessageAdditionalHeader> additionalHeader,
Promise<NetconfClientSession> promise) {
NetconfMessage startExiMessage = NetconfStartExiMessage.create(options, START_EXI_MESSAGE_ID);
- NetconfHelloMessage helloMessage = NetconfHelloMessage.createClientHello(CLIENT_CAPABILITIES, additionalHeader);
+ NetconfHelloMessage helloMessage = null;
+ try {
+ helloMessage = NetconfHelloMessage.createClientHello(CLIENT_CAPABILITIES, additionalHeader);
+ } catch (NetconfDocumentedException e) {
+ logger.error("Unable to create client hello message with capabilities {} and additional handler {}",CLIENT_CAPABILITIES,additionalHeader);
+ throw new IllegalStateException(e);
+ }
NetconfClientSessionPreferences proposal = new NetconfClientSessionPreferences(helloMessage,startExiMessage);
return new NetconfClientSessionNegotiator(proposal, promise, channel, timer,
public class SimpleNetconfClientSessionListener implements NetconfClientSessionListener {
private static final class RequestEntry {
- final Promise<NetconfMessage> promise;
- final NetconfMessage request;
+ private final Promise<NetconfMessage> promise;
+ private final NetconfMessage request;
public RequestEntry(Promise<NetconfMessage> future, NetconfMessage request) {
this.promise = Preconditions.checkNotNull(future);
org.opendaylight.controller.netconf.util.mapping,
org.opendaylight.controller.netconf.util.osgi,
org.opendaylight.controller.netconf.util.xml,
+ org.opendaylight.controller.netconf.util.exception,
org.opendaylight.controller.netconf.util.handler,
org.opendaylight.protocol.framework,
org.osgi.framework,
final Set<Capability> caps = netconfOperationService.getCapabilities();
for (Capability cap : caps) {
- if (cap.getModuleName().isPresent() == false)
- continue;
- if (cap.getRevision().isPresent() == false)
- continue;
- if (cap.getCapabilitySchema().isPresent() == false)
+ if (!cap.getModuleName().isPresent()
+ || !cap.getRevision().isPresent()
+ || !cap.getCapabilitySchema().isPresent()){
continue;
+ }
final String currentModuleName = cap.getModuleName().get();
Map<String, String> revisionMap = mappedModulesToRevisionToSchema.get(currentModuleName);
public DefaultCommitNotificationProducer(MBeanServer mBeanServer) {
this.mbeanServer = mBeanServer;
+ logger.debug("Registering to JMX under {}", on);
registerMBean(this, mbeanServer, on);
}
try {
mbs.registerMBean(instance, on);
} catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
- throw new RuntimeException("Unable to register " + instance + " as " + on, e);
+ throw new IllegalStateException("Unable to register " + instance + " as " + on, e);
}
}
package org.opendaylight.controller.netconf.impl;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-
public class NetconfServerSessionListener implements NetconfSessionListener<NetconfServerSession> {
static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionListener.class);
// TODO: should send generic error or close session?
logger.error("Unexpected exception", e);
session.onIncommingRpcFail();
- throw new RuntimeException("Unable to process incoming message " + netconfMessage, e);
+ throw new IllegalStateException("Unable to process incoming message " + netconfMessage, e);
} catch (NetconfDocumentedException e) {
+ logger.trace("Error occured while processing mesage {}",e);
session.onOutgoingRpcError();
session.onIncommingRpcFail();
SendErrorExceptionUtil.sendErrorMessage(session, e, netconfMessage);
import static org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider.NetconfOperationProviderUtil.getNetconfSessionIdForReporting;
+import com.google.common.collect.ImmutableSet;
import java.util.Set;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
import io.netty.channel.Channel;
import io.netty.util.Timer;
import io.netty.util.concurrent.Promise;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfHelloMessage, NetconfServerSession, NetconfServerSessionListener> {
- private static final Set<String> DEFAULT_CAPABILITIES = Sets.newHashSet(
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0);
+ private static final Set<String> DEFAULT_BASE_CAPABILITIES = ImmutableSet.of(
+ XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0
+ // FIXME, Chunk framing causes ConcurrentClientsTest to fail, investigate
+// XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1,
+ // FIXME, EXI causing issues with sal-netconf-connector, investigate
+// XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0
+ );
private final Timer timer;
private final long connectionTimeoutMillis;
private final DefaultCommitNotificationProducer commitNotificationProducer;
private final SessionMonitoringService monitoringService;
+ private static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionNegotiatorFactory.class);
+ // TODO too many params, refactor
public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationProvider netconfOperationProvider,
SessionIdProvider idProvider, long connectionTimeoutMillis,
- DefaultCommitNotificationProducer commitNot, SessionMonitoringService monitoringService) {
+ DefaultCommitNotificationProducer commitNot,
+ SessionMonitoringService monitoringService) {
this.timer = timer;
this.netconfOperationProvider = netconfOperationProvider;
this.idProvider = idProvider;
getNetconfSessionIdForReporting(sessionId));
CapabilityProvider capabilityProvider = new CapabilityProviderImpl(netconfOperationServiceSnapshot);
- NetconfServerSessionPreferences proposal = new NetconfServerSessionPreferences(
- createHelloMessage(sessionId, capabilityProvider), sessionId);
+ NetconfServerSessionPreferences proposal = null;
+ try {
+ proposal = new NetconfServerSessionPreferences(
+ createHelloMessage(sessionId, capabilityProvider), sessionId);
+ } catch (NetconfDocumentedException e) {
+ logger.error("Unable to create hello mesage for session {} with capability provider {}", sessionId,capabilityProvider);
+ throw new IllegalStateException(e);
+ }
NetconfServerSessionListenerFactory sessionListenerFactory = new NetconfServerSessionListenerFactory(
commitNotificationProducer, monitoringService,
sessionListenerFactory.getSessionListener(), connectionTimeoutMillis);
}
- private NetconfHelloMessage createHelloMessage(long sessionId, CapabilityProvider capabilityProvider) {
- return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), DEFAULT_CAPABILITIES), sessionId);
+ private NetconfHelloMessage createHelloMessage(long sessionId, CapabilityProvider capabilityProvider) throws NetconfDocumentedException {
+ return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), DEFAULT_BASE_CAPABILITIES), sessionId);
}
}
package org.opendaylight.controller.netconf.impl.mapping.operations;
-import java.io.InputStream;
-import java.util.Map;
-
+import com.google.common.base.Preconditions;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
+import java.io.InputStream;
public class DefaultCommit extends AbstractNetconfOperation {
@Override
public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
- Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false,
+ Preconditions.checkArgument(!subsequentOperation.isExecutionTermination(),
"Subsequent netconf operation expected by %s", this);
if (isCommitWithoutNotification(requestMessage)) {
logger.debug("Skipping commit notification");
} else {
// Send commit notification if commit was not issued by persister
- requestMessage = removePersisterAttributes(requestMessage);
+ removePersisterAttributes(requestMessage);
Element cfgSnapshot = getConfigSnapshot(operationRouter);
logger.debug("Config snapshot retrieved successfully {}", cfgSnapshot);
notificationProducer.sendCommitNotification("ok", cfgSnapshot, cap.getCapabilities());
return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(1);
}
- private Document removePersisterAttributes(Document message) {
- final Element documentElement = message.getDocumentElement();
- documentElement.removeAttribute(NOTIFY_ATTR);
- return message;
+ private void removePersisterAttributes(Document message) {
+ message.getDocumentElement().removeAttribute(NOTIFY_ATTR);
}
private boolean isCommitWithoutNotification(Document message) {
- XmlElement xmlElement = XmlElement.fromDomElementWithExpected(message.getDocumentElement(),
- XmlNetconfConstants.RPC_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ XmlElement xmlElement = null;
+ try {
+ xmlElement = XmlElement.fromDomElementWithExpected(message.getDocumentElement(),
+ XmlNetconfConstants.RPC_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ } catch (NetconfDocumentedException e) {
+ logger.trace("Commit operation is not valid due to {}",e);
+ return false;
+ }
String attr = xmlElement.getAttribute(NOTIFY_ATTR);
- if (attr == null || attr.equals(""))
+ if (attr == null || attr.equals("")){
return false;
- else if (attr.equals(Boolean.toString(false))) {
+ } else if (attr.equals(Boolean.toString(false))) {
logger.debug("Commit operation received with notify=false attribute {}", message);
return true;
} else {
getConfigMessage, null);
XmlElement dataElement;
- try {
- XmlElement xmlElement = XmlElement.fromDomElementWithExpected(responseDocument.getDocumentElement(),
- XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- dataElement = xmlElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY);
- } catch (IllegalArgumentException e) {
- final String msg = "Unexpected response from get-config operation";
- logger.warn(msg, e);
- Map<String, String> info = Maps.newHashMap();
- info.put(NetconfDocumentedException.ErrorTag.operation_failed.toString(), e.getMessage());
- throw new NetconfDocumentedException(msg, e, NetconfDocumentedException.ErrorType.application,
- NetconfDocumentedException.ErrorTag.operation_failed,
- NetconfDocumentedException.ErrorSeverity.error, info);
- }
-
+ XmlElement xmlElement = XmlElement.fromDomElementWithExpected(responseDocument.getDocumentElement(),
+ XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ dataElement = xmlElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY);
return dataElement.getDomElement();
}
package org.opendaylight.controller.netconf.impl.mapping.operations;
-import java.util.HashMap;
-import java.util.Map;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
+import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.collect.Maps;
+import java.util.Map;
public final class DefaultGetSchema extends AbstractLastNetconfOperation {
public static final String GET_SCHEMA = "get-schema";
protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
GetSchemaEntry entry;
- try {
- entry = new GetSchemaEntry(xml);
- } catch (final IllegalArgumentException e) {
- logger.warn("Error parsing xml", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(NetconfDocumentedException.ErrorTag.bad_attribute.name(), e.getMessage());
- throw new NetconfDocumentedException(e.getMessage(), e, NetconfDocumentedException.ErrorType.rpc,
- NetconfDocumentedException.ErrorTag.bad_attribute, NetconfDocumentedException.ErrorSeverity.error,
- errorInfo);
- } catch (final IllegalStateException e) {
- logger.warn("Error parsing xml", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(NetconfDocumentedException.ErrorTag.bad_attribute.name(), e.getMessage());
- throw new NetconfDocumentedException(e.getMessage(), e, NetconfDocumentedException.ErrorType.rpc,
- NetconfDocumentedException.ErrorTag.bad_attribute, NetconfDocumentedException.ErrorSeverity.error,
- errorInfo);
- }
+ entry = new GetSchemaEntry(xml);
String schema;
try {
private final String identifier;
private final Optional<String> version;
- GetSchemaEntry(XmlElement getSchemaElement) {
+ GetSchemaEntry(XmlElement getSchemaElement) throws NetconfDocumentedException {
getSchemaElement.checkName(GET_SCHEMA);
getSchemaElement.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING);
- XmlElement identifierElement = getSchemaElement.getOnlyChildElementWithSameNamespace(IDENTIFIER);
+ XmlElement identifierElement = null;
+ try {
+ identifierElement = getSchemaElement.getOnlyChildElementWithSameNamespace(IDENTIFIER);
+ } catch (MissingNameSpaceException e) {
+ logger.trace("Can't get identifier element as only child element with same namespace due to {}",e);
+ throw NetconfDocumentedException.wrap(e);
+ }
identifier = identifierElement.getTextContent();
Optional<XmlElement> versionElement = getSchemaElement
.getOnlyChildElementWithSameNamespaceOptionally(VERSION);
private ServiceRegistration<NetconfMonitoringService> regMonitoring;
@Override
- public void start(final BundleContext context) throws Exception {
+ public void start(final BundleContext context) {
InetSocketAddress address = NetconfConfigUtil.extractTCPNetconfAddress(context,
"TCP is not configured, netconf not available.", false);
}
@Override
- public void stop(final BundleContext context) throws Exception {
+ public void stop(final BundleContext context) {
logger.info("Shutting down netconf because YangStoreService service was removed");
commitNot.close();
@Override
public void onSessionUp(NetconfManagementSession session) {
logger.debug("Session {} up", session);
- Preconditions.checkState(sessions.contains(session) == false, "Session %s was already added", session);
+ Preconditions.checkState(!sessions.contains(session), "Session %s was already added", session);
sessions.add(session);
}
import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession;
import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCommit;
import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultGetSchema;
+import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation;
import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStartExi;
import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStopExi;
-import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation;
import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
+import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
for (NetconfOperationService netconfOperationService : netconfOperationServiceSnapshot.getServices()) {
final Set<NetconfOperation> netOpsFromService = netconfOperationService.getNetconfOperations();
for (NetconfOperation netconfOperation : netOpsFromService) {
- Preconditions.checkState(result.contains(netconfOperation) == false,
+ Preconditions.checkState(!result.contains(netconfOperation),
"Netconf operation %s already present", netconfOperation);
result.add(netconfOperation);
}
Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly");
NetconfOperationExecution netconfOperationExecution;
- String messageAsString = XmlUtil.toString(message);
+ String messageAsString = "";
try {
+ messageAsString = XmlUtil.toString(message);
netconfOperationExecution = getNetconfOperationWithHighestPriority(message, session);
} catch (IllegalArgumentException | IllegalStateException e) {
logger.warn("Unable to handle rpc {} on session {}", messageAsString, session, e);
}
private NetconfOperationExecution getNetconfOperationWithHighestPriority(
- Document message, NetconfServerSession session) {
+ Document message, NetconfServerSession session) throws NetconfDocumentedException {
- TreeMap<HandlingPriority, NetconfOperation> sortedByPriority = getSortedNetconfOperationsWithCanHandle(
+ NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority = getSortedNetconfOperationsWithCanHandle(
message, session);
Preconditions.checkArgument(sortedByPriority.isEmpty() == false,
}
private TreeMap<HandlingPriority, NetconfOperation> getSortedNetconfOperationsWithCanHandle(Document message,
- NetconfServerSession session) {
+ NetconfServerSession session) throws NetconfDocumentedException {
TreeMap<HandlingPriority, NetconfOperation> sortedPriority = Maps.newTreeMap();
for (NetconfOperation netconfOperation : allNetconfOperations) {
if (netconfOperation instanceof DefaultNetconfOperation) {
((DefaultNetconfOperation) netconfOperation).setNetconfSession(session);
}
- if (handlingPriority.equals(HandlingPriority.CANNOT_HANDLE) == false) {
+ if (!handlingPriority.equals(HandlingPriority.CANNOT_HANDLE)) {
- Preconditions.checkState(sortedPriority.containsKey(handlingPriority) == false,
+ Preconditions.checkState(!sortedPriority.containsKey(handlingPriority),
"Multiple %s available to handle message %s with priority %s",
NetconfOperation.class.getName(), message, handlingPriority);
sortedPriority.put(handlingPriority, netconfOperation);
return sortedPriority;
}
+ public static final NetconfOperationChainedExecution EXECUTION_TERMINATION_POINT = new NetconfOperationChainedExecution() {
+ @Override
+ public boolean isExecutionTermination() {
+ return true;
+ }
+
+ @Override
+ public Document execute(Document requestMessage) throws NetconfDocumentedException {
+ throw new NetconfDocumentedException("This execution represents the termination point in operation execution and cannot be executed itself",
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
+ };
+
private static class NetconfOperationExecution implements NetconfOperationChainedExecution {
private final NetconfOperation netconfOperation;
private NetconfOperationChainedExecution subsequentExecution;
}
public static NetconfOperationExecution createExecutionChain(
- TreeMap<HandlingPriority, NetconfOperation> sortedByPriority, HandlingPriority handlingPriority) {
+ NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority, HandlingPriority handlingPriority) {
NetconfOperation netconfOperation = sortedByPriority.get(handlingPriority);
HandlingPriority subsequentHandlingPriority = sortedByPriority.lowerKey(handlingPriority);
package org.opendaylight.controller.netconf.impl;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+
+import java.io.DataOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
import org.opendaylight.controller.netconf.mapping.api.Capability;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.controller.netconf.util.messages.NetconfStartExiMessage;
import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
public class ConcurrentClientsTest {
SessionIdProvider idProvider = new SessionIdProvider();
hashedWheelTimer = new HashedWheelTimer();
+
NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService());
commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
-
-
NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory);
dispatch = new NetconfServerDispatcher(serverChannelInitializer, nettyGroup, nettyGroup);
return Sets.<NetconfOperation> newHashSet(new NetconfOperation() {
@Override
public HandlingPriority canHandle(Document message) {
- return HandlingPriority.getHandlingPriority(Integer.MAX_VALUE);
+ return XmlUtil.toString(message).contains(NetconfStartExiMessage.START_EXI) ?
+ HandlingPriority.CANNOT_HANDLE :
+ HandlingPriority.HANDLE_WITH_MAX_PRIORITY;
}
@Override
commitNot.close();
}
- @Test
+ @Test(timeout = 30 * 1000)
public void multipleClients() throws Exception {
List<TestingThread> threads = new ArrayList<>();
}
}
- @Test
+ @Test(timeout = 30 * 1000)
public void synchronizationTest() throws Exception {
new BlockingThread("foo").run2();
}
- @Test
+ @Test(timeout = 30 * 1000)
public void multipleBlockingClients() throws Exception {
List<BlockingThread> threads = new ArrayList<>();
for (int i = 0; i < CONCURRENCY; i++) {
+++ /dev/null
-
-#24
-<rpc message-id="101" xm
-#28
-lns="urn:ietf:params:xml:ns:
-#2
-ne
-#33
-tconf:base:1.0">
- <my-own-method
-#3
- xm
-#13
-lns="http://e
-#34
-xample.net/me/my-own/1.0">
- <my
-#8
--first-p
-#21
-arameter>14</my-first
-#26
--parameter>
- <another-p
-#23
-arameter>fred</another-
-#31
-parameter>
- </my-own-method>
- <
-#2
-/r
-#3
-pc>
-##
+++ /dev/null
-
-#22
-<rpc message-id="101"
-#24
-xmlns="urn:ietf:params:x
-#15
-ml:ns:netconf:b
-#54
-ase:1.0">
- <get-config>
- <source>
- <r
-#2
-un
-#9
-ning/>
-
-#18
- </source> <fi
-#33
-lter type="subtree">
- <top x
-#4
-mlns
-#31
-="http://example.com/schema/1.2
-#15
-/config">
-
-#19
- <users>
-
-#8
- <us
-#3
-er/
-#5
->
-
-#77
- </users>
- </top>
- </filter>
- </g
-#17
-et-config>
-</rpc>
-##
+++ /dev/null
-
-#43
-<rpc message-id="101" xmlns="urn:ietf:param
-#14
-s:xml:ns:netco
-#14
-nf:base:1.0">
-
-#26
-<get-config>
- <source>
-
-#35
- <running/>
- </source>
-
-#39
- <filter type="subtree">
- <
-#40
-top xmlns="http://example.com/schema/1.2
-#26
-/config">
- <users>
-
-#36
- <user>
- <name>f
-#56
-red</name>
- </user>
- </users>
-
-#28
- </top>
- </fil
-#1
-t
-#28
-er>
- </get-config>
- </rpc>
-##
+++ /dev/null
-
-#17
-<rpc message-id="
-#25
-101" xmlns="urn:ietf:para
-#19
-ms:xml:ns:netconf:b
-#3
-ase
-#19
-:1.0">
- <get-confi
-#61
-g>
- <source>
- <running/>
- </source>
-
-#43
- <filter type="subtree">
- <!-- requ
-#13
-est a text ve
-#22
-rsion of the configura
-#9
-tion -->
-
-#16
- <config-text
-#45
-xmlns="http://example.com/text/1.2/config"/>
-
-#22
- </filter>
- </
-#18
-get-config>
-</rpc>
-##
+++ /dev/null
-
-#43
-<rpc message-id="101" xmlns="urn:ietf:param
-#41
-s:xml:ns:netconf:base:1.0">
- <edit-confi
-#29
-g>
- <target>
- <ru
-#13
-nning/>
- <
-#4
-/tar
-#18
-get>
- <config>
-
-#41
- <top xmlns="http://example.com/schema/1
-#32
-.2/config">
- <interface>
-
-#29
- <name>Ethernet0/0</na
-#30
-me>
- <mtu>1500</mtu>
-
-#61
-</interface>
- </top>
- </config>
- </e
-#9
-dit-confi
-#9
-g>
-</rpc>
-##
+++ /dev/null
-curl http://localhost:17777/jolokia/read/org.opendaylight.controller:instanceName=fixed1,type=ConfigBean,interfaceName=testing-threadpool | jsonpp
-{
- "request": {
- "mbean": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean",
- "type": "read"
- },
- "status": 200,
- "timestamp": 1362416252,
- "value": {
- "ExportedInterfaces": [
- "testing-threadpool",
- "modifiable-threadpool"
- ],
- "ImplementationName": "fixed",
- "ThreadCount": 10,
- "TriggerNewInstanceCreation": false
- }
-}
\ No newline at end of file
+++ /dev/null
-$ curl 'http://localhost:17777/jolokia/exec/org.opendaylight.controller:type=ConfigRegistry/lookupConfigBeans()' | jsonpp
-{
- "request": {
- "mbean": "org.opendaylight.controller:type=ConfigRegistry",
- "operation": "lookupConfigBeans()",
- "type": "exec"
- },
- "status": 200,
- "timestamp": 1362417043,
- "value": [
- {
- "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=modifiable-threadpool,type=ConfigBean"
- },
- {
- "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean"
- }
- ]
-}
+++ /dev/null
-<rpc message-id="104"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <commit/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="102"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <lock>
- <target>
- <candidate/>
- </target>
- </lock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="101"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <lock>
- <target>
- <running/>
- </target>
- </lock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="103"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <default-operation>none</default-operation>
- <test-option>test-then-set</test-option>
- <error-option>stop-on-error</error-option>
- <nc:config
- xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- xmlns="uri-for-my-data-model-namespace">
- <some-existing-node>
- <my-new-node nc:operation="create">
- <my-new-leaf>7</my-new-leaf>
- </my-new-node>
- </some-existing-node>
- </nc:config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="105"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unlock>
- <target>
- <candidate/>
- </target>
- </unlock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="106"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unlock>
- <target>
- <running/>
- </target>
- </unlock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <rpc-error>
- <error-type>rpc</error-type>
- <error-tag>missing-attribute</error-tag>
- <error-severity>error</error-severity>
- <error-info>
- <bad-attribute>message-id</bad-attribute>
- <bad-element>rpc</bad-element>
- </error-info>
- </rpc-error>
-</rpc-reply>
+++ /dev/null
-{
- "value":null,
- "status":200,
- "request": {
- "type":"exec",
- "mbean":"java.util.logging:type=Logging",
- "operation":"setLoggerLevel",
- "arguments":["global","INFO"]
- }
-}
\ No newline at end of file
+++ /dev/null
-<jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>EXEC</type>
- <operation>lookupConfigBeans</operation>
- <arguments>abc,bcd.aas</arguments>
- <arguments>64</arguments>
-</jmxbean>
\ No newline at end of file
+++ /dev/null
-<jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>EXEC</type>
- <operation>lookupConfigBeans</operation>
- <arguments>
- <elements>22</elements>
- <elements>69</elements>
- </arguments>
-</jmxbean>
\ No newline at end of file
+++ /dev/null
-<jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>EXEC</type>
- <operation>lookupConfigBeans</operation>
- <arguments>
- <map>
- <topology-registry>single</topology-registry>
- <bgp-update>mock</bgp-update>
- </map>
- <array>2</array>
- <array>22</array>
- <anotherArg>arg</anotherArg>
- </arguments>
-</jmxbean>
\ No newline at end of file
+++ /dev/null
-<config>
- <jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>EXEC</type>
- <operation>lookupConfigBeans</operation>
- <attribute>abc,bcd.aas</attribute>
- <attribute>22</attribute>
- </jmxbean>
- <jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>WRITE</type>
- <attribute>attribute</attribute>
- <value>22</value>
- </jmxbean>
- <jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>EXEC</type>
- <operation>lookupConfigBeans</operation>
- <arguments>
- <map>
- <topology-registry>single</topology-registry>
- <bgp-update>mock</bgp-update>
- </map>
- <array>2</array>
- <array>22</array>
- <anotherArg>arg</anotherArg>
- </arguments>
- </jmxbean>
-</config>
\ No newline at end of file
+++ /dev/null
-<jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>WRITE</type>
- <attribute>attribute</attribute>
- <value>22</value>
-</jmxbean>
\ No newline at end of file
+++ /dev/null
-<jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>WRITE</type>
- <attribute>attribute</attribute>
- <value>22</value>
- <value>222</value>
- <value>223</value>
-</jmxbean>
\ No newline at end of file
+++ /dev/null
-<jmxbean>
- <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
- <type>WRITE</type>
- <attribute>setAtr</attribute>
- <value>
- <abc>1</abc>
- <bcd>2</bcd>
- </value>
-</jmxbean>
+++ /dev/null
-{
- "timestamp":1362488209,
- "status":200,
- "request":{
- "mbean":"org.opendaylight.controller:type=ConfigRegistry",
- "attribute":"AvailableInterfacesAndImplementations",
- "type":"read"
- },
- "value":{
- "topology-registry":[
- "single"
- ],
- "bgp-update":[
- "mock",
- "bgp-impl"
- ],
- "positioning-service":[
- "combine",
- "onehop",
- "ondemand",
- "pxe",
- "precompute"
- ],
- "serializer":[
- "serializer-impl"
- ],
- "network-topology-factory":[
- "mock-xml",
- "bgp-network-topology-factory",
- "transient"
- ],
- "dwe-topology":[
- "ebgp",
- "defaultmetric",
- "igp",
- "network"
- ],
- "thread-factory":[
- "naming-thread-factory"
- ],
- "bgp-parser":[
- "parser"
- ],
- "pcep-dispatcher":[
- "dispatcher"
- ],
- "threadpool":[
- "flexible",
- "fixed",
- "scheduled"
- ],
- "scheduled-threadpool":[
- "scheduled"
- ],
- "positioning-onehop":[
- "onehop"
- ],
- "bgp-dispatcher":[
- "bgp-dispatcher-impl"
- ],
- "cost-combiner":[
- "pxe"
- ],
- "apsp-provider":[
- "jgrapht",
- "parallel",
- "single-threaded"
- ],
- "topology":[
- "ebgp",
- "defaultmetric",
- "igp",
- "network"
- ],
- "soap-resource":[
- "positioning-adaptor-pxe"
- ],
- "database-provider-factory":[
- "transient"
- ],
- "bgp-proposal-checker":[
- "bgp-proposal-checker-impl"
- ],
- "bgp-proposal":[
- "bgp-proposal-impl"
- ],
- "listenable-network-topology-factory":[
- "transient"
- ],
- "event-bus":[
- "sync",
- "async"
- ],
- "topology-registry-provider":[
- "single"
- ],
- "topology-provider-factory":[
- "transient"
- ],
- "rest-resource":[
- "topology-resource-holder",
- "alto-resource-holder",
- "topology-visual-holder",
- "network-resource-holder",
- "path-resource-holder"
- ],
- "listenable-database-provider-factory":[
- "transient"
- ],
- "topology-validator":[
- "accept-all",
- "threshold"
- ],
- "replicator":[
- "replicator-impl"
- ],
- "server":[
- "soap",
- "rest"
- ],
- "combiner-pxe":[
- "pxe"
- ],
- "rest":[
- "rest"
- ],
- "soap":[
- "soap"
- ],
- "path-service":[
- "cariden"
- ]
- }
-}
\ No newline at end of file
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,NetconfITTest.getModuleFactoriesS().toArray(
new ModuleFactory[0])));
NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray(
new ModuleFactory[0])));
NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
import org.opendaylight.controller.netconf.StubUserManager;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray(
new ModuleFactory[0])));
loadMessages();
}
}
- private void assertIsOK(final Document rpcReply) {
+ private void assertIsOK(final Document rpcReply) throws NetconfDocumentedException {
assertEquals("rpc-reply", rpcReply.getDocumentElement().getLocalName());
assertEquals("ok", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName());
}
- private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException {
+ private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException, NetconfDocumentedException {
return assertGetConfigWorks(netconfClient, this.getConfig);
}
private Document assertGetConfigWorks(final TestingNetconfClient netconfClient, final NetconfMessage getConfigMessage)
- throws InterruptedException, ExecutionException, TimeoutException {
+ throws InterruptedException, ExecutionException, TimeoutException, NetconfDocumentedException {
final NetconfMessage rpcReply = netconfClient.sendMessage(getConfigMessage);
assertNotNull(rpcReply);
assertEquals("data", XmlElement.fromDomDocument(rpcReply.getDocument()).getOnlyChildElement().getName());
import org.mockito.Mock;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, NetconfITTest.getModuleFactoriesS().toArray(
new ModuleFactory[0])));
monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-public class HandlingPriority implements Comparable<HandlingPriority> {
+public final class HandlingPriority implements Comparable<HandlingPriority> {
public static final HandlingPriority CANNOT_HANDLE = new HandlingPriority();
public static final HandlingPriority HANDLE_WITH_DEFAULT_PRIORITY = new HandlingPriority(Integer.MIN_VALUE);
@Override
public int compareTo(HandlingPriority o) {
- if (this == o)
+ if (this == o){
return 0;
- if (this == CANNOT_HANDLE)
+ }
+ if (this.equals(CANNOT_HANDLE)){
return -1;
- if (o == CANNOT_HANDLE)
+ }
+ if (o.equals(CANNOT_HANDLE)){
return 1;
+ }
- if (priority > o.priority)
+ if (priority > o.priority){
return 1;
- if (priority == o.priority)
+ }
+ if (priority.equals(o.priority)){
return 0;
- if (priority < o.priority)
+ }
+ if (priority < o.priority){
return -1;
-
+ }
throw new IllegalStateException("Unexpected state");
}
@Override
public boolean equals(Object o) {
- if (this == o)
+ if (this == o){
return true;
- if (!(o instanceof HandlingPriority))
+ }
+ if (!(o instanceof HandlingPriority)){
return false;
+ }
HandlingPriority that = (HandlingPriority) o;
- if (priority != null ? !priority.equals(that.priority) : that.priority != null)
+ if (priority != null ? !priority.equals(that.priority) : that.priority != null){
return false;
+ }
return true;
}
* @param requestMessage
* @return
*/
- HandlingPriority canHandle(Document requestMessage);
+ HandlingPriority canHandle(Document message) throws NetconfDocumentedException;
/**
* Execute current netconf operation and trigger execution of subsequent
org.opendaylight.controller.netconf.api,
org.opendaylight.controller.netconf.mapping.api,
org.opendaylight.controller.netconf.util.mapping,
+ org.opendaylight.controller.netconf.util.exception,
org.osgi.framework,
org.slf4j,
org.w3c.dom,
*/
package org.opendaylight.controller.netconf.monitoring;
-import java.util.Map;
-
+import com.google.common.collect.Maps;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
+import java.util.Map;
public class Get extends AbstractNetconfOperation {
this.netconfMonitor = netconfMonitor;
}
- private Element getPlaceholder(Document innerResult) {
+ private Element getPlaceholder(Document innerResult) throws NetconfDocumentedException {
try {
- XmlElement rootElement = XmlElement.fromDomElementWithExpected(innerResult.getDocumentElement(),
- XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ XmlElement rootElement = null;
+ rootElement = XmlElement.fromDomElementWithExpected(innerResult.getDocumentElement(),
+ XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.RFC4741_TARGET_NAMESPACE);
return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
} catch (RuntimeException e) {
throw new IllegalArgumentException(String.format(
@Override
public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation)
throws NetconfDocumentedException {
- Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false,
- "Subsequent netconf operation expected by %s", this);
+ if (subsequentOperation.isExecutionTermination()){
+ throw new NetconfDocumentedException(String.format("Subsequent netconf operation expected by %s", this),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
try {
Document innerResult = subsequentOperation.execute(requestMessage);
*/
package org.opendaylight.controller.netconf.monitoring;
-public class MonitoringConstants {
+public final class MonitoringConstants {
+ private MonitoringConstants(){
+ // not called - private constructor for utility class
+ }
public static final String MODULE_NAME = "ietf-netconf-monitoring";
public static final String MODULE_REVISION = "2010-10-04";
private NetconfMonitoringServiceTracker monitor;
@Override
- public void start(final BundleContext context) throws Exception {
+ public void start(final BundleContext context) {
monitor = new NetconfMonitoringServiceTracker(context);
monitor.open();
}
@Override
- public void stop(final BundleContext context) throws Exception {
+ public void stop(final BundleContext context) {
if(monitor!=null) {
try {
monitor.close();
*/
package org.opendaylight.controller.netconf.monitoring.osgi;
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.HashSet;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
import java.util.List;
import java.util.Set;
-
import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
import org.opendaylight.controller.netconf.mapping.api.Capability;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
import org.opendaylight.controller.netconf.monitoring.Get;
import org.opendaylight.controller.netconf.monitoring.MonitoringConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
public class NetconfMonitoringOperationService implements NetconfOperationService {
- public static final HashSet<Capability> CAPABILITIES = Sets.<Capability>newHashSet(new Capability() {
+ public static final Set<Capability> CAPABILITIES = Sets.<Capability>newHashSet(new Capability() {
@Override
public String getCapabilityUri() {
this.monitor = monitor;
}
- private static String readSchema() {
- String schemaLocation = "/META-INF/yang/ietf-netconf-monitoring.yang";
- URL resource = Schemas.class.getClassLoader().getResource(schemaLocation);
- Preconditions.checkNotNull(resource, "Unable to read schema content from %s", schemaLocation);
- File file = new File(resource.getFile());
- try {
- return Files.toString(file, Charsets.UTF_8);
- } catch (IOException e) {
- throw new RuntimeException("Unable to load schema from " + schemaLocation, e);
- }
- }
-
@Override
public Set<Capability> getCapabilities() {
return CAPABILITIES;
*/
package org.opendaylight.controller.netconf.ssh;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.util.concurrent.atomic.AtomicLong;
-import javax.annotation.concurrent.ThreadSafe;
import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
import org.opendaylight.controller.netconf.ssh.threads.SocketThread;
import org.opendaylight.controller.usermanager.IUserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.concurrent.ThreadSafe;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.util.concurrent.atomic.AtomicLong;
+
@ThreadSafe
-public class NetconfSSHServer implements Runnable {
+public final class NetconfSSHServer implements Runnable {
private ServerSocket ss = null;
private static final Logger logger = LoggerFactory.getLogger(NetconfSSHServer.class);
private final AuthProvider authProvider;
private boolean up = false;
- private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws Exception{
+ private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws IllegalStateException, IOException {
logger.trace("Creating SSH server socket on port {}",serverPort);
this.ss = new ServerSocket(serverPort);
if (!ss.isBound()){
- throw new Exception("Socket can't be bound to requested port :"+serverPort);
+ throw new IllegalStateException("Socket can't be bound to requested port :"+serverPort);
}
logger.trace("Server socket created.");
this.clientAddress = clientAddress;
this.up = true;
}
- public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws Exception {
+ public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws IllegalStateException, IOException {
return new NetconfSSHServer(serverPort, clientAddress,authProvider);
}
- public void stop() throws Exception {
+ public void stop() throws IOException {
up = false;
logger.trace("Closing SSH server socket.");
ss.close();
try {
SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(),authProvider);
} catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ logger.error("Exception occurred during socket thread initialization {}",e);
}
}
}
}
@Override
- public boolean authenticated(String username, String password) throws Exception {
+ public boolean authenticated(String username, String password) {
if (AuthProvider.um == null) {
- throw new Exception("No usermanager service available.");
+ throw new IllegalStateException("No usermanager service available.");
}
AuthResultEnum authResult = AuthProvider.um.authenticate(username, password);
return authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC);
public interface AuthProviderInterface {
- public boolean authenticated(String username, String password) throws Exception;
+ public boolean authenticated(String username, String password) throws IllegalStateException;
public char[] getPEMAsCharArray() throws Exception;
public void removeUserManagerService();
public void addUserManagerService(IUserManager userManagerService);
private IUserManager iUserManager;
private BundleContext context = null;
- ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
+ private ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
@Override
public IUserManager addingService(ServiceReference<IUserManager> reference) {
logger.trace("Service {} added, let there be SSH bridge.", reference);
@Override
- public void start(BundleContext context) throws Exception {
+ public void start(BundleContext context) {
this.context = context;
listenForManagerService();
}
@Override
- public void stop(BundleContext context) throws Exception {
+ public void stop(BundleContext context) throws IOException {
if (server != null){
server.stop();
logger.trace("Netconf SSH bridge is down ...");
}
}
- private void startSSHServer() throws Exception {
+ private void startSSHServer() throws IllegalStateException, IOException {
logger.trace("Starting netconf SSH bridge.");
Optional<InetSocketAddress> sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE);
InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context,
String path = NetconfConfigUtil.getPrivateKeyPath(context);
path = path.replace("\\", "/"); // FIXME: shouldn't this convert lines to system dependent path separator?
if (path.equals("")){
- throw new Exception("Missing netconf.ssh.pk.path key in configuration file.");
+ throw new IllegalStateException("Missing netconf.ssh.pk.path key in configuration file.");
}
File privateKeyFile = new File(path);
- String privateKeyPEMString;
+ String privateKeyPEMString = null;
if (privateKeyFile.exists() == false) {
// generate & save to file
- privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile);
+ try {
+ privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile);
+ } catch (Exception e) {
+ logger.error("Exception occured while generating PEM string {}",e);
+ }
} else {
// read from file
try (FileInputStream fis = new FileInputStream(path)) {
throw new IllegalStateException("Error reading RSA key from file " + path);
}
}
- AuthProvider authProvider = new AuthProvider(iUserManager, privateKeyPEMString);
+ AuthProvider authProvider = null;
+ try {
+ authProvider = new AuthProvider(iUserManager, privateKeyPEMString);
+ } catch (Exception e) {
+ logger.error("Error instantiating AuthProvider {}",e);
+ }
this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
Thread serverThread = new Thread(server,"netconf SSH server thread");
logger.trace("Netconf SSH bridge up and running.");
} else {
logger.trace("No valid connection configuration for SSH bridge found.");
- throw new Exception("No valid connection configuration for SSH bridge found.");
+ throw new IllegalStateException("No valid connection configuration for SSH bridge found.");
}
}
- private void onUserManagerFound(IUserManager userManager) throws Exception{
+ private void onUserManagerFound(IUserManager userManager) throws IOException {
if (server!=null && server.isUp()){
server.addUserManagerService(userManager);
} else {
if (netconf_ssh_input != null) {
netconf_ssh_input.join();
}
- } catch (InterruptedException e) {
+ } catch (InterruptedException e1) {
Thread.currentThread().interrupt();
- logger.error("netconf_ssh_input join error ", e);
+ logger.error("netconf_ssh_input join error ", e1);
}
try {
if (netconf_ssh_output != null) {
netconf_ssh_output.join();
}
- } catch (InterruptedException e) {
+ } catch (InterruptedException e2) {
Thread.currentThread().interrupt();
- logger.error("netconf_ssh_output join error ", e);
+ logger.error("netconf_ssh_output join error ", e2);
}
}
} else {
org.opendaylight.controller.netconf.util.mapping,
org.opendaylight.controller.netconf.util.messages,
org.opendaylight.controller.netconf.util.handler,
- org.opendaylight.controller.netconf.util.handler.*,</Export-Package>
+ org.opendaylight.controller.netconf.util.handler.*,
+ org.opendaylight.controller.netconf.util.exception,</Export-Package>
<Import-Package>com.google.common.base,
com.google.common.collect,
ch.ethz.ssh2,
@Override
public ChannelFuture sendMessage(final NetconfMessage netconfMessage) {
final ChannelFuture future = channel.writeAndFlush(netconfMessage);
- if (delayedEncoder !=null) {
+ if (delayedEncoder != null) {
replaceMessageEncoder(delayedEncoder);
delayedEncoder = null;
}
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.Promise;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.NetconfSessionListener;
import org.opendaylight.controller.netconf.api.NetconfSessionPreferences;
}
@Override
- protected void handleMessage(NetconfHelloMessage netconfMessage) {
- S session = getSessionForHelloMessage(netconfMessage);
+ protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
+ S session = getSessionForHelloMessage(netconfMessage) ;
negotiationSuccessful(session);
}
- protected final S getSessionForHelloMessage(NetconfHelloMessage netconfMessage) {
+ protected final S getSessionForHelloMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
Preconditions.checkNotNull(netconfMessage, "netconfMessage");
final Document doc = netconfMessage.getDocument();
return channel.pipeline().replace(handlerKey, handlerKey, decoder);
}
- protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message);
+ protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException;
protected synchronized void changeState(final State newState) {
logger.debug("Changing state from : {} to : {}", state, newState);
package org.opendaylight.controller.netconf.util;
import com.google.common.base.Preconditions;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
return (doc == null) ? null : new NetconfMessage(doc);
}
- public static Document checkIsMessageOk(NetconfMessage responseMessage) {
- return checkIsMessageOk(responseMessage.getDocument());
- }
-
- public static Document checkIsMessageOk(Document response) {
+ public static Document checkIsMessageOk(Document response) throws NetconfDocumentedException {
XmlElement element = XmlElement.fromDomDocument(response);
Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
element = element.getOnlyChildElement();
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.util.exception;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class MissingNameSpaceException extends NetconfDocumentedException {
+
+ public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity) {
+ this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
+ }
+
+ public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
+ super(message,errorType,errorTag,errorSeverity,errorInfo);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.util.exception;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class UnexpectedElementException extends NetconfDocumentedException {
+
+ public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity) {
+ this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
+ }
+
+ public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
+ super(message,errorType,errorTag,errorSeverity,errorInfo);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.util.exception;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class UnexpectedNamespaceException extends NetconfDocumentedException {
+
+ public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity) {
+ this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
+ }
+
+ public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
+ final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
+ super(message,errorType,errorTag,errorSeverity,errorInfo);
+ }
+}
}
@Override
- protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
+ protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
while (msg.readableBytes() > chunkSize) {
ByteBuf chunk = Unpooled.buffer(chunkSize);
chunk.writeBytes(createChunkHeader(chunkSize));
public class EOMFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf> {
@Override
- protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
+ protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
out.writeBytes(msg);
out.writeBytes(NetconfMessageConstants.END_OF_MESSAGE);
}
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.MessageToByteEncoder;
-public class FramingMechanismHandlerFactory {
+public final class FramingMechanismHandlerFactory {
private static final Logger logger = LoggerFactory.getLogger(FramingMechanismHandlerFactory.class);
- private FramingMechanismHandlerFactory() {}
+ private FramingMechanismHandlerFactory() {
+ // not called - private constructor for utility class
+ }
public static MessageToByteEncoder<ByteBuf> createHandler(FramingMechanism framingMechanism) {
logger.debug("{} framing mechanism was selected.", framingMechanism);
public class NetconfChunkAggregator extends ByteToMessageDecoder {
private final static Logger logger = LoggerFactory.getLogger(NetconfChunkAggregator.class);
+ private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM = "Got byte {} while waiting for {}";
+ private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM = "Got byte {} while waiting for {}-{}";
public static final int DEFAULT_MAXIMUM_CHUNK_SIZE = 16 * 1024 * 1024;
private static enum State {
private long chunkSize;
private CompositeByteBuf chunk;
+ private void checkNewLine(byte b,String errorMessage){
+ if (b != '\n') {
+ logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'\n');
+ throw new IllegalStateException(errorMessage);
+ }
+ }
+
+ private void checkHash(byte b,String errorMessage){
+ if (b != '#') {
+ logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'#');
+ throw new IllegalStateException(errorMessage);
+ }
+ }
+
+ private void checkChunkSize(){
+ if (chunkSize > maxChunkSize) {
+ logger.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize);
+ throw new IllegalStateException("Maximum chunk size exceeded");
+ }
+
+ }
@Override
- protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws IllegalStateException {
while (in.isReadable()) {
switch (state) {
case HEADER_ONE:
{
final byte b = in.readByte();
- if (b != '\n') {
- logger.debug("Got byte {} while waiting for {}", b, (byte)'\n');
- throw new IllegalStateException("Malformed chunk header encountered (byte 0)");
- }
+ checkNewLine(b, "Malformed chunk header encountered (byte 0)");
state = State.HEADER_TWO;
case HEADER_TWO:
{
final byte b = in.readByte();
- if (b != '#') {
- logger.debug("Got byte {} while waiting for {}", b, (byte)'#');
- throw new IllegalStateException("Malformed chunk header encountered (byte 1)");
- }
+ checkHash(b, "Malformed chunk header encountered (byte 1)");
state = State.HEADER_LENGTH_FIRST;
break;
}
if (b < '0' || b > '9') {
- logger.debug("Got byte {} while waiting for {}-{}", b, (byte)'0', (byte)'9');
+ logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'0', (byte)'9');
throw new IllegalStateException("Invalid chunk size encountered");
}
chunkSize *= 10;
chunkSize += b - '0';
-
- if (chunkSize > maxChunkSize) {
- logger.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize);
- throw new IllegalStateException("Maximum chunk size exceeded");
- }
+ checkChunkSize();
break;
}
case DATA:
in.discardReadBytes();
return;
}
-
aggregateChunks(in.readBytes((int) chunkSize));
state = State.FOOTER_ONE;
break;
case FOOTER_ONE:
{
final byte b = in.readByte();
- if (b != '\n') {
- logger.debug("Got byte {} while waiting for {}", b, (byte)'\n');
- throw new IllegalStateException("Malformed chunk footer encountered (byte 0)");
- }
-
+ checkNewLine(b,"Malformed chunk footer encountered (byte 0)");
state = State.FOOTER_TWO;
chunkSize = 0;
break;
case FOOTER_TWO:
{
final byte b = in.readByte();
-
- if (b != '#') {
- logger.debug("Got byte {} while waiting for {}", b, (byte)'#');
- throw new IllegalStateException("Malformed chunk footer encountered (byte 1)");
- }
-
+ checkHash(b,"Malformed chunk footer encountered (byte 1)");
state = State.FOOTER_THREE;
break;
}
// In this state, either header-of-new-chunk or message-end is expected
// Depends on the next character
- if (isHeaderLengthFirst(b)) {
- // Extract header length#1 from new chunk
- chunkSize = processHeaderLengthFirst(b);
- // Proceed with next chunk processing
- state = State.HEADER_LENGTH_OTHER;
- } else if (b == '#') {
- state = State.FOOTER_FOUR;
- } else {
- logger.debug("Got byte {} while waiting for {} or {}-{}", b, (byte) '#', (byte) '1', (byte) '9');
- throw new IllegalStateException("Malformed chunk footer encountered (byte 2)");
- }
+ extractNewChunkOrMessageEnd(b);
break;
}
case FOOTER_FOUR:
{
final byte b = in.readByte();
- if (b != '\n') {
- logger.debug("Got byte {} while waiting for {}", b, (byte)'\n');
- throw new IllegalStateException("Malformed chunk footer encountered (byte 3)");
- }
-
+ checkNewLine(b,"Malformed chunk footer encountered (byte 3)");
state = State.HEADER_ONE;
out.add(chunk);
chunk = null;
in.discardReadBytes();
}
+ private void extractNewChunkOrMessageEnd(byte b) {
+ if (isHeaderLengthFirst(b)) {
+ // Extract header length#1 from new chunk
+ chunkSize = processHeaderLengthFirst(b);
+ // Proceed with next chunk processing
+ state = State.HEADER_LENGTH_OTHER;
+ } else if (b == '#') {
+ state = State.FOOTER_FOUR;
+ } else {
+ logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte) '#', (byte) '1', (byte) '9');
+ throw new IllegalStateException("Malformed chunk footer encountered (byte 2)");
+ }
+ }
+
private void initChunk() {
chunk = Unpooled.compositeBuffer();
}
}
private static int processHeaderLengthFirst(byte b) {
- if (isHeaderLengthFirst(b) == false) {
- logger.debug("Got byte {} while waiting for {}-{}", b, (byte)'1', (byte)'9');
+ if (!isHeaderLengthFirst(b)) {
+ logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'1', (byte)'9');
throw new IllegalStateException("Invalid chunk size encountered (byte 0)");
}
private final static Logger logger = LoggerFactory.getLogger(NetconfEOMAggregator.class);
@Override
- protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
int index = indexOfSequence(in, NetconfMessageConstants.END_OF_MESSAGE);
if (index == -1) {
logger.debug("Message is not complete, read again.");
*/
package org.opendaylight.controller.netconf.util.handler;
-import java.io.ByteArrayInputStream;
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufOutputStream;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
import java.io.OutputStream;
-
+import javax.xml.transform.Transformer;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.openexi.sax.Transmogrifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
-
-import com.google.common.base.Preconditions;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufOutputStream;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
public final class NetconfMessageToEXIEncoder extends MessageToByteEncoder<NetconfMessage> {
private static final Logger LOG = LoggerFactory.getLogger(NetconfMessageToEXIEncoder.class);
- //private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
+ private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
private final NetconfEXICodec codec;
public NetconfMessageToEXIEncoder(final NetconfEXICodec codec) {
final Transmogrifier transmogrifier = codec.getTransmogrifier();
transmogrifier.setOutputStream(os);
- // FIXME transformer not working, see EXILibTest
- transmogrifier.encode(new InputSource(new ByteArrayInputStream(XmlUtil.toString(msg.getDocument()).getBytes())));
- //final Transformer transformer = saxTransformerFactory.newTransformer();
- //transformer.transform(new DOMSource(msg.getDocument()), new SAXResult(transmogrifier.getSAXTransmogrifier()));
+ final Transformer transformer = saxTransformerFactory.newTransformer();
+ transformer.transform(new DOMSource(msg.getDocument()), new SAXResult(transmogrifier.getSAXTransmogrifier()));
}
}
}
import io.netty.handler.codec.ByteToMessageDecoder;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
+import org.xml.sax.SAXException;
/**
* Customized NetconfXMLToMessageDecoder that reads additional header with
@Override
@VisibleForTesting
- public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+ public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws IOException, SAXException, NetconfDocumentedException {
if (in.readableBytes() == 0) {
LOG.debug("No more content in incoming buffer.");
return;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
+import java.io.IOException;
import java.util.List;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
+import org.xml.sax.SAXException;
public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder {
private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class);
@Override
@VisibleForTesting
- public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+ public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws IOException, SAXException {
if (in.readableBytes() != 0) {
LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
out.add(new NetconfMessage(XmlUtil.readXmlToDocument(new ByteBufInputStream(in))));
public void authenticate(Connection connection) throws IOException {
boolean isAuthenticated = connection.authenticateWithPassword(username, password);
- if (isAuthenticated == false) {
+ if (!isAuthenticated) {
throw new IOException("Authentication failed.");
}
}
}
public void close() {
- for (SshSession session : openSessions.values())
+ for (SshSession session : openSessions.values()){
closeSession(session);
+ }
openSessions.clear();
}
}
- while (stopRequested.get() == false) {
+ while (!stopRequested.get()) {
byte[] readBuff = new byte[BUFFER_SIZE];
int c = stdOut.read(readBuff);
if (c == -1) {
// Netty closed connection prematurely.
// Just pass and move on.
} catch (Exception e) {
- throw new RuntimeException(e);
+ throw new IllegalStateException(e);
} finally {
sshClient.close();
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
-
import java.io.IOException;
import java.io.InputStream;
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
- throw new RuntimeException(e);
+ throw new IllegalStateException(e);
}
}
return this.bb.readByte() & 0xFF;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
-
public abstract class AbstractLastNetconfOperation extends AbstractNetconfOperation {
protected AbstractLastNetconfOperation(String netconfSessionIdForReporting) {
@Override
protected Element handle(Document document, XmlElement operationElement,
NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
- Preconditions.checkArgument(subsequentOperation.isExecutionTermination(),
- "No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation);
+ if (!subsequentOperation.isExecutionTermination()){
+ throw new NetconfDocumentedException(String.format("No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.malformed_message,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
return handleWithNoSubsequentOperations(document, operationElement);
}
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public abstract class AbstractNetconfOperation implements NetconfOperation {
private final String netconfSessionIdForReporting;
+ private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfOperation.class);
protected AbstractNetconfOperation(String netconfSessionIdForReporting) {
this.netconfSessionIdForReporting = netconfSessionIdForReporting;
}
@Override
- public HandlingPriority canHandle(Document message) {
- OperationNameAndNamespace operationNameAndNamespace = new OperationNameAndNamespace(message);
+ public HandlingPriority canHandle(Document message) throws NetconfDocumentedException {
+ OperationNameAndNamespace operationNameAndNamespace = null;
+ operationNameAndNamespace = new OperationNameAndNamespace(message);
return canHandle(operationNameAndNamespace.getOperationName(), operationNameAndNamespace.getNamespace());
}
public static final class OperationNameAndNamespace {
private final String operationName, namespace;
- public OperationNameAndNamespace(Document message) {
- XmlElement requestElement = getRequestElementWithCheck(message);
+ public OperationNameAndNamespace(Document message) throws NetconfDocumentedException {
+ XmlElement requestElement = null;
+ requestElement = getRequestElementWithCheck(message);
XmlElement operationElement = requestElement.getOnlyChildElement();
operationName = operationElement.getName();
}
}
- protected static XmlElement getRequestElementWithCheck(Document message) {
+ protected static XmlElement getRequestElementWithCheck(Document message) throws NetconfDocumentedException {
return XmlElement.fromDomElementWithExpected(message.getDocumentElement(), XmlNetconfConstants.RPC_KEY,
XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
}
package org.opendaylight.controller.netconf.util.messages;
-import java.util.Set;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import java.util.Set;
/**
* NetconfMessage that can carry additional header with session metadata. See {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader}
private final NetconfHelloMessageAdditionalHeader additionalHeader;
- public NetconfHelloMessage(Document doc, NetconfHelloMessageAdditionalHeader additionalHeader) {
+ public NetconfHelloMessage(Document doc, NetconfHelloMessageAdditionalHeader additionalHeader) throws NetconfDocumentedException {
super(doc);
checkHelloMessage(doc);
this.additionalHeader = additionalHeader;
}
- public NetconfHelloMessage(Document doc) {
+ public NetconfHelloMessage(Document doc) throws NetconfDocumentedException {
this(doc, null);
}
return additionalHeader== null ? Optional.<NetconfHelloMessageAdditionalHeader>absent() : Optional.of(additionalHeader);
}
- private static void checkHelloMessage(Document doc) {
- try {
- XmlElement.fromDomElementWithExpected(doc.getDocumentElement(), HELLO_TAG,
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ private static void checkHelloMessage(Document doc) throws NetconfDocumentedException {
+ XmlElement.fromDomElementWithExpected(doc.getDocumentElement(), HELLO_TAG,
+ XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- } catch (IllegalArgumentException | IllegalStateException e) {
- throw new IllegalArgumentException(String.format(
- "Hello message invalid format, should contain %s tag from namespace %s, but is: %s", HELLO_TAG,
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlUtil.toString(doc)), e);
- }
}
public static NetconfHelloMessage createClientHello(Iterable<String> capabilities,
- Optional<NetconfHelloMessageAdditionalHeader> additionalHeaderOptional) {
+ Optional<NetconfHelloMessageAdditionalHeader> additionalHeaderOptional) throws NetconfDocumentedException {
Document doc = createHelloMessageDoc(capabilities);
return additionalHeaderOptional.isPresent() ? new NetconfHelloMessage(doc, additionalHeaderOptional.get())
: new NetconfHelloMessage(doc);
return doc;
}
- public static NetconfHelloMessage createServerHello(Set<String> capabilities, long sessionId) {
+ public static NetconfHelloMessage createServerHello(Set<String> capabilities, long sessionId) throws NetconfDocumentedException {
Document doc = createHelloMessageDoc(capabilities);
Element sessionIdElement = doc.createElement(XmlNetconfConstants.SESSION_ID);
sessionIdElement.setTextContent(Long.toString(sessionId));
import com.google.common.base.Charsets;
-public class NetconfMessageConstants {
+public final class NetconfMessageConstants {
+
+ private NetconfMessageConstants(){}
/**
* The NETCONF 1.0 old-style message separator. This is framing mechanism
* is used by default.
public static final int MAX_HEADER_LENGTH = 13;
public static final byte[] END_OF_CHUNK = "\n##\n".getBytes(Charsets.UTF_8);
+
}
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import javax.annotation.Nullable;
public final class NetconfMessageUtil {
+ private static final Logger logger = LoggerFactory.getLogger(NetconfMessageUtil.class);
+
private NetconfMessageUtil() {}
- public static boolean isOKMessage(NetconfMessage message) {
+ public static boolean isOKMessage(NetconfMessage message) throws NetconfDocumentedException {
return isOKMessage(message.getDocument());
}
- public static boolean isOKMessage(Document document) {
+ public static boolean isOKMessage(Document document) throws NetconfDocumentedException {
return isOKMessage(XmlElement.fromDomDocument(document));
}
- public static boolean isOKMessage(XmlElement xmlElement) {
+ public static boolean isOKMessage(XmlElement xmlElement) throws NetconfDocumentedException {
if(xmlElement.getChildElements().size() != 1) {
return false;
}
return xmlElement.getOnlyChildElement().getName().equals(XmlNetconfConstants.OK);
}
- public static boolean isErrorMessage(NetconfMessage message) {
+ public static boolean isErrorMessage(NetconfMessage message) throws NetconfDocumentedException {
return isErrorMessage(message.getDocument());
}
- public static boolean isErrorMessage(Document document) {
+ public static boolean isErrorMessage(Document document) throws NetconfDocumentedException {
return isErrorMessage(XmlElement.fromDomDocument(document));
}
- public static boolean isErrorMessage(XmlElement xmlElement) {
+ public static boolean isErrorMessage(XmlElement xmlElement) throws NetconfDocumentedException {
if(xmlElement.getChildElements().size() != 1) {
return false;
}
return xmlElement.getOnlyChildElement().getName().equals(XmlNetconfConstants.RPC_ERROR);
}
- public static Collection<String> extractCapabilitiesFromHello(Document doc) {
+ public static Collection<String> extractCapabilitiesFromHello(Document doc) throws NetconfDocumentedException {
XmlElement responseElement = XmlElement.fromDomDocument(doc);
XmlElement capabilitiesElement = responseElement
.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CAPABILITIES);
@Override
public String apply(@Nullable XmlElement input) {
// Trim possible leading/tailing whitespace
- return input.getTextContent().trim();
+ try {
+ return input.getTextContent().trim();
+ } catch (NetconfDocumentedException e) {
+ logger.trace("Error fetching inpit text content becauese {}",e);
+ return null;
+ }
}
});
XPathConstants.NODE);
errorSeverityNode.setTextContent(sendErrorException.getErrorSeverity().getTagValue());
- if (sendErrorException.getErrorInfo() != null && sendErrorException.getErrorInfo().isEmpty() == false) {
+ if (sendErrorException.getErrorInfo() != null && !sendErrorException.getErrorInfo().isEmpty()) {
/*
* <error-info> <bad-attribute>message-id</bad-attribute>
* <bad-element>rpc</bad-element> </error-info>
Optional<InetSocketAddress> inetSocketAddressOptional = extractSomeNetconfAddress(context, InfixProp.tcp, exceptionMessageIfNotFound, forClient);
- if (inetSocketAddressOptional.isPresent() == false) {
+ if (!inetSocketAddressOptional.isPresent()) {
throw new IllegalStateException("Netconf tcp address not found." + exceptionMessageIfNotFound);
}
InetSocketAddress inetSocketAddress = inetSocketAddressOptional.get();
package org.opendaylight.controller.netconf.util.xml;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
+import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException;
+import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public final class XmlElement {
private final Element element;
+ private static final Logger logger = LoggerFactory.getLogger(XmlElement.class);
private XmlElement(Element element) {
this.element = element;
return new XmlElement(xml.getDocumentElement());
}
- public static XmlElement fromString(String s) {
+ public static XmlElement fromString(String s) throws NetconfDocumentedException {
try {
return new XmlElement(XmlUtil.readXmlToElement(s));
} catch (IOException | SAXException e) {
- throw new IllegalArgumentException("Unable to create from " + s, e);
+ throw NetconfDocumentedException.wrap(e);
}
}
- public static XmlElement fromDomElementWithExpected(Element element, String expectedName) {
+ public static XmlElement fromDomElementWithExpected(Element element, String expectedName) throws NetconfDocumentedException {
XmlElement xmlElement = XmlElement.fromDomElement(element);
xmlElement.checkName(expectedName);
return xmlElement;
}
- public static XmlElement fromDomElementWithExpected(Element element, String expectedName, String expectedNamespace) {
+ public static XmlElement fromDomElementWithExpected(Element element, String expectedName, String expectedNamespace) throws NetconfDocumentedException {
XmlElement xmlElement = XmlElement.fromDomElementWithExpected(element, expectedName);
xmlElement.checkNamespace(expectedNamespace);
return xmlElement;
}
- private static Map<String, String> extractNamespaces(Element typeElement) {
+ private static Map<String, String> extractNamespaces(Element typeElement) throws NetconfDocumentedException {
Map<String, String> namespaces = new HashMap<>();
NamedNodeMap attributes = typeElement.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
if (attribKey.equals(XmlUtil.XMLNS_ATTRIBUTE_KEY)) {
prefix = "";
} else {
- Preconditions.checkState(attribKey.startsWith(XmlUtil.XMLNS_ATTRIBUTE_KEY + ":"));
+ if (!attribKey.startsWith(XmlUtil.XMLNS_ATTRIBUTE_KEY + ":")){
+ throw new NetconfDocumentedException("Attribute doesn't start with :",
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
prefix = attribKey.substring(XmlUtil.XMLNS_ATTRIBUTE_KEY.length() + 1);
}
namespaces.put(prefix, attribute.getNodeValue());
return namespaces;
}
- public void checkName(String expectedName) {
- Preconditions.checkArgument(getName().equals(expectedName), "Expected %s xml element but was %s", expectedName,
- getName());
+ public void checkName(String expectedName) throws UnexpectedElementException {
+ if (!getName().equals(expectedName)){
+ throw new UnexpectedElementException(String.format("Expected %s xml element but was %s", expectedName,
+ getName()),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
}
- public void checkNamespaceAttribute(String expectedNamespace) {
- Preconditions.checkArgument(getNamespaceAttribute().equals(expectedNamespace),
- "Unexpected namespace %s for element %s, should be %s", getNamespaceAttribute(), expectedNamespace);
+ public void checkNamespaceAttribute(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException {
+ if (!getNamespaceAttribute().equals(expectedNamespace))
+ {
+ throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s for element %s, should be %s",
+ getNamespaceAttribute(),
+ expectedNamespace),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
}
- public void checkNamespace(String expectedNamespace) {
- Preconditions.checkArgument(getNamespace().equals(expectedNamespace),
- "Unexpected namespace %s for element %s, should be %s", getNamespace(), expectedNamespace);
+ public void checkNamespace(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException {
+ if (!getNamespace().equals(expectedNamespace))
+ {
+ throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s for element %s, should be %s",
+ getNamespace(),
+ expectedNamespace),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
}
public String getName() {
final List<XmlElement> result = new ArrayList<>();
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
- if (item instanceof Element == false) {
+ if (!(item instanceof Element)) {
continue;
}
if (strat.accept((Element) item)) {
return getChildElementsInternal(new ElementFilteringStrategy() {
@Override
public boolean accept(Element e) {
- return XmlElement.fromDomElement(e).getNamespace().equals(namespace);
+ try {
+ return XmlElement.fromDomElement(e).getNamespace().equals(namespace);
+ } catch (MissingNameSpaceException e1) {
+ return false;
+ }
}
});
});
}
- public XmlElement getOnlyChildElement(String childName) {
+ public XmlElement getOnlyChildElement(String childName) throws NetconfDocumentedException {
List<XmlElement> nameElements = getChildElements(childName);
- Preconditions.checkState(nameElements.size() == 1, "One element " + childName + " expected in " + toString());
+ if (nameElements.size() != 1){
+ throw new NetconfDocumentedException("One element " + childName + " expected in " + toString(),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
return nameElements.get(0);
}
}
}
- public XmlElement getOnlyChildElementWithSameNamespace(String childName) {
+ public XmlElement getOnlyChildElementWithSameNamespace(String childName) throws NetconfDocumentedException {
return getOnlyChildElement(childName, getNamespace());
}
}
}
- public XmlElement getOnlyChildElementWithSameNamespace() {
+ public XmlElement getOnlyChildElementWithSameNamespace() throws NetconfDocumentedException {
XmlElement childElement = getOnlyChildElement();
childElement.checkNamespace(getNamespace());
return childElement;
}
}
- public XmlElement getOnlyChildElement(final String childName, String namespace) {
+ public XmlElement getOnlyChildElement(final String childName, String namespace) throws NetconfDocumentedException {
List<XmlElement> children = getChildElementsWithinNamespace(namespace);
children = Lists.newArrayList(Collections2.filter(children, new Predicate<XmlElement>() {
@Override
return xmlElement.getName().equals(childName);
}
}));
- Preconditions.checkState(children.size() == 1, "One element %s:%s expected in %s but was %s", namespace,
- childName, toString(), children.size());
+ if (children.size() != 1){
+ throw new NetconfDocumentedException(String.format("One element %s:%s expected in %s but was %s", namespace,
+ childName, toString(), children.size()),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
+
return children.get(0);
}
- public XmlElement getOnlyChildElement() {
+ public XmlElement getOnlyChildElement() throws NetconfDocumentedException {
List<XmlElement> children = getChildElements();
- Preconditions.checkState(children.size() == 1, "One element expected in %s but was %s", toString(),
- children.size());
+ if (children.size() != 1){
+ throw new NetconfDocumentedException(String.format( "One element expected in %s but was %s", toString(),
+ children.size()),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
return children.get(0);
}
- public String getTextContent() {
+ public String getTextContent() throws NetconfDocumentedException {
Node textChild = element.getFirstChild();
- Preconditions.checkNotNull(textChild, "Child node expected, got null for " + getName() + " : " + element);
- Preconditions.checkState(textChild instanceof Text, getName() + " should contain text." +
- Text.class.getName() + " expected, got " + textChild);
+ if (null == textChild){
+ throw new NetconfDocumentedException(String.format( "Child node expected, got null for " + getName() + " : " + element),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
+ if (!(textChild instanceof Text)){
+ throw new NetconfDocumentedException(String.format(getName() + " should contain text." +
+ Text.class.getName() + " expected, got " + textChild),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
String content = textChild.getTextContent();
// Trim needed
return content.trim();
}
- public String getNamespaceAttribute() {
+ public String getNamespaceAttribute() throws MissingNameSpaceException {
String attribute = element.getAttribute(XmlUtil.XMLNS_ATTRIBUTE_KEY);
- Preconditions.checkState(attribute != null && !attribute.equals(""), "Element %s must specify namespace",
- toString());
+ if (attribute == null || attribute.equals("")){
+ throw new MissingNameSpaceException(String.format("Element %s must specify namespace",
+ toString()),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
return attribute;
}
- public String getNamespace() {
+ public String getNamespace() throws MissingNameSpaceException {
String namespaceURI = element.getNamespaceURI();
- Preconditions.checkState(namespaceURI != null, "No namespace defined for %s", this);
+ if (namespaceURI == null || namespaceURI.equals("")){
+ throw new MissingNameSpaceException(String.format("No namespace defined for %s", this),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.operation_failed,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
return namespaceURI;
}
final StringBuilder sb = new StringBuilder("XmlElement{");
sb.append("name='").append(getName()).append('\'');
if (element.getNamespaceURI() != null) {
- sb.append(", namespace='").append(getNamespace()).append('\'');
+ try {
+ sb.append(", namespace='").append(getNamespace()).append('\'');
+ } catch (MissingNameSpaceException e) {
+ logger.trace("Missing namespace for element.");
+ }
}
sb.append('}');
return sb.toString();
* namespace is returned with empty string as key. If no default namespace
* is found value will be null.
*/
- public Map.Entry<String/* prefix */, String/* namespace */> findNamespaceOfTextContent() {
+ public Map.Entry<String/* prefix */, String/* namespace */> findNamespaceOfTextContent() throws NetconfDocumentedException {
Map<String, String> namespaces = extractNamespaces(element);
String textContent = getTextContent();
int indexOfColon = textContent.indexOf(':');
} else {
prefix = "";
}
- if (namespaces.containsKey(prefix) == false) {
+ if (!namespaces.containsKey(prefix)) {
throw new IllegalArgumentException("Cannot find namespace for " + XmlUtil.toString(element) + ". Prefix from content is "
+ prefix + ". Found namespaces " + namespaces);
}
return Maps.immutableEntry(prefix, namespaces.get(prefix));
}
- public List<XmlElement> getChildElementsWithSameNamespace(final String childName) {
+ public List<XmlElement> getChildElementsWithSameNamespace(final String childName) throws MissingNameSpaceException {
List<XmlElement> children = getChildElementsWithinNamespace(getNamespace());
return Lists.newArrayList(Collections2.filter(children, new Predicate<XmlElement>() {
@Override
}
public void checkUnrecognisedElements(List<XmlElement> recognisedElements,
- XmlElement... additionalRecognisedElements) {
+ XmlElement... additionalRecognisedElements) throws NetconfDocumentedException {
List<XmlElement> childElements = getChildElements();
childElements.removeAll(recognisedElements);
for (XmlElement additionalRecognisedElement : additionalRecognisedElements) {
childElements.remove(additionalRecognisedElement);
}
- Preconditions.checkState(childElements.isEmpty(), "Unrecognised elements %s in %s", childElements, this);
+ if (!childElements.isEmpty()){
+ throw new NetconfDocumentedException(String.format("Unrecognised elements %s in %s", childElements, this),
+ NetconfDocumentedException.ErrorType.application,
+ NetconfDocumentedException.ErrorTag.invalid_value,
+ NetconfDocumentedException.ErrorSeverity.error);
+ }
}
- public void checkUnrecognisedElements(XmlElement... additionalRecognisedElements) {
- checkUnrecognisedElements(Collections.<XmlElement> emptyList(), additionalRecognisedElements);
+ public void checkUnrecognisedElements(XmlElement... additionalRecognisedElements) throws NetconfDocumentedException {
+ checkUnrecognisedElements(Collections.<XmlElement>emptyList(), additionalRecognisedElements);
}
@Override
public boolean hasNamespace() {
try {
getNamespaceAttribute();
- } catch (IllegalStateException e) {
+ } catch (MissingNameSpaceException e) {
try {
getNamespace();
- } catch (IllegalStateException e1) {
+ } catch (MissingNameSpaceException e1) {
return false;
}
return true;
public static final String SESSION_ID = "session-id";
//
+ // TODO duplicate
+ public static final String RFC4741_TARGET_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0";
public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 = "urn:ietf:params:xml:ns:netconf:base:1.0";
- public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1 = "urn:ietf:params:xml:ns:netconf:base:1.1";
+// public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1 = "urn:ietf:params:xml:ns:netconf:base:1.1";
+ public static final String URN_IETF_PARAMS_NETCONF_BASE_1_0 = "urn:ietf:params:netconf:base:1.0";
+ public static final String URN_IETF_PARAMS_NETCONF_BASE_1_1 = "urn:ietf:params:netconf:base:1.1";
public static final String URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0 = "urn:ietf:params:xml:ns:netconf:exi:1.0";
public static final String URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 = "urn:ietf:params:netconf:capability:exi:1.0";
package org.opendaylight.controller.netconf.util.xml;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.SchemaFactory;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
public final class XmlUtil {
try {
dBuilder = BUILDERFACTORY.newDocumentBuilder();
} catch (ParserConfigurationException e) {
- throw new RuntimeException("Failed to parse XML document", e);
+ throw new IllegalStateException("Failed to parse XML document", e);
}
Document doc = dBuilder.parse(xmlContent);
public static Document newDocument() {
try {
DocumentBuilder builder = BUILDERFACTORY.newDocumentBuilder();
- Document document = builder.newDocument();
- return document;
+ return builder.newDocument();
} catch (ParserConfigurationException e) {
- throw new RuntimeException("Failed to create document", e);
+ throw new IllegalStateException("Failed to create document", e);
}
}
transformer.transform(source, result);
return result.getWriter().toString();
- } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
- throw new RuntimeException("Unable to serialize xml element " + xml, e);
+ } catch (Exception | TransformerFactoryConfigurationError e) {
+ throw new IllegalStateException("Unable to serialize xml element " + xml, 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 org.opendaylight.controller.netconf.util;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.StringWriter;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.sax.SAXResult;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.openexi.proc.common.AlignmentType;
-import org.openexi.proc.common.GrammarOptions;
-import org.openexi.proc.grammars.GrammarCache;
-import org.openexi.sax.EXIReader;
-import org.openexi.sax.Transmogrifier;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.InputSource;
-
-/**
- * This test case tests nagasena library used for exi encode/decode.
- *
- * This library does not work correctly, since it is impossible to encode and then decode DOM xml.
- * Encoding DOM using sax Transformer produces invalid xml, that cannot be decoded (Problem seems to be the namespace handling).
- *
- */
-@Ignore
-public class EXILibTest {
-
- public static final AlignmentType ALIGNMENT_TYPE = AlignmentType.preCompress;
-
- @Test
- public void testExiLibWithSaxTransformer() throws Exception {
- final byte[] encode = encodeEXI(getDom2());
- final byte[] encodeWithTransformer = encodeEXITransformer(getDom2());
-
- // System.err.println(Arrays.toString(encode));
- // System.err.println(Arrays.toString(encodeWithTransformer));
-
- // This works fine (encoded from string)
- decodeEXI(encode);
- // Error, encoded from Dom with Transformer cannot be decoded, Exception is thrown
- //
- // either:
- // org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
- //
- // or:
- // java.lang.NullPointerException
- //
- // depends on GrammarOptions.addNS(go); option set
- decodeEXI(encodeWithTransformer);
- }
-
- private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
-
- public static byte[] encodeEXITransformer(final Element xml) throws Exception {
- final Transmogrifier transmogrifier = new Transmogrifier();
-
- transmogrifier.setAlignmentType(ALIGNMENT_TYPE);
-
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- transmogrifier.setGrammarCache(getGrammarCache());
-
- transmogrifier.setOutputStream(out);
-
- final Transformer transformer = saxTransformerFactory.newTransformer();
- transformer.transform(new DOMSource(xml), new SAXResult(transmogrifier.getSAXTransmogrifier()));
-
- return out.toByteArray();
- }
-
- public static byte[] encodeEXI(final Element xml) throws Exception {
- final Transmogrifier transmogrifier = new Transmogrifier();
-
- transmogrifier.setAlignmentType(ALIGNMENT_TYPE);
-
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- transmogrifier.setGrammarCache(getGrammarCache());
-
- transmogrifier.setOutputStream(out);
-
- transmogrifier.encode(new InputSource(new ByteArrayInputStream(toString(xml, false).getBytes())));
-
- out.flush();
-
- return out.toByteArray();
- }
-
- private static GrammarCache getGrammarCache() {
- short go = GrammarOptions.DEFAULT_OPTIONS;
-
- // This option on or off, nagasena still fails
-// go = GrammarOptions.addNS(go);
-
- return new GrammarCache(null, go);
- }
-
- public static Document decodeEXI(final byte[] input) throws Exception {
-
- final GrammarCache grammarCache;
- final DOMResult domResult = new DOMResult();
-
- try(ByteArrayInputStream in = new ByteArrayInputStream(input)) {
-
- final EXIReader reader = new EXIReader();
-
- reader.setAlignmentType(ALIGNMENT_TYPE);
- grammarCache = getGrammarCache();
-
- reader.setGrammarCache(grammarCache);
-
- final SAXTransformerFactory transformerFactory
- = (SAXTransformerFactory) TransformerFactory.newInstance();
- final TransformerHandler handler = transformerFactory.newTransformerHandler();
- handler.setResult(domResult);
-
- reader.setContentHandler(handler);
-
- reader.parse(new InputSource(in));
- }
-
- return (Document) domResult.getNode();
- }
-
- public static Element getDom() {
- final Element dom;
-
- final Document d = newDocument();
-
- dom = d.createElement("rpc");
- dom.setAttribute("xmlns", "a.b.c");
- dom.setAttribute("message-id", "id");
- dom.appendChild(d.createElement("inner"));
-
- return dom;
- }
-
- public static Element getDom2() {
- final Element dom;
-
- final Document d = newDocument();
-
- dom = d.createElementNS("a.b.c", "rpc");
- dom.setAttribute("message-id", "id");
- dom.appendChild(d.createElement("inner"));
-
- return dom;
- }
-
- private static final DocumentBuilderFactory BUILDERFACTORY;
-
- static {
- final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- factory.setCoalescing(true);
- factory.setIgnoringElementContentWhitespace(true);
- factory.setIgnoringComments(true);
- BUILDERFACTORY = factory;
- }
-
- private static Document newDocument() {
- try {
- final DocumentBuilder builder = BUILDERFACTORY.newDocumentBuilder();
- return builder.newDocument();
- } catch (final ParserConfigurationException e) {
- throw new RuntimeException("Failed to create document", e);
- }
- }
-
- private static String toString(final Element xml, final boolean addXmlDeclaration) {
- try {
- final Transformer transformer = TransformerFactory.newInstance().newTransformer();
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, addXmlDeclaration ? "no" : "yes");
-
- final StreamResult result = new StreamResult(new StringWriter());
- final DOMSource source = new DOMSource(xml);
- transformer.transform(source, result);
-
- return result.getWriter().toString();
- } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
- throw new RuntimeException("Unable to serialize xml element " + xml, e);
- }
- }
-}
package org.opendaylight.controller.netconf.util;
import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
public void testConflictingVersionDetection() throws Exception {
Document document = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconfMessages/conflictingversion/conflictingVersionResponse.xml"));
try{
- NetconfUtil.checkIsMessageOk(new NetconfMessage(document));
+ NetconfUtil.checkIsMessageOk(document);
fail();
}catch(IllegalStateException e){
assertThat(e.getMessage(), containsString("Optimistic lock failed. Expected parent version 21, was 18"));
routing.getRoute(incomingNodeConnector.getNode(), destHost.getnodeconnectorNode()) != null)) {
log.trace("Host {} is at {}", dIP, destHost.getnodeConnector());
- HostNodePair key = new HostNodePair(destHost, destHost.getnodeconnectorNode());
// If SimpleForwarding is aware of this host, it will try to install
// a path. Forward packet until it's done.
- if (dataPacketService != null && this.rulesDB.containsKey(key)) {
-
+ if (dataPacketService != null) {
/*
* if we know where the host is and there's a path from where this
<parent>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.openexi</artifactId>
- <version>0000.0002.0035.0-SNAPSHOT</version>
+ <version>0000.0002.0038.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<packaging>bundle</packaging>
<properties>
- <archive>nagasena-rta-0000.0002.0035.0.jar</archive>
+ <archive>nagasena-rta-0000.0002.0038.0.jar</archive>
</properties>
<build>
<parent>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.openexi</artifactId>
- <version>0000.0002.0035.0-SNAPSHOT</version>
+ <version>0000.0002.0038.0-SNAPSHOT</version>
</parent>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<packaging>bundle</packaging>
<properties>
- <archive>nagasena-0000.0002.0035.0.jar</archive>
+ <archive>nagasena-0000.0002.0038.0.jar</archive>
</properties>
<build>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.openexi</artifactId>
- <version>0000.0002.0035.0-SNAPSHOT</version>
+ <version>0000.0002.0038.0-SNAPSHOT</version>
<packaging>pom</packaging>
<prerequisites>
<maven>3.0.4</maven>