<module>mdsal</module>
<module>protocol-framework</module>
<module>akka</module>
- <module>restconf</module>
<module>extras</module>
</modules>
</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Necessary TODO: Put your copyright here.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
---><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <relativePath>../../opendaylight/md-sal</relativePath>
- </parent>
- <!--
- Necessary TODO: Hookup your parent pom here, else you will not get necessary versions,
- maven repos etc. If you run this archetype in a subdirectory of your project, it
- will pick the pom.xml from the parent directory as the parent pom, which may or may
- not be correct.
- -->
- <artifactId>features-restconf</artifactId>
- <groupId>org.opendaylight.controller</groupId>
- <!-- Optional TODO: Uncomment version if you are not using a parent pom.xml
- <version>1.2.0-SNAPSHOT</version>
- -->
- <packaging>jar</packaging>
- <properties>
- <features.file>features.xml</features.file>
- </properties>
- <dependencies>
- <!--
- Necessary TODO: Put dependencies on any feature repos
- you use in your features.xml file.
-
- Note: they will need to be <type>xml</xml>
- and <classifier>features</classifier>.
- One other thing to watch for is to make sure they are
- <scope>compile</compile>, which they should be by default,
- but be cautious lest they be at a different scope in a parent pom.
-
- Examples:
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>features-yangtools</artifactId>
- <version>0.8.0-SNAPSHOT</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-mdsal</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>features-openflowplugin</artifactId>
- <version>0.2.0-SNAPSHOT</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- -->
-
- <!--
- Necessary TODO: Put dependencies for bundles directly referenced
- in your features.xml file. For every <bundle> reference in your
- features.xml file, you need a corresponding dependency here.
-
- Examples:
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>controller-provider</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>controller-model</artifactId>
- <version>${project.version}</version>
- </dependency>
- -->
-
- <!--
- Necessary TODO: Put dependencies for configfiles directly referenced
- in your features.xml file. For every <configfile> reference in your
- features.xml file, you need a corresponding dependency here.
-
- Example (presuming here version is coming from the parent pom):
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>controller-config</artifactId>
- <version>${project.version}</version>
- <type>xml</type>
- <classifier>config</classifier>
- </dependency>
- -->
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>features-yangtools</artifactId>
- <version>${yangtools.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-mdsal</artifactId>
- <version>${mdsal.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <!-- dependency>
- <groupId>org.opendaylight.aaa</groupId>
- <artifactId>features-aaa</artifactId>
- <version>${aaa.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency -->
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remote</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-rest-connector</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-core</artifactId>
- </dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-server</artifactId>
- </dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-servlet</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-rest-connector-config</artifactId>
- <version>${mdsal.version}</version>
- <type>xml</type>
- <classifier>config</classifier>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.datatype</groupId>
- <artifactId>jackson-datatype-json-org</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.module</groupId>
- <artifactId>jackson-module-jaxb-annotations</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.jaxrs</groupId>
- <artifactId>jackson-jaxrs-base</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.jaxrs</groupId>
- <artifactId>jackson-jaxrs-json-provider</artifactId>
- </dependency>
- <dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-codec-gson</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller.samples</groupId>
- <artifactId>clustering-it-model</artifactId>
- <version>${mdsal.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.samples</groupId>
- <artifactId>clustering-it-provider</artifactId>
- <version>${mdsal.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.samples</groupId>
- <artifactId>clustering-it-config</artifactId>
- <version>${mdsal.version}</version>
- <type>xml</type>
- <classifier>config</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.samples</groupId>
- <artifactId>clustering-it-config</artifactId>
- <version>${mdsal.version}</version>
- <type>xml</type>
- <classifier>testmoduleshardconf</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.samples</groupId>
- <artifactId>clustering-it-config</artifactId>
- <version>${mdsal.version}</version>
- <type>xml</type>
- <classifier>testmoduleconf</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-rest-docgen</artifactId>
- </dependency>
-
- <!--
- Optional TODO: Remove TODO comments.
- -->
- <!-- test to validate features.xml -->
- <dependency>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>features-test</artifactId>
- <scope>test</scope>
- </dependency>
- <!-- dependency for opendaylight-karaf-empty for use by testing -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>opendaylight-karaf-empty</artifactId>
- <version>${commons.opendaylight.version}</version>
- <type>zip</type>
- </dependency>
- <!-- Uncomment this if you get an error : java.lang.NoSuchMethodError: org.slf4j.helpers.MessageFormatter.format(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Lorg/slf4j/helpers/FormattingTuple;
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>1.7.2</version>
- </dependency>
- -->
-
- </dependencies>
- <build>
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- <filtering>true</filtering>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <executions>
- <execution>
- <id>filter</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>resources</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <phase>package</phase>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/${features.file}</file>
- <type>xml</type>
- <classifier>features</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>${surefire.version}</version>
- <configuration>
- <systemPropertyVariables>
- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
- <karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>
- </systemPropertyVariables>
- <dependenciesToScan>
- <dependency>org.opendaylight.odlparent:features-test</dependency>
- </dependenciesToScan>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <scm>
- <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=summary</url>
- </scm>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<features name="odl-controller-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
- <!--
- Necessary TODO: Please read the features guidelines:
- https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Feature_Best_Practices
- -->
- <!--
- Necessary TODO: Add repo entries for the repositories of features you refer to
- in this feature file but do not define here.
- Examples:
- <repository>mvn:org.opendaylight.yangtools/features-yangtools/0.8.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/1.3.0-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/0.2.0-SNAPSHOT/xml/features</repository>
- -->
- <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
- <!-- repository>mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features</repository -->
- <feature name='odl-restconf-all' version='${project.version}' description='OpenDaylight :: Restconf :: All'>
- <!--
- Necessary TODO:
- List all of the user consumable features you define in this feature file here.
- Generally you would *not* list individual bundles here, but only features defined in *this* file.
- It is useful to list them in the same order they occur in the file.
-
- Examples:
- <feature version='${project.version}'>odl-controller-provider</feature>
- <feature version='${project.version}'>odl-controller-model</feature>
- -->
- <feature version='${project.version}'>odl-restconf</feature>
- <feature version='${project.version}'>odl-mdsal-apidocs</feature>
- </feature>
- <!--
- Necessary TODO: Define your features. It is useful to list then in order of dependency. So if A depends on B, list A first.
- When naming your features please be mindful of the guidelines:
- https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines
- Particularly:
- a) Prefixing names with 'odl-': https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Feature_Naming
- b) Descriptions: https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Description
- c) Avoid start-levels: https://wiki.opendaylight.org/view/Runtime:Karaf_Features_Guidelines#Avoid_start-levels
-
- It's also nice to list inside a feature, first the features it needs, then the bundles it needs, then the configfiles.
- Examples:
-
- * Basic MD-SAL Provider
- <feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider '>
- <feature version='1.3.0-SNAPSHOT'>odl-mdsal-broker</feature>
- <feature version='${project.version}'>odl-controller-model</feature>
- <bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
- ... whatever other bundles you need
- </feature>
-
- * Basic MD-SAL Model feature
- <feature name='odl-controller-model' version='${project.version}' description='OpenDaylight :: controller :: Model'>
- <feature version='0.8.0-SNAPSHOT'>odl-yangtools-binding</feature>
- <feature version='0.8.0-SNAPSHOT'>odl-yangtools-models</feature>
- <bundle>mvn:org.opendaylight.controller/controller-model/${project.version}</bundle>
- ... whatever other bundles you need
- </feature>
-
- * Config Subsystem example - the config file is your config subsystem configuration
- <feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider'>
- <feature version='1.3.0-SNAPSHOT'>odl-mdsal-broker</feature>
- <bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
- <configfile finalname="etc/opendaylight/karaf/80-controller.xml">mvn:org.opendaylight.controller/controller-config/${project.version}/xml/config</configfile>
- ... whatever other bundles you need
- </feature>
-
- * Basic MD-SAL Provider that uses openflowplugin-flow-services (which brings along odl-mdsal-broker)
- <feature name='odl-controller-provider' version='${project.version}' description='OpenDaylight :: controller :: Provider'>
- <feature version='0.2.0-SNAPSHOT'>odl-openflowplugin-flow-services</feature>
- <bundle>mvn:org.opendaylight.controller/controller-provider/${project.version}</bundle>
- ... whatever other bundles you need
- </feature>
-
- -->
-
- <feature name='odl-restconf' version='${project.version}' description="OpenDaylight :: Restconf">
- <!-- feature version='${aaa.version}'>odl-aaa-authn</feature -->
- <feature version='${mdsal.version}'>odl-restconf-noauth</feature>
- </feature>
- <feature name='odl-restconf-noauth' version='${project.version}' description="OpenDaylight :: Restconf">
- <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
- <feature>war</feature>
- <!-- presently we need sal-remote to be listed BEFORE sal-rest-connector because sal-rest-connector
- has a yang file which augments a yang file in sal-remote, and order seems to matter -->
- <bundle>mvn:org.opendaylight.controller/sal-remote/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/sal-rest-connector/${project.version}</bundle>
- <bundle>mvn:com.google.code.gson/gson/${gson.version}</bundle>
- <bundle>mvn:org.opendaylight.yangtools/yang-data-codec-gson/${yangtools.version}</bundle>
- <bundle>mvn:org.opendaylight.yangtools/yang-model-export/${yangtools.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
- <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-codec-http/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-common/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-handler/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
- <configfile finalname="${config.configfile.directory}/${config.restconf.configfile}">mvn:org.opendaylight.controller/sal-rest-connector-config/${mdsal.version}/xml/config</configfile>
- </feature>
- <feature name ='odl-mdsal-apidocs' version='${project.version}' description="OpenDaylight :: MDSAL :: APIDOCS">
- <feature version='${project.version}'>odl-restconf</feature>
- <bundle>mvn:org.opendaylight.controller/sal-rest-docgen/${project.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.datatype/jackson-datatype-json-org/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
- <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
- <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
- <bundle>wrap:mvn:org.json/json/${org.json.version}</bundle>
- </feature>
-
- <feature name='odl-toaster-rest' version='${project.version}'>
- <feature version='${project.version}'>odl-restconf</feature>
- <feature version='${project.version}'>odl-toaster</feature>
- </feature>
-
- <feature name='odl-toaster-ui' version='${project.version}'>
- <feature version='${project.version}'>odl-mdsal-apidocs</feature>
- <feature version='${project.version}'>odl-mdsal-xsql</feature>
- <feature version='${project.version}'>odl-toaster-rest</feature>
- </feature>
- <!-- Optional TODO: Remove TODO Comments -->
-
-</features>
<!-- Base Models -->
<module>sal-remote</module>
- <module>sal-restconf-broker</module>
<!-- Connectors -->
<module>sal-connector-api</module>
- <module>sal-rest-connector</module>
- <module>sal-rest-connector-config</module>
-
- <!-- Documentation -->
- <module>sal-rest-docgen</module>
- <module>sal-rest-docgen-maven</module>
<module>sal-akka-raft</module>
<module>sal-akka-raft-example</module>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- </parent>
- <artifactId>sal-rest-connector-config</artifactId>
- <description>Configuration files for sal-rest-connector</description>
- <packaging>jar</packaging>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/initial/10-rest-connector.xml</file>
- <type>xml</type>
- <classifier>config</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
-This program and the accompanying materials are made available under the
-terms of the Eclipse Public License v1.0 which accompanies this distribution,
-and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<snapshot>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <!-- default OF-switch-connection-provider (port 6633) -->
- <module>
- <type xmlns:rest="urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector">rest:rest-connector-impl</type>
- <name>rest-connector-default-impl</name>
- <websocket-port>8185</websocket-port>
- <dom-broker>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-broker>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:rest="urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector">rest:rest-connector</type>
- <instance>
- <name>rest-connector-default</name>
- <provider>
- /modules/module[type='rest-connector-impl'][name='rest-connector-default-impl']
- </provider>
- </instance>
- </service>
- </services>
- </data>
- </configuration>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector?module=opendaylight-rest-connector&revision=2014-07-24</capability>
- </required-capabilities>
-</snapshot>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- </parent>
- <artifactId>sal-rest-connector</artifactId>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-connector-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-core-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-dom-config</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remote</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-model-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-parser-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-restconf</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-yang-types-20130715</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>jaxrs-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-spi</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-codec-gson</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-model-export</artifactId>
- <!-- FIXME: remove explicit version, once model export package is part of yangtools-artefacts -->
- <version>0.8.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>net.java.dev.stax-utils</groupId>
- <artifactId>stax-utils</artifactId>
- <version>20070216</version>
- </dependency>
-
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!-- Testing Dependencies -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.glassfish.jersey.test-framework.providers</groupId>
- <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Name>MD SAL Restconf Connector</Bundle-Name>
- <Private-Package>org.opendaylight.controller.sal.rest.*,
- org.opendaylight.controller.sal.restconf.rpc.*,
- org.opendaylight.controller.sal.restconf.impl,
- org.opendaylight.controller.md.sal.rest.common.*,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.rest.connector.rev140724.*,
- </Private-Package>
- <Import-Package>*,
- com.sun.jersey.spi.container.servlet, org.eclipse.jetty.servlets</Import-Package>
- <Embed-Dependency>stax-utils</Embed-Dependency>
- <Web-ContextPath>/restconf</Web-ContextPath>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>config</id>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
- <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
- <additionalConfiguration>
- <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
- </additionalConfiguration>
- </generator>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>${salGeneratorPath}</outputBaseDir>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- <scm>
- <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-</project>
+++ /dev/null
-package org.opendaylight.controller.config.yang.md.sal.rest.connector;
-
-import org.opendaylight.controller.sal.restconf.impl.RestconfProviderImpl;
-
-
-public class RestConnectorModule extends org.opendaylight.controller.config.yang.md.sal.rest.connector.AbstractRestConnectorModule {
-
- private static RestConnectorRuntimeRegistration runtimeRegistration;
-
- public RestConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public RestConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.md.sal.rest.connector.RestConnectorModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- // Create an instance of our provider
- RestconfProviderImpl instance = new RestconfProviderImpl();
- // Set its port
- instance.setWebsocketPort(getWebsocketPort());
- // Register it with the Broker
- getDomBrokerDependency().registerProvider(instance);
-
- if(runtimeRegistration != null){
- runtimeRegistration.close();
- }
-
- runtimeRegistration =
- getRootRuntimeBeanRegistratorWrapper().register(instance);
-
- return instance;
- }
-}
-
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: opendaylight-rest-connector yang module local name: rest-connector-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Jul 25 04:33:31 CDT 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.md.sal.rest.connector;
-
-public class RestConnectorModuleFactory extends org.opendaylight.controller.config.yang.md.sal.rest.connector.AbstractRestConnectorModuleFactory {
-
-}
+++ /dev/null
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.md.sal.rest.common;
-
-import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-
-/**
- * sal-rest-connector
- * org.opendaylight.controller.md.sal.rest.common
- *
- * Utility class is centralizing all needed validation functionality for a Restconf osgi module.
- * All methods have to throw {@link RestconfDocumentedException} only, which is a representation
- * for all error situation followed by restconf-netconf specification.
- * @see {@link https://tools.ietf.org/html/draft-bierman-netconf-restconf-02}
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Feb 24, 2015
- */
-public class RestconfValidationUtils {
-
- private RestconfValidationUtils () {
- throw new UnsupportedOperationException("Utility class");
- }
-
- /**
- * Method returns {@link RestconfDocumentedException} for a false condition.
- *
- * @param condition - condition for rise {@link RestconfDocumentedException}
- * @param type - input {@link ErrorType} for create {@link RestconfDocumentedException}
- * @param tag - input {@link ErrorTag} for create {@link RestconfDocumentedException}
- * @param message - input error message for create {@link RestconfDocumentedException}
- */
- public static void checkDocumentedError(final boolean condition, final ErrorType type,
- final ErrorTag tag, final String message) {
- if(!condition) {
- throw new RestconfDocumentedException(message, type, tag);
- }
- }
-
- /**
- * Method returns {@link RestconfDocumentedException} if value is NULL or same input value.
- * {@link ErrorType} is relevant for server application layer
- * {@link ErrorTag} is 404 data-missing
- * @see {@link https://tools.ietf.org/html/draft-bierman-netconf-restconf-02}
- *
- * @param value - some value from {@link org.opendaylight.yangtools.yang.model.api.Module}
- * @param moduleName - name of {@link org.opendaylight.yangtools.yang.model.api.Module}
- * @return - T value (same input value)
- */
- public static <T> T checkNotNullDocumented(final T value, final String moduleName) {
- if(value == null) {
- final String errMsg = "Module " + moduleName + "was not found.";
- throw new RestconfDocumentedException(errMsg, ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
- }
- return value;
- }
-}
+++ /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.rest.schema;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-
-@Provider
-@Produces(SchemaRetrievalService.YANG_MEDIA_TYPE)
-public class SchemaExportContentYangBodyWriter implements MessageBodyWriter<SchemaExportContext> {
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return type.equals(SchemaExportContext.class);
- }
-
- @Override
- public long getSize(final SchemaExportContext t, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final SchemaExportContext t, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
- WebApplicationException {
- final PrintWriter writer = new PrintWriter(entityStream);
- writer.write(t.getModule().getSource());
-
- }
-}
+++ /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.rest.schema;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import javax.xml.stream.XMLStreamException;
-import org.opendaylight.yangtools.yang.model.export.YinExportUtils;
-
-@Provider
-@Produces(SchemaRetrievalService.YIN_MEDIA_TYPE)
-public class SchemaExportContentYinBodyWriter implements MessageBodyWriter<SchemaExportContext> {
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return type.equals(SchemaExportContext.class);
- }
-
- @Override
- public long getSize(final SchemaExportContext t, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final SchemaExportContext t, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
- WebApplicationException {
- try {
- YinExportUtils.writeModuleToOutputStream(t.getSchemaContext(), t.getModule(), entityStream);
- } catch (final XMLStreamException e) {
- throw new IllegalStateException(e);
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.sal.rest.schema;
-
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class SchemaExportContext {
-
- private final SchemaContext schemaContext;
- private final Module module;
-
- public SchemaExportContext(final SchemaContext ctx, final Module module) {
- schemaContext = ctx;
- this.module = module;
- }
-
- public SchemaContext getSchemaContext() {
- return schemaContext;
- }
-
- public Module getModule() {
- return module;
- }
-
-}
+++ /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.rest.schema;
-
-import com.google.common.annotations.Beta;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-
-@Beta
-public interface SchemaRetrievalService {
-
- public static final String YANG_MEDIA_TYPE = "application/yang";
- public static final String YIN_MEDIA_TYPE = "application/yin+xml";
-
- @GET
- @Produces({YIN_MEDIA_TYPE,YANG_MEDIA_TYPE})
- @Path("/modules/module/{identifier:.+}/schema")
- SchemaExportContext getSchema(@PathParam("identifier") String mountAndModuleId);
-}
+++ /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.rest.schema;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
-import java.text.ParseException;
-import java.util.Date;
-import java.util.Iterator;
-import org.opendaylight.controller.md.sal.rest.common.RestconfValidationUtils;
-import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
-import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class SchemaRetrievalServiceImpl implements SchemaRetrievalService {
-
- private final ControllerContext salContext;
-
- private static final Splitter SLASH_SPLITTER = Splitter.on("/");
- private static final String MOUNT_ARG = ControllerContext.MOUNT;
-
- public SchemaRetrievalServiceImpl(final ControllerContext controllerContext) {
- salContext = controllerContext;
- }
-
-
- @Override
- public SchemaExportContext getSchema(final String mountAndModule) {
- final SchemaContext schemaContext;
- final Iterable<String> pathComponents = SLASH_SPLITTER.split(mountAndModule);
- final Iterator<String> componentIter = pathComponents.iterator();
- if(!Iterables.contains(pathComponents, MOUNT_ARG)) {
- schemaContext = salContext.getGlobalSchema();
- } else {
- final StringBuilder pathBuilder = new StringBuilder();
- while(componentIter.hasNext()) {
- final String current = componentIter.next();
- // It is argument, not last element.
- if(pathBuilder.length() != 0) {
- pathBuilder.append("/");
- }
- pathBuilder.append(current);
- if(MOUNT_ARG.equals(current)) {
- // We stop right at mountpoint, last two arguments should
- // be module name and revision
- break;
- }
- }
- schemaContext = getMountSchemaContext(pathBuilder.toString());
-
- }
-
- RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Module name must be supplied.");
- final String moduleName = componentIter.next();
- RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Revision date must be supplied.");
- final String revisionString = componentIter.next();
- return getExportUsingNameAndRevision(schemaContext, moduleName, revisionString);
- }
-
- private SchemaExportContext getExportUsingNameAndRevision(final SchemaContext schemaContext, final String moduleName,
- final String revisionStr) {
- try {
- final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse(revisionStr);
- final Module module = schemaContext.findModuleByName(moduleName, revision);
- return new SchemaExportContext(schemaContext, RestconfValidationUtils.checkNotNullDocumented(module, moduleName));
- } catch (final ParseException e) {
- throw new RestconfDocumentedException("Supplied revision is not in expected date format YYYY-mm-dd", e);
- }
- }
-
- private SchemaContext getMountSchemaContext(final String identifier) {
- final InstanceIdentifierContext<?> mountContext = salContext.toMountPointIdentifier(identifier);
- return mountContext.getSchemaContext();
- }
-
-
-
-}
-
+++ /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.rest.api;
-
-import org.opendaylight.yangtools.yang.common.QName;
-
-public class Draft02 {
- public static interface MediaTypes {
- String API = "application/yang.api";
- String DATASTORE = "application/yang.datastore";
- String DATA = "application/yang.data";
- String OPERATION = "application/yang.operation";
- String PATCH = "application/yang.patch";
- String PATCH_STATUS = "application/yang.patch-status";
- String STREAM = "application/yang.stream";
- }
-
- public static interface RestConfModule {
- String REVISION = "2013-10-19";
-
- String NAME = "ietf-restconf";
-
- String NAMESPACE = "urn:ietf:params:xml:ns:yang:ietf-restconf";
-
- String RESTCONF_GROUPING_SCHEMA_NODE = "restconf";
-
- String RESTCONF_CONTAINER_SCHEMA_NODE = "restconf";
-
- String MODULES_CONTAINER_SCHEMA_NODE = "modules";
-
- String MODULE_LIST_SCHEMA_NODE = "module";
-
- String STREAMS_CONTAINER_SCHEMA_NODE = "streams";
-
- String STREAM_LIST_SCHEMA_NODE = "stream";
-
- String OPERATIONS_CONTAINER_SCHEMA_NODE = "operations";
-
- String ERRORS_GROUPING_SCHEMA_NODE = "errors";
-
- String ERRORS_CONTAINER_SCHEMA_NODE = "errors";
-
- String ERROR_LIST_SCHEMA_NODE = "error";
-
- QName IETF_RESTCONF_QNAME = QName.create(Draft02.RestConfModule.NAMESPACE, Draft02.RestConfModule.REVISION,
- Draft02.RestConfModule.NAME);
-
- QName ERRORS_CONTAINER_QNAME = QName.create(IETF_RESTCONF_QNAME, ERRORS_CONTAINER_SCHEMA_NODE);
-
- QName ERROR_LIST_QNAME = QName.create(IETF_RESTCONF_QNAME, ERROR_LIST_SCHEMA_NODE);
-
- QName ERROR_TYPE_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-type");
-
- QName ERROR_TAG_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-tag");
-
- QName ERROR_APP_TAG_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-app-tag");
-
- QName ERROR_MESSAGE_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-message");
-
- QName ERROR_INFO_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-info");
- }
-
- public static interface Paths {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.rest.api;
-
-/*
- * This is a simple dummy interface to allow us to create instances of RestconfProvider
- * via the config subsystem.
- */
-public interface RestConnector {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.rest.api;
-
-public interface RestconfConstants {
-
-
- public static String IDENTIFIER = "identifier";
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.rest.api;
-
-import java.io.Closeable;
-import java.io.Flushable;
-import java.io.IOException;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public interface RestconfNormalizedNodeWriter extends Flushable, Closeable {
-
- RestconfNormalizedNodeWriter write(final NormalizedNode<?, ?> node) throws IOException;
-}
+++ /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.sal.rest.api;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.Encoded;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
-
-/**
- * The URI hierarchy for the RESTCONF resources consists of an entry point container, 4 top-level resources, and 1
- * field.
- * <ul>
- * <li><b>/restconf</b> - {@link #getRoot()}
- * <ul>
- * <li><b>/config</b> - {@link #readConfigurationData(String)}
- * {@link #updateConfigurationData(String, NormalizedNodeContext)}
- * {@link #createConfigurationData(NormalizedNodeContext)}
- * {@link #createConfigurationData(String, NormalizedNodeContext)}
- * {@link #deleteConfigurationData(String)}
- * <li><b>/operational</b> - {@link #readOperationalData(String)}
- * <li>/modules - {@link #getModules()}
- * <ul>
- * <li>/module
- * </ul>
- * <li><b>/operations</b> - {@link #invokeRpc(String, NormalizedNodeContext)}
- * {@link #invokeRpc(String, NormalizedNodeContext)}
- * <li>/version (field)
- * </ul>
- * </ul>
- */
-@Path("/")
-public interface RestconfService {
-
- public static final String XML = "+xml";
- public static final String JSON = "+json";
-
- @GET
- public Object getRoot();
-
- @GET
- @Path("/modules")
- @Produces({ Draft02.MediaTypes.API + JSON, Draft02.MediaTypes.API + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext getModules(@Context UriInfo uriInfo);
-
- @GET
- @Path("/modules/{identifier:.+}")
- @Produces({ Draft02.MediaTypes.API + JSON, Draft02.MediaTypes.API + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext getModules(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
-
- @GET
- @Path("/modules/module/{identifier:.+}")
- @Produces({ Draft02.MediaTypes.API + JSON, Draft02.MediaTypes.API + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext getModule(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
-
- @GET
- @Path("/operations")
- @Produces({ Draft02.MediaTypes.API + JSON, Draft02.MediaTypes.API + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext getOperations(@Context UriInfo uriInfo);
-
- @GET
- @Path("/operations/{identifier:.+}")
- @Produces({ Draft02.MediaTypes.API + JSON, Draft02.MediaTypes.API + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext getOperations(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
-
- @POST
- @Path("/operations/{identifier:.+}")
- @Produces({ Draft02.MediaTypes.OPERATION + JSON, Draft02.MediaTypes.OPERATION + XML,
- Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- @Consumes({ Draft02.MediaTypes.OPERATION + JSON, Draft02.MediaTypes.OPERATION + XML,
- Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext invokeRpc(@Encoded @PathParam("identifier") String identifier, NormalizedNodeContext payload,
- @Context UriInfo uriInfo);
-
- @POST
- @Path("/operations/{identifier:.+}")
- @Produces({ Draft02.MediaTypes.OPERATION + JSON, Draft02.MediaTypes.OPERATION + XML,
- Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- @Deprecated // method isn't use anywhere
- public NormalizedNodeContext invokeRpc(@Encoded @PathParam("identifier") String identifier,
- @DefaultValue("") String noPayload, @Context UriInfo uriInfo);
-
- @GET
- @Path("/config/{identifier:.+}")
- @Produces({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext readConfigurationData(@Encoded @PathParam("identifier") String identifier,
- @Context UriInfo uriInfo);
-
- @GET
- @Path("/operational/{identifier:.+}")
- @Produces({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext readOperationalData(@Encoded @PathParam("identifier") String identifier,
- @Context UriInfo uriInfo);
-
- @PUT
- @Path("/config/{identifier:.+}")
- @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public Response updateConfigurationData(@Encoded @PathParam("identifier") String identifier, NormalizedNodeContext payload);
-
- @POST
- @Path("/config/{identifier:.+}")
- @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public Response createConfigurationData(@Encoded @PathParam("identifier") String identifier, NormalizedNodeContext payload,
- @Context UriInfo uriInfo);
-
- @POST
- @Path("/config")
- @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public Response createConfigurationData(NormalizedNodeContext payload, @Context UriInfo uriInfo);
-
- @DELETE
- @Path("/config/{identifier:.+}")
- public Response deleteConfigurationData(@Encoded @PathParam("identifier") String identifier);
-
- @GET
- @Path("/streams/stream/{identifier:.+}")
- public Response subscribeToStream(@Encoded @PathParam("identifier") String identifier, @Context UriInfo uriInfo);
-
- @GET
- @Path("/streams")
- @Produces({ Draft02.MediaTypes.API + JSON, Draft02.MediaTypes.API + XML, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext getAvailableStreams(@Context UriInfo uriInfo);
-
-}
+++ /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.rest.api;
-
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.rest.impl;
-
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Request;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.controller.sal.rest.api.RestconfConstants;
-import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
-
-public class AbstractIdentifierAwareJaxRsProvider {
-
- private static final String POST = "POST";
-
- @Context
- private UriInfo uriInfo;
-
- @Context
- private Request request;
-
- protected final String getIdentifier() {
- return uriInfo.getPathParameters(false).getFirst(RestconfConstants.IDENTIFIER);
- }
-
- protected InstanceIdentifierContext<?> getInstanceIdentifierContext() {
- return ControllerContext.getInstance().toInstanceIdentifier(getIdentifier());
- }
-
- protected UriInfo getUriInfo() {
- return uriInfo;
- }
-
- protected boolean isPost() {
- return POST.equals(request.getMethod());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.rest.impl;
-
-import static org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter.UNKNOWN_SIZE;
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.controller.sal.rest.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-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.api.schema.OrderedMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamAttributeWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is an experimental iterator over a {@link NormalizedNode}. This is essentially
- * the opposite of a {@link XMLStreamReader} -- unlike instantiating an iterator over
- * the backing data, this encapsulates a {@link NormalizedNodeStreamWriter} and allows
- * us to write multiple nodes.
- */
-@Beta
-public class DepthAwareNormalizedNodeWriter implements RestconfNormalizedNodeWriter {
- private final NormalizedNodeStreamWriter writer;
- protected int currentDepth = 0;
- protected final int maxDepth;
-
- private DepthAwareNormalizedNodeWriter(final NormalizedNodeStreamWriter writer, final int maxDepth) {
- this.writer = Preconditions.checkNotNull(writer);
- this.maxDepth = maxDepth;
- }
-
- protected final NormalizedNodeStreamWriter getWriter() {
- return writer;
- }
-
- /**
- * Create a new writer backed by a {@link NormalizedNodeStreamWriter}.
- *
- * @param writer Back-end writer
- * @return A new instance.
- */
- public static DepthAwareNormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer, final int maxDepth) {
- return forStreamWriter(writer, true, maxDepth);
- }
-
- /**
- * Create a new writer backed by a {@link NormalizedNodeStreamWriter}. Unlike the simple {@link #forStreamWriter(NormalizedNodeStreamWriter)}
- * method, this allows the caller to switch off RFC6020 XML compliance, providing better
- * throughput. The reason is that the XML mapping rules in RFC6020 require the encoding
- * to emit leaf nodes which participate in a list's key first and in the order in which
- * they are defined in the key. For JSON, this requirement is completely relaxed and leaves
- * can be ordered in any way we see fit. The former requires a bit of work: first a lookup
- * for each key and then for each emitted node we need to check whether it was already
- * emitted.
- *
- * @param writer Back-end writer
- * @param orderKeyLeaves whether the returned instance should be RFC6020 XML compliant.
- * @return A new instance.
- */
- public static DepthAwareNormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer, final boolean
- orderKeyLeaves, final int maxDepth) {
- if (orderKeyLeaves) {
- return new OrderedDepthAwareNormalizedNodeWriter(writer, maxDepth);
- } else {
- return new DepthAwareNormalizedNodeWriter(writer, maxDepth);
- }
- }
-
- /**
- * Iterate over the provided {@link NormalizedNode} and emit write
- * events to the encapsulated {@link NormalizedNodeStreamWriter}.
- *
- * @param node Node
- * @return
- * @throws IOException when thrown from the backing writer.
- */
- public final DepthAwareNormalizedNodeWriter write(final NormalizedNode<?, ?> node) throws IOException {
- if (wasProcessedAsCompositeNode(node)) {
- return this;
- }
-
- if (wasProcessAsSimpleNode(node)) {
- return this;
- }
-
- throw new IllegalStateException("It wasn't possible to serialize node " + node);
- }
-
- @Override
- public void flush() throws IOException {
- writer.flush();
- }
-
- @Override
- public void close() throws IOException {
- writer.flush();
- writer.close();
- }
-
- /**
- * Emit a best guess of a hint for a particular set of children. It evaluates the
- * iterable to see if the size can be easily gotten to. If it is, we hint at the
- * real number of child nodes. Otherwise we emit UNKNOWN_SIZE.
- *
- * @param children Child nodes
- * @return Best estimate of the collection size required to hold all the children.
- */
- static final int childSizeHint(final Iterable<?> children) {
- return (children instanceof Collection) ? ((Collection<?>) children).size() : UNKNOWN_SIZE;
- }
-
- private boolean wasProcessAsSimpleNode(final NormalizedNode<?, ?> node) throws IOException {
- if (node instanceof LeafSetEntryNode) {
- if (currentDepth < maxDepth) {
- final LeafSetEntryNode<?> nodeAsLeafList = (LeafSetEntryNode<?>) node;
- if (writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer).leafSetEntryNode(nodeAsLeafList.getValue(), nodeAsLeafList.getAttributes());
- } else {
- writer.leafSetEntryNode(nodeAsLeafList.getValue());
- }
- }
- return true;
- } else if (node instanceof LeafNode) {
- final LeafNode<?> nodeAsLeaf = (LeafNode<?>)node;
- if(writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer).leafNode(nodeAsLeaf.getIdentifier(), nodeAsLeaf.getValue(), nodeAsLeaf.getAttributes());
- } else {
- writer.leafNode(nodeAsLeaf.getIdentifier(), nodeAsLeaf.getValue());
- }
- return true;
- } else if (node instanceof AnyXmlNode) {
- final AnyXmlNode anyXmlNode = (AnyXmlNode)node;
- writer.anyxmlNode(anyXmlNode.getIdentifier(), anyXmlNode.getValue());
- return true;
- }
-
- return false;
- }
-
- /**
- * Emit events for all children and then emit an endNode() event.
- *
- * @param children Child iterable
- * @return True
- * @throws IOException when the writer reports it
- */
- protected final boolean writeChildren(final Iterable<? extends NormalizedNode<?, ?>> children) throws IOException {
- if (currentDepth < maxDepth) {
- for (NormalizedNode<?, ?> child : children) {
- write(child);
- }
- }
- writer.endNode();
- return true;
- }
-
- protected boolean writeMapEntryChildren(final MapEntryNode mapEntryNode) throws IOException {
- if (currentDepth < maxDepth) {
- writeChildren(mapEntryNode.getValue());
- } else if (currentDepth == maxDepth) {
- writeOnlyKeys(mapEntryNode.getIdentifier().getKeyValues());
- }
- return true;
- }
-
- private void writeOnlyKeys(Map<QName, Object> keyValues) throws IllegalArgumentException, IOException {
- for (Map.Entry<QName, Object> entry : keyValues.entrySet()) {
- writer.leafNode(new NodeIdentifier(entry.getKey()), entry.getValue());
- }
- writer.endNode();
-
- }
-
- protected boolean writeMapEntryNode(final MapEntryNode node) throws IOException {
- if(writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer)
- .startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue()), node.getAttributes());
- } else {
- writer.startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue()));
- }
- currentDepth++;
- writeMapEntryChildren(node);
- currentDepth--;
- return true;
- }
-
- private boolean wasProcessedAsCompositeNode(final NormalizedNode<?, ?> node) throws IOException {
- boolean processedAsCompositeNode = false;
- if (node instanceof ContainerNode) {
- final ContainerNode n = (ContainerNode) node;
- if(writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer).startContainerNode(n.getIdentifier(), childSizeHint(n.getValue()), n.getAttributes());
- } else {
- writer.startContainerNode(n.getIdentifier(), childSizeHint(n.getValue()));
- }
- currentDepth++;
- processedAsCompositeNode = writeChildren(n.getValue());
- currentDepth--;
- }
- else if (node instanceof MapEntryNode) {
- processedAsCompositeNode = writeMapEntryNode((MapEntryNode) node);
- }
- else if (node instanceof UnkeyedListEntryNode) {
- final UnkeyedListEntryNode n = (UnkeyedListEntryNode) node;
- writer.startUnkeyedListItem(n.getIdentifier(), childSizeHint(n.getValue()));
- currentDepth++;
- processedAsCompositeNode = writeChildren(n.getValue());
- currentDepth--;
- }
- else if (node instanceof ChoiceNode) {
- final ChoiceNode n = (ChoiceNode) node;
- writer.startChoiceNode(n.getIdentifier(), childSizeHint(n.getValue()));
- processedAsCompositeNode = writeChildren(n.getValue());
- }
- else if (node instanceof AugmentationNode) {
- final AugmentationNode n = (AugmentationNode) node;
- writer.startAugmentationNode(n.getIdentifier());
- processedAsCompositeNode = writeChildren(n.getValue());
- }
- else if (node instanceof UnkeyedListNode) {
- final UnkeyedListNode n = (UnkeyedListNode) node;
- writer.startUnkeyedList(n.getIdentifier(), childSizeHint(n.getValue()));
- processedAsCompositeNode = writeChildren(n.getValue());
- }
- else if (node instanceof OrderedMapNode) {
- final OrderedMapNode n = (OrderedMapNode) node;
- writer.startOrderedMapNode(n.getIdentifier(), childSizeHint(n.getValue()));
- processedAsCompositeNode = writeChildren(n.getValue());
- }
- else if (node instanceof MapNode) {
- final MapNode n = (MapNode) node;
- writer.startMapNode(n.getIdentifier(), childSizeHint(n.getValue()));
- processedAsCompositeNode = writeChildren(n.getValue());
- }
- else if (node instanceof LeafSetNode) {
- //covers also OrderedLeafSetNode for which doesn't exist start* method
- final LeafSetNode<?> n = (LeafSetNode<?>) node;
- writer.startLeafSet(n.getIdentifier(), childSizeHint(n.getValue()));
- currentDepth++;
- processedAsCompositeNode = writeChildren(n.getValue());
- currentDepth--;
- }
-
- return processedAsCompositeNode;
- }
-
- private static final class OrderedDepthAwareNormalizedNodeWriter extends DepthAwareNormalizedNodeWriter {
- private static final Logger LOG = LoggerFactory.getLogger(OrderedDepthAwareNormalizedNodeWriter.class);
-
- OrderedDepthAwareNormalizedNodeWriter(final NormalizedNodeStreamWriter writer, final int maxDepth) {
- super(writer, maxDepth);
- }
-
- @Override
- protected boolean writeMapEntryNode(final MapEntryNode node) throws IOException {
- final NormalizedNodeStreamWriter writer = getWriter();
- if(writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer).startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue()), node.getAttributes());
- } else {
- writer.startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue()));
- }
-
- final Set<QName> qnames = node.getIdentifier().getKeyValues().keySet();
- // Write out all the key children
- for (QName qname : qnames) {
- final Optional<? extends NormalizedNode<?, ?>> child = node.getChild(new NodeIdentifier(qname));
- if (child.isPresent()) {
- write(child.get());
- } else {
- LOG.info("No child for key element {} found", qname);
- }
- }
-
- // Write all the rest
- currentDepth++;
- boolean result = writeChildren(Iterables.filter(node.getValue(), new Predicate<NormalizedNode<?, ?>>() {
- @Override
- public boolean apply(final NormalizedNode<?, ?> input) {
- if (input instanceof AugmentationNode) {
- return true;
- }
- if (!qnames.contains(input.getNodeType())) {
- return true;
- }
-
- LOG.debug("Skipping key child {}", input);
- return false;
- }
- }));
- currentDepth--;
- return result;
- }
- }
-}
+++ /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.rest.impl;
-
-import com.google.common.collect.Iterables;
-import com.google.gson.stream.JsonReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.Provider;
-import org.opendaylight.controller.sal.rest.api.Draft02;
-import org.opendaylight.controller.sal.rest.api.RestconfService;
-import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
-import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-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.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-import org.opendaylight.yangtools.yang.data.impl.schema.ResultAlreadySetException;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Provider
-@Consumes({ Draft02.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.OPERATION + RestconfService.JSON,
- MediaType.APPLICATION_JSON })
-public class JsonNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsProvider implements MessageBodyReader<NormalizedNodeContext> {
-
- private final static Logger LOG = LoggerFactory.getLogger(JsonNormalizedNodeBodyReader.class);
-
- @Override
- public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return true;
- }
-
- @Override
- public NormalizedNodeContext readFrom(final Class<NormalizedNodeContext> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
- WebApplicationException {
- try {
- final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
- if (entityStream.available() < 1) {
- return new NormalizedNodeContext(path, null);
- }
- final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
- final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
-
- final SchemaNode parentSchema;
- if(isPost()) {
- // FIXME: We need dispatch for RPC.
- parentSchema = path.getSchemaNode();
- } else if(path.getSchemaNode() instanceof SchemaContext) {
- parentSchema = path.getSchemaContext();
- } else {
- if (SchemaPath.ROOT.equals(path.getSchemaNode().getPath().getParent())) {
- parentSchema = path.getSchemaContext();
- } else {
- parentSchema = SchemaContextUtil.findDataSchemaNode(path.getSchemaContext(), path.getSchemaNode().getPath().getParent());
- }
- }
-
- final JsonParserStream jsonParser = JsonParserStream.create(writer, path.getSchemaContext(), parentSchema);
- final JsonReader reader = new JsonReader(new InputStreamReader(entityStream));
- jsonParser.parse(reader);
-
- NormalizedNode<?, ?> result = resultHolder.getResult();
- final List<YangInstanceIdentifier.PathArgument> iiToDataList = new ArrayList<>();
- InstanceIdentifierContext<? extends SchemaNode> newIIContext;
-
- while (result instanceof AugmentationNode || result instanceof ChoiceNode) {
- final Object childNode = ((DataContainerNode) result).getValue().iterator().next();
- if (isPost()) {
- iiToDataList.add(result.getIdentifier());
- }
- result = (NormalizedNode<?, ?>) childNode;
- }
-
- if (isPost()) {
- if (result instanceof MapEntryNode) {
- iiToDataList.add(new YangInstanceIdentifier.NodeIdentifier(result.getNodeType()));
- iiToDataList.add(result.getIdentifier());
- } else {
- iiToDataList.add(result.getIdentifier());
- }
- } else {
- if (result instanceof MapNode) {
- result = Iterables.getOnlyElement(((MapNode) result).getValue());
- }
- }
-
- final YangInstanceIdentifier fullIIToData = YangInstanceIdentifier.create(Iterables.concat(
- path.getInstanceIdentifier().getPathArguments(), iiToDataList));
-
- newIIContext = new InstanceIdentifierContext<>(fullIIToData, path.getSchemaNode(), path.getMountPoint(),
- path.getSchemaContext());
-
- return new NormalizedNodeContext(newIIContext, result);
- } catch (final RestconfDocumentedException e) {
- throw e;
- } catch (final ResultAlreadySetException e) {
- LOG.debug("Error parsing json input:", e);
-
- throw new RestconfDocumentedException("Error parsing json input: Failed to create new parse result data. " +
- "Are you creating multiple resources/subresources in POST request?");
- } catch (final Exception e) {
- LOG.debug("Error parsing json input", e);
-
- throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE);
- }
- }
-}
-
+++ /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.rest.impl;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.gson.stream.JsonWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.net.URI;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import org.opendaylight.controller.sal.rest.api.Draft02;
-import org.opendaylight.controller.sal.rest.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.controller.sal.rest.api.RestconfService;
-import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
-import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-@Provider
-@Produces({ Draft02.MediaTypes.API + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
- Draft02.MediaTypes.OPERATION + RestconfService.JSON, MediaType.APPLICATION_JSON })
-public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<NormalizedNodeContext> {
-
- private static final int DEFAULT_INDENT_SPACES_NUM = 2;
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
- return type.equals(NormalizedNodeContext.class);
- }
-
- @Override
- public long getSize(final NormalizedNodeContext t, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final NormalizedNodeContext t, final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream)
- throws IOException, WebApplicationException {
- NormalizedNode<?, ?> data = t.getData();
- if (data == null) {
- return;
- }
-
- @SuppressWarnings("unchecked")
- final InstanceIdentifierContext<SchemaNode> context = (InstanceIdentifierContext<SchemaNode>) t.getInstanceIdentifierContext();
-
- SchemaPath path = context.getSchemaNode().getPath();
- final JsonWriter jsonWriter = createJsonWriter(entityStream, t.getWriterParameters().isPrettyPrint());
- jsonWriter.beginObject();
- writeNormalizedNode(jsonWriter,path,context,data, t.getWriterParameters().getDepth());
- jsonWriter.endObject();
- jsonWriter.flush();
- }
-
- private void writeNormalizedNode(JsonWriter jsonWriter, SchemaPath path,
- InstanceIdentifierContext<SchemaNode> context, NormalizedNode<?, ?> data, Optional<Integer> depth) throws
- IOException {
- final RestconfNormalizedNodeWriter nnWriter;
- if (SchemaPath.ROOT.equals(path)) {
- /*
- * Creates writer without initialNs and we write children of root data container
- * which is not visible in restconf
- */
- nnWriter = createNormalizedNodeWriter(context,path,jsonWriter, depth);
- writeChildren(nnWriter,(ContainerNode) data);
- } else if (context.getSchemaNode() instanceof RpcDefinition) {
- /*
- * RpcDefinition is not supported as initial codec in JSONStreamWriter,
- * so we need to emit initial output declaratation..
- */
- path = ((RpcDefinition) context.getSchemaNode()).getOutput().getPath();
- nnWriter = createNormalizedNodeWriter(context,path,jsonWriter, depth);
- jsonWriter.name("output");
- jsonWriter.beginObject();
- writeChildren(nnWriter, (ContainerNode) data);
- jsonWriter.endObject();
- } else {
- path = path.getParent();
-
- if(data instanceof MapEntryNode) {
- data = ImmutableNodes.mapNodeBuilder(data.getNodeType()).withChild(((MapEntryNode) data)).build();
- }
- nnWriter = createNormalizedNodeWriter(context,path,jsonWriter, depth);
- nnWriter.write(data);
- }
- nnWriter.flush();
- }
-
- private void writeChildren(final RestconfNormalizedNodeWriter nnWriter, final ContainerNode data) throws IOException {
- for(final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
- nnWriter.write(child);
- }
- }
-
- private RestconfNormalizedNodeWriter createNormalizedNodeWriter(final InstanceIdentifierContext<SchemaNode> context,
- final SchemaPath path, final JsonWriter jsonWriter, Optional<Integer> depth) {
-
- final SchemaNode schema = context.getSchemaNode();
- final JSONCodecFactory codecs = getCodecFactory(context);
-
- final URI initialNs;
- if ((schema instanceof DataSchemaNode)
- && !((DataSchemaNode)schema).isAugmenting()
- && !(schema instanceof SchemaContext)) {
- initialNs = schema.getQName().getNamespace();
- } else if (schema instanceof RpcDefinition) {
- initialNs = schema.getQName().getNamespace();
- } else {
- initialNs = null;
- }
- final NormalizedNodeStreamWriter streamWriter = JSONNormalizedNodeStreamWriter.createNestedWriter(codecs,path,initialNs,jsonWriter);
- if (depth.isPresent()) {
- return DepthAwareNormalizedNodeWriter.forStreamWriter(streamWriter, depth.get());
- } else {
- return RestconfDelegatingNormalizedNodeWriter.forStreamWriter(streamWriter);
- }
- }
-
- private JsonWriter createJsonWriter(final OutputStream entityStream, boolean prettyPrint) {
- if (prettyPrint) {
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8),
- DEFAULT_INDENT_SPACES_NUM);
- } else {
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
- }
- }
-
- private JSONCodecFactory getCodecFactory(final InstanceIdentifierContext<?> context) {
- // TODO: Performance: Cache JSON Codec factory and schema context
- return JSONCodecFactory.create(context.getSchemaContext());
- }
-
-}
+++ /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.rest.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import javanet.staxutils.IndentingXMLStreamWriter;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import javax.xml.XMLConstants;
-import javax.xml.stream.FactoryConfigurationError;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.controller.sal.rest.api.Draft02;
-import org.opendaylight.controller.sal.rest.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.controller.sal.rest.api.RestconfService;
-import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
-import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-@Provider
-@Produces({ Draft02.MediaTypes.API + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML,
- Draft02.MediaTypes.OPERATION + RestconfService.XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
-public class NormalizedNodeXmlBodyWriter implements MessageBodyWriter<NormalizedNodeContext> {
-
- private static final XMLOutputFactory XML_FACTORY;
-
- static {
- XML_FACTORY = XMLOutputFactory.newFactory();
- XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
- }
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return type.equals(NormalizedNodeContext.class);
- }
-
- @Override
- public long getSize(final NormalizedNodeContext t, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final NormalizedNodeContext t, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
- WebApplicationException {
- final InstanceIdentifierContext<?> pathContext = t.getInstanceIdentifierContext();
- if (t.getData() == null) {
- return;
- }
-
- XMLStreamWriter xmlWriter;
- try {
- xmlWriter = XML_FACTORY.createXMLStreamWriter(entityStream);
- if (t.getWriterParameters().isPrettyPrint()) {
- xmlWriter = new IndentingXMLStreamWriter(xmlWriter);
- }
- } catch (final XMLStreamException e) {
- throw new IllegalStateException(e);
- } catch (final FactoryConfigurationError e) {
- throw new IllegalStateException(e);
- }
- NormalizedNode<?, ?> data = t.getData();
- SchemaPath schemaPath = pathContext.getSchemaNode().getPath();
-
-
-
- writeNormalizedNode(xmlWriter, schemaPath, pathContext, data, t.getWriterParameters().getDepth());
-
- }
-
- private void writeNormalizedNode(XMLStreamWriter xmlWriter, SchemaPath schemaPath, InstanceIdentifierContext<?>
- pathContext, NormalizedNode<?, ?> data, Optional<Integer> depth) throws IOException {
- final RestconfNormalizedNodeWriter nnWriter;
- final SchemaContext schemaCtx = pathContext.getSchemaContext();
- if (SchemaPath.ROOT.equals(schemaPath)) {
- nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, schemaPath, depth);
- writeElements(xmlWriter, nnWriter, (ContainerNode) data);
- } else if (pathContext.getSchemaNode() instanceof RpcDefinition) {
- nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx,
- ((RpcDefinition) pathContext.getSchemaNode()).getOutput().getPath(), depth);
- writeElements(xmlWriter, nnWriter, (ContainerNode) data);
- } else {
- nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, schemaPath.getParent(), depth);
- if (data instanceof MapEntryNode) {
- // Restconf allows returning one list item. We need to wrap it
- // in map node in order to serialize it properly
- data = ImmutableNodes.mapNodeBuilder(data.getNodeType()).addChild((MapEntryNode) data).build();
- }
- nnWriter.write(data);
- }
- nnWriter.flush();
- }
-
- private RestconfNormalizedNodeWriter createNormalizedNodeWriter(XMLStreamWriter xmlWriter,
- SchemaContext schemaContext, SchemaPath schemaPath, Optional<Integer> depth) {
- NormalizedNodeStreamWriter xmlStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter, schemaContext, schemaPath);
- if (depth.isPresent()) {
- return DepthAwareNormalizedNodeWriter.forStreamWriter(xmlStreamWriter, depth.get());
- } else {
- return RestconfDelegatingNormalizedNodeWriter.forStreamWriter(xmlStreamWriter);
- }
- }
-
- private void writeElements(final XMLStreamWriter xmlWriter, final RestconfNormalizedNodeWriter nnWriter,
- final ContainerNode data)
- throws IOException {
- try {
- final QName name = data.getNodeType();
- xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, name.getLocalName(), name.getNamespace().toString());
- xmlWriter.writeDefaultNamespace(name.getNamespace().toString());
- for(NormalizedNode<?,?> child : data.getValue()) {
- nnWriter.write(child);
- }
- nnWriter.flush();
- xmlWriter.writeEndElement();
- xmlWriter.flush();
- } catch (final XMLStreamException e) {
- Throwables.propagate(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.sal.rest.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.xml.stream.events.StartElement;
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.Predicate;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
-public final class RestUtil {
-
- // FIXME: BUG-1275: this is code duplicates data.impl.codec
-
- public static final String SQUOTE = "'";
- public static final String DQUOTE = "\"";
- private static final Pattern PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
-
- public final static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
- TypeDefinition<?> superType = type;
- while (superType.getBaseType() != null) {
- superType = superType.getBaseType();
- }
- return superType;
- }
-
- public static IdentityValuesDTO asInstanceIdentifier(final String value, final PrefixesMaping prefixMap) {
- final String valueTrimmed = value.trim();
- if (!valueTrimmed.startsWith("/")) {
- return null;
- }
- final String[] xPathParts = valueTrimmed.split("/");
- if (xPathParts.length < 2) { // must be at least "/pr:node"
- return null;
- }
- final IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(value);
- for (int i = 1; i < xPathParts.length; i++) {
- final String xPathPartTrimmed = xPathParts[i].trim();
-
- final String xPathPartStr = getIdAndPrefixAsStr(xPathPartTrimmed);
- final IdentityValue identityValue = toIdentity(xPathPartStr, prefixMap);
- if (identityValue == null) {
- return null;
- }
-
- final List<Predicate> predicates = toPredicates(xPathPartTrimmed, prefixMap);
- if (predicates == null) {
- return null;
- }
- identityValue.setPredicates(predicates);
-
- identityValuesDTO.add(identityValue);
- }
- return identityValuesDTO.getValuesWithNamespaces().isEmpty() ? null : identityValuesDTO;
- }
-
- private static String getIdAndPrefixAsStr(final String pathPart) {
- final int predicateStartIndex = pathPart.indexOf("[");
- return predicateStartIndex == -1 ? pathPart : pathPart.substring(0, predicateStartIndex);
- }
-
- private static IdentityValue toIdentity(final String xPathPart, final PrefixesMaping prefixMap) {
- final String xPathPartTrimmed = xPathPart.trim();
- if (xPathPartTrimmed.isEmpty()) {
- return null;
- }
- final String[] prefixAndIdentifier = xPathPartTrimmed.split(":");
- // it is not "prefix:value"
- if (prefixAndIdentifier.length != 2) {
- return null;
- }
- final String prefix = prefixAndIdentifier[0].trim();
- final String identifier = prefixAndIdentifier[1].trim();
- if (prefix.isEmpty() || identifier.isEmpty()) {
- return null;
- }
- final String namespace = prefixMap.getNamespace(prefix);
- return new IdentityValue(namespace, identifier);
- }
-
- private static List<Predicate> toPredicates(final String predicatesStr, final PrefixesMaping prefixMap) {
- final List<Predicate> result = new ArrayList<>();
- final List<String> predicates = new ArrayList<>();
- final Matcher matcher = PREDICATE_PATTERN.matcher(predicatesStr);
- while (matcher.find()) {
- predicates.add(matcher.group(1).trim());
- }
- for (final String predicate : predicates) {
- final int indexOfEqualityMark = predicate.indexOf("=");
- if (indexOfEqualityMark != -1) {
- final String predicateValue = toPredicateValue(predicate.substring(indexOfEqualityMark + 1));
- if (predicate.startsWith(".")) { // it is leaf-list
- if (predicateValue == null) {
- return null;
- }
- result.add(new Predicate(null, predicateValue));
- } else {
- final IdentityValue identityValue = toIdentity(predicate.substring(0, indexOfEqualityMark), prefixMap);
- if (identityValue == null || predicateValue == null) {
- return null;
- }
- result.add(new Predicate(identityValue, predicateValue));
- }
- }
- }
- return result;
- }
-
- private static String toPredicateValue(final String predicatedValue) {
- final String predicatedValueTrimmed = predicatedValue.trim();
- if ((predicatedValueTrimmed.startsWith(DQUOTE) || predicatedValueTrimmed.startsWith(SQUOTE))
- && (predicatedValueTrimmed.endsWith(DQUOTE) || predicatedValueTrimmed.endsWith(SQUOTE))) {
- return predicatedValueTrimmed.substring(1, predicatedValueTrimmed.length() - 1);
- }
- return null;
- }
-
- public interface PrefixesMaping {
- public String getNamespace(String prefix);
- }
-
- public static class PrefixMapingFromXml implements PrefixesMaping {
- StartElement startElement = null;
-
- public PrefixMapingFromXml(final StartElement startElement) {
- this.startElement = startElement;
- }
-
- @Override
- public String getNamespace(final String prefix) {
- return startElement.getNamespaceContext().getNamespaceURI(prefix);
- }
- }
-
- public static class PrefixMapingFromJson implements PrefixesMaping {
-
- @Override
- public String getNamespace(final String prefix) {
- return prefix;
- }
- }
-
-}
+++ /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.rest.impl;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.HashSet;
-import java.util.Set;
-import javax.ws.rs.core.Application;
-import org.opendaylight.controller.md.sal.rest.schema.SchemaExportContentYangBodyWriter;
-import org.opendaylight.controller.md.sal.rest.schema.SchemaExportContentYinBodyWriter;
-import org.opendaylight.controller.md.sal.rest.schema.SchemaRetrievalServiceImpl;
-import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.controller.sal.restconf.impl.StatisticsRestconfServiceWrapper;
-
-public class RestconfApplication extends Application {
-
- @Override
- public Set<Class<?>> getClasses() {
- return ImmutableSet.<Class<?>> builder()
- .add(RestconfDocumentedExceptionMapper.class)
- .add(XmlNormalizedNodeBodyReader.class)
- .add(JsonNormalizedNodeBodyReader.class)
- .add(NormalizedNodeJsonBodyWriter.class)
- .add(NormalizedNodeXmlBodyWriter.class)
- .add(SchemaExportContentYinBodyWriter.class)
- .add(SchemaExportContentYangBodyWriter.class)
- .build();
- }
-
- @Override
- public Set<Object> getSingletons() {
- final Set<Object> singletons = new HashSet<>();
- final ControllerContext controllerContext = ControllerContext.getInstance();
- final BrokerFacade brokerFacade = BrokerFacade.getInstance();
- final RestconfImpl restconfImpl = RestconfImpl.getInstance();
- final SchemaRetrievalServiceImpl schemaRetrieval = new SchemaRetrievalServiceImpl(controllerContext);
- restconfImpl.setBroker(brokerFacade);
- restconfImpl.setControllerContext(controllerContext);
- singletons.add(controllerContext);
- singletons.add(brokerFacade);
- singletons.add(schemaRetrieval);
- singletons.add(new RestconfCompositeWrapper(StatisticsRestconfServiceWrapper.getInstance(), schemaRetrieval));
-// singletons.add(StructuredDataToXmlProvider.INSTANCE);
-// singletons.add(StructuredDataToJsonProvider.INSTANCE);
-// singletons.add(JsonToCompositeNodeProvider.INSTANCE);
-// singletons.add(XmlToCompositeNodeProvider.INSTANCE);
- return singletons;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.rest.impl;
-
-import com.google.common.base.Preconditions;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.controller.md.sal.rest.schema.SchemaExportContext;
-import org.opendaylight.controller.md.sal.rest.schema.SchemaRetrievalService;
-import org.opendaylight.controller.sal.rest.api.RestconfService;
-import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
-
-public class RestconfCompositeWrapper implements RestconfService, SchemaRetrievalService {
-
- private final RestconfService restconf;
- private final SchemaRetrievalService schema;
-
- public RestconfCompositeWrapper(final RestconfService restconf, final SchemaRetrievalService schema) {
- this.restconf = Preconditions.checkNotNull(restconf);
- this.schema = Preconditions.checkNotNull(schema);
- }
-
- @Override
- public Object getRoot() {
- return restconf.getRoot();
- }
-
- @Override
- public NormalizedNodeContext getModules(final UriInfo uriInfo) {
- return restconf.getModules(uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getModules(final String identifier, final UriInfo uriInfo) {
- return restconf.getModules(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) {
- return restconf.getModule(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getOperations(final UriInfo uriInfo) {
- return restconf.getOperations(uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getOperations(final String identifier, final UriInfo uriInfo) {
- return restconf.getOperations(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
- return restconf.invokeRpc(identifier, payload, uriInfo);
- }
-
- @Override
- @Deprecated
- public NormalizedNodeContext invokeRpc(final String identifier, final String noPayload, final UriInfo uriInfo) {
- return restconf.invokeRpc(identifier, noPayload, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
- return restconf.readConfigurationData(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo uriInfo) {
- return restconf.readOperationalData(identifier, uriInfo);
- }
-
- @Override
- public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload) {
- return restconf.updateConfigurationData(identifier, payload);
- }
-
- @Override
- public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
- return restconf.createConfigurationData(identifier, payload, uriInfo);
- }
-
- @Override
- public Response createConfigurationData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
- return restconf.createConfigurationData(payload, uriInfo);
- }
-
- @Override
- public Response deleteConfigurationData(final String identifier) {
- return restconf.deleteConfigurationData(identifier);
- }
-
- @Override
- public Response subscribeToStream(final String identifier, final UriInfo uriInfo) {
- return restconf.subscribeToStream(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getAvailableStreams(final UriInfo uriInfo) {
- return restconf.getAvailableStreams(uriInfo);
- }
-
- @Override
- public SchemaExportContext getSchema(final String mountId) {
- return schema.getSchema(mountId);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.rest.impl;
-
-import java.io.IOException;
-import org.opendaylight.controller.sal.rest.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-
-/**
- * This class just delegates all of the functionality to Yangtools normalized node writer
- */
-public class RestconfDelegatingNormalizedNodeWriter implements RestconfNormalizedNodeWriter {
- private NormalizedNodeWriter delegNNWriter;
-
- private RestconfDelegatingNormalizedNodeWriter(NormalizedNodeStreamWriter streamWriter, final boolean
- orderKeyLeaves) {
- this.delegNNWriter = NormalizedNodeWriter.forStreamWriter(streamWriter, orderKeyLeaves);
- }
-
- public static RestconfDelegatingNormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer) {
- return forStreamWriter(writer, true);
- }
-
- public static RestconfDelegatingNormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer, final boolean
- orderKeyLeaves) {
- return new RestconfDelegatingNormalizedNodeWriter(writer, orderKeyLeaves);
- }
-
- public RestconfDelegatingNormalizedNodeWriter write(final NormalizedNode<?, ?> node) throws IOException {
- delegNNWriter.write(node);
- return this;
- }
-
- @Override
- public void flush() throws IOException {
- delegNNWriter.flush();
- }
-
- @Override
- public void close() throws IOException {
- delegNNWriter.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.rest.impl;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
-import com.google.gson.stream.JsonWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.net.URI;
-import java.util.Iterator;
-import java.util.List;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.ext.ExceptionMapper;
-import javax.ws.rs.ext.Provider;
-import javax.xml.XMLConstants;
-import javax.xml.stream.FactoryConfigurationError;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.controller.sal.rest.api.Draft02;
-import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
-import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-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.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class defines an ExceptionMapper that handles RestconfDocumentedExceptions thrown by resource implementations
- * and translates appropriately to restconf error response as defined in the RESTCONF RFC draft.
- *
- * @author Thomas Pantelis
- */
-@Provider
-public class RestconfDocumentedExceptionMapper implements ExceptionMapper<RestconfDocumentedException> {
-
- private final static Logger LOG = LoggerFactory.getLogger(RestconfDocumentedExceptionMapper.class);
-
- private static final XMLOutputFactory XML_FACTORY;
-
- static {
- XML_FACTORY = XMLOutputFactory.newFactory();
- XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
- }
-
- @Context
- private HttpHeaders headers;
-
- @Override
- public Response toResponse(final RestconfDocumentedException exception) {
-
- LOG.debug("In toResponse: {}", exception.getMessage());
-
- final List<MediaType> accepts = headers.getAcceptableMediaTypes();
- accepts.remove(MediaType.WILDCARD_TYPE);
-
- LOG.debug("Accept headers: {}", accepts);
-
- final MediaType mediaType;
- if (accepts != null && accepts.size() > 0) {
- mediaType = accepts.get(0); // just pick the first one
- } else {
- // Default to the content type if there's no Accept header
- mediaType = MediaType.APPLICATION_JSON_TYPE;
- }
-
- LOG.debug("Using MediaType: {}", mediaType);
-
- final List<RestconfError> errors = exception.getErrors();
- if (errors.isEmpty()) {
- // We don't actually want to send any content but, if we don't set any content here,
- // the tomcat front-end will send back an html error report. To prevent that, set a
- // single space char in the entity.
-
- return Response.status(exception.getStatus()).type(MediaType.TEXT_PLAIN_TYPE).entity(" ").build();
- }
-
- final int status = errors.iterator().next().getErrorTag().getStatusCode();
-
- final ControllerContext context = ControllerContext.getInstance();
- final DataNodeContainer errorsSchemaNode = (DataNodeContainer) context.getRestconfModuleErrorsSchemaNode();
-
- if (errorsSchemaNode == null) {
- return Response.status(status).type(MediaType.TEXT_PLAIN_TYPE).entity(exception.getMessage()).build();
- }
-
- Preconditions.checkState(errorsSchemaNode instanceof ContainerSchemaNode,
- "Found Errors SchemaNode isn't ContainerNode");
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> errContBuild =
- Builders.containerBuilder((ContainerSchemaNode) errorsSchemaNode);
-
- final List<DataSchemaNode> schemaList = ControllerContext.findInstanceDataChildrenByName(errorsSchemaNode,
- Draft02.RestConfModule.ERROR_LIST_SCHEMA_NODE);
- final DataSchemaNode errListSchemaNode = Iterables.getFirst(schemaList, null);
- Preconditions.checkState(errListSchemaNode instanceof ListSchemaNode, "Found Error SchemaNode isn't ListSchemaNode");
- final CollectionNodeBuilder<MapEntryNode, MapNode> listErorsBuilder = Builders
- .mapBuilder((ListSchemaNode) errListSchemaNode);
-
-
- for (final RestconfError error : errors) {
- listErorsBuilder.withChild(toErrorEntryNode(error, errListSchemaNode));
- }
- errContBuild.withChild(listErorsBuilder.build());
-
- final NormalizedNodeContext errContext = new NormalizedNodeContext(new InstanceIdentifierContext<>(null,
- (DataSchemaNode) errorsSchemaNode, null, context.getGlobalSchema()), errContBuild.build());
-
- Object responseBody;
- if (mediaType.getSubtype().endsWith("json")) {
- responseBody = toJsonResponseBody(errContext, errorsSchemaNode);
- } else {
- responseBody = toXMLResponseBody(errContext, errorsSchemaNode);
- }
-
- return Response.status(status).type(mediaType).entity(responseBody).build();
- }
-
- private MapEntryNode toErrorEntryNode(final RestconfError error, final DataSchemaNode errListSchemaNode) {
- Preconditions.checkArgument(errListSchemaNode instanceof ListSchemaNode,
- "errListSchemaNode has to be of type ListSchemaNode");
- final ListSchemaNode listStreamSchemaNode = (ListSchemaNode) errListSchemaNode;
- final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> errNodeValues = Builders
- .mapEntryBuilder(listStreamSchemaNode);
-
- List<DataSchemaNode> lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName(
- (listStreamSchemaNode), "error-type");
- final DataSchemaNode errTypSchemaNode = Iterables.getFirst(lsChildDataSchemaNode, null);
- Preconditions.checkState(errTypSchemaNode instanceof LeafSchemaNode);
- errNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) errTypSchemaNode)
- .withValue(error.getErrorType().getErrorTypeTag()).build());
-
- lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName(
- (listStreamSchemaNode), "error-tag");
- final DataSchemaNode errTagSchemaNode = Iterables.getFirst(lsChildDataSchemaNode, null);
- Preconditions.checkState(errTagSchemaNode instanceof LeafSchemaNode);
- errNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) errTagSchemaNode)
- .withValue(error.getErrorTag().getTagValue()).build());
-
- if (error.getErrorAppTag() != null) {
- lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName(
- (listStreamSchemaNode), "error-app-tag");
- final DataSchemaNode errAppTagSchemaNode = Iterables.getFirst(lsChildDataSchemaNode, null);
- Preconditions.checkState(errAppTagSchemaNode instanceof LeafSchemaNode);
- errNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) errAppTagSchemaNode)
- .withValue(error.getErrorAppTag()).build());
- }
-
- lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName(
- (listStreamSchemaNode), "error-message");
- final DataSchemaNode errMsgSchemaNode = Iterables.getFirst(lsChildDataSchemaNode, null);
- Preconditions.checkState(errMsgSchemaNode instanceof LeafSchemaNode);
- errNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) errMsgSchemaNode)
- .withValue(error.getErrorMessage()).build());
-
- if(error.getErrorInfo() != null) {
- // Oddly, error-info is defined as an empty container in the restconf yang. Apparently the
- // intention is for implementors to define their own data content so we'll just treat it as a leaf
- // with string data.
- errNodeValues.withChild(ImmutableNodes.leafNode(Draft02.RestConfModule.ERROR_INFO_QNAME,
- error.getErrorInfo()));
- }
-
- // TODO : find how could we add possible "error-path"
-
- return errNodeValues.build();
- }
-
- private Object toJsonResponseBody(final NormalizedNodeContext errorsNode, final DataNodeContainer errorsSchemaNode) {
-
- final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
- NormalizedNode<?, ?> data = errorsNode.getData();
- final InstanceIdentifierContext<?> context = errorsNode.getInstanceIdentifierContext();
- final DataSchemaNode schema = (DataSchemaNode) context.getSchemaNode();
-
- SchemaPath path = context.getSchemaNode().getPath();
- final OutputStreamWriter outputWriter = new OutputStreamWriter(outStream, Charsets.UTF_8);
- if (data == null) {
- throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
- }
-
- boolean isDataRoot = false;
- URI initialNs = null;
- if (SchemaPath.ROOT.equals(path)) {
- isDataRoot = true;
- } else {
- path = path.getParent();
- // FIXME: Add proper handling of reading root.
- }
- if(!schema.isAugmenting() && !(schema instanceof SchemaContext)) {
- initialNs = schema.getQName().getNamespace();
- }
-
- final JsonWriter jsonWriter = JsonWriterFactory.createJsonWriter(outputWriter);
- final NormalizedNodeStreamWriter jsonStreamWriter = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
- JSONCodecFactory.create(context.getSchemaContext()), path, initialNs, jsonWriter);
-
- // We create a delegating writer to special-case error-info as error-info is defined as an empty
- // container in the restconf yang schema but we create a leaf node so we can output it. The delegate
- // stream writer validates the node type against the schema and thus will expect a LeafSchemaNode but
- // the schema has a ContainerSchemaNode so, to avoid an error, we override the leafNode behavior
- // for error-info.
- final NormalizedNodeStreamWriter streamWriter = new DelegatingNormalizedNodeStreamWriter(jsonStreamWriter) {
- @Override
- public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
- if(name.getNodeType().equals(Draft02.RestConfModule.ERROR_INFO_QNAME)) {
- jsonWriter.name(Draft02.RestConfModule.ERROR_INFO_QNAME.getLocalName());
- jsonWriter.value(value.toString());
- } else {
- super.leafNode(name, value);
- }
- }
- };
-
- final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(streamWriter);
- try {
- if(isDataRoot) {
- writeDataRoot(outputWriter,nnWriter,(ContainerNode) data);
- } else {
- if(data instanceof MapEntryNode) {
- data = ImmutableNodes.mapNodeBuilder(data.getNodeType()).withChild(((MapEntryNode) data)).build();
- }
- nnWriter.write(data);
- }
- nnWriter.flush();
- outputWriter.flush();
- }
- catch (final IOException e) {
- LOG.warn("Error writing error response body", e);
- }
-
- return outStream.toString();
-
- }
-
- private Object toXMLResponseBody(final NormalizedNodeContext errorsNode, final DataNodeContainer errorsSchemaNode) {
-
- final InstanceIdentifierContext<?> pathContext = errorsNode.getInstanceIdentifierContext();
- final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-
- final XMLStreamWriter xmlWriter;
- try {
- xmlWriter = XML_FACTORY.createXMLStreamWriter(outStream, "UTF-8");
- } catch (final XMLStreamException e) {
- throw new IllegalStateException(e);
- } catch (final FactoryConfigurationError e) {
- throw new IllegalStateException(e);
- }
- NormalizedNode<?, ?> data = errorsNode.getData();
- SchemaPath schemaPath = pathContext.getSchemaNode().getPath();
-
- boolean isDataRoot = false;
- if (SchemaPath.ROOT.equals(schemaPath)) {
- isDataRoot = true;
- } else {
- schemaPath = schemaPath.getParent();
- }
-
- final NormalizedNodeStreamWriter xmlStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter,
- pathContext.getSchemaContext(), schemaPath);
-
- // We create a delegating writer to special-case error-info as error-info is defined as an empty
- // container in the restconf yang schema but we create a leaf node so we can output it. The delegate
- // stream writer validates the node type against the schema and thus will expect a LeafSchemaNode but
- // the schema has a ContainerSchemaNode so, to avoid an error, we override the leafNode behavior
- // for error-info.
- final NormalizedNodeStreamWriter streamWriter = new DelegatingNormalizedNodeStreamWriter(xmlStreamWriter) {
- @Override
- public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
- if(name.getNodeType().equals(Draft02.RestConfModule.ERROR_INFO_QNAME)) {
- String ns = Draft02.RestConfModule.ERROR_INFO_QNAME.getNamespace().toString();
- try {
- xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX,
- Draft02.RestConfModule.ERROR_INFO_QNAME.getLocalName(), ns);
- xmlWriter.writeCharacters(value.toString());
- xmlWriter.writeEndElement();
- } catch (XMLStreamException e) {
- throw new IOException("Error writing error-info", e);
- }
- } else {
- super.leafNode(name, value);
- }
- }
- };
-
- final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(streamWriter);
- try {
- if (isDataRoot) {
- writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
- } else {
- if (data instanceof MapEntryNode) {
- // Restconf allows returning one list item. We need to wrap it
- // in map node in order to serialize it properly
- data = ImmutableNodes.mapNodeBuilder(data.getNodeType()).addChild((MapEntryNode) data).build();
- }
- nnWriter.write(data);
- nnWriter.flush();
- }
- }
- catch (final IOException e) {
- LOG.warn("Error writing error response body.", e);
- }
-
- return outStream.toString();
- }
-
- private void writeRootElement(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter, final ContainerNode data)
- throws IOException {
- try {
- final QName name = SchemaContext.NAME;
- xmlWriter.writeStartElement(name.getNamespace().toString(), name.getLocalName());
- for (final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
- nnWriter.write(child);
- }
- nnWriter.flush();
- xmlWriter.writeEndElement();
- xmlWriter.flush();
- } catch (final XMLStreamException e) {
- Throwables.propagate(e);
- }
- }
-
- private void writeDataRoot(final OutputStreamWriter outputWriter, final NormalizedNodeWriter nnWriter, final ContainerNode data) throws IOException {
- final Iterator<DataContainerChild<? extends PathArgument, ?>> iterator = data.getValue().iterator();
- while(iterator.hasNext()) {
- final DataContainerChild<? extends PathArgument, ?> child = iterator.next();
- nnWriter.write(child);
- nnWriter.flush();
- }
- }
-
- private static class DelegatingNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
- private final NormalizedNodeStreamWriter delegate;
-
- DelegatingNormalizedNodeStreamWriter(NormalizedNodeStreamWriter delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public void leafNode(NodeIdentifier name, Object value) throws IOException, IllegalArgumentException {
- delegate.leafNode(name, value);
- }
-
- @Override
- public void startLeafSet(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException {
- delegate.startLeafSet(name, childSizeHint);
- }
-
- @Override
- public void leafSetEntryNode(Object value) throws IOException, IllegalArgumentException {
- delegate.leafSetEntryNode(value);
- }
-
- @Override
- public void startContainerNode(NodeIdentifier name, int childSizeHint) throws IOException,
- IllegalArgumentException {
- delegate.startContainerNode(name, childSizeHint);
- }
-
- @Override
- public void startUnkeyedList(NodeIdentifier name, int childSizeHint) throws IOException,
- IllegalArgumentException {
- delegate.startUnkeyedList(name, childSizeHint);
- }
-
- @Override
- public void startUnkeyedListItem(NodeIdentifier name, int childSizeHint) throws IOException,
- IllegalStateException {
- delegate.startUnkeyedListItem(name, childSizeHint);
- }
-
- @Override
- public void startMapNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException {
- delegate.startMapNode(name, childSizeHint);
- }
-
- @Override
- public void startMapEntryNode(NodeIdentifierWithPredicates identifier, int childSizeHint) throws IOException,
- IllegalArgumentException {
- delegate.startMapEntryNode(identifier, childSizeHint);
- }
-
- @Override
- public void startOrderedMapNode(NodeIdentifier name, int childSizeHint) throws IOException,
- IllegalArgumentException {
- delegate.startOrderedMapNode(name, childSizeHint);
- }
-
- @Override
- public void startChoiceNode(NodeIdentifier name, int childSizeHint) throws IOException,
- IllegalArgumentException {
- delegate.startChoiceNode(name, childSizeHint);
- }
-
- @Override
- public void startAugmentationNode(AugmentationIdentifier identifier) throws IOException,
- IllegalArgumentException {
- delegate.startAugmentationNode(identifier);
- }
-
- @Override
- public void anyxmlNode(NodeIdentifier name, Object value) throws IOException, IllegalArgumentException {
- delegate.anyxmlNode(name, value);
- }
-
- @Override
- public void endNode() throws IOException, IllegalStateException {
- delegate.endNode();
- }
-
- @Override
- public void close() throws IOException {
- delegate.close();
- }
-
- @Override
- public void flush() throws IOException {
- delegate.flush();
- }
- }
-}
+++ /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.rest.impl;
-
-public class UnsupportedFormatException extends Exception {
-
- private static final long serialVersionUID = -1741388894406313402L;
-
- public UnsupportedFormatException() {
- super();
- }
-
- public UnsupportedFormatException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public UnsupportedFormatException(String message) {
- super(message);
- }
-
- public UnsupportedFormatException(Throwable cause) {
- super(cause);
- }
-
-}
+++ /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.rest.impl;
-
-import com.google.common.collect.Iterables;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.List;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.Provider;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import org.opendaylight.controller.sal.rest.api.Draft02;
-import org.opendaylight.controller.sal.rest.api.RestconfService;
-import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
-import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-@Provider
-@Consumes({ Draft02.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.OPERATION + RestconfService.XML,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
-public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsProvider implements MessageBodyReader<NormalizedNodeContext> {
-
- private final static Logger LOG = LoggerFactory.getLogger(XmlNormalizedNodeBodyReader.class);
- private static final DocumentBuilderFactory BUILDERFACTORY;
-
- static {
- final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- try {
- factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
- factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
- factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
- factory.setXIncludeAware(false);
- factory.setExpandEntityReferences(false);
- } catch (final ParserConfigurationException e) {
- throw new ExceptionInInitializerError(e);
- }
- factory.setNamespaceAware(true);
- factory.setCoalescing(true);
- factory.setIgnoringElementContentWhitespace(true);
- factory.setIgnoringComments(true);
- BUILDERFACTORY = factory;
- }
-
- @Override
- public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return true;
- }
-
- @Override
- public NormalizedNodeContext readFrom(final Class<NormalizedNodeContext> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
- WebApplicationException {
- try {
- final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
-
- if (entityStream.available() < 1) {
- // represent empty nopayload input
- return new NormalizedNodeContext(path, null);
- }
-
- final DocumentBuilder dBuilder;
- try {
- dBuilder = BUILDERFACTORY.newDocumentBuilder();
- } catch (final ParserConfigurationException e) {
- throw new RuntimeException("Failed to parse XML document", e);
- }
- final Document doc = dBuilder.parse(entityStream);
-
- return parse(path,doc);
- } catch (final RestconfDocumentedException e){
- throw e;
- } catch (final Exception e) {
- LOG.debug("Error parsing xml input", e);
-
- throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE);
- }
- }
-
- private NormalizedNodeContext parse(final InstanceIdentifierContext<?> pathContext,final Document doc) {
-
- final List<Element> elements = Collections.singletonList(doc.getDocumentElement());
- final SchemaNode schemaNodeContext = pathContext.getSchemaNode();
- DataSchemaNode schemaNode;
- boolean isRpc = false;
- if (schemaNodeContext instanceof RpcDefinition) {
- schemaNode = ((RpcDefinition) schemaNodeContext).getInput();
- isRpc = true;
- } else if (schemaNodeContext instanceof DataSchemaNode) {
- schemaNode = (DataSchemaNode) schemaNodeContext;
- } else {
- throw new IllegalStateException("Unknow SchemaNode");
- }
-
- final String docRootElm = doc.getDocumentElement().getLocalName();
- final List<YangInstanceIdentifier.PathArgument> iiToDataList = new ArrayList<>();
- InstanceIdentifierContext<? extends SchemaNode> outIIContext;
-
-
- // FIXME the factory instance should be cached if the schema context is the same
- final DomToNormalizedNodeParserFactory parserFactory =
- DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, pathContext.getSchemaContext());
-
- if (isPost() && !isRpc) {
- final Deque<Object> foundSchemaNodes = findPathToSchemaNodeByName(schemaNode, docRootElm);
- if (foundSchemaNodes.isEmpty()) {
- throw new IllegalStateException(String.format("Child \"%s\" was not found in parent schema node \"%s\"",
- docRootElm, schemaNode.getQName()));
- }
- while (!foundSchemaNodes.isEmpty()) {
- final Object child = foundSchemaNodes.pop();
- if (child instanceof AugmentationSchema) {
- final AugmentationSchema augmentSchemaNode = (AugmentationSchema) child;
- iiToDataList.add(SchemaUtils.getNodeIdentifierForAugmentation(augmentSchemaNode));
- } else if (child instanceof DataSchemaNode) {
- schemaNode = (DataSchemaNode) child;
- iiToDataList.add(new YangInstanceIdentifier.NodeIdentifier(schemaNode.getQName()));
- }
- }
- }
-
- NormalizedNode<?, ?> parsed = null;
-
- if(schemaNode instanceof ContainerSchemaNode) {
- parsed = parserFactory.getContainerNodeParser().parse(Collections.singletonList(doc.getDocumentElement()), (ContainerSchemaNode) schemaNode);
- } else if(schemaNode instanceof ListSchemaNode) {
- final ListSchemaNode casted = (ListSchemaNode) schemaNode;
- parsed = parserFactory.getMapEntryNodeParser().parse(elements, casted);
- if (isPost()) {
- iiToDataList.add(parsed.getIdentifier());
- }
- }
- // FIXME : add another DataSchemaNode extensions e.g. LeafSchemaNode
-
- final YangInstanceIdentifier fullIIToData = YangInstanceIdentifier.create(Iterables.concat(
- pathContext.getInstanceIdentifier().getPathArguments(), iiToDataList));
-
- outIIContext = new InstanceIdentifierContext<>(fullIIToData, pathContext.getSchemaNode(), pathContext.getMountPoint(),
- pathContext.getSchemaContext());
-
- return new NormalizedNodeContext(outIIContext, parsed);
- }
-
- private static Deque<Object> findPathToSchemaNodeByName(final DataSchemaNode schemaNode, final String elementName) {
- final Deque<Object> result = new ArrayDeque<>();
- final ArrayList<ChoiceSchemaNode> choiceSchemaNodes = new ArrayList<>();
- final Collection<DataSchemaNode> children = ((DataNodeContainer) schemaNode).getChildNodes();
- for (final DataSchemaNode child : children) {
- if (child instanceof ChoiceSchemaNode) {
- choiceSchemaNodes.add((ChoiceSchemaNode) child);
- } else if (child.getQName().getLocalName().equalsIgnoreCase(elementName)) {
- result.push(child);
- if (child.isAugmenting()) {
- final AugmentationSchema augment = findCorrespondingAugment(schemaNode, child);
- if (augment != null) {
- result.push(augment);
- }
- }
- return result;
- }
- }
-
- for (final ChoiceSchemaNode choiceNode : choiceSchemaNodes) {
- for (final ChoiceCaseNode caseNode : choiceNode.getCases()) {
- final Deque<Object> resultFromRecursion = findPathToSchemaNodeByName(caseNode, elementName);
- if (!resultFromRecursion.isEmpty()) {
- resultFromRecursion.push(choiceNode);
- if (choiceNode.isAugmenting()) {
- final AugmentationSchema augment = findCorrespondingAugment(schemaNode, choiceNode);
- if (augment != null) {
- resultFromRecursion.push(augment);
- }
- }
- return resultFromRecursion;
- }
- }
- }
- return result;
- }
-
- private static AugmentationSchema findCorrespondingAugment(final DataSchemaNode parent, final DataSchemaNode child) {
- if (parent instanceof AugmentationTarget && !(parent instanceof ChoiceSchemaNode)) {
- for (final AugmentationSchema augmentation : ((AugmentationTarget) parent).getAvailableAugmentations()) {
- final DataSchemaNode childInAugmentation = augmentation.getDataChildByName(child.getQName());
- if (childInAugmentation != null) {
- return augmentation;
- }
- }
- }
- return null;
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.rest.impl;
\ No newline at end of file
+++ /dev/null
-/**
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.restconf.impl;
-
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import javax.ws.rs.core.Response.Status;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BrokerFacade {
- private final static Logger LOG = LoggerFactory.getLogger(BrokerFacade.class);
-
- private final static BrokerFacade INSTANCE = new BrokerFacade();
- private volatile DOMRpcService rpcService;
- private volatile ConsumerSession context;
- private DOMDataBroker domDataBroker;
-
- private BrokerFacade() {
- }
-
- public void setRpcService(final DOMRpcService router) {
- rpcService = router;
- }
-
- public void setContext(final ConsumerSession context) {
- this.context = context;
- }
-
- public static BrokerFacade getInstance() {
- return BrokerFacade.INSTANCE;
- }
-
- private void checkPreconditions() {
- if (context == null || domDataBroker == null) {
- throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
- }
- }
-
- // READ configuration
- public NormalizedNode<?, ?> readConfigurationData(final YangInstanceIdentifier path) {
- checkPreconditions();
- return readDataViaTransaction(domDataBroker.newReadOnlyTransaction(), CONFIGURATION, path);
- }
-
- public NormalizedNode<?, ?> readConfigurationData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- return readDataViaTransaction(domDataBrokerService.get().newReadOnlyTransaction(), CONFIGURATION, path);
- }
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
- }
-
- // READ operational
- public NormalizedNode<?, ?> readOperationalData(final YangInstanceIdentifier path) {
- checkPreconditions();
- return readDataViaTransaction(domDataBroker.newReadOnlyTransaction(), OPERATIONAL, path);
- }
-
- public NormalizedNode<?, ?> readOperationalData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- return readDataViaTransaction(domDataBrokerService.get().newReadOnlyTransaction(), OPERATIONAL, path);
- }
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
- }
-
- // PUT configuration
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPut(
- final SchemaContext globalSchema, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
- checkPreconditions();
- return putDataViaTransaction(domDataBroker.newReadWriteTransaction(), CONFIGURATION, path, payload, globalSchema);
- }
-
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPut(
- final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- return putDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path,
- payload, mountPoint.getSchemaContext());
- }
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
- }
-
- // POST configuration
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPost(
- final SchemaContext globalSchema, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
- checkPreconditions();
- return postDataViaTransaction(domDataBroker.newReadWriteTransaction(), CONFIGURATION, path, payload, globalSchema);
- }
-
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPost(
- final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- return postDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path,
- payload, mountPoint.getSchemaContext());
- }
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
- }
-
- // DELETE configuration
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataDelete(
- final YangInstanceIdentifier path) {
- checkPreconditions();
- return deleteDataViaTransaction(domDataBroker.newWriteOnlyTransaction(), CONFIGURATION, path);
- }
-
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataDelete(
- final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- return deleteDataViaTransaction(domDataBrokerService.get().newWriteOnlyTransaction(), CONFIGURATION, path);
- }
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
- }
-
- // RPC
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final SchemaPath type, final NormalizedNode<?, ?> input) {
- checkPreconditions();
- if (rpcService == null) {
- throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
- }
- return rpcService.invokeRpc(type, input);
- }
-
- public void registerToListenDataChanges(final LogicalDatastoreType datastore, final DataChangeScope scope,
- final ListenerAdapter listener) {
- checkPreconditions();
-
- if (listener.isListening()) {
- return;
- }
-
- final YangInstanceIdentifier path = listener.getPath();
- final ListenerRegistration<DOMDataChangeListener> registration = domDataBroker.registerDataChangeListener(
- datastore, path, listener, scope);
-
- listener.setRegistration(registration);
- }
-
- private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataReadTransaction transaction,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path) {
- LOG.trace("Read " + datastore.name() + " via Restconf: {}", path);
- final ListenableFuture<Optional<NormalizedNode<?, ?>>> listenableFuture = transaction.read(datastore, path);
- if (listenableFuture != null) {
- Optional<NormalizedNode<?, ?>> optional;
- try {
- LOG.debug("Reading result data from transaction.");
- optional = listenableFuture.get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.warn("Exception by reading " + datastore.name() + " via Restconf: {}", path, e);
- throw new RestconfDocumentedException("Problem to get data from transaction.", e.getCause());
-
- }
- if (optional != null) {
- if (optional.isPresent()) {
- return optional.get();
- }
- }
- }
- return null;
- }
-
- private CheckedFuture<Void, TransactionCommitFailedException> postDataViaTransaction(
- final DOMDataReadWriteTransaction rWTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) {
- // FIXME: This is doing correct post for container and list children
- // not sure if this will work for choice case
- if(payload instanceof MapNode) {
- final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path);
- rWTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- ensureParentsByMerge(datastore, path, rWTransaction, schemaContext);
- for(final MapEntryNode child : ((MapNode) payload).getValue()) {
- final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
- checkItemDoesNotExists(rWTransaction, datastore, childPath);
- rWTransaction.put(datastore, childPath, child);
- }
- } else {
- checkItemDoesNotExists(rWTransaction,datastore, path);
- ensureParentsByMerge(datastore, path, rWTransaction, schemaContext);
- rWTransaction.put(datastore, path, payload);
- }
- return rWTransaction.submit();
- }
-
- private void checkItemDoesNotExists(final DOMDataReadWriteTransaction rWTransaction,final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- final ListenableFuture<Boolean> futureDatastoreData = rWTransaction.exists(store, path);
- try {
- if (futureDatastoreData.get()) {
- final String errMsg = "Post Configuration via Restconf was not executed because data already exists";
- LOG.trace(errMsg + ":{}", path);
- rWTransaction.cancel();
- throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
- ErrorTag.DATA_EXISTS);
- }
- } catch (InterruptedException | ExecutionException e) {
- LOG.warn("It wasn't possible to get data loaded from datastore at path " + path, e);
- }
-
- }
-
- private CheckedFuture<Void, TransactionCommitFailedException> putDataViaTransaction(
- final DOMDataReadWriteTransaction writeTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) {
- LOG.trace("Put " + datastore.name() + " via Restconf: {}", path);
- ensureParentsByMerge(datastore, path, writeTransaction, schemaContext);
- writeTransaction.put(datastore, path, payload);
- return writeTransaction.submit();
- }
-
- private CheckedFuture<Void, TransactionCommitFailedException> deleteDataViaTransaction(
- final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path) {
- LOG.trace("Delete " + datastore.name() + " via Restconf: {}", path);
- writeTransaction.delete(datastore, path);
- return writeTransaction.submit();
- }
-
- public void setDomDataBroker(final DOMDataBroker domDataBroker) {
- this.domDataBroker = domDataBroker;
- }
-
- private void ensureParentsByMerge(final LogicalDatastoreType store,
- final YangInstanceIdentifier normalizedPath, final DOMDataReadWriteTransaction rwTx, final SchemaContext schemaContext) {
- final List<PathArgument> normalizedPathWithoutChildArgs = new ArrayList<>();
- YangInstanceIdentifier rootNormalizedPath = null;
-
- final Iterator<PathArgument> it = normalizedPath.getPathArguments().iterator();
-
- while(it.hasNext()) {
- final PathArgument pathArgument = it.next();
- if(rootNormalizedPath == null) {
- rootNormalizedPath = YangInstanceIdentifier.create(pathArgument);
- }
-
- // Skip last element, its not a parent
- if(it.hasNext()) {
- normalizedPathWithoutChildArgs.add(pathArgument);
- }
- }
-
- // No parent structure involved, no need to ensure parents
- if(normalizedPathWithoutChildArgs.isEmpty()) {
- return;
- }
-
- Preconditions.checkArgument(rootNormalizedPath != null, "Empty path received");
-
- final NormalizedNode<?, ?> parentStructure =
- ImmutableNodes.fromInstanceId(schemaContext, YangInstanceIdentifier.create(normalizedPathWithoutChildArgs));
- rwTx.merge(store, rootNormalizedPath, parentStructure);
- }
-}
+++ /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;
-
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-import javax.ws.rs.core.Response.Status;
-import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
-import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
-import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.sal.rest.api.Draft02;
-import org.opendaylight.controller.sal.rest.impl.RestUtil;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
-import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.yangtools.concepts.Codec;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ControllerContext implements SchemaContextListener {
- private final static Logger LOG = LoggerFactory.getLogger(ControllerContext.class);
-
- private final static ControllerContext INSTANCE = new ControllerContext();
-
- private final static String NULL_VALUE = "null";
-
- private final static String MOUNT_MODULE = "yang-ext";
-
- private final static String MOUNT_NODE = "mount";
-
- public final static String MOUNT = "yang-ext:mount";
-
- private final static String URI_ENCODING_CHAR_SET = "ISO-8859-1";
-
- private static final Splitter SLASH_SPLITTER = Splitter.on('/');
-
- private static final YangInstanceIdentifier ROOT = YangInstanceIdentifier.builder().build();
-
- private final AtomicReference<Map<QName, RpcDefinition>> qnameToRpc =
- new AtomicReference<>(Collections.<QName, RpcDefinition>emptyMap());
-
- private volatile SchemaContext globalSchema;
- private volatile DOMMountPointService mountService;
-
- private DataNormalizer dataNormalizer;
-
- public void setGlobalSchema(final SchemaContext globalSchema) {
- this.globalSchema = globalSchema;
- dataNormalizer = new DataNormalizer(globalSchema);
- }
-
- public void setMountService(final DOMMountPointService mountService) {
- this.mountService = mountService;
- }
-
- private ControllerContext() {
- }
-
- public static ControllerContext getInstance() {
- return ControllerContext.INSTANCE;
- }
-
- private void checkPreconditions() {
- if (globalSchema == null) {
- throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
- }
- }
-
- public void setSchemas(final SchemaContext schemas) {
- onGlobalContextUpdated(schemas);
- }
-
- public InstanceIdentifierContext<?> toInstanceIdentifier(final String restconfInstance) {
- return toIdentifier(restconfInstance, false);
- }
-
- public SchemaContext getGlobalSchema() {
- return globalSchema;
- }
-
- public InstanceIdentifierContext<?> toMountPointIdentifier(final String restconfInstance) {
- return toIdentifier(restconfInstance, true);
- }
-
- private InstanceIdentifierContext<?> toIdentifier(final String restconfInstance, final boolean toMountPointIdentifier) {
- checkPreconditions();
-
- if(restconfInstance == null) {
- return new InstanceIdentifierContext<>(ROOT, globalSchema, null, globalSchema);
- }
-
- final List<String> pathArgs = urlPathArgsDecode(SLASH_SPLITTER.split(restconfInstance));
- omitFirstAndLastEmptyString(pathArgs);
- if (pathArgs.isEmpty()) {
- return null;
- }
-
- final String first = pathArgs.iterator().next();
- final String startModule = ControllerContext.toModuleName(first);
- if (startModule == null) {
- throw new RestconfDocumentedException("First node in URI has to be in format \"moduleName:nodeName\"",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- final InstanceIdentifierBuilder builder = YangInstanceIdentifier.builder();
- final Module latestModule = globalSchema.findModuleByName(startModule, null);
-
- if (latestModule == null) {
- throw new RestconfDocumentedException("The module named '" + startModule + "' does not exist.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- final InstanceIdentifierContext<?> iiWithSchemaNode = collectPathArguments(builder, pathArgs, latestModule, null,
- toMountPointIdentifier);
-
- if (iiWithSchemaNode == null) {
- throw new RestconfDocumentedException("URI has bad format", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- return iiWithSchemaNode;
- }
-
- private static List<String> omitFirstAndLastEmptyString(final List<String> list) {
- if (list.isEmpty()) {
- return list;
- }
-
- final String head = list.iterator().next();
- if (head.isEmpty()) {
- list.remove(0);
- }
-
- if (list.isEmpty()) {
- return list;
- }
-
- final String last = list.get(list.size() - 1);
- if (last.isEmpty()) {
- list.remove(list.size() - 1);
- }
-
- return list;
- }
- public Module findModuleByName(final String moduleName) {
- checkPreconditions();
- Preconditions.checkArgument(moduleName != null && !moduleName.isEmpty());
- return globalSchema.findModuleByName(moduleName, null);
- }
-
- public Module findModuleByName(final DOMMountPoint mountPoint, final String moduleName) {
- Preconditions.checkArgument(moduleName != null && mountPoint != null);
-
- final SchemaContext mountPointSchema = mountPoint.getSchemaContext();
- if (mountPointSchema == null) {
- return null;
- }
-
- return mountPointSchema.findModuleByName(moduleName, null);
- }
-
- public Module findModuleByNamespace(final URI namespace) {
- checkPreconditions();
- Preconditions.checkArgument(namespace != null);
- return globalSchema.findModuleByNamespaceAndRevision(namespace, null);
- }
-
- public Module findModuleByNamespace(final DOMMountPoint mountPoint, final URI namespace) {
- Preconditions.checkArgument(namespace != null && mountPoint != null);
-
- final SchemaContext mountPointSchema = mountPoint.getSchemaContext();
- if (mountPointSchema == null) {
- return null;
- }
-
- return mountPointSchema.findModuleByNamespaceAndRevision(namespace, null);
- }
-
- public Module findModuleByNameAndRevision(final QName module) {
- checkPreconditions();
- Preconditions.checkArgument(module != null && module.getLocalName() != null && module.getRevision() != null);
-
- return globalSchema.findModuleByName(module.getLocalName(), module.getRevision());
- }
-
- public Module findModuleByNameAndRevision(final DOMMountPoint mountPoint, final QName module) {
- checkPreconditions();
- Preconditions.checkArgument(module != null && module.getLocalName() != null && module.getRevision() != null
- && mountPoint != null);
-
- final SchemaContext schemaContext = mountPoint.getSchemaContext();
- return schemaContext == null ? null : schemaContext.findModuleByName(module.getLocalName(),
- module.getRevision());
- }
-
- public DataNodeContainer getDataNodeContainerFor(final YangInstanceIdentifier path) {
- checkPreconditions();
-
- final Iterable<PathArgument> elements = path.getPathArguments();
- final PathArgument head = elements.iterator().next();
- final QName startQName = head.getNodeType();
- final Module initialModule = globalSchema.findModuleByNamespaceAndRevision(startQName.getNamespace(),
- startQName.getRevision());
- DataNodeContainer node = initialModule;
- for (final PathArgument element : elements) {
- final QName _nodeType = element.getNodeType();
- final DataSchemaNode potentialNode = ControllerContext.childByQName(node, _nodeType);
- if (potentialNode == null || !ControllerContext.isListOrContainer(potentialNode)) {
- return null;
- }
- node = (DataNodeContainer) potentialNode;
- }
-
- return node;
- }
-
- public String toFullRestconfIdentifier(final YangInstanceIdentifier path, final DOMMountPoint mount) {
- checkPreconditions();
-
- final Iterable<PathArgument> elements = path.getPathArguments();
- final StringBuilder builder = new StringBuilder();
- final PathArgument head = elements.iterator().next();
- final QName startQName = head.getNodeType();
- final SchemaContext schemaContext;
- if (mount != null) {
- schemaContext = mount.getSchemaContext();
- } else {
- schemaContext = globalSchema;
- }
- final Module initialModule = schemaContext.findModuleByNamespaceAndRevision(startQName.getNamespace(),
- startQName.getRevision());
- DataNodeContainer node = initialModule;
- for (final PathArgument element : elements) {
- if (!(element instanceof AugmentationIdentifier)) {
- final QName _nodeType = element.getNodeType();
- final DataSchemaNode potentialNode = ControllerContext.childByQName(node, _nodeType);
- if (!(element instanceof NodeIdentifier && potentialNode instanceof ListSchemaNode) &&
- !(potentialNode instanceof ChoiceSchemaNode)) {
- builder.append(convertToRestconfIdentifier(element, potentialNode, mount));
- if (potentialNode instanceof DataNodeContainer) {
- node = (DataNodeContainer) potentialNode;
- }
- }
- }
- }
-
- return builder.toString();
- }
-
- public String findModuleNameByNamespace(final URI namespace) {
- checkPreconditions();
-
- final Module module = this.findModuleByNamespace(namespace);
- return module == null ? null : module.getName();
- }
-
- public String findModuleNameByNamespace(final DOMMountPoint mountPoint, final URI namespace) {
- final Module module = this.findModuleByNamespace(mountPoint, namespace);
- return module == null ? null : module.getName();
- }
-
- public URI findNamespaceByModuleName(final String moduleName) {
- final Module module = this.findModuleByName(moduleName);
- return module == null ? null : module.getNamespace();
- }
-
- public URI findNamespaceByModuleName(final DOMMountPoint mountPoint, final String moduleName) {
- final Module module = this.findModuleByName(mountPoint, moduleName);
- return module == null ? null : module.getNamespace();
- }
-
- public Set<Module> getAllModules(final DOMMountPoint mountPoint) {
- checkPreconditions();
-
- final SchemaContext schemaContext = mountPoint == null ? null : mountPoint.getSchemaContext();
- return schemaContext == null ? null : schemaContext.getModules();
- }
-
- public Set<Module> getAllModules() {
- checkPreconditions();
- return globalSchema.getModules();
- }
-
- private static final CharSequence toRestconfIdentifier(final SchemaContext context, final QName qname) {
- final Module schema = context.findModuleByNamespaceAndRevision(qname.getNamespace(), qname.getRevision());
- return schema == null ? null : schema.getName() + ':' + qname.getLocalName();
- }
-
- public CharSequence toRestconfIdentifier(final QName qname, final DOMMountPoint mount) {
- final SchemaContext schema;
- if (mount != null) {
- schema = mount.getSchemaContext();
- } else {
- checkPreconditions();
- schema = globalSchema;
- }
-
- return toRestconfIdentifier(schema, qname);
- }
-
- public CharSequence toRestconfIdentifier(final QName qname) {
- checkPreconditions();
-
- return toRestconfIdentifier(globalSchema, qname);
- }
-
- public CharSequence toRestconfIdentifier(final DOMMountPoint mountPoint, final QName qname) {
- if (mountPoint == null) {
- return null;
- }
-
- return toRestconfIdentifier(mountPoint.getSchemaContext(), qname);
- }
-
- public Module getRestconfModule() {
- return findModuleByNameAndRevision(Draft02.RestConfModule.IETF_RESTCONF_QNAME);
- }
-
- private static final Predicate<GroupingDefinition> ERRORS_GROUPING_FILTER = new Predicate<GroupingDefinition>() {
- @Override
- public boolean apply(final GroupingDefinition g) {
- return Draft02.RestConfModule.ERRORS_GROUPING_SCHEMA_NODE.equals(g.getQName().getLocalName());
- }
- };
-
- public DataSchemaNode getRestconfModuleErrorsSchemaNode() {
- final Module restconfModule = getRestconfModule();
- if (restconfModule == null) {
- return null;
- }
-
- final Set<GroupingDefinition> groupings = restconfModule.getGroupings();
-
- final Iterable<GroupingDefinition> filteredGroups = Iterables.filter(groupings, ERRORS_GROUPING_FILTER);
-
- final GroupingDefinition restconfGrouping = Iterables.getFirst(filteredGroups, null);
-
- final List<DataSchemaNode> instanceDataChildrenByName = findInstanceDataChildrenByName(restconfGrouping,
- Draft02.RestConfModule.ERRORS_CONTAINER_SCHEMA_NODE);
- return Iterables.getFirst(instanceDataChildrenByName, null);
- }
-
- private static final Predicate<GroupingDefinition> GROUPING_FILTER = new Predicate<GroupingDefinition>() {
- @Override
- public boolean apply(final GroupingDefinition g) {
- return Draft02.RestConfModule.RESTCONF_GROUPING_SCHEMA_NODE.equals(g.getQName().getLocalName());
- }
- };
-
- public DataSchemaNode getRestconfModuleRestConfSchemaNode(final Module inRestconfModule, final String schemaNodeName) {
- Module restconfModule = inRestconfModule;
- if (restconfModule == null) {
- restconfModule = getRestconfModule();
- }
-
- if (restconfModule == null) {
- return null;
- }
-
- final Set<GroupingDefinition> groupings = restconfModule.getGroupings();
- final Iterable<GroupingDefinition> filteredGroups = Iterables.filter(groupings, GROUPING_FILTER);
- final GroupingDefinition restconfGrouping = Iterables.getFirst(filteredGroups, null);
-
- final List<DataSchemaNode> instanceDataChildrenByName = findInstanceDataChildrenByName(restconfGrouping,
- Draft02.RestConfModule.RESTCONF_CONTAINER_SCHEMA_NODE);
- final DataSchemaNode restconfContainer = Iterables.getFirst(instanceDataChildrenByName, null);
-
- if (Objects.equal(schemaNodeName, Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE)) {
- final List<DataSchemaNode> instances = findInstanceDataChildrenByName(
- ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE);
- return Iterables.getFirst(instances, null);
- } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE)) {
- final List<DataSchemaNode> instances = findInstanceDataChildrenByName(
- ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
- return Iterables.getFirst(instances, null);
- } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE)) {
- List<DataSchemaNode> instances = findInstanceDataChildrenByName(
- ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
- final DataSchemaNode modules = Iterables.getFirst(instances, null);
- instances = findInstanceDataChildrenByName(((DataNodeContainer) modules),
- Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
- return Iterables.getFirst(instances, null);
- } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE)) {
- final List<DataSchemaNode> instances = findInstanceDataChildrenByName(
- ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
- return Iterables.getFirst(instances, null);
- } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE)) {
- List<DataSchemaNode> instances = findInstanceDataChildrenByName(
- ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
- final DataSchemaNode modules = Iterables.getFirst(instances, null);
- instances = findInstanceDataChildrenByName(((DataNodeContainer) modules),
- Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
- return Iterables.getFirst(instances, null);
- } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE)) {
- final List<DataSchemaNode> instances = findInstanceDataChildrenByName(
- ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
- return Iterables.getFirst(instances, null);
- }
-
- return null;
- }
-
- private static DataSchemaNode childByQName(final ChoiceSchemaNode container, final QName name) {
- for (final ChoiceCaseNode caze : container.getCases()) {
- final DataSchemaNode ret = ControllerContext.childByQName(caze, name);
- if (ret != null) {
- return ret;
- }
- }
-
- return null;
- }
-
- private static DataSchemaNode childByQName(final ChoiceCaseNode container, final QName name) {
- return container.getDataChildByName(name);
- }
-
- private static DataSchemaNode childByQName(final ContainerSchemaNode container, final QName name) {
- return ControllerContext.dataNodeChildByQName(container, name);
- }
-
- private static DataSchemaNode childByQName(final ListSchemaNode container, final QName name) {
- return ControllerContext.dataNodeChildByQName(container, name);
- }
-
- private static DataSchemaNode childByQName(final Module container, final QName name) {
- return ControllerContext.dataNodeChildByQName(container, name);
- }
-
- private static DataSchemaNode childByQName(final DataSchemaNode container, final QName name) {
- return null;
- }
-
- private static DataSchemaNode dataNodeChildByQName(final DataNodeContainer container, final QName name) {
- final DataSchemaNode ret = container.getDataChildByName(name);
- if (ret == null) {
- for (final DataSchemaNode node : container.getChildNodes()) {
- if ((node instanceof ChoiceSchemaNode)) {
- final ChoiceSchemaNode choiceNode = ((ChoiceSchemaNode) node);
- final DataSchemaNode childByQName = ControllerContext.childByQName(choiceNode, name);
- if (childByQName != null) {
- return childByQName;
- }
- }
- }
- }
- return ret;
- }
-
- private String toUriString(final Object object, final LeafSchemaNode leafNode, final DOMMountPoint mount) throws UnsupportedEncodingException {
- final Codec<Object, Object> codec = RestCodec.from(leafNode.getType(), mount);
- return object == null ? "" : URLEncoder.encode(codec.serialize(object).toString(), ControllerContext.URI_ENCODING_CHAR_SET);
- }
-
- private InstanceIdentifierContext<?> collectPathArguments(final InstanceIdentifierBuilder builder,
- final List<String> strings, final DataNodeContainer parentNode, final DOMMountPoint mountPoint,
- final boolean returnJustMountPoint) {
- Preconditions.<List<String>> checkNotNull(strings);
-
- if (parentNode == null) {
- return null;
- }
-
- if (strings.isEmpty()) {
- return createContext(builder.toInstance(), ((DataSchemaNode) parentNode), mountPoint,mountPoint != null ? mountPoint.getSchemaContext() : globalSchema);
- }
-
- final String head = strings.iterator().next();
- final String nodeName = toNodeName(head);
- final String moduleName = ControllerContext.toModuleName(head);
-
- DataSchemaNode targetNode = null;
- if (!Strings.isNullOrEmpty(moduleName)) {
- if (Objects.equal(moduleName, ControllerContext.MOUNT_MODULE)
- && Objects.equal(nodeName, ControllerContext.MOUNT_NODE)) {
- if (mountPoint != null) {
- throw new RestconfDocumentedException("Restconf supports just one mount point in URI.",
- ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
- }
-
- if (mountService == null) {
- throw new RestconfDocumentedException(
- "MountService was not found. Finding behind mount points does not work.",
- ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
- }
-
- final YangInstanceIdentifier partialPath = dataNormalizer.toNormalized(builder.build());
- final Optional<DOMMountPoint> mountOpt = mountService.getMountPoint(partialPath);
- if (!mountOpt.isPresent()) {
- LOG.debug("Instance identifier to missing mount point: {}", partialPath);
- throw new RestconfDocumentedException("Mount point does not exist.", ErrorType.PROTOCOL,
- ErrorTag.DATA_MISSING);
- }
- final DOMMountPoint mount = mountOpt.get();
-
- final SchemaContext mountPointSchema = mount.getSchemaContext();
- if (mountPointSchema == null) {
- throw new RestconfDocumentedException("Mount point does not contain any schema with modules.",
- ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- if (returnJustMountPoint || strings.size() == 1) {
- final YangInstanceIdentifier instance = YangInstanceIdentifier.builder().toInstance();
- return new InstanceIdentifierContext<>(instance, mountPointSchema, mount,mountPointSchema);
- }
-
- final String moduleNameBehindMountPoint = toModuleName(strings.get(1));
- if (moduleNameBehindMountPoint == null) {
- throw new RestconfDocumentedException(
- "First node after mount point in URI has to be in format \"moduleName:nodeName\"",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- final Module moduleBehindMountPoint = mountPointSchema.findModuleByName(moduleNameBehindMountPoint, null);
- if (moduleBehindMountPoint == null) {
- throw new RestconfDocumentedException("\"" + moduleName
- + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- final List<String> subList = strings.subList(1, strings.size());
- return collectPathArguments(YangInstanceIdentifier.builder(), subList, moduleBehindMountPoint, mount,
- returnJustMountPoint);
- }
-
- Module module = null;
- if (mountPoint == null) {
- checkPreconditions();
- module = globalSchema.findModuleByName(moduleName, null);
- if (module == null) {
- throw new RestconfDocumentedException("\"" + moduleName + "\" module does not exist.",
- ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
- } else {
- final SchemaContext schemaContext = mountPoint.getSchemaContext();
- if (schemaContext != null) {
- module = schemaContext.findModuleByName(moduleName, null);
- } else {
- module = null;
- }
- if (module == null) {
- throw new RestconfDocumentedException("\"" + moduleName
- + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
- }
-
- targetNode = findInstanceDataChildByNameAndNamespace(parentNode, nodeName, module.getNamespace());
-
- if (targetNode == null && parentNode instanceof Module) {
- final RpcDefinition rpc = ControllerContext.getInstance().getRpcDefinition(head);
- if (rpc != null) {
- return new InstanceIdentifierContext<RpcDefinition>(builder.build(), rpc, mountPoint,
- mountPoint != null ? mountPoint.getSchemaContext() : globalSchema);
- }
- }
-
- if (targetNode == null) {
- throw new RestconfDocumentedException("URI has bad format. Possible reasons:\n" + " 1. \"" + head
- + "\" was not found in parent data node.\n" + " 2. \"" + head
- + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + head + "\".",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
- } else {
- final List<DataSchemaNode> potentialSchemaNodes = findInstanceDataChildrenByName(parentNode, nodeName);
- if (potentialSchemaNodes.size() > 1) {
- final StringBuilder strBuilder = new StringBuilder();
- for (final DataSchemaNode potentialNodeSchema : potentialSchemaNodes) {
- strBuilder.append(" ").append(potentialNodeSchema.getQName().getNamespace()).append("\n");
- }
-
- throw new RestconfDocumentedException(
- "URI has bad format. Node \""
- + nodeName
- + "\" is added as augment from more than one module. "
- + "Therefore the node must have module name and it has to be in format \"moduleName:nodeName\"."
- + "\nThe node is added as augment from modules with namespaces:\n"
- + strBuilder.toString(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- if (potentialSchemaNodes.isEmpty()) {
- throw new RestconfDocumentedException("\"" + nodeName + "\" in URI was not found in parent data node",
- ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- targetNode = potentialSchemaNodes.iterator().next();
- }
-
- if (!ControllerContext.isListOrContainer(targetNode)) {
- throw new RestconfDocumentedException("URI has bad format. Node \"" + head
- + "\" must be Container or List yang type.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- int consumed = 1;
- if ((targetNode instanceof ListSchemaNode)) {
- final ListSchemaNode listNode = ((ListSchemaNode) targetNode);
- final int keysSize = listNode.getKeyDefinition().size();
- if ((strings.size() - consumed) < keysSize) {
- throw new RestconfDocumentedException("Missing key for list \"" + listNode.getQName().getLocalName()
- + "\".", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
- }
-
- final List<String> uriKeyValues = strings.subList(consumed, consumed + keysSize);
- final HashMap<QName, Object> keyValues = new HashMap<QName, Object>();
- int i = 0;
- for (final QName key : listNode.getKeyDefinition()) {
- {
- final String uriKeyValue = uriKeyValues.get(i);
- if (uriKeyValue.equals(NULL_VALUE)) {
- throw new RestconfDocumentedException("URI has bad format. List \""
- + listNode.getQName().getLocalName() + "\" cannot contain \"null\" value as a key.",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- addKeyValue(keyValues, listNode.getDataChildByName(key), uriKeyValue, mountPoint);
- i++;
- }
- }
-
- consumed = consumed + i;
- builder.nodeWithKey(targetNode.getQName(), keyValues);
- } else {
- builder.node(targetNode.getQName());
- }
-
- if ((targetNode instanceof DataNodeContainer)) {
- final List<String> remaining = strings.subList(consumed, strings.size());
- return collectPathArguments(builder, remaining, ((DataNodeContainer) targetNode), mountPoint,
- returnJustMountPoint);
- }
-
- return createContext(builder.build(), targetNode, mountPoint,mountPoint != null ? mountPoint.getSchemaContext() : globalSchema);
- }
-
- private InstanceIdentifierContext<?> createContext(final YangInstanceIdentifier instance, final DataSchemaNode dataSchemaNode,
- final DOMMountPoint mountPoint, final SchemaContext schemaContext) {
-
- final YangInstanceIdentifier instanceIdentifier = new DataNormalizer(schemaContext).toNormalized(instance);
- return new InstanceIdentifierContext<>(instanceIdentifier, dataSchemaNode, mountPoint,schemaContext);
- }
-
- public static DataSchemaNode findInstanceDataChildByNameAndNamespace(final DataNodeContainer container, final String name,
- final URI namespace) {
- Preconditions.<URI> checkNotNull(namespace);
-
- final List<DataSchemaNode> potentialSchemaNodes = findInstanceDataChildrenByName(container, name);
-
- final Predicate<DataSchemaNode> filter = new Predicate<DataSchemaNode>() {
- @Override
- public boolean apply(final DataSchemaNode node) {
- return Objects.equal(node.getQName().getNamespace(), namespace);
- }
- };
-
- final Iterable<DataSchemaNode> result = Iterables.filter(potentialSchemaNodes, filter);
- return Iterables.getFirst(result, null);
- }
-
- public static List<DataSchemaNode> findInstanceDataChildrenByName(final DataNodeContainer container, final String name) {
- Preconditions.<DataNodeContainer> checkNotNull(container);
- Preconditions.<String> checkNotNull(name);
-
- final List<DataSchemaNode> instantiatedDataNodeContainers = new ArrayList<DataSchemaNode>();
- collectInstanceDataNodeContainers(instantiatedDataNodeContainers, container, name);
- return instantiatedDataNodeContainers;
- }
-
- private static final Function<ChoiceSchemaNode, Set<ChoiceCaseNode>> CHOICE_FUNCTION = new Function<ChoiceSchemaNode, Set<ChoiceCaseNode>>() {
- @Override
- public Set<ChoiceCaseNode> apply(final ChoiceSchemaNode node) {
- return node.getCases();
- }
- };
-
- private static void collectInstanceDataNodeContainers(final List<DataSchemaNode> potentialSchemaNodes,
- final DataNodeContainer container, final String name) {
-
- final Predicate<DataSchemaNode> filter = new Predicate<DataSchemaNode>() {
- @Override
- public boolean apply(final DataSchemaNode node) {
- return Objects.equal(node.getQName().getLocalName(), name);
- }
- };
-
- final Iterable<DataSchemaNode> nodes = Iterables.filter(container.getChildNodes(), filter);
-
- // Can't combine this loop with the filter above because the filter is
- // lazily-applied by Iterables.filter.
- for (final DataSchemaNode potentialNode : nodes) {
- if (isInstantiatedDataSchema(potentialNode)) {
- potentialSchemaNodes.add(potentialNode);
- }
- }
-
- final Iterable<ChoiceSchemaNode> choiceNodes = Iterables.filter(container.getChildNodes(), ChoiceSchemaNode.class);
- final Iterable<Set<ChoiceCaseNode>> map = Iterables.transform(choiceNodes, CHOICE_FUNCTION);
-
- final Iterable<ChoiceCaseNode> allCases = Iterables.<ChoiceCaseNode> concat(map);
- for (final ChoiceCaseNode caze : allCases) {
- collectInstanceDataNodeContainers(potentialSchemaNodes, caze, name);
- }
- }
-
- public static boolean isInstantiatedDataSchema(final DataSchemaNode node) {
- return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode
- || node instanceof ContainerSchemaNode || node instanceof ListSchemaNode
- || node instanceof AnyXmlSchemaNode;
- }
-
- private void addKeyValue(final HashMap<QName, Object> map, final DataSchemaNode node, final String uriValue,
- final DOMMountPoint mountPoint) {
- Preconditions.checkNotNull(uriValue);
- Preconditions.checkArgument((node instanceof LeafSchemaNode));
-
- final String urlDecoded = urlPathArgDecode(uriValue);
- TypeDefinition<?> typedef = ((LeafSchemaNode) node).getType();
- final TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(typedef);
- if (baseType instanceof LeafrefTypeDefinition) {
- typedef = SchemaContextUtil.getBaseTypeForLeafRef((LeafrefTypeDefinition) baseType, globalSchema, node);
- }
- Codec<Object, Object> codec = RestCodec.from(typedef, mountPoint);
- Object decoded = codec.deserialize(urlDecoded);
- String additionalInfo = "";
- if (decoded == null) {
- if ((baseType instanceof IdentityrefTypeDefinition)) {
- decoded = toQName(urlDecoded);
- additionalInfo = "For key which is of type identityref it should be in format module_name:identity_name.";
- }
- }
-
- if (decoded == null) {
- throw new RestconfDocumentedException(uriValue + " from URI can't be resolved. " + additionalInfo,
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- map.put(node.getQName(), decoded);
- }
-
- private static String toModuleName(final String str) {
- final int idx = str.indexOf(':');
- if (idx == -1) {
- return null;
- }
-
- // Make sure there is only one occurrence
- if (str.indexOf(':', idx + 1) != -1) {
- return null;
- }
-
- return str.substring(0, idx);
- }
-
- private static String toNodeName(final String str) {
- final int idx = str.indexOf(':');
- if (idx == -1) {
- return str;
- }
-
- // Make sure there is only one occurrence
- if (str.indexOf(':', idx + 1) != -1) {
- return str;
- }
-
- return str.substring(idx + 1);
- }
-
- private QName toQName(final String name) {
- checkPreconditions();
- final String module = toModuleName(name);
- final String node = toNodeName(name);
- final Module m = globalSchema.findModuleByName(module, null);
- return m == null ? null : QName.create(m.getQNameModule(), node);
- }
-
- private static boolean isListOrContainer(final DataSchemaNode node) {
- return node instanceof ListSchemaNode || node instanceof ContainerSchemaNode;
- }
-
- public RpcDefinition getRpcDefinition(final String name) {
- final QName validName = toQName(name);
- return validName == null ? null : qnameToRpc.get().get(validName);
- }
-
- @Override
- public void onGlobalContextUpdated(final SchemaContext context) {
- if (context != null) {
- final Collection<RpcDefinition> defs = context.getOperations();
- final Map<QName, RpcDefinition> newMap = new HashMap<>(defs.size());
-
- for (final RpcDefinition operation : defs) {
- newMap.put(operation.getQName(), operation);
- }
-
- // FIXME: still not completely atomic
- qnameToRpc.set(ImmutableMap.copyOf(newMap));
- setGlobalSchema(context);
- }
- }
-
- public static List<String> urlPathArgsDecode(final Iterable<String> strings) {
- try {
- final List<String> decodedPathArgs = new ArrayList<String>();
- for (final String pathArg : strings) {
- final String _decode = URLDecoder.decode(pathArg, URI_ENCODING_CHAR_SET);
- decodedPathArgs.add(_decode);
- }
- return decodedPathArgs;
- } catch (final UnsupportedEncodingException e) {
- throw new RestconfDocumentedException("Invalid URL path '" + strings + "': " + e.getMessage(),
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
- }
-
- public String urlPathArgDecode(final String pathArg) {
- if (pathArg != null) {
- try {
- return URLDecoder.decode(pathArg, URI_ENCODING_CHAR_SET);
- } catch (final UnsupportedEncodingException e) {
- throw new RestconfDocumentedException("Invalid URL path arg '" + pathArg + "': " + e.getMessage(),
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
- }
-
- return null;
- }
-
- private CharSequence convertToRestconfIdentifier(final PathArgument argument, final DataSchemaNode node, final DOMMountPoint mount) {
- if (argument instanceof NodeIdentifier) {
- return convertToRestconfIdentifier((NodeIdentifier) argument, mount);
- } else if (argument instanceof NodeIdentifierWithPredicates && node instanceof ListSchemaNode) {
- return convertToRestconfIdentifierWithPredicates((NodeIdentifierWithPredicates) argument, (ListSchemaNode) node, mount);
- } else if (argument != null && node != null) {
- throw new IllegalArgumentException("Conversion of generic path argument is not supported");
- } else {
- throw new IllegalArgumentException("Unhandled parameter types: "
- + Arrays.<Object> asList(argument, node).toString());
- }
- }
-
- private CharSequence convertToRestconfIdentifier(final NodeIdentifier argument, final DOMMountPoint node) {
- return "/" + this.toRestconfIdentifier(argument.getNodeType(),node);
- }
-
- private CharSequence convertToRestconfIdentifierWithPredicates(final NodeIdentifierWithPredicates argument,
- final ListSchemaNode node, final DOMMountPoint mount) {
- final QName nodeType = argument.getNodeType();
- final CharSequence nodeIdentifier = this.toRestconfIdentifier(nodeType, mount);
- final Map<QName, Object> keyValues = argument.getKeyValues();
-
- final StringBuilder builder = new StringBuilder();
- builder.append('/');
- builder.append(nodeIdentifier);
- builder.append('/');
-
- final List<QName> keyDefinition = node.getKeyDefinition();
- boolean hasElements = false;
- for (final QName key : keyDefinition) {
- for (final DataSchemaNode listChild : node.getChildNodes()) {
- if (listChild.getQName().equals(key)) {
- if (!hasElements) {
- hasElements = true;
- } else {
- builder.append('/');
- }
-
- try {
- Preconditions.checkState(listChild instanceof LeafSchemaNode, "List key has to consist of leaves");
- builder.append(toUriString(keyValues.get(key), (LeafSchemaNode)listChild, mount));
- } catch (final UnsupportedEncodingException e) {
- LOG.error("Error parsing URI: {}", keyValues.get(key), e);
- return null;
- }
- break;
- }
- }
- }
-
- return builder.toString();
- }
-
- private static DataSchemaNode childByQName(final Object container, final QName name) {
- if (container instanceof ChoiceCaseNode) {
- return childByQName((ChoiceCaseNode) container, name);
- } else if (container instanceof ChoiceSchemaNode) {
- return childByQName((ChoiceSchemaNode) container, name);
- } else if (container instanceof ContainerSchemaNode) {
- return childByQName((ContainerSchemaNode) container, name);
- } else if (container instanceof ListSchemaNode) {
- return childByQName((ListSchemaNode) container, name);
- } else if (container instanceof DataSchemaNode) {
- return childByQName((DataSchemaNode) container, name);
- } else if (container instanceof Module) {
- return childByQName((Module) container, name);
- } else {
- throw new IllegalArgumentException("Unhandled parameter types: "
- + Arrays.<Object> asList(container, name).toString());
- }
- }
-
- public YangInstanceIdentifier toNormalized(final YangInstanceIdentifier legacy) {
- try {
- return dataNormalizer.toNormalized(legacy);
- } catch (final NullPointerException e) {
- throw new RestconfDocumentedException("Data normalizer isn't set. Normalization isn't possible", e);
- }
- }
-
- public YangInstanceIdentifier toXpathRepresentation(final YangInstanceIdentifier instanceIdentifier) {
- try {
- return dataNormalizer.toLegacy(instanceIdentifier);
- } catch (final NullPointerException e) {
- throw&