<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
org.apache.felix.dm,</Import-Package>
<Export-Package>org.opendaylight.controller.appauth,
org.opendaylight.controller.appauth.authorization</Export-Package>
- <Bundle-Activator></Bundle-Activator>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
* passed and so on.
*/
public class CacheConfigException extends Exception {
+ private static final long serialVersionUID = 1L;
/**
* Instantiates a new cache config exception.
* allocated already exists
*/
public class CacheExistException extends Exception {
+ private static final long serialVersionUID = 1L;
/**
* Instantiates a new cache exist exception.
* Listener being added fails for any reason
*/
public class CacheListenerAddException extends Exception {
+ private static final long serialVersionUID = 1L;
/**
* Instantiates a new cache listener add exception.
* @deprecated for internal use
* The Class ListenRoleChangeAddException.
*/
+@Deprecated
public class ListenRoleChangeAddException extends Exception {
+ private static final long serialVersionUID = 1L;
/**
* Instantiates a new listen role change add exception.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
!org.hornetq.*,
!org.jboss.*,
javax.transaction,
- *,
org.opendaylight.controller.clustering.services,
- org.opendaylight.controller.sal.core</Import-Package>
+ org.opendaylight.controller.sal.core,*</Import-Package>
<Bundle-Activator>org.opendaylight.controller.clustering.services_implementation.internal.Activator</Bundle-Activator>
<!-- Add in the DynamicImport-Package ONLY the packages that -->
<!-- contains types that MUST be unmarshalled by the -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
import java.io.Serializable;
public class ComplexClass implements IComplex, Serializable {
+ private static final long serialVersionUID = 1L;
private String identity;
public ComplexClass(String i) {
import java.io.Serializable;
public class ComplexClass1 implements IComplex, Serializable {
+ private static final long serialVersionUID = 1L;
private String identity;
public ComplexClass1(String i) {
import java.io.Serializable;
public class ComplexContainer implements Serializable {
- private IComplex f;
- private IComplex f1;
- private Integer state;
+ private static final long serialVersionUID = 1L;
+ private final IComplex f;
+ private final IComplex f1;
+ private final Integer state;
public ComplexContainer(String i, Integer s) {
this.state = s;
import java.io.Serializable;
public class StringContainer implements Serializable {
+ private static final long serialVersionUID = 1L;
private String mystring;
public StringContainer() {
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<asm.version>4.1</asm.version>
<!-- Plugin Versions -->
<bouncycastle.version>1.50</bouncycastle.version>
- <bundle.plugin.version>2.3.7</bundle.plugin.version>
+ <bundle.plugin.version>2.4.0</bundle.plugin.version>
<bundlescanner.version>0.4.2-SNAPSHOT</bundlescanner.version>
<checkstyle.version>2.10</checkstyle.version>
<clustering.services.version>0.5.1-SNAPSHOT</clustering.services.version>
<eclipse.persistence.version>2.5.0</eclipse.persistence.version>
<!-- enforcer version -->
<enforcer.version>1.3.1</enforcer.version>
- <enunciate.version>1.26.2</enunciate.version>
+ <enunciate.version>1.28</enunciate.version>
<exam.version>3.0.0</exam.version>
<!-- OpenEXI third party lib for netconf-->
<configFile>enunciate.xml</configFile>
</configuration>
<dependencies>
+ <dependency>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>enunciate-swagger</artifactId>
+ <version>${enunciate.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
--- /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>config-subsystem</artifactId>
+ <version>0.2.5-SNAPSHOT</version>
+ </parent>
+ <artifactId>config-features</artifactId>
+
+ <packaging>pom</packaging>
+
+ <properties>
+ <features.file>features.xml</features.file>
+ </properties>
+
+ <dependencies></dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <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/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+ </scm>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="config-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+ <feature name='config-all' version='${project.version}'>
+ <feature version='${project.version}'>odl-config-subsystem</feature>
+ </feature>
+
+ <feature name='odl-config-subsystem' version='${project.version}'>
+ <feature version='${yangtools.version}'>yangtools-concepts</feature>
+ <feature version='${yangtools.version}'>yangtools-binding</feature>
+ <feature version='${yangtools.version}'>yangtools-binding-generator</feature>
+ <feature version='${mdsal.version}'>odl-mdsal-commons</feature>
+ <bundle>mvn:org.opendaylight.controller/config-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/config-manager/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/yang-jmx-generator/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/config-persister-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/config-persister-file-xml-adapter/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/config-persister-directory-xml-adapter/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/shutdown-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/shutdown-impl/${project.version}</bundle>
+ <bundle>mvn:org.osgi/org.osgi.core/${osgi.core.version}</bundle>
+ <bundle>wrap:mvn:com.google.guava/guava/${guava.version}</bundle>
+ <bundle>mvn:org.javassist/javassist/${javassist.version}</bundle>
+ </feature>
+</features>
\ No newline at end of file
<module>shutdown-impl</module>
<module>netconf-config-dispatcher</module>
<module>config-module-archetype</module>
+ <module>feature</module>
</modules>
<dependencies>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
- <version>${jacoco.version}</version>
<executions>
<execution>
<goals>
package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory;
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
+import java.util.LinkedHashMap;
+
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder;
import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.TypeName;
-import java.util.LinkedHashMap;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
public class ConcreteModuleGeneratedObjectFactory {
}
private static String getNewCtor(FullyQualifiedName fqn) {
- LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>(){
- {
- put(ModuleIdentifier.class.getCanonicalName(), "identifier");
- put(DependencyResolver.class.getCanonicalName(), "dependencyResolver");
- }
- };
+ LinkedHashMap<String, String> parameters = new LinkedHashMap<>();
+ parameters.put(ModuleIdentifier.class.getCanonicalName(), "identifier");
+ parameters.put(DependencyResolver.class.getCanonicalName(), "dependencyResolver");
+
StringBuilder stringBuilder = getCtor(fqn, parameters);
return stringBuilder.toString();
}
}
private static String getCopyCtor(final FullyQualifiedName fqn) {
- LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>(){
- {
- put(ModuleIdentifier.class.getCanonicalName(), "identifier");
- put(DependencyResolver.class.getCanonicalName(), "dependencyResolver");
- put(fqn.toString(), "oldModule");
- put(AutoCloseable.class.getCanonicalName(), "oldInstance");
- }
- };
+ LinkedHashMap<String, String> parameters = new LinkedHashMap<>();
+ parameters.put(ModuleIdentifier.class.getCanonicalName(), "identifier");
+ parameters.put(DependencyResolver.class.getCanonicalName(), "dependencyResolver");
+ parameters.put(fqn.toString(), "oldModule");
+ parameters.put(AutoCloseable.class.getCanonicalName(), "oldInstance");
StringBuilder stringBuilder = getCtor(fqn, parameters);
return stringBuilder.toString();
}
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
-import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.List;
import java.util.regex.Pattern;
public static Optional<String> loadCopyright() {
- try (InputStream in = StringUtil.class.getResourceAsStream("/copyright.txt")) {
- if (in != null) {
- return Optional.of(IOUtils.toString(in));
+ /*
+ * FIXME: BUG-980: this is a nice feature, but the copyright needs to come
+ * from the project being processed, not this one.
+ try (InputStream in = StringUtil.class.getResourceAsStream("/copyright.txt")) {
+ if (in != null) {
+ return Optional.of(IOUtils.toString(in));
+ }
+ } catch (IOException e) {
+ logger.warn("Cannot load copyright.txt", e);
}
- } catch (IOException e) {
- logger.warn("Cannot load copyright.txt", e);
- }
+
+ */
return Optional.absent();
}
+++ /dev/null
-Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
-This program and the accompanying materials are made available under the
-terms of the Eclipse Public License v1.0 which accompanies this distribution,
-and is available at http://www.eclipse.org/legal/epl-v10.html
package org.opendaylight.controller.config.yangjmxgenerator.plugin.util;
+import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName;
}
@Test
+ @Ignore
public void testCopyright() throws IOException {
assertTrue(StringUtil.loadCopyright().isPresent());
}
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<version>${karaf.version}</version>
<type>kar</type>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-features</artifactId>
+ <version>${config.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
<!-- scope is runtime so the feature repo is listed in the features
service config file, and features may be installed using the
karaf-maven-plugin configuration -->
<type>xml</type>
<scope>runtime</scope>
</dependency>
+ -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>mdsal-features</artifactId>
+ <version>${mdsal.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-file</artifactId>
<type>xml</type>
<scope>runtime</scope>
</dependency>
- -->
</dependencies>
<build>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-generator-impl</artifactId>
- <version>${yangtools.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-generator-spi</artifactId>
- <version>${yangtools.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-generator-util</artifactId>
- <version>${yangtools.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-type-provider</artifactId>
- <version>${yangtools.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-api</artifactId>
- <version>${yangtools.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-impl</artifactId>
- <version>${yangtools.version}</version>
</dependency>
<!-- yang model dependencies -->
<dependency>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
- prefix:toaster-provider-impl
+ <type xmlns:toaster="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
+ toaster:toaster-provider-impl
</type>
<name>toaster-provider-impl</name>
<name>binding-rpc-broker</name>
</rpc-registry>
+ <data-broker>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+ <name>binding-data-broker</name>
+ </data-broker>
+
<notification-service>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
binding:binding-notification-service
</module>
<module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer:impl">
- prefix:toaster-consumer-impl
+ <type xmlns:kitchen="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
+ kitchen:kitchen-service-impl
</type>
- <name>toaster-consumer-impl</name>
+ <name>kitchen-service-impl</name>
<rpc-registry>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
</notification-service>
</module>
</modules>
-
+
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<service>
- <type xmlns:toaster="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider">toaster:toaster-provider</type>
- <instance>
- <name>toaster-provider</name>
- <provider>/modules/module[type='toaster-provider-impl'][name='toaster-provider-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:toaster="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer">toaster:toaster-consumer</type>
+ <type xmlns:kitchen="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
+ kitchen:kitchen-service
+ </type>
<instance>
- <name>toaster-consumer</name>
- <provider>/modules/module[type='toaster-consumer-impl'][name='toaster-consumer-impl']</provider>
+ <name>kitchen-service</name>
+ <provider>/modules/module[type='kitchen-service-impl'][name='kitchen-service-impl']</provider>
</instance>
</service>
</services>
</configuration>
<required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer?module=toaster-consumer&revision=2014-01-31</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer:impl?module=toaster-consumer-impl&revision=2014-01-31</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider?module=toaster-provider&revision=2014-01-31</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl?module=kitchen-service-impl&revision=2014-01-31</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl?module=toaster-provider-impl&revision=2014-01-31</capability>
</required-capabilities>
########################################
# Now add to classpath the OSGi JAR
########################################
-CLASSPATH="${basedir}"/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
+CLASSPATH=${CLASSPATH}:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
FWCLASSPATH=file:"${basedir}"/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
########################################
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<instructions>
<Import-Package>*</Import-Package>
<Export-Package>org.eclipse.osgi.framework.console</Export-Package>
- <Bundle-Activator></Bundle-Activator>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
for (FlowConfig flowConfig : flowConfigForNode) {
if (doesFlowContainNodeConnector(flowConfig.getFlow(), nodeConnector)) {
if (flowConfig.installInHw() && !flowConfig.getStatus().equals(StatusCode.SUCCESS.toString())) {
- Status status = this.installFlowEntry(flowConfig.getFlowEntry());
+ Status status = this.installFlowEntryAsync(flowConfig.getFlowEntry());
if (!status.isSuccess()) {
flowConfig.setStatus(status.getDescription());
} else {
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
/**
* Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
+ *
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.controller.sal.compatibility;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import org.eclipse.xtext.xbase.lib.Exceptions;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+
import org.opendaylight.controller.sal.common.util.Arguments;
import org.opendaylight.controller.sal.core.AdvertisedBandwidth;
import org.opendaylight.controller.sal.core.Bandwidth;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
-@SuppressWarnings("all")
-public class NodeMapping {
+public final class NodeMapping {
public final static String MD_SAL_TYPE = "MD_SAL";
-
+
private final static Class<Node> NODE_CLASS = Node.class;
-
+
private final static Class<NodeConnector> NODECONNECTOR_CLASS = NodeConnector.class;
-
+
private NodeMapping() {
throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
}
-
+
public static org.opendaylight.controller.sal.core.Node toADNode(final InstanceIdentifier<? extends Object> node) throws ConstructionException {
NodeId nodeId = NodeMapping.toNodeId(node);
return NodeMapping.toADNode(nodeId);
}
-
- public static org.opendaylight.controller.sal.core.Node toADNode(final NodeId id) {
- try {
+
+ public static org.opendaylight.controller.sal.core.Node toADNode(final NodeId id) throws ConstructionException {
String aDNodeId = NodeMapping.toADNodeId(id);
return new org.opendaylight.controller.sal.core.Node(NodeMapping.MD_SAL_TYPE, aDNodeId);
- } catch (Throwable e) {
- throw Exceptions.sneakyThrow(e);
- }
}
-
+
public static NodeId toNodeId(final InstanceIdentifier<? extends Object> node) {
Preconditions.<InstanceIdentifier<? extends Object>>checkNotNull(node);
List<PathArgument> path = node.getPath();
Preconditions.checkArgument(size >= 2);
final PathArgument arg = path.get(1);
final IdentifiableItem item = Arguments.<IdentifiableItem>checkInstanceOf(arg, IdentifiableItem.class);
- Identifier key = item.getKey();
+ Identifier<?> key = item.getKey();
final NodeKey nodeKey = Arguments.<NodeKey>checkInstanceOf(key, NodeKey.class);
return nodeKey.getId();
}
-
+
public static String toADNodeId(final NodeId nodeId) {
Preconditions.<NodeId>checkNotNull(nodeId);
return nodeId.getValue();
}
-
+
public static org.opendaylight.controller.sal.core.NodeConnector toADNodeConnector(final NodeConnectorRef source) throws ConstructionException {
Preconditions.<NodeConnectorRef>checkNotNull(source);
final InstanceIdentifier<?> path = Preconditions.<InstanceIdentifier<? extends Object>>checkNotNull(source.getValue());
final NodeConnectorKey connectorKey = Arguments.<NodeConnectorKey>checkInstanceOf(item.getKey(), NodeConnectorKey.class);
return NodeMapping.toADNodeConnector(connectorKey.getId(), NodeMapping.toNodeId(path));
}
-
- public static org.opendaylight.controller.sal.core.NodeConnector toADNodeConnector(final NodeConnectorId ncid, final NodeId nid) {
- try {
- String nodeConnectorType = NodeMapping.toNodeConnectorType(ncid, nid);
- Object aDNodeConnectorId = NodeMapping.toADNodeConnectorId(ncid, nid);
- org.opendaylight.controller.sal.core.Node aDNode = NodeMapping.toADNode(nid);
- return new org.opendaylight.controller.sal.core.NodeConnector(nodeConnectorType, aDNodeConnectorId, aDNode);
- } catch (Throwable e) {
- throw Exceptions.sneakyThrow(e);
- }
+
+ public static org.opendaylight.controller.sal.core.NodeConnector toADNodeConnector(final NodeConnectorId ncid, final NodeId nid) throws ConstructionException {
+ String nodeConnectorType = NodeMapping.toNodeConnectorType(ncid, nid);
+ Object aDNodeConnectorId = NodeMapping.toADNodeConnectorId(ncid, nid);
+ org.opendaylight.controller.sal.core.Node aDNode = NodeMapping.toADNode(nid);
+ return new org.opendaylight.controller.sal.core.NodeConnector(nodeConnectorType, aDNodeConnectorId, aDNode);
}
-
+
public static String toNodeConnectorType(final NodeConnectorId ncId, final NodeId nodeId) {
if (ncId.equals(toLocalNodeConnectorId(nodeId))) {
return NodeConnectorIDType.SWSTACK;
}
return nodeConnectorId.getValue();
}
-
+
public static NodeConnectorId toControllerNodeConnectorId(final NodeId node) {
return new NodeConnectorId(node.getValue() + ":" + 4294967293L);
}
-
+
public static NodeConnectorId toLocalNodeConnectorId(final NodeId node) {
return new NodeConnectorId(node.getValue() + ":" + 4294967294L);
}
-
+
public static NodeConnectorId toNormalNodeConnectorId(final NodeId node) {
return new NodeConnectorId(node.getValue() + ":" + 4294967290L);
}
-
+
public static NodeRef toNodeRef(final org.opendaylight.controller.sal.core.Node node) {
Preconditions.checkArgument(MD_SAL_TYPE.equals(node.getType()));
final String nodeId = Arguments.<String>checkInstanceOf(node.getID(), String.class);
final InstanceIdentifier<Node> nodePath = InstanceIdentifier.builder(Nodes.class).child(NODE_CLASS, nodeKey).toInstance();
return new NodeRef(nodePath);
}
-
+
public static NodeConnectorRef toNodeConnectorRef(final org.opendaylight.controller.sal.core.NodeConnector nodeConnector) {
final NodeRef node = NodeMapping.toNodeRef(nodeConnector.getNode());
nodeConnectorId = new NodeConnectorId(Arguments.<String>checkInstanceOf(nodeConnector.getID(), String.class));
}
final NodeConnectorKey connectorKey = new NodeConnectorKey(nodeConnectorId);
- final InstanceIdentifier<NodeConnector> path = InstanceIdentifier.builder(nodePath).child(NODECONNECTOR_CLASS, connectorKey).toInstance();
+ final InstanceIdentifier<NodeConnector> path = nodePath.child(NODECONNECTOR_CLASS, connectorKey);
return new NodeConnectorRef(path);
}
-
+
public static org.opendaylight.controller.sal.core.Node toADNode(final NodeRef node) throws ConstructionException {
return NodeMapping.toADNode(node.getValue());
}
-
+
public static HashSet<Property> toADNodeConnectorProperties(final NodeConnectorUpdated nc) {
final FlowCapableNodeConnectorUpdated fcncu = nc.<FlowCapableNodeConnectorUpdated>getAugmentation(FlowCapableNodeConnectorUpdated.class);
if (!Objects.equal(fcncu, null)) {
}
return new HashSet<Property>();
}
-
+
public static HashSet<Property> toADNodeConnectorProperties(final NodeConnector nc) {
final FlowCapableNodeConnector fcnc = nc.<FlowCapableNodeConnector>getAugmentation(FlowCapableNodeConnector.class);
if (!Objects.equal(fcnc, null)) {
}
return new HashSet<Property>();
}
-
+
public static HashSet<Property> toADNodeConnectorProperties(final FlowNodeConnector fcncu) {
final HashSet<org.opendaylight.controller.sal.core.Property> props = new HashSet<>();
}
return props;
}
-
+
public static Name toAdName(final String name) {
return new Name(name);
}
-
+
public static Config toAdConfig(final PortConfig pc) {
Config config = null;
if (pc.isPORTDOWN()) {
}
return config;
}
-
+
public static org.opendaylight.controller.sal.core.State toAdState(final State s) {
org.opendaylight.controller.sal.core.State state = null;
}
return state;
}
-
+
public static Bandwidth toAdBandwidth(final PortFeatures pf) {
Bandwidth bw = null;
if (pf.isTenMbHd() || pf.isTenMbFd()) {
}
return bw;
}
-
+
public static AdvertisedBandwidth toAdAdvertizedBandwidth(final PortFeatures pf) {
AdvertisedBandwidth abw = null;
final Bandwidth bw = toAdBandwidth(pf);
}
return abw;
}
-
+
public static SupportedBandwidth toAdSupportedBandwidth(final PortFeatures pf) {
SupportedBandwidth sbw = null;
final Bandwidth bw = toAdBandwidth(pf);
}
return sbw;
}
-
+
public static PeerBandwidth toAdPeerBandwidth(final PortFeatures pf) {
PeerBandwidth pbw = null;
final Bandwidth bw = toAdBandwidth(pf);
}
return pbw;
}
-
+
public static HashSet<Property> toADNodeProperties(final NodeUpdated nu) {
final FlowCapableNodeUpdated fcnu = nu.getAugmentation(FlowCapableNodeUpdated.class);
if (fcnu != null) {
}
return new HashSet<org.opendaylight.controller.sal.core.Property>();
}
-
+
public static HashSet<Property> toADNodeProperties(final FlowNode fcnu, final NodeId id) {
final HashSet<org.opendaylight.controller.sal.core.Property> props = new HashSet<>();
}
return props;
}
-
+
public static TimeStamp toADTimestamp() {
final Date date = new Date();
final TimeStamp timestamp = new TimeStamp(date.getTime(), "connectedSince");
return timestamp;
}
-
+
public static MacAddress toADMacAddress(final NodeId id) {
final String nodeId = id.getValue().replaceAll("openflow:", "");
long lNodeId = Long.parseLong(nodeId);
byte[] bytesFromDpid = ToSalConversionsUtils.bytesFromDpid(lNodeId);
return new MacAddress(bytesFromDpid);
}
-
+
public static Tables toADTables(final Short tables) {
return new Tables(tables.byteValue());
}
-
+
public static Capabilities toADCapabiliities(final List<Class<? extends FeatureCapability>> capabilities) {
int b = 0;
}
return new Capabilities(b);
}
-
+
public static Buffers toADBuffers(final Long buffers) {
return new Buffers(buffers.intValue());
}
for (InstanceIdentifier<? extends DataObject> path : modification.getRemovedOperationalData()) {
if (path.getTargetType() == Link.class) {
Link link = (Link) modification.getOriginalOperationalData().get(path);
- msg.add(toTopoEdgeUpdate(toAdEdge(link, topology), UpdateType.CHANGED, reader));
+ msg.add(toTopoEdgeUpdate(toAdEdge(link, topology), UpdateType.REMOVED, reader));
}
}
--- /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.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mdsal-features</artifactId>
+
+ <packaging>pom</packaging>
+
+ <properties>
+ <features.file>features.xml</features.file>
+ </properties>
+
+ <dependencies></dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <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/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+ </scm>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="mdsal-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+ <feature name='mdsal-all' version='${project.version}'>
+ <feature version='${project.version}'>odl-mdsal-commons</feature>
+ <feature version='${project.version}'>odl-mdsal-broker</feature>
+ <feature version='${project.version}'>odl-mdsal-restconf</feature>
+ </feature>
+ <feature name='odl-mdsal-commons' version='${project.version}'>
+ <feature version='${yangtools.version}'>yangtools-concepts</feature>
+ <feature version='${yangtools.version}'>yangtools-binding</feature>
+ <bundle>mvn:org.opendaylight.controller/sal-common/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-common-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-common-impl/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-common-util/${project.version}</bundle>
+ <bundle>wrap:mvn:com.google.guava/guava/${guava.version}</bundle>
+ <bundle>wrap:mvn:org.eclipse.xtend/org.eclipse.xtend.lib/${xtend.version}</bundle>
+ </feature>
+ <feature name='odl-mdsal-broker' version='${project.version}'>
+ <feature version='${yangtools.version}'>yangtools-concepts</feature>
+ <feature version='${yangtools.version}'>yangtools-binding</feature>
+ <feature version='${mdsal.version}'>odl-mdsal-commons</feature>
+ <feature version='${config.version}'>odl-config-subsystem</feature>
+ <bundle>mvn:org.opendaylight.controller/sal-core-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-core-spi/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-broker-impl/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-binding-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-binding-config/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-binding-broker-impl/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-binding-util/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/sal-connector-api/${project.version}</bundle>
+ </feature>
+ <feature name='odl-mdsal-restconf' version='${project.version}'>
+ <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+ <bundle>mvn:org.opendaylight.controller/sal-rest-connector/${project.version}</bundle>
+ <bundle>wrap:mvn:com.google.code.gson/gson/${gson.version}</bundle>
+ <bundle>wrap:mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
+ <bundle>wrap:mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller.thirdparty/com.sun.jersey.jersey-servlet/${jersey.version}</bundle>
+ <bundle>wrap:mvn:io.netty/netty-buffer/${netty.version}</bundle>
+ <bundle>wrap:mvn:io.netty/netty-codec/${netty.version}</bundle>
+ <bundle>wrap:mvn:io.netty/netty-codec-http/${netty.version}</bundle>
+ <bundle>wrap:mvn:io.netty/netty-common/${netty.version}</bundle>
+ <bundle>wrap:mvn:io.netty/netty-handler/${netty.version}</bundle>
+ <bundle>wrap:mvn:io.netty/netty-transport/${netty.version}</bundle>
+ </feature>
+</features>
\ No newline at end of file
-->
<!-- Documentation -->
<module>sal-rest-docgen</module>
+
+ <!-- Karaf feature -->
+ <module>feature</module>
+
</modules>
<build>
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
- <version>${yangtools.version}</version>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
*/
package org.opendaylight.controller.config.yang.md.sal.binding.impl;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import java.util.Hashtable;
import java.util.Map.Entry;
import java.util.Set;
+
import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
import org.opendaylight.yangtools.concepts.Delegator;
import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
/**
*
*/
@Override
public java.lang.AutoCloseable createInstance() {
-
+
RuntimeGeneratedMappingServiceProxy potential = tryToReuseGlobalInstance();
if(potential != null) {
return potential;
}
- RuntimeGeneratedMappingServiceImpl service = new RuntimeGeneratedMappingServiceImpl();
- service.setPool(SingletonHolder.CLASS_POOL);
- service.init();
+
+ final RuntimeGeneratedMappingServiceImpl service = new RuntimeGeneratedMappingServiceImpl(SingletonHolder.CLASS_POOL);
bundleContext.registerService(SchemaServiceListener.class, service, new Hashtable<String,String>());
return service;
}
BindingIndependentMappingService, //
Delegator<BindingIndependentMappingService>, //
AutoCloseable {
-
+
private BindingIndependentMappingService delegate;
private ServiceReference<BindingIndependentMappingService> reference;
private BundleContext bundleContext;
this.delegate = Preconditions.checkNotNull(delegate);
}
+ @Override
public CodecRegistry getCodecRegistry() {
return delegate.getCodecRegistry();
}
+ @Override
public CompositeNode toDataDom(DataObject data) {
return delegate.toDataDom(data);
}
+ @Override
public Entry<InstanceIdentifier, CompositeNode> toDataDom(
Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
return delegate.toDataDom(entry);
}
+ @Override
public InstanceIdentifier toDataDom(
org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
return delegate.toDataDom(path);
}
+ @Override
public DataObject dataObjectFromDataDom(
org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path,
CompositeNode result) throws DeserializationException {
return delegate.dataObjectFromDataDom(path, result);
}
+ @Override
public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> fromDataDom(InstanceIdentifier entry)
throws DeserializationException {
return delegate.fromDataDom(entry);
}
+ @Override
public Set<QName> getRpcQNamesFor(Class<? extends RpcService> service) {
return delegate.getRpcQNamesFor(service);
}
return delegate.getRpcServiceClassFor(namespace,revision);
}
+ @Override
public DataContainer dataObjectFromDataDom(Class<? extends DataContainer> inputClass, CompositeNode domInput) {
return delegate.dataObjectFromDataDom(inputClass, domInput);
}
-
+
@Override
public void close() throws Exception {
if(delegate != null) {
for (Map.Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : normalized
.entrySet()) {
try {
- Entry<InstanceIdentifier<? extends DataObject>, DataObject> binding = getCodec().toBinding(entry);
- newMap.put(binding.getKey(), binding.getValue());
+ Optional<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> potential = getCodec().toBinding(
+ entry);
+ if (potential.isPresent()) {
+ Entry<InstanceIdentifier<? extends DataObject>, DataObject> binding = potential.get();
+ newMap.put(binding.getKey(), binding.getValue());
+ }
} catch (DeserializationException e) {
- LOG.debug("Omitting {}", entry, e);
+ LOG.warn("Failed to transform {}, omitting it", entry, e);
}
}
return newMap;
Set<InstanceIdentifier<?>> hashSet = new HashSet<>();
for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath : normalized) {
try {
- InstanceIdentifier<? extends DataObject> binding = getCodec().toBinding(normalizedPath);
- hashSet.add(binding);
+ Optional<InstanceIdentifier<? extends DataObject>> potential = getCodec().toBinding(normalizedPath);
+ if (potential.isPresent()) {
+ InstanceIdentifier<? extends DataObject> binding = potential.get();
+ hashSet.add(binding);
+ }
} catch (DeserializationException e) {
- LOG.debug("Omitting {}", normalizedPath, e);
+ LOG.warn("Failed to transform {}, omitting it", normalizedPath, e);
}
}
return hashSet;
}
protected Optional<DataObject> toBindingData(final InstanceIdentifier<?> path, final NormalizedNode<?, ?> data) {
- if(path.isWildcarded()) {
+ if (path.isWildcarded()) {
return Optional.absent();
}
@Override
public DataObject getOriginalSubtree() {
if (originalDataCache == null) {
- originalDataCache = toBindingData(path, domEvent.getOriginalSubtree());
+ if(domEvent.getOriginalSubtree() != null) {
+ originalDataCache = toBindingData(path, domEvent.getOriginalSubtree());
+ } else {
+ originalDataCache = Optional.absent();
+ }
}
return originalDataCache.orNull();
}
@Override
public DataObject getUpdatedSubtree() {
if (updatedDataCache == null) {
- updatedDataCache = toBindingData(path, domEvent.getUpdatedSubtree());
+ if(domEvent.getUpdatedSubtree() != null) {
+ updatedDataCache = toBindingData(path, domEvent.getUpdatedSubtree());
+ } else {
+ updatedDataCache = Optional.absent();
+ }
}
-
return updatedDataCache.orNull();
}
@Override
public String toString() {
return Objects.toStringHelper(TranslatedDataChangeEvent.class) //
- .add("created", getCreatedData()) //
- .add("updated", getUpdatedData()) //
- .add("removed", getRemovedPaths()) //
- .add("dom", domEvent) //
- .toString();
+ .add("created", getCreatedData()) //
+ .add("updated", getUpdatedData()) //
+ .add("removed", getRemovedPaths()) //
+ .add("dom", domEvent) //
+ .toString();
}
}
import javax.annotation.Nullable;
-import org.eclipse.xtext.xbase.lib.Exceptions;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@Nullable
@Override
public Optional<DataObject> apply(@Nullable final Optional<NormalizedNode<?, ?>> normalizedNode) {
- try {
- final DataObject dataObject = normalizedNode.isPresent() ? codec.toBinding(path,
- normalizedNode.get()) : null;
+ if (normalizedNode.isPresent()) {
+ final DataObject dataObject;
+ try {
+ dataObject = codec.toBinding(path, normalizedNode.get());
+ } catch (DeserializationException e) {
+ LOG.warn("Failed to create dataobject from node {}", normalizedNode.get(), e);
+ throw new IllegalStateException("Failed to create dataobject", e);
+ }
+
if (dataObject != null) {
updateCache(store, path, dataObject);
+ return Optional.of(dataObject);
}
- return Optional.fromNullable(dataObject);
- } catch (DeserializationException e) {
- Exceptions.sneakyThrow(e);
}
- return null;
+ return Optional.absent();
}
});
}
final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
.toNormalizedNode(path, data);
- org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
- ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path);
- LOG.debug("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
- writeTransaction.put(store, normalized.getKey(), normalized.getValue());
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+ ensureParentsByMerge(writeTransaction, store, normalizedPath, path);
+ LOG.debug("Tx: {} : Putting data {}", getDelegate().getIdentifier(), normalizedPath);
+ writeTransaction.put(store, normalizedPath, normalized.getValue());
}
protected void doMergeWithEnsureParents(final DOMDataReadWriteTransaction writeTransaction,
final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
.toNormalizedNode(path, data);
- org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
- ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path);
- LOG.debug("Tx: {} : Merge data {}",getDelegate().getIdentifier(),normalized.getKey());
- writeTransaction.merge(store, normalized.getKey(), normalized.getValue());
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+ ensureParentsByMerge(writeTransaction, store, normalizedPath, path);
+ LOG.debug("Tx: {} : Merge data {}",getDelegate().getIdentifier(),normalizedPath);
+ writeTransaction.merge(store, normalizedPath, normalized.getValue());
}
private void ensureParentsByMerge(final DOMDataReadWriteTransaction writeTransaction,
import java.util.concurrent.Callable;
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.yangtools.concepts.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.binding.Augmentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toNormalized(
final InstanceIdentifier<? extends DataObject> binding) {
- // Used instance-identifier codec do not support serialization of last path
+ // Used instance-identifier codec do not support serialization of last
+ // path
// argument if it is Augmentation (behaviour expected by old datastore)
// in this case, we explicitly check if last argument is augmentation
// to process it separately
}
- public InstanceIdentifier<? extends DataObject> toBinding(
+ /**
+ *
+ * Returns a Binding-Aware instance identifier from normalized
+ * instance-identifier if it is possible to create representation.
+ *
+ * Returns Optional.absent for cases where target is mixin node except
+ * augmentation.
+ *
+ */
+ public Optional<InstanceIdentifier<? extends DataObject>> toBinding(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
throws DeserializationException {
PathArgument lastArgument = Iterables.getLast(normalized.getPath());
- // Used instance-identifier codec do not support serialization of last path
- // argument if it is AugmentationIdentifier (behaviour expected by old datastore)
+ // Used instance-identifier codec do not support serialization of last
+ // path
+ // argument if it is AugmentationIdentifier (behaviour expected by old
+ // datastore)
// in this case, we explicitly check if last argument is augmentation
// to process it separately
if (lastArgument instanceof AugmentationIdentifier) {
return toBindingImpl(normalized);
}
- private InstanceIdentifier<? extends DataObject> toBindingAugmented(
- final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized) throws DeserializationException {
- InstanceIdentifier<? extends DataObject> potential = toBindingImpl(normalized);
+ private Optional<InstanceIdentifier<? extends DataObject>> toBindingAugmented(
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
+ throws DeserializationException {
+ Optional<InstanceIdentifier<? extends DataObject>> potential = toBindingImpl(normalized);
// Shorthand check, if codec already supports deserialization
// of AugmentationIdentifier we will return
- if(isAugmentationIdentifier(potential)) {
+ if (potential.isPresent() && isAugmentationIdentifier(potential.get())) {
return potential;
}
AugmentationIdentifier lastArgument = (AugmentationIdentifier) Iterables.getLast(normalized.getPath());
- // Here we employ small trick - Binding-aware Codec injects an pointer to augmentation class
- // if child is referenced - so we will reference child and then shorten path.
+ // Here we employ small trick - Binding-aware Codec injects an pointer
+ // to augmentation class
+ // if child is referenced - so we will reference child and then shorten
+ // path.
for (QName child : lastArgument.getPossibleChildNames()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
- ImmutableList.<PathArgument> builder()
- .addAll(normalized.getPath()).add(new NodeIdentifier(child)).build());
+ ImmutableList.<PathArgument> builder().addAll(normalized.getPath()).add(new NodeIdentifier(child))
+ .build());
try {
-
- InstanceIdentifier<? extends DataObject> potentialPath = shortenToLastAugment(toBindingImpl(childPath));
- return potentialPath;
+ if (!isChoiceOrCasePath(childPath)) {
+ InstanceIdentifier<? extends DataObject> potentialPath = shortenToLastAugment(toBindingImpl(
+ childPath).get());
+ return Optional.<InstanceIdentifier<? extends DataObject>> of(potentialPath);
+ }
} catch (Exception e) {
- LOG.trace("Unable to deserialize aug. child path for {}",childPath,e);
+ LOG.trace("Unable to deserialize aug. child path for {}", childPath, e);
}
}
return toBindingImpl(normalized);
}
- private InstanceIdentifier<? extends DataObject> toBindingImpl(
+ private Optional<InstanceIdentifier<? extends DataObject>> toBindingImpl(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
throws DeserializationException {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier legacyPath;
+
try {
+ if (isChoiceOrCasePath(normalized)) {
+ return Optional.absent();
+ }
legacyPath = legacyToNormalized.toLegacy(normalized);
} catch (DataNormalizationException e) {
throw new IllegalStateException("Could not denormalize path.", e);
}
LOG.trace("InstanceIdentifier Path Deserialization: Legacy representation {}, Normalized representation: {}",
legacyPath, normalized);
- return bindingToLegacy.fromDataDom(legacyPath);
+ return Optional.<InstanceIdentifier<? extends DataObject>> of(bindingToLegacy.fromDataDom(legacyPath));
+ }
+
+ private boolean isChoiceOrCasePath(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
+ throws DataNormalizationException {
+ DataNormalizationOperation<?> op = findNormalizationOperation(normalized);
+ return op.isMixin() && op.getIdentifier() instanceof NodeIdentifier;
+ }
+
+ private DataNormalizationOperation<?> findNormalizationOperation(
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
+ throws DataNormalizationException {
+ DataNormalizationOperation<?> current = legacyToNormalized.getRootOperation();
+ for (PathArgument arg : normalized.getPath()) {
+ current = current.getChild(arg);
+ }
+ return current;
}
private static final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toEntry(
public DataObject toBinding(final InstanceIdentifier<?> path, final NormalizedNode<?, ?> normalizedNode)
throws DeserializationException {
CompositeNode legacy = null;
- if(isAugmentationIdentifier(path) && normalizedNode instanceof AugmentationNode) {
+ if (isAugmentationIdentifier(path) && normalizedNode instanceof AugmentationNode) {
QName augIdentifier = BindingReflections.findQName(path.getTargetType());
ContainerNode virtualNode = Builders.containerBuilder() //
.withNodeIdentifier(new NodeIdentifier(augIdentifier)) //
return legacyToNormalized;
}
- public Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toBinding(
+ public Optional<Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>> toBinding(
final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized)
throws DeserializationException {
- InstanceIdentifier<? extends DataObject> bindingPath = toBinding(normalized.getKey());
- DataObject bindingData = toBinding(bindingPath, normalized.getValue());
- return toEntry(bindingPath, bindingData);
+ Optional<InstanceIdentifier<? extends DataObject>> potentialPath = toBinding(normalized.getKey());
+ if (potentialPath.isPresent()) {
+ InstanceIdentifier<? extends DataObject> bindingPath = potentialPath.get();
+ DataObject bindingData = toBinding(bindingPath, normalized.getValue());
+ if (bindingData == null) {
+ LOG.warn("Failed to deserialize {} to Binding format. Binding path is: {}", normalized, bindingPath);
+ }
+ return Optional.of(toEntry(bindingPath, bindingData));
+ } else {
+ return Optional.absent();
+ }
}
@Override
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier processed = toNormalizedImpl(augPath);
// If used instance identifier codec added supports for deserialization
// of last AugmentationIdentifier we will just reuse it
- if(isAugmentationIdentifier(processed)) {
+ if (isAugmentationIdentifier(processed)) {
return processed;
}
- // Here we employ small trick - DataNormalizer injecst augmentation identifier if child is
- // also part of the path (since using a child we can safely identify augmentation)
+ // Here we employ small trick - DataNormalizer injecst augmentation
+ // identifier if child is
+ // also part of the path (since using a child we can safely identify
+ // augmentation)
// so, we scan augmentation for children add it to path
// and use original algorithm, then shorten it to last augmentation
- for (@SuppressWarnings("rawtypes") Class augChild : getAugmentationChildren(augPath.getTargetType())) {
+ for (@SuppressWarnings("rawtypes")
+ Class augChild : getAugmentationChildren(augPath.getTargetType())) {
@SuppressWarnings("unchecked")
InstanceIdentifier<?> childPath = augPath.child(augChild);
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized = toNormalizedImpl(childPath);
return processed;
}
-
-
private org.opendaylight.yangtools.yang.data.api.InstanceIdentifier shortenToLastAugmentation(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized) {
int position = 0;
final InstanceIdentifier<? extends DataObject> binding) {
int position = 0;
int foundPosition = -1;
- for(org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : binding.getPathArguments()) {
+ for (org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : binding.getPathArguments()) {
position++;
if (isAugmentation(arg.getType())) {
foundPosition = position;
return InstanceIdentifier.create(Iterables.limit(binding.getPathArguments(), foundPosition));
}
-
-
private org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toNormalizedImpl(
final InstanceIdentifier<? extends DataObject> binding) {
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier legacyPath = bindingToLegacy
return InstanceIdentifier.create(wildArgs);
}
-
private static boolean isAugmentation(final Class<? extends DataObject> type) {
return Augmentation.class.isAssignableFrom(type);
}
- private static boolean isAugmentationIdentifier(final InstanceIdentifier<?> path) {
- return Augmentation.class.isAssignableFrom(path.getTargetType());
+ private static boolean isAugmentationIdentifier(final InstanceIdentifier<?> potential) {
+ return Augmentation.class.isAssignableFrom(potential.getTargetType());
}
private boolean isAugmentationIdentifier(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier processed) {
*/
package org.opendaylight.controller.sal.binding.codegen;
-import com.google.common.base.Objects;
import java.lang.reflect.Field;
import java.util.Map;
-import org.eclipse.xtext.xbase.lib.Exceptions;
-import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification;
+
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
-@SuppressWarnings("all")
-public class RuntimeCodeHelper {
- /**
- * Helper method to return delegate from ManagedDirectedProxy with use of reflection.
- *
- * Note: This method uses reflection, but access to delegate field should be
- * avoided and called only if neccessary.
- */
- public static <T extends RpcService> T getDelegate(final RpcService proxy) {
- try {
- Class<? extends RpcService> _class = proxy.getClass();
- final Field field = _class.getField(RuntimeCodeSpecification.DELEGATE_FIELD);
- boolean _equals = Objects.equal(field, null);
- if (_equals) {
- UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("Unable to get delegate from proxy");
- throw _unsupportedOperationException;
- }
- try {
- Object _get = field.get(proxy);
- return ((T) _get);
- } catch (Throwable _e) {
- throw Exceptions.sneakyThrow(_e);
- }
- } catch (Throwable _e_1) {
- throw Exceptions.sneakyThrow(_e_1);
+public final class RuntimeCodeHelper {
+ private RuntimeCodeHelper() {
+ throw new UnsupportedOperationException("Utility class should never be instantiated");
+ }
+
+ private static Field getField(final Class<?> cls, final String name) {
+ try {
+ return cls.getField(name);
+ } catch (NoSuchFieldException e) {
+ throw new IllegalArgumentException(
+ String.format("Class %s is missing field %s", cls, name), e);
+ } catch (SecurityException e) {
+ throw new IllegalStateException(String.format("Failed to examine class %s", cls), e);
+ }
}
- }
- /**
- * Helper method to set delegate to ManagedDirectedProxy with use of reflection.
- *
- * Note: This method uses reflection, but setting delegate field should not occur too much
- * to introduce any significant performance hits.
- */
- public static void setDelegate(final RpcService proxy, final RpcService delegate) {
- try {
- Class<? extends RpcService> _class = proxy.getClass();
- final Field field = _class.getField(RuntimeCodeSpecification.DELEGATE_FIELD);
- boolean _equals = Objects.equal(field, null);
- if (_equals) {
- UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("Unable to set delegate to proxy");
- throw _unsupportedOperationException;
- }
- boolean _or = false;
- boolean _equals_1 = Objects.equal(delegate, null);
- if (_equals_1) {
- _or = true;
- } else {
- Class<? extends Object> _type = field.getType();
- Class<? extends RpcService> _class_1 = delegate.getClass();
- boolean _isAssignableFrom = _type.isAssignableFrom(_class_1);
- _or = (_equals_1 || _isAssignableFrom);
- }
- if (_or) {
- field.set(proxy, delegate);
- } else {
- IllegalArgumentException _illegalArgumentException = new IllegalArgumentException("delegate class is not assignable to proxy");
- throw _illegalArgumentException;
- }
- } catch (Throwable _e) {
- throw Exceptions.sneakyThrow(_e);
+ private static Field getDelegateField(final Class<?> cls) {
+ return getField(cls, RuntimeCodeSpecification.DELEGATE_FIELD);
}
- }
- /**
- * Helper method to set delegate to ManagedDirectedProxy with use of reflection.
- *
- * Note: This method uses reflection, but setting delegate field should not occur too much
- * to introduce any significant performance hits.
- */
- public static void setDelegate(final Object proxy, final Object delegate) {
- try {
- Class<? extends Object> _class = proxy.getClass();
- final Field field = _class.getField(RuntimeCodeSpecification.DELEGATE_FIELD);
- boolean _equals = Objects.equal(field, null);
- if (_equals) {
- UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("Unable to set delegate to proxy");
- throw _unsupportedOperationException;
- }
- boolean _or = false;
- boolean _equals_1 = Objects.equal(delegate, null);
- if (_equals_1) {
- _or = true;
- } else {
- Class<? extends Object> _type = field.getType();
- Class<? extends Object> _class_1 = delegate.getClass();
- boolean _isAssignableFrom = _type.isAssignableFrom(_class_1);
- _or = (_equals_1 || _isAssignableFrom);
- }
- if (_or) {
- field.set(proxy, delegate);
- } else {
- IllegalArgumentException _illegalArgumentException = new IllegalArgumentException("delegate class is not assignable to proxy");
- throw _illegalArgumentException;
- }
- } catch (Throwable _e) {
- throw Exceptions.sneakyThrow(_e);
+ private static Object getFieldValue(final Field field, final Object obj) {
+ try {
+ return field.get(obj);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException(String.format("Failed to get field %s of object %s", field, obj), e);
+ }
+ }
+
+ private static void setFieldValue(final Field field, final Object obj, final Object value) {
+ try {
+ field.set(obj, value);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException(String.format("Failed to set field %s to %s", field, value), e);
+ }
+ }
+
+ /**
+ * Helper method to return delegate from ManagedDirectedProxy with use of reflection.
+ *
+ * Note: This method uses reflection, but access to delegate field should be
+ * avoided and called only if necessary.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T extends RpcService> T getDelegate(final RpcService proxy) {
+ return (T)getFieldValue(getDelegateField(proxy.getClass()), proxy);
+ }
+
+ /**
+ * Helper method to set delegate to ManagedDirectedProxy with use of reflection.
+ *
+ * Note: This method uses reflection, but setting delegate field should not occur too much
+ * to introduce any significant performance hits.
+ */
+ public static void setDelegate(final Object proxy, final Object delegate) {
+ final Field field = getDelegateField(proxy.getClass());
+
+ if (delegate != null) {
+ final Class<?> ft = field.getType();
+ if (!ft.isAssignableFrom(delegate.getClass())) {
+ throw new IllegalArgumentException(
+ String.format("Field %s type %s is not compatible with delegate type %s",
+ field, ft, delegate.getClass()));
+ }
+ }
+
+ setFieldValue(field, proxy, delegate);
}
- }
- public static Map<InstanceIdentifier<? extends Object>,? extends RpcService> getRoutingTable(final RpcService target, final Class<? extends BaseIdentity> tableClass) {
- try {
- Class<? extends RpcService> _class = target.getClass();
- String _routingTableField = RuntimeCodeSpecification.getRoutingTableField(tableClass);
- final Field field = _class.getField(_routingTableField);
- boolean _equals = Objects.equal(field, null);
- if (_equals) {
- UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException(
- "Unable to get routing table. Table field does not exists");
- throw _unsupportedOperationException;
- }
- try {
- Object _get = field.get(target);
- return ((Map<InstanceIdentifier<? extends Object>,? extends RpcService>) _get);
- } catch (Throwable _e) {
- throw Exceptions.sneakyThrow(_e);
- }
- } catch (Throwable _e_1) {
- throw Exceptions.sneakyThrow(_e_1);
+ @SuppressWarnings("unchecked")
+ public static Map<InstanceIdentifier<? extends Object>,? extends RpcService> getRoutingTable(final RpcService target, final Class<? extends BaseIdentity> tableClass) {
+ final Field field = getField(target.getClass(), RuntimeCodeSpecification.getRoutingTableField(tableClass));
+ return (Map<InstanceIdentifier<? extends Object>,? extends RpcService>) getFieldValue(field, target);
}
- }
- public static void setRoutingTable(final RpcService target, final Class<? extends BaseIdentity> tableClass, final Map<InstanceIdentifier<? extends Object>,? extends RpcService> routingTable) {
- try {
- Class<? extends RpcService> _class = target.getClass();
- String _routingTableField = RuntimeCodeSpecification.getRoutingTableField(tableClass);
- final Field field = _class.getField(_routingTableField);
- boolean _equals = Objects.equal(field, null);
- if (_equals) {
- UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException(
- "Unable to set routing table. Table field does not exists");
- throw _unsupportedOperationException;
- }
- field.set(target, routingTable);
- } catch (Throwable _e) {
- throw Exceptions.sneakyThrow(_e);
+ public static void setRoutingTable(final RpcService target, final Class<? extends BaseIdentity> tableClass, final Map<InstanceIdentifier<? extends Object>,? extends RpcService> routingTable) {
+ final Field field = getField(target.getClass(), RuntimeCodeSpecification.getRoutingTableField(tableClass));
+ setFieldValue(field, target, routingTable);
}
- }
-}
\ No newline at end of file
+}
class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator, NotificationInvokerFactory {
val CtClass BROKER_NOTIFICATION_LISTENER;
- val ClassPool classPool;
val extension JavassistUtils utils;
val Map<Class<? extends NotificationListener>, RuntimeGeneratedInvokerPrototype> invokerClasses;
new(ClassPool pool) {
- classPool = pool;
utils = new JavassistUtils(pool);
invokerClasses = new WeakHashMap();
BROKER_NOTIFICATION_LISTENER = org.opendaylight.controller.sal.binding.api.NotificationListener.asCtClass;
*/
package org.opendaylight.controller.sal.binding.codegen.impl;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import javassist.ClassPool;
-import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
-import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
-
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import javassist.ClassPool;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
+import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
public class SingletonHolder {
+ private static final Logger logger = LoggerFactory.getLogger(SingletonHolder.class);
public static final ClassPool CLASS_POOL = ClassPool.getDefault();
public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(
public static final int CORE_NOTIFICATION_THREADS = 4;
public static final int MAX_NOTIFICATION_THREADS = 32;
// block caller thread after MAX_NOTIFICATION_THREADS + MAX_NOTIFICATION_QUEUE_SIZE pending notifications
- public static final int MAX_NOTIFICATION_QUEUE_SIZE = 10;
+ public static final int MAX_NOTIFICATION_QUEUE_SIZE = 1000;
public static final int NOTIFICATION_THREAD_LIFE = 15;
+ private static final String NOTIFICATION_QUEUE_SIZE_PROPERTY = "mdsal.notificationqueue.size";
private static ListeningExecutorService NOTIFICATION_EXECUTOR = null;
private static ListeningExecutorService COMMIT_EXECUTOR = null;
* should use service injection to make the executor configurable.
*/
@Deprecated
- public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() {
+ public static synchronized ListeningExecutorService getDefaultNotificationExecutor() {
if (NOTIFICATION_EXECUTOR == null) {
+ int queueSize = MAX_NOTIFICATION_QUEUE_SIZE;
+ String queueValue = System.getProperty(NOTIFICATION_QUEUE_SIZE_PROPERTY);
+ if (StringUtils.isNotBlank(queueValue)) {
+ try {
+ queueSize = Integer.parseInt(queueValue);
+ logger.trace("Queue size was set to {}", queueSize);
+ }catch(NumberFormatException e) {
+ logger.warn("Cannot parse {} as set by {}, using default {}", queueValue,
+ NOTIFICATION_QUEUE_SIZE_PROPERTY, queueSize);
+ }
+ }
// Overriding the queue:
// ThreadPoolExecutor would not create new threads if the queue is not full, thus adding
// occurs in RejectedExecutionHandler.
// This impl saturates threadpool first, then queue. When both are full caller will get blocked.
- BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(MAX_NOTIFICATION_QUEUE_SIZE) {
+ BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(queueSize) {
+ private static final long serialVersionUID = 1L;
+
@Override
public boolean offer(Runnable r) {
// ThreadPoolExecutor will spawn a new thread after core size is reached only if the queue.offer returns false.
* should use service injection to make the executor configurable.
*/
@Deprecated
- public static synchronized final ListeningExecutorService getDefaultCommitExecutor() {
+ public static synchronized ListeningExecutorService getDefaultCommitExecutor() {
if (COMMIT_EXECUTOR == null) {
ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("md-sal-binding-commit-%d").build();
/*
Provider, //
AutoCloseable {
-
-
private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
-
private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
.builder().toInstance();
private DataModificationTransaction createBindingToDomTransaction(
final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
DataModificationTransaction target = biDataService.beginTransaction();
- LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(),source.getIdentifier());
+ LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(), source.getIdentifier());
for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
target.removeConfigurationData(biEntry);
- LOG.debug("Delete of Binding Configuration Data {} is translated to {}",entry,biEntry);
+ LOG.debug("Delete of Binding Configuration Data {} is translated to {}", entry, biEntry);
}
for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
target.removeOperationalData(biEntry);
- LOG.debug("Delete of Binding Operational Data {} is translated to {}",entry,biEntry);
+ LOG.debug("Delete of Binding Operational Data {} is translated to {}", entry, biEntry);
}
for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
.entrySet()) {
Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
.toDataDom(entry);
target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
- LOG.debug("Update of Binding Configuration Data {} is translated to {}",entry,biEntry);
+ LOG.debug("Update of Binding Configuration Data {} is translated to {}", entry, biEntry);
}
for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
.entrySet()) {
Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
.toDataDom(entry);
target.putOperationalData(biEntry.getKey(), biEntry.getValue());
- LOG.debug("Update of Binding Operational Data {} is translated to {}",entry,biEntry);
+ LOG.debug("Update of Binding Operational Data {} is translated to {}", entry, biEntry);
}
return target;
return biDataService;
}
- protected void setDomDataService(final org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
+ protected void setDomDataService(
+ final org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
this.biDataService = biDataService;
}
}
public void startDataForwarding() {
- if(baDataService instanceof AbstractForwardedDataBroker) {
+ if (baDataService instanceof AbstractForwardedDataBroker) {
dataForwarding = true;
return;
}
final DataProviderService baData;
if (baDataService instanceof BindingMountPointImpl) {
- baData = ((BindingMountPointImpl)baDataService).getDataBrokerImpl();
+ baData = ((BindingMountPointImpl) baDataService).getDataBrokerImpl();
LOG.debug("Extracted BA Data provider {} from mount point {}", baData, baDataService);
} else {
baData = baDataService;
}
DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
- LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
- domTransaction.getIdentifier());
+ LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .",
+ bindingTransaction.getIdentifier(), domTransaction.getIdentifier());
return wrapped;
}
}
DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
@Override
- public void onRegister(final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
+ public void onRegister(
+ final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration
.getPath());
}
@Override
- public void onUnregister(final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
+ public void onUnregister(
+ final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
// NOOP for now
// FIXME: do registration based on only active commit handlers.
}
*
*/
private class DomToBindingRpcForwardingManager implements
- RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>,
- RouterInstantiationListener,
+ RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>, RouterInstantiationListener,
GlobalRpcRegistrationListener {
private final Map<Class<? extends RpcService>, DomToBindingRpcForwarder> forwarders = new WeakHashMap<>();
}
} catch (Exception e) {
- LOG.error("Could not forward Rpcs of type {}", service.getName(),e);
+ LOG.error("Could not forward Rpcs of type {}", service.getName(), e);
}
registrations = ImmutableSet.of();
}
* @param service
* @param context
*/
- public DomToBindingRpcForwarder(final Class<? extends RpcService> service, final Class<? extends BaseIdentity> context) {
+ public DomToBindingRpcForwarder(final Class<? extends RpcService> service,
+ final Class<? extends BaseIdentity> context) {
this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
this.supportedRpcs = mappingService.getRpcQNamesFor(service);
Builder<RoutedRpcRegistration> registrationsBuilder = ImmutableSet
registrations = registrationsBuilder.build();
}
- public void registerPaths(final Class<? extends BaseIdentity> context, final Class<? extends RpcService> service,
- final Set<InstanceIdentifier<?>> set) {
+ public void registerPaths(final Class<? extends BaseIdentity> context,
+ final Class<? extends RpcService> service, final Set<InstanceIdentifier<?>> set) {
QName ctx = BindingReflections.findQName(context);
for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform(
toDOMInstanceIdentifier)) {
}
}
-
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if (EQUALS_METHOD.equals(method)) {
}
}
-
@Override
public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode domInput) {
checkArgument(rpc != null);
strategy = new DefaultInvocationStrategy(rpc, targetMethod, outputClass.get(), inputClass
.get());
} else {
- strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod);
+ strategy = new NoInputInvocationStrategy(rpc, targetMethod, outputClass.get());
}
- } else if(inputClass.isPresent()){
- strategy = new NoOutputInvocationStrategy(rpc,targetMethod, inputClass.get());
+ } else if (inputClass.isPresent()) {
+ strategy = new NoOutputInvocationStrategy(rpc, targetMethod, inputClass.get());
} else {
- strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod);
+ strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod);
}
return strategy;
}
public abstract RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput)
throws Exception;
- public RpcResult<CompositeNode> invokeOn(final RpcService rpcService, final CompositeNode domInput) throws Exception {
+ public RpcResult<CompositeNode> invokeOn(final RpcService rpcService, final CompositeNode domInput)
+ throws Exception {
return uncheckedInvoke(rpcService, domInput);
}
}
@SuppressWarnings("unchecked")
@Override
- public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception {
+ public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput)
+ throws Exception {
DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
Future<RpcResult<?>> futureResult = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
if (futureResult == null) {
RpcResult<?> bindingResult = futureResult.get();
final Object resultObj = bindingResult.getResult();
if (resultObj instanceof DataObject) {
- final CompositeNode output = mappingService.toDataDom((DataObject)resultObj);
- return Rpcs.getRpcResult(true, output, Collections.<RpcError>emptySet());
+ final CompositeNode output = mappingService.toDataDom((DataObject) resultObj);
+ return Rpcs.getRpcResult(true, output, Collections.<RpcError> emptySet());
}
return Rpcs.getRpcResult(true);
}
@Override
public ListenableFuture<RpcResult<?>> forwardToDomBroker(final DataObject input) {
- if(biRpcRegistry == null) {
+ if (biRpcRegistry == null) {
return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
}
CompositeNode xml = mappingService.toDataDom(input);
CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
- return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
- @Override
- public RpcResult<?> apply(RpcResult<CompositeNode> input) {
- Object baResultValue = null;
- if (input.getResult() != null) {
- baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), input.getResult());
- }
- return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors());
- }
- });
+ return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml),
+ new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
+ @Override
+ public RpcResult<?> apply(final RpcResult<CompositeNode> input) {
+ Object baResultValue = null;
+ if (input.getResult() != null) {
+ baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(),
+ input.getResult());
+ }
+ return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors());
+ }
+ });
+ }
+ }
+
+ private class NoInputInvocationStrategy extends RpcInvocationStrategy {
+
+ @SuppressWarnings("rawtypes")
+ private final WeakReference<Class> outputClass;
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public NoInputInvocationStrategy(final QName rpc, final Method targetMethod, final Class<?> outputClass) {
+ super(rpc, targetMethod);
+ this.outputClass = new WeakReference(outputClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput)
+ throws Exception {
+ Future<RpcResult<?>> futureResult = (Future<RpcResult<?>>) targetMethod.invoke(rpcService);
+ if (futureResult == null) {
+ return Rpcs.getRpcResult(false);
+ }
+ RpcResult<?> bindingResult = futureResult.get();
+ final Object resultObj = bindingResult.getResult();
+ if (resultObj instanceof DataObject) {
+ final CompositeNode output = mappingService.toDataDom((DataObject) resultObj);
+ return Rpcs.getRpcResult(true, output, Collections.<RpcError> emptySet());
+ }
+ return Rpcs.getRpcResult(true);
+ }
+
+ @Override
+ public Future<RpcResult<?>> forwardToDomBroker(final DataObject input) {
+ if (biRpcRegistry != null) {
+ CompositeNode xml = mappingService.toDataDom(input);
+ CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
+ return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml),
+ new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
+ @Override
+ public RpcResult<?> apply(final RpcResult<CompositeNode> input) {
+ Object baResultValue = null;
+ if (input.getResult() != null) {
+ baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(),
+ input.getResult());
+ }
+ return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors());
+ }
+ });
+ } else {
+ return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
+ }
}
}
}
@Override
- public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception {
+ public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput)
+ throws Exception {
@SuppressWarnings("unchecked")
Future<RpcResult<Void>> result = (Future<RpcResult<Void>>) targetMethod.invoke(rpcService);
RpcResult<Void> bindingResult = result.get();
private class NoOutputInvocationStrategy extends RpcInvocationStrategy {
-
@SuppressWarnings("rawtypes")
private final WeakReference<Class> inputClass;
@SuppressWarnings({ "rawtypes", "unchecked" })
public NoOutputInvocationStrategy(final QName rpc, final Method targetMethod,
final Class<? extends DataContainer> inputClass) {
- super(rpc,targetMethod);
+ super(rpc, targetMethod);
this.inputClass = new WeakReference(inputClass);
}
-
@Override
- public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception {
+ public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput)
+ throws Exception {
DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
Future<RpcResult<?>> result = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
if (result == null) {
@Override
public ListenableFuture<RpcResult<?>> forwardToDomBroker(final DataObject input) {
- if(biRpcRegistry == null) {
+ if (biRpcRegistry == null) {
return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
}
CompositeNode xml = mappingService.toDataDom(input);
- CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
+ CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
- return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
- @Override
- public RpcResult<?> apply(RpcResult<CompositeNode> input) {
- return Rpcs.<Void>getRpcResult(input.isSuccessful(), null, input.getErrors());
- }
- });
+ return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml),
+ new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
+ @Override
+ public RpcResult<?> apply(final RpcResult<CompositeNode> input) {
+ return Rpcs.<Void> getRpcResult(input.isSuccessful(), null, input.getErrors());
+ }
+ });
}
}
private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
.toInstance();
- private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier
- .builder(NODES_INSTANCE_ID_BA) //
- .child(Node.class, NODE_KEY).toInstance();
+ private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA =
+ NODES_INSTANCE_ID_BA.child(Node.class, NODE_KEY);
private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
/**
* Test for Bug 148
- *
+ *
* @throws Exception
*/
@Test
// Node meterStatsNodeWithDuration = createTestNode(NodeMeterStatistics.class, nodeMeterStatistics(5, true));
// commitNodeAndVerifyTransaction(meterStatsNodeWithDuration);
//
-//
+//
// Node nodeWithUpdatedList = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
// AugmentationVerifier.from(nodeWithUpdatedList) //
// .assertHasAugmentation(FlowCapableNode.class) //
// .assertHasAugmentation(NodeMeterStatistics.class);
-//
+//
// List<MeterStats> meterStats = nodeWithUpdatedList.getAugmentation(NodeMeterStatistics.class).getMeterStatistics().getMeterStats();
// assertNotNull(meterStats);
// assertFalse(meterStats.isEmpty());
public void startBindingToDomMappingService() {
checkState(classPool != null, "ClassPool needs to be present");
- mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
- mappingServiceImpl.setPool(classPool);
- mappingServiceImpl.init();
+ mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl(classPool);
}
public void updateYangSchema(final String[] files) {
private static final NodeKey NODE_FOO_KEY = new NodeKey(new NodeId("foo"));
private static final NodeKey NODE_BAR_KEY = new NodeKey(new NodeId("foo"));
private static InstanceIdentifier<Nodes> NODES_PATH = InstanceIdentifier.builder(Nodes.class).build();
- private static InstanceIdentifier<Node> NODE_FOO_PATH = InstanceIdentifier.builder(NODES_PATH)
- .child(Node.class, NODE_FOO_KEY).build();
- private static InstanceIdentifier<Node> NODE_BAR_PATH = InstanceIdentifier.builder(NODES_PATH)
- .child(Node.class, NODE_FOO_KEY).build();
+ private static InstanceIdentifier<Node> NODE_FOO_PATH = NODES_PATH.child(Node.class, NODE_FOO_KEY);
+ private static InstanceIdentifier<Node> NODE_BAR_PATH = NODES_PATH.child(Node.class, NODE_FOO_KEY);
@Test
public void testConcurrentCreate() throws InterruptedException, ExecutionException {
private static final UnorderedListKey UNORDERED_FOO_KEY = new UnorderedListKey("foo");
private static final UnorderedListKey UNORDERED_BAR_KEY = new UnorderedListKey("bar");
- private static final InstanceIdentifier<UnorderedList> UNORDERED_FOO_PATH = InstanceIdentifier.builder(UNORDERED_CONTAINER_PATH).child(UnorderedList.class,UNORDERED_FOO_KEY).build();
- private static final InstanceIdentifier<UnorderedList> UNORDERED_BAR_PATH = InstanceIdentifier.builder(UNORDERED_CONTAINER_PATH).child(UnorderedList.class,UNORDERED_BAR_KEY).build();
+ private static final InstanceIdentifier<UnorderedList> UNORDERED_FOO_PATH = UNORDERED_CONTAINER_PATH.child(UnorderedList.class,UNORDERED_FOO_KEY);
+ private static final InstanceIdentifier<UnorderedList> UNORDERED_BAR_PATH = UNORDERED_CONTAINER_PATH.child(UnorderedList.class,UNORDERED_BAR_KEY);
private static final OrderedListKey ORDERED_FOO_KEY = new OrderedListKey("foo");
private static final OrderedListKey ORDERED_BAR_KEY = new OrderedListKey("bar");
- private static final InstanceIdentifier<OrderedList> ORDERED_FOO_PATH = InstanceIdentifier.builder(ORDERED_CONTAINER_PATH).child(OrderedList.class,ORDERED_FOO_KEY).build();
- private static final InstanceIdentifier<OrderedList> ORDERED_BAR_PATH = InstanceIdentifier.builder(ORDERED_CONTAINER_PATH).child(OrderedList.class,ORDERED_BAR_KEY).build();
+ private static final InstanceIdentifier<OrderedList> ORDERED_FOO_PATH = ORDERED_CONTAINER_PATH.child(OrderedList.class,ORDERED_FOO_KEY);
+ private static final InstanceIdentifier<OrderedList> ORDERED_BAR_PATH = ORDERED_CONTAINER_PATH.child(OrderedList.class,ORDERED_BAR_KEY);
@Test
private static final FlowKey FLOW_KEY = new FlowKey(new FlowId("test"));
- private static final InstanceIdentifier<Flow> NODE_0_FLOW_PATH = InstanceIdentifier.builder(NODE_0_TABLE_PATH)
- .child(Flow.class, FLOW_KEY).build();
+ private static final InstanceIdentifier<Flow> NODE_0_FLOW_PATH = NODE_0_TABLE_PATH.child(Flow.class, FLOW_KEY);
- private static final InstanceIdentifier<Flow> NODE_1_FLOW_PATH = InstanceIdentifier.builder(NODE_1_TABLE_PATH)
- .child(Flow.class, FLOW_KEY).build();
+ private static final InstanceIdentifier<Flow> NODE_1_FLOW_PATH = NODE_1_TABLE_PATH.child(Flow.class, FLOW_KEY);
- private static final InstanceIdentifier<TableFeatures> NODE_0_TABLE_FEATURES_PATH = InstanceIdentifier
- .builder(NODE_0_TABLE_PATH).child(TableFeatures.class, TABLE_FEATURES_KEY).build();
+ private static final InstanceIdentifier<TableFeatures> NODE_0_TABLE_FEATURES_PATH =
+ NODE_0_TABLE_PATH.child(TableFeatures.class, TABLE_FEATURES_KEY);
private static final TableFeatures TABLE_FEATURES = new TableFeaturesBuilder()//
.setKey(TABLE_FEATURES_KEY) //
.toInstance();
- private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier//
- .builder(NODES_INSTANCE_ID_BA) //
- .child(Node.class, NODE_KEY).toInstance();
+ private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = NODES_INSTANCE_ID_BA.child(Node.class, NODE_KEY);
- private static final InstanceIdentifier<SupportedActions> SUPPORTED_ACTIONS_INSTANCE_ID_BA = InstanceIdentifier//
- .builder(NODES_INSTANCE_ID_BA) //
+ private static final InstanceIdentifier<SupportedActions> SUPPORTED_ACTIONS_INSTANCE_ID_BA = //
+ NODES_INSTANCE_ID_BA.builder() //
.child(Node.class, NODE_KEY) //
.augmentation(FlowCapableNode.class) //
.child(SupportedActions.class)
NodeConnectorId ncId = new NodeConnectorId("openflow:1:bar");
NodeConnectorKey nodeKey = new NodeConnectorKey(ncId );
- InstanceIdentifier<NodeConnector> ncInstanceId = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).child(NodeConnector.class, nodeKey).toInstance();
+ InstanceIdentifier<NodeConnector> ncInstanceId = NODE_INSTANCE_ID_BA.child(NodeConnector.class, nodeKey);
NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder();
ncBuilder.setId(ncId);
ncBuilder.setKey(nodeKey);
*/
package org.opendaylight.controller.sal.binding.test.bugfix;
-import com.google.common.collect.ImmutableSet;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import com.google.common.collect.ImmutableSet;
public class FlagsSerializationTest extends AbstractDataServiceTest {
private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
private static final FlowKey FLOW_KEY = new FlowKey(new FlowId(FLOW_ID));
private static final TableKey TABLE_KEY = new TableKey(TABLE_ID);
-
+
private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
NODE_ID);
// private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier FLOW_INSTANCE_ID_BI = //
// org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-//
+//
// .node(Flows.QNAME) //
// .nodeWithKey(Flow.QNAME, FLOW_KEY_BI) //
// .toInstance();
private static final InstanceIdentifier<? extends DataObject> FLOW_INSTANCE_ID_BA = //
- InstanceIdentifier.builder(NODE_INSTANCE_ID_BA) //
+ NODE_INSTANCE_ID_BA.builder() //
.augmentation(FlowCapableNode.class)
.child(Table.class,TABLE_KEY)
.child(Flow.class, FLOW_KEY) //
FlowModFlags checkOverlapFlags = new FlowModFlags(true,false,false,false,false);
ImmutableSet<String> domCheckOverlapFlags = ImmutableSet.<String>of("CHECK_OVERLAP");
testFlags(checkOverlapFlags,domCheckOverlapFlags);
-
-
-
+
+
+
FlowModFlags allFalseFlags = new FlowModFlags(false,false,false,false,false);
ImmutableSet<String> domAllFalseFlags = ImmutableSet.<String>of();
testFlags(allFalseFlags,domAllFalseFlags);
-
+
FlowModFlags allTrueFlags = new FlowModFlags(true,true,true,true,true);
ImmutableSet<String> domAllTrueFlags = ImmutableSet.<String>of("CHECK_OVERLAP","NO_BYT_COUNTS", "NO_PKT_COUNTS", "RESET_COUNTS", "SEND_FLOW_REM");
testFlags(allTrueFlags,domAllTrueFlags);
-
+
FlowModFlags nullFlags = null;
ImmutableSet<String> domNullFlags = null;
testFlags(null,null);
-
-
+
+
}
private void testFlags(FlowModFlags flagsToTest, ImmutableSet<String> domFlags) throws Exception {
Flow flow = createFlow(flagsToTest);
assertNotNull(flow);
-
+
CompositeNode domFlow = biDataService.readConfigurationData(mappingService.toDataDom(FLOW_INSTANCE_ID_BA));
-
+
assertNotNull(domFlow);
org.opendaylight.yangtools.yang.data.api.Node<?> readedFlags = domFlow.getFirstSimpleByName(FLOW_FLAGS_QNAME);
-
+
if(domFlags != null) {
assertNotNull(readedFlags);
assertEquals(domFlags,readedFlags.getValue());
assertNull(readedFlags);
}
assertEquals(flagsToTest, flow.getFlags());
-
+
DataModificationTransaction transaction = baDataService.beginTransaction();
transaction.removeConfigurationData(FLOW_INSTANCE_ID_BA);
RpcResult<TransactionStatus> result = transaction.commit().get();
assertEquals(TransactionStatus.COMMITED, result.getResult());
-
+
}
private Flow createFlow(FlowModFlags flagsToTest) throws Exception {
flow.setKey(FLOW_KEY);
flow.setMatch(match.build());
-
+
flow.setFlags(flagsToTest);
-
+
InstructionsBuilder instructions = new InstructionsBuilder();
InstructionBuilder instruction = new InstructionBuilder();
-
+
instruction.setOrder(10);
ApplyActionsBuilder applyActions = new ApplyActionsBuilder();
List<Action> actionList = new ArrayList<>();
private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
.toInstance();
- private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier//
- .builder(NODES_INSTANCE_ID_BA) //
+ private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = //
+ NODES_INSTANCE_ID_BA.builder() //
.child(Node.class, NODE_KEY).toInstance();
- private static final InstanceIdentifier<SupportedActions> SUPPORTED_ACTIONS_INSTANCE_ID_BA = InstanceIdentifier//
- .builder(NODES_INSTANCE_ID_BA) //
+ private static final InstanceIdentifier<SupportedActions> SUPPORTED_ACTIONS_INSTANCE_ID_BA = //
+ NODES_INSTANCE_ID_BA.builder() //
.child(Node.class, NODE_KEY) //
.augmentation(FlowCapableNode.class) //
.child(SupportedActions.class).toInstance();
- private static final InstanceIdentifier<FlowCapableNode> ALL_FLOW_CAPABLE_NODES = InstanceIdentifier //
- .builder(NODES_INSTANCE_ID_BA) //
+ private static final InstanceIdentifier<FlowCapableNode> ALL_FLOW_CAPABLE_NODES = //
+ NODES_INSTANCE_ID_BA.builder() //
.child(Node.class) //
.augmentation(FlowCapableNode.class) //
.build();
.nodeWithKey(Node.QNAME, NODE_KEY_BI) //
.node(SUPPORTED_ACTIONS_QNAME) //
.toInstance();
- private static final InstanceIdentifier<FlowCapableNode> FLOW_AUGMENTATION_PATH = InstanceIdentifier //
- .builder(NODE_INSTANCE_ID_BA) //
+ private static final InstanceIdentifier<FlowCapableNode> FLOW_AUGMENTATION_PATH =
+ NODE_INSTANCE_ID_BA.builder() //
.augmentation(FlowCapableNode.class) //
.build();
fnub.setDescription("Description Foo");
fnub.setSoftware("JUnit emulated");
FlowCapableNode fnu = fnub.build();
- InstanceIdentifier<FlowCapableNode> augmentIdentifier = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA)
- .augmentation(FlowCapableNode.class).toInstance();
+ InstanceIdentifier<FlowCapableNode> augmentIdentifier = NODE_INSTANCE_ID_BA
+ .augmentation(FlowCapableNode.class);
DataModificationTransaction augmentedTransaction = baDataService.beginTransaction();
augmentedTransaction.putOperationalData(augmentIdentifier, fnu);
lastReceivedChangeEvent = SettableFuture.create();
assertEquals(TransactionStatus.COMMITED, result.getResult());
- FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(InstanceIdentifier
- .builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance());
+ FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(
+ NODE_INSTANCE_ID_BA.augmentation(FlowCapableNode.class));
assertNotNull(readedAugmentation);
assertEquals(fnu.getHardware(), readedAugmentation.getHardware());
private void testPutNodeConnectorWithAugmentation() throws Exception {
NodeConnectorKey ncKey = new NodeConnectorKey(new NodeConnectorId("test:0:0"));
- InstanceIdentifier<NodeConnector> ncPath = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA)
- .child(NodeConnector.class, ncKey).toInstance();
- InstanceIdentifier<FlowCapableNodeConnector> ncAugmentPath = InstanceIdentifier.builder(ncPath)
- .augmentation(FlowCapableNodeConnector.class).toInstance();
+ InstanceIdentifier<NodeConnector> ncPath = NODE_INSTANCE_ID_BA
+ .child(NodeConnector.class, ncKey);
+ InstanceIdentifier<FlowCapableNodeConnector> ncAugmentPath = ncPath
+ .augmentation(FlowCapableNodeConnector.class);
NodeConnectorBuilder nc = new NodeConnectorBuilder();
nc.setKey(ncKey);
.child(Node.class, NODE_KEY).toInstance();
private static final InstanceIdentifier<Table> TABLE_INSTANCE_ID_BA = //
- InstanceIdentifier.builder(NODE_INSTANCE_ID_BA) //
+ NODE_INSTANCE_ID_BA.builder() //
.augmentation(FlowCapableNode.class).child(Table.class, TABLE_KEY).build();
private static final InstanceIdentifier<? extends DataObject> FLOW_INSTANCE_ID_BA = //
- InstanceIdentifier.builder(TABLE_INSTANCE_ID_BA) //
- .child(Flow.class, FLOW_KEY) //
- .toInstance();
+ TABLE_INSTANCE_ID_BA.child(Flow.class, FLOW_KEY);
/**
*
* The scenario tests writing parent node, which also contains child items
DataObject readedTable = baDataService.readConfigurationData(TABLE_INSTANCE_ID_BA);
assertNotNull("Readed table should not be nul.", readedTable);
assertTrue(readedTable instanceof Table);
-
+
DataObject readedFlow = baDataService.readConfigurationData(FLOW_INSTANCE_ID_BA);
assertNotNull("Readed flow should not be null.",readedFlow);
assertTrue(readedFlow instanceof Flow);
assertEquals(flow, readedFlow);
}
-}
\ No newline at end of file
+}
private static final TableKey TABLE_KEY_BA = new TableKey((short) 0);
private static final InstanceIdentifier<Flow> FLOWS_PATH_BA = //
- InstanceIdentifier.builder(NODE_INSTANCE_ID_BA) //
+ NODE_INSTANCE_ID_BA.builder() //
.augmentation(FlowCapableNode.class) //
.child(Table.class, TABLE_KEY_BA) //
.child(Flow.class) //
.toInstance();
private static final InstanceIdentifier<Flow> FLOW_INSTANCE_ID_BA = //
- InstanceIdentifier.builder(FLOWS_PATH_BA.firstIdentifierOf(Table.class)) //
- .child(Flow.class, FLOW_KEY) //
- .toInstance();
+ FLOWS_PATH_BA.firstIdentifierOf(Table.class).child(Flow.class, FLOW_KEY);
@Test
public void simpleModifyOperation() throws Exception {
.child(Node.class, NODE_KEY).toInstance();
private static GroupKey GROUP_KEY = new GroupKey(new GroupId(0L));
- private static final InstanceIdentifier<GroupStatistics> GROUP_STATISTICS_ID_BA = InstanceIdentifier
- .builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class) //
+ private static final InstanceIdentifier<GroupStatistics> GROUP_STATISTICS_ID_BA = NODE_INSTANCE_ID_BA
+ .builder().augmentation(FlowCapableNode.class) //
.child(Group.class, GROUP_KEY) //
.augmentation(NodeGroupStatistics.class) //
.child(GroupStatistics.class) //
void registerPath(C context, P path);
void unregisterPath(C context, P path);
+ @Override
+ void close();
}
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-import org.eclipse.xtext.xbase.lib.Exceptions;
import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
}
protected ImmutableList<DataCommitHandler<P, D>> affectedCommitHandlers(final Set<P> paths) {
- final Callable<ImmutableList<DataCommitHandler<P, D>>> _function = new Callable<ImmutableList<DataCommitHandler<P, D>>>() {
+ final Supplier<ImmutableList<DataCommitHandler<P, D>>> _function = new Supplier<ImmutableList<DataCommitHandler<P, D>>>() {
@Override
- public ImmutableList<DataCommitHandler<P, D>> call() throws Exception {
+ public ImmutableList<DataCommitHandler<P, D>> get() {
Map<P, Collection<DataCommitHandlerRegistrationImpl<P, D>>> _asMap = commitHandlers.asMap();
Set<Entry<P, Collection<DataCommitHandlerRegistrationImpl<P, D>>>> _entrySet = _asMap.entrySet();
FluentIterable<Entry<P, Collection<DataCommitHandlerRegistrationImpl<P, D>>>> _from = FluentIterable
}
protected ImmutableList<DataCommitHandler<P, D>> probablyAffectedCommitHandlers(final HashSet<P> paths) {
- final Callable<ImmutableList<DataCommitHandler<P, D>>> _function = new Callable<ImmutableList<DataCommitHandler<P, D>>>() {
+ final Supplier<ImmutableList<DataCommitHandler<P, D>>> _function = new Supplier<ImmutableList<DataCommitHandler<P, D>>>() {
@Override
- public ImmutableList<DataCommitHandler<P, D>> call() throws Exception {
+ public ImmutableList<DataCommitHandler<P, D>> get() {
Map<P, Collection<DataCommitHandlerRegistrationImpl<P, D>>> _asMap = commitHandlers.asMap();
Set<Entry<P, Collection<DataCommitHandlerRegistrationImpl<P, D>>>> _entrySet = _asMap.entrySet();
FluentIterable<Entry<P, Collection<DataCommitHandlerRegistrationImpl<P, D>>>> _from = FluentIterable
return _dataReadRouter.readOperationalData(path);
}
- private static <T extends Object> T withLock(final Lock lock, final Callable<T> method) {
+ private static <T extends Object> T withLock(final Lock lock, final Supplier<T> method) {
lock.lock();
try {
- return method.call();
- } catch (Exception e) {
- throw Exceptions.sneakyThrow(e);
+ return method.get();
} finally {
lock.unlock();
}
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.dom.store.impl;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.dom.store.impl;
import java.util.Collections;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import com.google.common.base.Optional;
-import com.google.common.primitives.UnsignedLong;
class DataAndMetadataSnapshot {
public static DataAndMetadataSnapshot createEmpty(final NodeIdentifier rootNode) {
NormalizedNode<?, ?> data = Builders.containerBuilder().withNodeIdentifier(rootNode).build();
- StoreMetadataNode metadata = StoreMetadataNode.builder()
- .setNodeVersion(UnsignedLong.ZERO)
- .setSubtreeVersion(UnsignedLong.ZERO)
- .setData(data)
- .build();
+ StoreMetadataNode metadata = StoreMetadataNode.createEmpty(data);
return new DataAndMetadataSnapshot(metadata,Optional.<SchemaContext>absent());
}
public static DataAndMetadataSnapshot createEmpty(final SchemaContext ctx) {
NodeIdentifier rootNodeIdentifier = new NodeIdentifier(ctx.getQName());
NormalizedNode<?, ?> data = Builders.containerBuilder().withNodeIdentifier(rootNodeIdentifier).build();
- StoreMetadataNode metadata = StoreMetadataNode.builder()
- .setData(data)
- .setNodeVersion(UnsignedLong.ZERO)
- .setSubtreeVersion(UnsignedLong.ZERO)
- .build();
+ StoreMetadataNode metadata = StoreMetadataNode.createEmpty(data);
return new DataAndMetadataSnapshot(metadata, Optional.of(ctx));
}
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.dom.store.impl;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-public interface DataChangeListenerRegistration<L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>>
-extends ListenerRegistration<L> {
-
-
+public interface DataChangeListenerRegistration<L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> extends ListenerRegistration<L> {
@Override
- public L getInstance();
+ L getInstance();
InstanceIdentifier getPath();
DataChangeScope getScope();
-
-
-
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class DataPreconditionFailedException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 596430355175413427L;
+ private final InstanceIdentifier path;
+
+ public DataPreconditionFailedException(final InstanceIdentifier path) {
+ this.path = path;
+ }
+
+ public DataPreconditionFailedException(final InstanceIdentifier path,final String message) {
+ super(message);
+ this.path = path;
+ }
+
+
+ public DataPreconditionFailedException(final InstanceIdentifier path,final Throwable cause) {
+ super(cause);
+ this.path = path;
+ }
+
+ public DataPreconditionFailedException(final InstanceIdentifier path,final String message, final Throwable cause) {
+ super(message, cause);
+ this.path = path;
+ }
+
+ public DataPreconditionFailedException(final InstanceIdentifier path,final String message, final Throwable cause, final boolean enableSuppression,
+ final boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ this.path = path;
+ }
+
+ public InstanceIdentifier getPath() {
+ return path;
+ }
+
+}
private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataStore.class);
private static final InstanceIdentifier PUBLIC_ROOT_PATH = InstanceIdentifier.builder().build();
-
private final ListeningExecutorService executor;
private final String name;
private final AtomicLong txCounter = new AtomicLong(0);
final InstanceIdentifier path, final L listener, final DataChangeScope scope) {
/*
- * Make sure commit is not occurring right now. Listener has to be registered and its
- * state capture enqueued at a consistent point.
+ * Make sure commit is not occurring right now. Listener has to be
+ * registered and its state capture enqueued at a consistent point.
*
- * FIXME: improve this to read-write lock, such that multiple listener registrations
- * can occur simultaneously
+ * FIXME: improve this to read-write lock, such that multiple listener
+ * registrations can occur simultaneously
*/
final DataChangeListenerRegistration<L> reg;
synchronized (this) {
- LOG.debug("{}: Registering data change listener {} for {}",name,listener,path);
+ LOG.debug("{}: Registering data change listener {} for {}", name, listener, path);
reg = listenerTree.registerDataChangeListener(path, listener, scope);
};
}
- private synchronized DOMStoreThreePhaseCommitCohort submit(
- final SnapshotBackedWriteTransaction writeTx) {
- LOG.debug("Tx: {} is submitted. Modifications: {}",writeTx.getIdentifier(),writeTx.getMutatedView());
+ private synchronized DOMStoreThreePhaseCommitCohort submit(final SnapshotBackedWriteTransaction writeTx) {
+ LOG.debug("Tx: {} is submitted. Modifications: {}", writeTx.getIdentifier(), writeTx.getMutatedView());
return new ThreePhaseCommitImpl(writeTx);
}
return name + "-" + txCounter.getAndIncrement();
}
- private void commit(final DataAndMetadataSnapshot currentSnapshot,
- final StoreMetadataNode newDataTree, final ResolveDataChangeEventsTask listenerResolver) {
- LOG.debug("Updating Store snaphot version: {} with version:{}",currentSnapshot.getMetadataTree().getSubtreeVersion(),newDataTree.getSubtreeVersion());
+ private void commit(final DataAndMetadataSnapshot currentSnapshot, final StoreMetadataNode newDataTree,
+ final ResolveDataChangeEventsTask listenerResolver) {
+ LOG.debug("Updating Store snaphot version: {} with version:{}", currentSnapshot.getMetadataTree()
+ .getSubtreeVersion(), newDataTree.getSubtreeVersion());
- if(LOG.isTraceEnabled()) {
- LOG.trace("Data Tree is {}",StoreUtils.toStringTree(newDataTree));
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Data Tree is {}", StoreUtils.toStringTree(newDataTree));
}
final DataAndMetadataSnapshot newSnapshot = DataAndMetadataSnapshot.builder() //
.build();
/*
- * The commit has to occur atomically with regard to listener registrations.
+ * The commit has to occur atomically with regard to listener
+ * registrations.
*/
synchronized (this) {
final boolean success = snapshot.compareAndSet(currentSnapshot, newSnapshot);
checkState(success, "Store snapshot and transaction snapshot differ. This should never happen.");
for (ChangeListenerNotifyTask task : listenerResolver.call()) {
- LOG.trace("Scheduling invocation of listeners: {}",task);
+ LOG.trace("Scheduling invocation of listeners: {}", task);
executor.submit(task);
}
}
/**
* Add class-specific toString attributes.
*
- * @param toStringHelper ToStringHelper instance
+ * @param toStringHelper
+ * ToStringHelper instance
* @return ToStringHelper instance which was passed in
*/
protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
}
}
- private static class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements DOMStoreReadTransaction {
+ private static class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements
+ DOMStoreReadTransaction {
private DataAndMetadataSnapshot stableSnapshot;
public SnapshotBackedReadTransaction(final Object identifier, final DataAndMetadataSnapshot snapshot) {
super(identifier);
this.stableSnapshot = Preconditions.checkNotNull(snapshot);
- LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot.getMetadataTree().getSubtreeVersion());
+ LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot.getMetadataTree()
+ .getSubtreeVersion());
}
@Override
}
}
- private static class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction implements DOMStoreWriteTransaction {
+ private static class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction implements
+ DOMStoreWriteTransaction {
private MutableDataTree mutableTree;
private InMemoryDOMDataStore store;
private boolean ready = false;
super(identifier);
mutableTree = MutableDataTree.from(snapshot, applyOper);
this.store = store;
- LOG.debug("Write Tx: {} allocated with snapshot {}",identifier,snapshot.getMetadataTree().getSubtreeVersion());
+ LOG.debug("Write Tx: {} allocated with snapshot {}", identifier, snapshot.getMetadataTree()
+ .getSubtreeVersion());
}
@Override
public void write(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
checkNotReady();
try {
- LOG.trace("Tx: {} Write: {}:{}",getIdentifier(),path,data);
+ LOG.trace("Tx: {} Write: {}:{}", getIdentifier(), path, data);
mutableTree.write(path, data);
- // FIXME: Add checked exception
+ // FIXME: Add checked exception
} catch (Exception e) {
- LOG.error("Tx: {}, failed to write {}:{} in {}",getIdentifier(),path,data,mutableTree,e);
+ LOG.error("Tx: {}, failed to write {}:{} in {}", getIdentifier(), path, data, mutableTree, e);
}
}
public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
checkNotReady();
try {
- LOG.trace("Tx: {} Merge: {}:{}",getIdentifier(),path,data);
+ LOG.trace("Tx: {} Merge: {}:{}", getIdentifier(), path, data);
mutableTree.merge(path, data);
- // FIXME: Add checked exception
+ // FIXME: Add checked exception
} catch (Exception e) {
- LOG.error("Tx: {}, failed to write {}:{} in {}",getIdentifier(),path,data,mutableTree,e);
+ LOG.error("Tx: {}, failed to write {}:{} in {}", getIdentifier(), path, data, mutableTree, e);
}
}
public void delete(final InstanceIdentifier path) {
checkNotReady();
try {
- LOG.trace("Tx: {} Delete: {}",getIdentifier(),path);
+ LOG.trace("Tx: {} Delete: {}", getIdentifier(), path);
mutableTree.delete(path);
- // FIXME: Add checked exception
+ // FIXME: Add checked exception
} catch (Exception e) {
- LOG.error("Tx: {}, failed to delete {} in {}",getIdentifier(),path,mutableTree,e);
+ LOG.error("Tx: {}, failed to delete {} in {}", getIdentifier(), path, mutableTree, e);
}
}
@Override
public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
- LOG.trace("Tx: {} Read: {}",getIdentifier(),path);
+ LOG.trace("Tx: {} Read: {}", getIdentifier(), path);
try {
return Futures.immediateFuture(getMutatedView().read(path));
} catch (Exception e) {
- LOG.error("Tx: {} Failed Read of {}",getIdentifier(),path,e);
+ LOG.error("Tx: {} Failed Read of {}", getIdentifier(), path, e);
throw e;
}
}
@Override
public Boolean call() throws Exception {
- boolean applicable = snapshotOperation.isApplicable(modification,
+ Boolean applicable = false;
+ try {
+ snapshotOperation.checkApplicable(PUBLIC_ROOT_PATH, modification,
Optional.of(snapshotCapture.getMetadataTree()));
- LOG.debug("Store Transcation: {} : canCommit : {}", transaction.getIdentifier(), applicable);
+ applicable = true;
+ } catch (DataPreconditionFailedException e) {
+ LOG.warn("Store Tx: {} Data Precondition failed for {}.",transaction.getIdentifier(),e.getPath(),e);
+ applicable = false;
+ }
+ LOG.debug("Store Transaction: {} : canCommit : {}", transaction.getIdentifier(), applicable);
return applicable;
}
});
@Override
public ListenableFuture<Void> preCommit() {
storeSnapshot = snapshot.get();
- if(modification.getModificationType() == ModificationType.UNMODIFIED) {
+ if (modification.getModificationType() == ModificationType.UNMODIFIED) {
return Futures.immediateFuture(null);
}
return executor.submit(new Callable<Void>() {
-
-
@Override
public Void call() throws Exception {
StoreMetadataNode metadataTree = storeSnapshot.getMetadataTree();
@Override
public ListenableFuture<Void> commit() {
- if(modification.getModificationType() == ModificationType.UNMODIFIED) {
+ if (modification.getModificationType() == ModificationType.UNMODIFIED) {
return Futures.immediateFuture(null);
}
- checkState(proposedSubtree != null,"Proposed subtree must be computed");
- checkState(storeSnapshot != null,"Proposed subtree must be computed");
+ checkState(proposedSubtree != null, "Proposed subtree must be computed");
+ checkState(storeSnapshot != null, "Proposed subtree must be computed");
// return ImmediateFuture<>;
- InMemoryDOMDataStore.this.commit(storeSnapshot, proposedSubtree.get(),listenerResolver);
+ InMemoryDOMDataStore.this.commit(storeSnapshot, proposedSubtree.get(), listenerResolver);
return Futures.<Void> immediateFuture(null);
}
}
@Override
- public boolean isApplicable(final NodeModification modification, final Optional<StoreMetadataNode> storeMetadata) {
+ public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> storeMetadata) {
throw new IllegalStateException("Schema Context is not available.");
}
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import com.google.common.base.Optional;
*/
Optional<StoreMetadataNode> apply(NodeModification modification, Optional<StoreMetadataNode> storeMeta, UnsignedLong subtreeVersion);
- /**
- *
- * Checks if provided node modification could be applied to current metadata node.
- *
- * @param modification Modification
- * @param current Metadata Node to which modification should be applied
- * @return true if modification is applicable
- * false if modification is no applicable
- */
- boolean isApplicable(NodeModification modification, Optional<StoreMetadataNode> current);
-
/**
*
* Performs structural verification of NodeModification, such as writen values / types
* if suboperation is not supported for specified tree node.
*/
@Override
- public Optional<ModificationApplyOperation> getChild(PathArgument child);
-
-
+ Optional<ModificationApplyOperation> getChild(PathArgument child);
+ /**
+ *
+ * Checks if provided node modification could be applied to current metadata node.
+ *
+ * @param modification Modification
+ * @param current Metadata Node to which modification should be applied
+ * @return true if modification is applicable
+ * false if modification is no applicable
+ * @throws DataPreconditionFailedException
+ */
+ void checkApplicable(InstanceIdentifier path, NodeModification modification, Optional<StoreMetadataNode> current) throws DataPreconditionFailedException;
}
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.dom.store.impl;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
return applyOperation;
}
- public boolean isApplicable(final Optional<StoreMetadataNode> data) {
- return applyOperation.isApplicable(modification, data);
- }
-
public Optional<StoreMetadataNode> apply(final Optional<StoreMetadataNode> data, final UnsignedLong subtreeVersion) {
return applyOperation.apply(modification, data, subtreeVersion);
}
Optional<ModificationApplyOperation> childOp = applyOperation.getChild(childId);
return from(childOp.get(),childMod);
}
-}
\ No newline at end of file
+}
final Collection<Node> listeners, final NormalizedNode<?, ?> beforeData,
final NormalizedNode<?, ?> afterData) {
- if (beforeData instanceof NormalizedNodeContainer<?, ?, ?> && !listeners.isEmpty()) {
+ if (beforeData instanceof NormalizedNodeContainer<?, ?, ?>) {
// Node is container (contains child) and we have interested
// listeners registered for it, that means we need to do
// resolution of changes on children level and can not
// shortcut resolution.
-
+ LOG.trace("Resolving subtree replace event for {} before {}, after {}",path,beforeData,afterData);
@SuppressWarnings("unchecked")
NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> beforeCont = (NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>>) beforeData;
@SuppressWarnings("unchecked")
// Node is either of Leaf type (does not contain child nodes)
// or we do not have listeners, so normal equals method is
// sufficient for determining change.
-
+ LOG.trace("Resolving leaf replace event for {} , before {}, after {}",path,beforeData,afterData);
DOMImmutableDataChangeEvent event = builder(DataChangeScope.BASE).setBefore(beforeData).setAfter(afterData)
.addUpdated(path, beforeData, afterData).build();
addPartialTask(listeners, event);
private DOMImmutableDataChangeEvent resolveSameEventRecursivelly(final InstanceIdentifier path,
final Collection<Node> listeners, final NormalizedNode<PathArgument, ?> node,
final SimpleEventFactory eventFactory) {
-
final DOMImmutableDataChangeEvent event = eventFactory.create(path, node);
DOMImmutableDataChangeEvent propagateEvent = event;
- // We have listeners for this node or it's children, so we will try
+ // We have listeners for this node or it's children, so we will try
// to do additional processing
if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
+ LOG.trace("Resolving subtree recursive event for {}, type {}", path, eventFactory);
+
Builder eventBuilder = builder(DataChangeScope.BASE);
eventBuilder.merge(event);
eventBuilder.setBefore(event.getOriginalSubtree());
NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> container = (NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>>) node;
for (NormalizedNode<PathArgument, ?> child : container.getValue()) {
PathArgument childId = child.getIdentifier();
+ LOG.trace("Resolving event for child {}", childId);
Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory));
}
propagateEvent = builder(DataChangeScope.BASE).build();
}
if (!listeners.isEmpty()) {
- addPartialTask(listeners, event);
+ addPartialTask(listeners, propagateEvent);
}
return propagateEvent;
}
private DOMImmutableDataChangeEvent addPartialTask(final Collection<ListenerTree.Node> listeners,
final DOMImmutableDataChangeEvent event) {
-
for (ListenerTree.Node listenerNode : listeners) {
if (!listenerNode.getListeners().isEmpty()) {
+ LOG.trace("Adding event {} for listeners {}",event,listenerNode);
events.put(listenerNode, event);
}
}
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.dom.store.impl;
import static com.google.common.base.Preconditions.checkArgument;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreNodeCompositeBuilder;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
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.NormalizedNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.primitives.UnsignedLong;
public abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
protected abstract void verifyWritenStructure(NormalizedNode<?, ?> writenValue);
@Override
- public boolean isApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
+ public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
switch (modification.getModificationType()) {
case DELETE:
- return isDeleteApplicable(modification, current);
+ checkDeleteApplicable(modification, current);
case SUBTREE_MODIFIED:
- return isSubtreeModificationApplicable(modification, current);
+ checkSubtreeModificationApplicable(path,modification, current);
+ return;
case WRITE:
- return isWriteApplicable(modification, current);
+ checkWriteApplicable(path,modification, current);
+ return;
case MERGE:
- return isMergeApplicable(modification,current);
+ checkMergeApplicable(path,modification,current);
+ return;
case UNMODIFIED:
- return true;
+ return;
default:
- return false;
+ throw new UnsupportedOperationException("Suplied modification type "+modification.getModificationType()+ "is not supported.");
}
+
}
- private boolean isMergeApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
+ protected void checkMergeApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
Optional<StoreMetadataNode> original = modification.getOriginal();
if (original.isPresent() && current.isPresent()) {
- return isNotConflicting(original.get(), current.get());
- } else if (current.isPresent()) {
- return true;
+ checkNotConflicting(path,original.get(), current.get());
}
- return true;
}
- protected boolean isWriteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
+ protected void checkWriteApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
Optional<StoreMetadataNode> original = modification.getOriginal();
if (original.isPresent() && current.isPresent()) {
- return isNotConflicting(original.get(), current.get());
- } else if (current.isPresent()) {
- return false;
+ checkNotConflicting(path,original.get(), current.get());
+ } else if(original.isPresent()) {
+ throw new DataPreconditionFailedException(path,"Node was deleted by other transaction.");
}
- return true;
-
}
- protected final boolean isNotConflicting(final StoreMetadataNode original, final StoreMetadataNode current) {
- return original.getNodeVersion().equals(current.getNodeVersion())
- && original.getSubtreeVersion().equals(current.getSubtreeVersion());
+ protected static final void checkNotConflicting(final InstanceIdentifier path,final StoreMetadataNode original, final StoreMetadataNode current) throws DataPreconditionFailedException {
+ checkDataPrecondition(path, original.getNodeVersion().equals(current.getNodeVersion()),"Node was replaced by other transaction.");
+ checkDataPrecondition(path,original.getSubtreeVersion().equals(current.getSubtreeVersion()), "Node children was modified by other transaction");
}
- protected abstract boolean isSubtreeModificationApplicable(final NodeModification modification,
- final Optional<StoreMetadataNode> current);
+ protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path,final NodeModification modification,
+ final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException;
- private boolean isDeleteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
- // FiXME: Add delete conflict detection.
- return true;
+ private void checkDeleteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
}
@Override
}
@Override
- protected boolean isSubtreeModificationApplicable(final NodeModification modification,
- final Optional<StoreMetadataNode> current) {
- return false;
+ protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification,
+ final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
+ throw new DataPreconditionFailedException(path, "Subtree modification is not allowed.");
}
}
}
}
+ @Override
+ protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification,
+ final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
+ // FIXME: Implement proper write check for replacement of node container
+ // prerequisite is to have transaction chain available for clients
+ // otherwise this will break chained writes to same node.
+ }
+
@SuppressWarnings("rawtypes")
@Override
protected void verifyWritenStructure(final NormalizedNode<?, ?> writenValue) {
@Override
protected StoreMetadataNode applyWrite(final NodeModification modification,
final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
- //
+
NormalizedNode<?, ?> newValue = modification.getWritenValue();
- UnsignedLong nodeVersion = subtreeVersion;
+ final UnsignedLong nodeVersion;
if (currentMeta.isPresent()) {
nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion());
+ } else {
+ nodeVersion = subtreeVersion;
}
- StoreMetadataNode newValueMeta = StoreMetadataNode.createRecursively(newValue, nodeVersion, nodeVersion);
+ final StoreMetadataNode newValueMeta = StoreMetadataNode.createRecursively(newValue, nodeVersion, nodeVersion);
if (!modification.hasAdditionalModifications()) {
return newValueMeta;
}
+
@SuppressWarnings("rawtypes")
- NormalizedNodeContainerBuilder dataBuilder = createBuilder(modification.getIdentifier());
+ NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue);
StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.from(dataBuilder) //
.setNodeVersion(nodeVersion) //
.setSubtreeVersion(subtreeVersion);
- Set<PathArgument> processedPreexisting = applyPreexistingChildren(modification, newValueMeta.getChildren(),
- builder, nodeVersion);
- applyNewChildren(modification, processedPreexisting, builder, nodeVersion);
-
- return builder.build();
-
+ return mutateChildren(modification.getModifications(), newValueMeta, builder, nodeVersion);
}
@Override
@Override
public StoreMetadataNode applySubtreeChange(final NodeModification modification,
final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
+ // Bump subtree version to its new target
+ final UnsignedLong updatedSubtreeVersion = StoreUtils.increase(currentMeta.getSubtreeVersion());
- UnsignedLong updatedSubtreeVersion = StoreUtils.increase(currentMeta.getSubtreeVersion());
@SuppressWarnings("rawtypes")
- NormalizedNodeContainerBuilder dataBuilder = createBuilder(modification.getIdentifier());
- StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.from(dataBuilder)
+ NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData());
+ StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.from(dataBuilder, currentMeta)
.setIdentifier(modification.getIdentifier()).setNodeVersion(currentMeta.getNodeVersion())
.setSubtreeVersion(updatedSubtreeVersion);
- // We process preexisting nodes
- Set<PathArgument> processedPreexisting = applyPreexistingChildren(modification, currentMeta.getChildren(),
- builder, updatedSubtreeVersion);
- applyNewChildren(modification, processedPreexisting, builder, updatedSubtreeVersion);
- return builder.build();
+
+ return mutateChildren(modification.getModifications(), currentMeta, builder, updatedSubtreeVersion);
}
- private void applyNewChildren(final NodeModification modification, final Set<PathArgument> ignore,
- final StoreNodeCompositeBuilder builder, final UnsignedLong subtreeVersion) {
- for (NodeModification childModification : modification.getModifications()) {
- PathArgument childIdentifier = childModification.getIdentifier();
- // We skip allready processed modifications
- if (ignore.contains(childIdentifier)) {
- continue;
- }
+ private StoreMetadataNode mutateChildren(final Iterable<NodeModification> modifications, final StoreMetadataNode meta,
+ final StoreNodeCompositeBuilder builder, final UnsignedLong nodeVersion) {
- builder.addIfPresent(resolveChildOperation(childIdentifier) //
- .apply(childModification, Optional.<StoreMetadataNode> absent(), subtreeVersion));
- }
- }
+ for (NodeModification mod : modifications) {
+ final PathArgument id = mod.getIdentifier();
+ final Optional<StoreMetadataNode> cm = meta.getChild(id);
- private Set<PathArgument> applyPreexistingChildren(final NodeModification modification,
- final Iterable<StoreMetadataNode> children, final StoreNodeCompositeBuilder nodeBuilder,
- final UnsignedLong subtreeVersion) {
- Builder<PathArgument> processedModifications = ImmutableSet.<PathArgument> builder();
- for (StoreMetadataNode childMeta : children) {
- PathArgument childIdentifier = childMeta.getIdentifier();
- // We retrieve Child modification metadata
- Optional<NodeModification> childModification = modification.getChild(childIdentifier);
- // Node is modified
- if (childModification.isPresent()) {
- processedModifications.add(childIdentifier);
- Optional<StoreMetadataNode> result = resolveChildOperation(childIdentifier) //
- .apply(childModification.get(), Optional.of(childMeta), subtreeVersion);
- nodeBuilder.addIfPresent(result);
+ Optional<StoreMetadataNode> result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
+ if (result.isPresent()) {
+ builder.add(result.get());
} else {
- // Child is unmodified - reuse existing metadata and data
- // snapshot
- nodeBuilder.add(childMeta);
+ builder.remove(id);
}
}
- return processedModifications.build();
+
+ return builder.build();
}
@Override
- protected boolean isSubtreeModificationApplicable(final NodeModification modification,
- final Optional<StoreMetadataNode> current) {
- if (false == current.isPresent()) {
- return false;
- }
- boolean result = true;
+ protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification,
+ final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
+ checkDataPrecondition(path, current.isPresent(), "Node was deleted by other transaction.");
+ checkChildPreconditions(path,modification,current);
+
+ }
+
+ private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
StoreMetadataNode currentMeta = current.get();
for (NodeModification childMod : modification.getModifications()) {
PathArgument childId = childMod.getIdentifier();
Optional<StoreMetadataNode> childMeta = currentMeta.getChild(childId);
- result &= resolveChildOperation(childId).isApplicable(childMod, childMeta);
+ InstanceIdentifier childPath = StoreUtils.append(path, childId);
+ resolveChildOperation(childId).checkApplicable(childPath,childMod, childMeta);
+ }
+ }
+
+ @Override
+ protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification,
+ final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
+ if(current.isPresent()) {
+ checkChildPreconditions(path,modification,current);
}
- return result;
}
@SuppressWarnings("rawtypes")
- protected abstract NormalizedNodeContainerBuilder createBuilder(PathArgument identifier);
+ protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode<?, ?> original);
}
public static abstract class DataNodeContainerModificationStrategy<T extends DataNodeContainer> extends
@Override
@SuppressWarnings("rawtypes")
- protected abstract DataContainerNodeBuilder createBuilder(PathArgument identifier);
+ protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode<?, ?> original);
@Override
public String toString() {
@Override
@SuppressWarnings("rawtypes")
- protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
- // TODO Auto-generated method stub
- checkArgument(identifier instanceof NodeIdentifier);
- return ImmutableContainerNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof ContainerNode);
+ return ImmutableContainerNodeBuilder.create((ContainerNode) original);
}
-
}
public static class UnkeyedListItemModificationStrategy extends
@Override
@SuppressWarnings("rawtypes")
- protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
- checkArgument(identifier instanceof NodeIdentifier);
- return ImmutableUnkeyedListEntryNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof UnkeyedListEntryNode);
+ return ImmutableUnkeyedListEntryNodeBuilder.create((UnkeyedListEntryNode) original);
}
-
}
public static class AugmentationModificationStrategy extends
protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) {
super(createAugmentProxy(schema,resolved), AugmentationNode.class);
- // FIXME: Use resolved children instead of unresolved.
-
}
@Override
- protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
- return Builders.augmentationBuilder().withNodeIdentifier((AugmentationIdentifier) identifier);
+ @SuppressWarnings("rawtypes")
+ protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof AugmentationNode);
+ return ImmutableAugmentationNodeBuilder.create((AugmentationNode) original);
}
-
}
public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy {
@Override
@SuppressWarnings("rawtypes")
- protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
- checkArgument(identifier instanceof NodeIdentifier);
- return ImmutableChoiceNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode);
+ return ImmutableChoiceNodeBuilder.create((org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode) original);
}
-
}
public static class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
@Override
@SuppressWarnings("rawtypes")
- protected final DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
- return ImmutableMapEntryNodeBuilder.create().withNodeIdentifier((NodeIdentifierWithPredicates) identifier);
+ protected final DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof MapEntryNode);
+ return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original);
}
-
}
public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
@SuppressWarnings("rawtypes")
@Override
- protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
- return ImmutableLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof LeafSetNode<?>);
+ return ImmutableLeafSetNodeBuilder.create((LeafSetNode<?>) original);
}
@Override
}
return Optional.absent();
}
-
}
public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
@SuppressWarnings("rawtypes")
@Override
- protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
- return ImmutableOrderedLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof OrderedLeafSetNode<?>);
+ return ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode<?>) original);
}
@Override
}
return Optional.absent();
}
-
}
public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
}
@Override
- protected boolean isSubtreeModificationApplicable(final NodeModification modification,
- final Optional<StoreMetadataNode> current) {
- return false;
+ protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification,
+ final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
+ throw new DataPreconditionFailedException(path, "Subtree modification is not allowed.");
}
}
@SuppressWarnings("rawtypes")
@Override
- protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
- return ImmutableMapNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof MapNode);
+ return ImmutableMapNodeBuilder.create((MapNode) original);
}
@Override
@SuppressWarnings("rawtypes")
@Override
- protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
- return ImmutableOrderedMapNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+ checkArgument(original instanceof OrderedMapNode);
+ return ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original);
}
@Override
return new AugmentationSchemaProxy(schema, realChildSchemas);
}
+ public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException {
+ if(!condition) {
+ throw new DataPreconditionFailedException(path, message);
+ }
+ return condition;
+ }
+
}
*/
package org.opendaylight.controller.md.sal.dom.store.impl;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
public class SchemaAwareApplyOperationRoot extends SchemaAwareApplyOperation.DataNodeContainerModificationStrategy<ContainerSchemaNode> {
-
private final SchemaContext context;
public SchemaAwareApplyOperationRoot(final SchemaContext context) {
this.context = context;
}
- @Override
- protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
- return ImmutableContainerNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
- }
-
public SchemaContext getContext() {
return context;
}
return "SchemaAwareApplyOperationRoot [context=" + context + "]";
}
+ @Override
+ @SuppressWarnings("rawtypes")
+ protected DataContainerNodeBuilder createBuilder(NormalizedNode<?, ?> original) {
+ return ImmutableContainerNodeBuilder.create((ContainerNode) original);
+ }
}
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.dom.store.impl;
import java.util.Collections;
import static com.google.common.base.Preconditions.checkState;
+import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
this.children = Preconditions.checkNotNull(children);
}
+ public static StoreMetadataNode createEmpty(final NormalizedNode<?, ?> data) {
+ return new StoreMetadataNode(data, UnsignedLong.ZERO, UnsignedLong.ZERO,
+ Collections.<PathArgument, StoreMetadataNode>emptyMap());
+ }
+
+ public StoreMetadataNode(final NormalizedNode<?, ?> data, final UnsignedLong nodeVersion,
+ final UnsignedLong subtreeVersion) {
+ this(data, nodeVersion, subtreeVersion, Collections.<PathArgument, StoreMetadataNode>emptyMap());
+ }
+
public static Builder builder() {
return new Builder();
}
+ public static Builder builder(StoreMetadataNode node) {
+ return new Builder(node);
+ }
+
public UnsignedLong getNodeVersion() {
return this.nodeVersion;
}
private UnsignedLong nodeVersion;
private UnsignedLong subtreeVersion;
private NormalizedNode<?, ?> data;
- private Map<PathArgument, StoreMetadataNode> children = new LinkedHashMap<>();
+ private Map<PathArgument, StoreMetadataNode> children;
private boolean dirty = false;
- private Builder() {}
+ private Builder() {
+ children = new LinkedHashMap<>();
+ }
+ public Builder(StoreMetadataNode node) {
+ children = new LinkedHashMap<>(node.children);
+ }
public UnsignedLong getVersion() {
return nodeVersion;
return this;
}
+ public Builder remove(final PathArgument id) {
+ if (dirty) {
+ children = new LinkedHashMap<>(children);
+ dirty = false;
+ }
+ children.remove(id);
+ return this;
+ }
+
public StoreMetadataNode build() {
checkState(data != null, "Data node should not be null.");
checkState(subtreeVersion.compareTo(nodeVersion) >= 0,
public static StoreMetadataNode createRecursively(final NormalizedNode<?, ?> node, final UnsignedLong version) {
return createRecursively(node, version, version);
}
-
}
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedLong;
/**
private StoreNodeCompositeBuilder(final NormalizedNodeContainerBuilder nodeBuilder) {
this.metadata = StoreMetadataNode.builder();
- this.data = nodeBuilder;
+ this.data = Preconditions.checkNotNull(nodeBuilder);
+ }
+
+ public StoreNodeCompositeBuilder(NormalizedNodeContainerBuilder nodeBuilder, StoreMetadataNode currentMeta) {
+ this.metadata = StoreMetadataNode.builder(currentMeta);
+ this.data = Preconditions.checkNotNull(nodeBuilder);
}
@SuppressWarnings("unchecked")
}
@SuppressWarnings("unchecked")
- public StoreNodeCompositeBuilder addIfPresent(final Optional<StoreMetadataNode> potential) {
- if (potential.isPresent()) {
- StoreMetadataNode node = potential.get();
- metadata.add(node);
- data.addChild(node.getData());
- }
+ public StoreNodeCompositeBuilder remove(PathArgument id) {
+ metadata.remove(id);
+ data.removeChild(id);
return this;
}
return new StoreNodeCompositeBuilder(nodeBuilder);
}
+ public static StoreNodeCompositeBuilder from(final NormalizedNodeContainerBuilder nodeBuilder, StoreMetadataNode currentMeta) {
+ return new StoreNodeCompositeBuilder(nodeBuilder, currentMeta);
+ }
+
@SuppressWarnings("unchecked")
public StoreNodeCompositeBuilder setIdentifier(final PathArgument identifier) {
data.withNodeIdentifier(identifier);
metadata.setSubtreeVersion(updatedSubtreeVersion);
return this;
}
-
}
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
-public class TreeNodeUtils {
+public final class TreeNodeUtils {
+ private TreeNodeUtils() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
/**
* Finds a node in tree
return current;
}
-
public static <T extends StoreTreeNode<T>> T findNodeChecked(final T tree, final InstanceIdentifier path) {
T current = tree;
List<PathArgument> nested = new ArrayList<>(path.getPath().size());
try {
listener.onRouteChange(initial);
} catch (Exception e) {
- LOG.error("Unhandled exception during sending initial route change event {} to {}",initial,listener);
+ LOG.error("Unhandled exception during sending initial route change event {} to {}",initial,listener, e);
}
return reg;
}
InstanceIdentifier normalizedPath = normalizer.toNormalized(LEAF_TWO_PATH_LEGACY);
- Node<?> outerListLegacy = normalizer.toLegacy(OUTER_LIST_WITH_CHOICE);
+ Node<?> outerListLegacy = DataNormalizer.toLegacy(OUTER_LIST_WITH_CHOICE);
assertNotNull(outerListLegacy);
-
-
-
-
}
}
import java.util.concurrent.ExecutionException;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
}
@Test
+ @Ignore
public void testTransactionConflict() throws InterruptedException, ExecutionException {
DOMStoreReadWriteTransaction txOne = domStore.newReadWriteTransaction();
DOMStoreReadWriteTransaction txTwo = domStore.newReadWriteTransaction();
<dependencies>
<dependency>
+
<groupId>${project.groupId}</groupId>
<artifactId>netconf-client</artifactId>
<version>${netconf.version}</version>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-client</artifactId>
- <version>${netconf.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netty-threadgroup-config</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>threadpool-config-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-inventory</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-impl</artifactId>
import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkCondition;
import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkNotNull;
+import com.google.common.net.InetAddresses;
import io.netty.util.HashedWheelTimer;
import io.netty.util.concurrent.GlobalEventExecutor;
-
import java.io.File;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
import org.opendaylight.controller.netconf.util.handler.ssh.authentication.LoginPassword;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceListener;
import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.inventory.rev140108.NetconfNode;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider;
import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider;
import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.net.InetAddresses;
-
/**
*
*/
@Override
public java.lang.AutoCloseable createInstance() {
+ ServiceReference<DataProviderService> serviceReference = bundleContext.getServiceReference(DataProviderService.class);
+
+ DataProviderService dataProviderService =
+ bundleContext.getService(serviceReference);
getDomRegistryDependency();
NetconfDevice device = new NetconfDevice(getIdentifier().getInstanceName());
device.setEventExecutor(getEventExecutorDependency());
device.setDispatcher(getClientDispatcher() == null ? createDispatcher() : getClientDispatcherDependency());
device.setSchemaSourceProvider(getGlobalNetconfSchemaProvider(bundleContext));
-
+ device.setDataProviderService(dataProviderService);
getDomRegistryDependency().registerProvider(device, bundleContext);
device.start();
return device;
import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.inventory.rev140108.NetconfNode;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
SchemaSourceProvider<InputStream> remoteSourceProvider;
- DataBrokerService dataBroker;
+ private volatile DataBrokerService dataBroker;
NetconfDeviceListener listener;
private boolean rollbackSupported;
private NetconfClientConfiguration clientConfig;
+ private volatile DataProviderService dataProviderService;
public NetconfDevice(String name) {
this.name = name;
}
private void updateDeviceState(boolean up, Set<QName> capabilities) {
+ checkDataStoreState();
+
DataModificationTransaction transaction = dataBroker.beginTransaction();
CompositeNodeBuilder<ImmutableCompositeNode> it = ImmutableCompositeNode.builder();
public void onSessionInitiated(ProviderSession session) {
dataBroker = session.getService(DataBrokerService.class);
+ processingExecutor.submit(new Runnable() {
+ @Override
+ public void run() {
+ updateInitialState();
+ }
+ });
+
+ mountService = session.getService(MountProvisionService.class);
+ if (mountService != null) {
+ mountInstance = mountService.createOrGetMountPoint(path);
+ }
+ }
+
+ private void updateInitialState() {
+ checkDataStoreState();
+
DataModificationTransaction transaction = dataBroker.beginTransaction();
if (operationalNodeNotExisting(transaction)) {
transaction.putOperationalData(path, getNodeWithId());
} catch (ExecutionException e) {
throw new RuntimeException("Read configuration data " + path + " failed", e);
}
-
- mountService = session.getService(MountProvisionService.class);
- if (mountService != null) {
- mountInstance = mountService.createOrGetMountPoint(path);
- }
}
+ private void checkDataStoreState() {
+ // read data from Nodes/Node in order to wait with write until schema for Nodes/Node is present in datastore
+ dataProviderService.readOperationalData(org.opendaylight.yangtools.yang.binding.InstanceIdentifier.builder(
+ Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class).augmentation(NetconfNode.class).build()); }
+
CompositeNode getNodeWithId() {
SimpleNodeTOImpl id = new SimpleNodeTOImpl(INVENTORY_ID, null, name);
return new CompositeNodeTOImpl(INVENTORY_NODE, null, Collections.<Node<?>> singletonList(id));
this.clientConfig = clientConfig;
}
+ public void setDataProviderService(final DataProviderService dataProviderService) {
+ this.dataProviderService = dataProviderService;
+ }
}
class NetconfDeviceSchemaContextProvider {
for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument component : Lists
.reverse(identifier.getPath())) {
- previous = toNode(component, previous);
+ if (component instanceof NodeIdentifierWithPredicates) {
+ previous = toNode((NodeIdentifierWithPredicates)component, previous);
+ } else {
+ previous = toNode(component, previous);
+ }
}
return filter("subtree", previous);
}
package org.opendaylight.controller.sal.connector.remoterpc;
-import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
import java.util.Collection;
import java.util.Collections;
Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> routingTable =
routingTableProvider.getRoutingTable();
- checkNotNull(routingTable.isPresent(), "Routing table is null");
+ checkState(routingTable.isPresent(), "Routing table is null");
return routingTable.get();
}
package org.opendaylight.controller.sal.connector.remoterpc.dto;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
-import java.io.*;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
public class Message implements Serializable {
+ private static final long serialVersionUID = 1L;
public static enum MessageType {
PING((byte) 0),
}
public static class Response extends Message implements RpcRouter.RpcReply {
+ private static final long serialVersionUID = 1L;
private ResponseCode code; // response code
public static enum ResponseCode {
SUCCESS(200), BADREQUEST(400), TIMEOUT(408), GONE(410), SERVERERROR(500), SERVICEUNAVAILABLE(503);
- private int code;
+ private final int code;
ResponseCode(int code) {
this.code = code;
*/
public static class MessageBuilder{
- private Message message;
+ private final Message message;
public MessageBuilder(){
message = new Message();
*/
package org.opendaylight.controller.sal.connector.remoterpc.dto;
+import java.io.Serializable;
+
import org.opendaylight.controller.sal.connector.api.RpcRouter;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import java.io.Serializable;
-
public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>,Serializable {
+ private static final long serialVersionUID = 1L;
private QName context;
private QName type;
*/
package org.opendaylight.controller.sal.connector.remoterpc;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
import junit.framework.Assert;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import org.zeromq.ZMQ;
-import java.io.IOException;
-import java.util.concurrent.*;
-
/**
*
*/
serverThread.execute(MessagingUtil.startReplyServer(context, serverAddress, 1));
threadPool.execute(createEmptyMessageTaskAndHandle(handler, serverAddress));
}
- Thread.currentThread().sleep(5000);//wait for all messages to get processed
+ Thread.sleep(5000);//wait for all messages to get processed
//should be connected to 5 remote server
Assert.assertEquals(5, handler.getWorkerCount());
}
import org.opendaylight.yangtools.restconf.client.api.UnsupportedProtocolException;
import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public SalRemoteClientImpl(final URL url) {
Preconditions.checkNotNull(url);
- this.mappingService = new RuntimeGeneratedMappingServiceImpl();
- this.mappingService.setPool(ClassPool.getDefault());
- this.mappingService.init();
+ this.mappingService = new RuntimeGeneratedMappingServiceImpl(ClassPool.getDefault());
final ModuleInfoBackedContext moduleInfo = ModuleInfoBackedContext.create();
moduleInfo.addModuleInfos(BindingReflections.loadModuleInfos());
Uri destPortUri = destPort.getValue().firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId();
Action outputToControllerAction = new ActionBuilder() //
+ .setOrder(0)
.setAction(new OutputActionCaseBuilder() //
.setOutputAction(new OutputActionBuilder() //
.setMaxLength(new Integer(0xffff)) //
// Wrap our Apply Action in an Instruction
Instruction applyActionsInstruction = new InstructionBuilder() //
+ .setOrder(0)
.setInstruction(new ApplyActionsCaseBuilder()//
.setApplyActions(applyActions) //
.build()) //
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>org.opendaylight.controller.sample.toaster.provider.api,
- org.opendaylight.controller.config.yang.toaster-consumer,</Export-Package>
- <Import-Package>*</Import-Package>
- </instructions>
- </configuration>
</plugin>
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: toaster-consumer-impl yang module local name: toaster-consumer-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Feb 05 11:31:30 CET 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.kitchen_service.impl;
+
+import org.opendaylight.controller.config.yang.config.kitchen_service.impl.AbstractKitchenServiceModule;
+import org.opendaylight.controller.sample.kitchen.api.EggsType;
+import org.opendaylight.controller.sample.kitchen.api.KitchenService;
+import org.opendaylight.controller.sample.kitchen.impl.KitchenServiceImpl;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+*
+*/
+public final class KitchenServiceModule extends AbstractKitchenServiceModule {
+ private static final Logger log = LoggerFactory.getLogger(KitchenServiceModule.class);
+
+ public KitchenServiceModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public KitchenServiceModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ KitchenServiceModule oldModule, java.lang.AutoCloseable oldInstance) {
+
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ protected void customValidation(){
+ // No need to validate dependencies, since all dependencies have mandatory true flag in yang
+ // config-subsystem will perform the validation
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ ToasterService toasterService = getRpcRegistryDependency().getRpcService(ToasterService.class);
+
+ final KitchenServiceImpl kitchenService = new KitchenServiceImpl(toasterService);
+
+ final Registration<NotificationListener> toasterListenerReg =
+ getNotificationServiceDependency().registerNotificationListener( kitchenService );
+
+ final KitchenServiceRuntimeRegistration runtimeReg =
+ getRootRuntimeBeanRegistratorWrapper().register( kitchenService );
+
+ final class AutoCloseableKitchenService implements KitchenService, AutoCloseable {
+
+ @Override
+ public void close() throws Exception {
+ toasterListenerReg.close();
+ runtimeReg.close();
+ log.info("Toaster consumer (instance {}) torn down.", this);
+ }
+
+ @Override
+ public boolean makeBreakfast( EggsType eggs, Class<? extends ToastType> toast, int toastDoneness ) {
+ return kitchenService.makeBreakfast( eggs, toast, toastDoneness );
+ }
+ }
+
+ AutoCloseable ret = new AutoCloseableKitchenService();
+ log.info("KitchenService (instance {}) initialized.", ret );
+ return ret;
+ }
+}
*
* Do not modify this file unless it is present under src/main directory
*/
-package org.opendaylight.controller.config.yang.config.toaster_consumer.impl;
+package org.opendaylight.controller.config.yang.config.kitchen_service.impl;
+
+import org.opendaylight.controller.config.yang.config.kitchen_service.impl.AbstractKitchenServiceModuleFactory;
/**
*
*/
-public class ToasterConsumerModuleFactory extends org.opendaylight.controller.config.yang.config.toaster_consumer.impl.AbstractToasterConsumerModuleFactory
+public class KitchenServiceModuleFactory extends AbstractKitchenServiceModuleFactory
{
+++ /dev/null
-/**
-* Generated file
-
-* Generated from: yang module name: toaster-consumer-impl yang module local name: toaster-consumer-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Feb 05 11:31:30 CET 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.config.toaster_consumer.impl;
-
-import org.opendaylight.controller.sal.binding.api.NotificationListener;
-import org.opendaylight.controller.sample.toaster.provider.api.ToastConsumer;
-import org.opendaylight.controller.sample.toaster.provider.impl.ToastConsumerImpl;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastDone;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
-import org.opendaylight.yangtools.concepts.Registration;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
-*
-*/
-public final class ToasterConsumerModule extends org.opendaylight.controller.config.yang.config.toaster_consumer.impl.AbstractToasterConsumerModule
- {
- private static final Logger log = LoggerFactory.getLogger(ToasterConsumerModule.class);
-
- public ToasterConsumerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public ToasterConsumerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
- ToasterConsumerModule oldModule, java.lang.AutoCloseable oldInstance) {
-
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- protected void customValidation(){
- // No need to validate dependencies, since all dependencies have mandatory true flag in yang
- // config-subsystem will perform the validation
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- ToasterService toasterService = getRpcRegistryDependency().getRpcService(ToasterService.class);
-
- final ToastConsumerImpl consumer = new ToastConsumerImpl(toasterService);
- final Registration<NotificationListener<ToastDone>> notificationRegistration = getNotificationServiceDependency()
- .registerNotificationListener(ToastDone.class, consumer);
-
- final ToasterConsumerRuntimeRegistration runtimeRegistration = getRootRuntimeBeanRegistratorWrapper().register(consumer);
-
- final class AutoCloseableToastConsumer implements AutoCloseable, ToastConsumer {
-
- @Override
- public void close() throws Exception {
- runtimeRegistration.close();
- notificationRegistration.close();
- log.info("Toaster consumer (instance {}) torn down.", this);
- }
-
- @Override
- public boolean createToast(Class<? extends ToastType> type, int doneness) {
- return consumer.createToast(type, doneness);
- }
- }
-
- AutoCloseable ret = new AutoCloseableToastConsumer();
- log.info("Toaster consumer (instance {}) initialized.", ret);
- return ret;
- }
-}
--- /dev/null
+package org.opendaylight.controller.sample.kitchen.api;
+
+public enum EggsType {
+ SCRAMBLED,
+ OVER_EASY,
+ POACHED
+}
--- /dev/null
+package org.opendaylight.controller.sample.kitchen.api;
+
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
+
+public interface KitchenService {
+ boolean makeBreakfast( EggsType eggs, Class<? extends ToastType> toast, int toastDoneness );
+}
--- /dev/null
+package org.opendaylight.controller.sample.kitchen.impl;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.config.yang.config.kitchen_service.impl.KitchenServiceRuntimeMXBean;
+import org.opendaylight.controller.sample.kitchen.api.EggsType;
+import org.opendaylight.controller.sample.kitchen.api.KitchenService;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInputBuilder;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterListener;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterOutOfBread;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterRestocked;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.WheatBread;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class KitchenServiceImpl implements KitchenService, KitchenServiceRuntimeMXBean, ToasterListener {
+
+ private static final Logger log = LoggerFactory.getLogger( KitchenServiceImpl.class );
+
+ private final ToasterService toaster;
+
+ private volatile boolean toasterOutOfBread;
+
+ public KitchenServiceImpl(ToasterService toaster) {
+ this.toaster = toaster;
+ }
+
+ @Override
+ public boolean makeBreakfast( EggsType eggs, Class<? extends ToastType> toast, int toastDoneness ) {
+
+ if( toasterOutOfBread )
+ {
+ log.info( "We're out of toast but we can make eggs" );
+ return true;
+ }
+
+ // Access the ToasterService to make the toast.
+ // We don't actually make the eggs for this example - sorry.
+ MakeToastInputBuilder toastInput = new MakeToastInputBuilder();
+ toastInput.setToasterDoneness( (long) toastDoneness);
+ toastInput.setToasterToastType( toast );
+
+ try {
+ RpcResult<Void> result = toaster.makeToast( toastInput.build() ).get();
+
+ if( result.isSuccessful() ) {
+ log.info( "makeToast succeeded" );
+ } else {
+ log.warn( "makeToast failed: " + result.getErrors() );
+ }
+
+ return result.isSuccessful();
+ } catch( InterruptedException | ExecutionException e ) {
+ log.warn( "Error occurred during toast creation" );
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean makeScrambledWithWheat() {
+ return makeBreakfast( EggsType.SCRAMBLED, WheatBread.class, 2 );
+ }
+
+ /**
+ * Implemented from the ToasterListener interface.
+ */
+ @Override
+ public void onToasterOutOfBread( ToasterOutOfBread notification ) {
+ log.info( "ToasterOutOfBread notification" );
+ toasterOutOfBread = true;
+ }
+
+ /**
+ * Implemented from the ToasterListener interface.
+ */
+ @Override
+ public void onToasterRestocked( ToasterRestocked notification ) {
+ log.info( "ToasterRestocked notification - amountOfBread: " + notification.getAmountOfBread() );
+ toasterOutOfBread = false;
+ }
+}
+++ /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.sample.toaster.provider.api;
-
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
-
-public interface ToastConsumer {
-
- boolean createToast(Class<? extends ToastType> type,int doneness);
-
-}
+++ /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.sample.toaster.provider.impl;
-
-import java.util.concurrent.ExecutionException;
-
-import org.opendaylight.controller.config.yang.config.toaster_consumer.impl.ToasterConsumerRuntimeMXBean;
-import org.opendaylight.controller.sal.binding.api.NotificationListener;
-import org.opendaylight.controller.sample.toaster.provider.api.ToastConsumer;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.*;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ToastConsumerImpl implements
- ToastConsumer,
- NotificationListener<ToastDone>,ToasterConsumerRuntimeMXBean {
-
- private static final Logger log = LoggerFactory.getLogger(ToastConsumerImpl.class);
-
- private ToasterService toaster;
-
- public ToastConsumerImpl(ToasterService toaster) {
- this.toaster = toaster;
- }
-
- @Override
- public boolean createToast(Class<? extends ToastType> type, int doneness) {
- MakeToastInputBuilder toastInput = new MakeToastInputBuilder();
- toastInput.setToasterDoneness((long) doneness);
- toastInput.setToasterToastType(type);
-
- try {
- RpcResult<Void> result = toaster.makeToast(toastInput.build()).get();
-
- if (result.isSuccessful()) {
- log.trace("Toast was successfully finished");
- } else {
- log.warn("Toast was not successfully finished");
- }
- return result.isSuccessful();
- } catch (InterruptedException | ExecutionException e) {
- log.warn("Error occurred during toast creation");
- }
- return false;
-
- }
-
- @Override
- public void onNotification(ToastDone notification) {
- log.trace("ToastDone Notification Received: {} ",notification.getToastStatus());
- }
-
- @Override
- public Boolean makeHashBrownToast(Integer doneness) {
- return createToast(HashBrown.class, doneness);
- }
-}
// vi: set smarttab et sw=4 tabstop=4:
-module toaster-consumer-impl {
+module kitchen-service-impl {
yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer:impl";
- prefix "toaster-consumer-impl";
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl";
+ prefix "kitchen-service-impl";
import config { prefix config; revision-date 2013-04-05; }
import rpc-context { prefix rpcx; revision-date 2013-06-17; }
- import toaster-consumer { prefix toaster-consumer; revision-date 2014-01-31; }
import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
description
"This module contains the base YANG definitions for
- toaster-consumer impl implementation.";
+ kitchen-service impl implementation.";
revision "2014-01-31" {
description
"Initial revision.";
}
- // This is the definition of a service implementation
- identity toaster-consumer-impl {
+ // This is the definition of kitchen service interface identity.
+ identity kitchen-service {
+ base "config:service-type";
+ config:java-class "org.opendaylight.controller.sample.kitchen.api.KitchenService";
+ }
+
+ // This is the definition of kitchen service implementation module identity.
+ identity kitchen-service-impl {
base config:module-type;
- config:provided-service toaster-consumer:toaster-consumer;
- config:java-name-prefix ToasterConsumer;
+ config:provided-service kitchen-service;
+ config:java-name-prefix KitchenService;
}
augment "/config:modules/config:module/config:configuration" {
- case toaster-consumer-impl {
- when "/config:modules/config:module/config:type = 'toaster-consumer-impl'";
+ case kitchen-service-impl {
+ when "/config:modules/config:module/config:type = 'kitchen-service-impl'";
container rpc-registry {
uses config:service-ref {
}
}
}
-
}
}
-
+
augment "/config:modules/config:module/config:state" {
- case toaster-consumer-impl {
- when "/config:modules/config:module/config:type = 'toaster-consumer-impl'";
- rpcx:rpc-context-instance "make-hash-brown-toast-rpc";
+ case kitchen-service-impl {
+ when "/config:modules/config:module/config:type = 'kitchen-service-impl'";
+
+ rpcx:rpc-context-instance "make-scrambled-with-wheat-rpc";
}
}
- identity make-hash-brown-toast-rpc;
+ identity make-scrambled-with-wheat-rpc;
- rpc make-hash-brown-toast {
+ rpc make-scrambled-with-wheat {
+ description
+ "Shortcut JMX call to make breakfast with scrambled eggs and wheat toast for testing.";
+
input {
uses rpcx:rpc-context-ref {
refine context-instance {
- rpcx:rpc-context-instance make-hash-brown-toast-rpc;
+ rpcx:rpc-context-instance make-scrambled-with-wheat-rpc;
}
}
- leaf doneness {
- type uint16;
- }
}
+
output {
leaf result {
type boolean;
+++ /dev/null
-// vi: set smarttab et sw=4 tabstop=4:
-module toaster-consumer {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer";
- prefix "toaster-consumer";
-
- import config { prefix config; revision-date 2013-04-05; }
-
- description
- "This module contains the base YANG definitions for
- toaster-consumer services.";
-
- revision "2014-01-31" {
- description
- "Initial revision.";
- }
-
- // This is the definition of a service
- identity toaster-consumer {
-
- base "config:service-type";
-
- config:java-class "org.opendaylight.controller.sample.toaster.provider.api.ToastConsumer";
- }
-}
\ No newline at end of file
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-it</artifactId>
- <version>1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller.samples</groupId>
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.opendaylight.controller.sample.toaster.provider.api.ToastConsumer;
+import org.opendaylight.controller.sample.kitchen.api.EggsType;
+import org.opendaylight.controller.sample.kitchen.api.KitchenService;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.HashBrown;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.WhiteBread;
import org.ops4j.pax.exam.Configuration;
import javax.inject.Inject;
import javax.management.MBeanServer;
import javax.management.ObjectName;
+
import java.lang.management.ManagementFactory;
import static org.junit.Assert.assertEquals;
@Inject
@Filter(timeout=60*1000)
- ToastConsumer toastConsumer;
+ KitchenService kitchenService;
@Configuration
public Option[] config() {
public void testToaster() throws Exception {
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
- ObjectName consumerOn = new ObjectName("org.opendaylight.controller:instanceName=toaster-consumer-impl,type=RuntimeBean,moduleFactoryName=toaster-consumer-impl");
ObjectName providerOn = new ObjectName("org.opendaylight.controller:instanceName=toaster-provider-impl,type=RuntimeBean,moduleFactoryName=toaster-provider-impl");
long toastsMade = (long) platformMBeanServer.getAttribute(providerOn, "ToastsMade");
boolean toasts = true;
// Make toasts using OSGi service
- toasts &= toastConsumer.createToast(HashBrown.class, 4);
- toasts &= toastConsumer.createToast(WhiteBread.class, 8);
-
- // Make toast using JMX/config-subsystem
- toasts &= (Boolean)platformMBeanServer.invoke(consumerOn, "makeHashBrownToast", new Object[]{4}, new String[]{Integer.class.getName()});
+ toasts &= kitchenService.makeBreakfast( EggsType.SCRAMBLED, HashBrown.class, 4);
+ toasts &= kitchenService.makeBreakfast( EggsType.POACHED, WhiteBread.class, 8 );
- Assert.assertTrue("Not all toasts done by " + toastConsumer, toasts);
+ Assert.assertTrue("Not all toasts done by " + kitchenService, toasts);
// Verify toasts made count on provider via JMX/config-subsystem
toastsMade = (long) platformMBeanServer.getAttribute(providerOn, "ToastsMade");
- assertEquals(3, toastsMade);
+ assertEquals(2, toastsMade);
}
}
<snapshots>
<snapshot>
<required-capabilities>
- <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27</capability>
+ <!-- <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27</capability>-->
<capability>
urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
</capability>
urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16</capability>
- <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
- </capability>
+ <!-- <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09</capability>-->
<capability>
urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
</capability>
<capability>http://netconfcentral.org/ns/toaster?module=toaster&revision=2009-11-20</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer?module=toaster-consumer&revision=2014-01-31</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer:impl?module=toaster-consumer-impl&revision=2014-01-31</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider?module=toaster-provider&revision=2014-01-31</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl?module=kitchen-service-impl&revision=2014-01-31</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl?module=toaster-provider-impl&revision=2014-01-31</capability>
</required-capabilities>
<name>binding-rpc-broker</name>
</rpc-registry>
+ <data-broker>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+ <name>ref_binding-data-broker</name>
+ </data-broker>
+
<notification-service>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
binding:binding-notification-service
</module>
<module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer:impl">
- prefix:toaster-consumer-impl
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
+ prefix:kitchen-service-impl
</type>
- <name>toaster-consumer-impl</name>
+ <name>kitchen-service-impl</name>
<rpc-registry>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
</modules>
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:kitchen="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
+ kitchen:kitchen-service
+ </type>
+ <instance>
+ <name>kitchen-service</name>
+ <provider>/modules/module[type='kitchen-service-impl'][name='kitchen-service-impl']</provider>
+ </instance>
+ </service>
<service>
<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
dom:schema-service
package org.opendaylight.controller.config.yang.config.toaster_provider.impl;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sample.toaster.provider.OpendaylightToaster;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterData;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// Register to md-sal
opendaylightToaster.setNotificationProvider(getNotificationServiceDependency());
- opendaylightToaster.setDataProvider(getDataBrokerDependency());
+
+ DataProviderService dataBrokerService = getDataBrokerDependency();
+ opendaylightToaster.setDataProvider(dataBrokerService);
+
+ final ListenerRegistration<DataChangeListener> dataChangeListenerRegistration =
+ dataBrokerService.registerDataChangeListener( OpendaylightToaster.TOASTER_IID, opendaylightToaster );
+
final BindingAwareBroker.RpcRegistration<ToasterService> rpcRegistration = getRpcRegistryDependency()
.addRpcImplementation(ToasterService.class, opendaylightToaster);
// Wrap toaster as AutoCloseable and close registrations to md-sal at
// close()
- final class AutoCloseableToaster implements AutoCloseable, ToasterData {
+ final class AutoCloseableToaster implements AutoCloseable {
@Override
public void close() throws Exception {
+ dataChangeListenerRegistration.close();
rpcRegistration.close();
runtimeReg.close();
opendaylightToaster.close();
log.info("Toaster provider (instance {}) torn down.", this);
}
-
- @Override
- public Toaster getToaster() {
- return opendaylightToaster.getToaster();
- }
}
AutoCloseable ret = new AutoCloseableToaster();
*/
package org.opendaylight.controller.sample.toaster.provider;
+import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicLong;
import org.opendaylight.controller.config.yang.config.toaster_provider.impl.ToasterProviderRuntimeMXBean;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.common.util.RpcErrors;
import org.opendaylight.controller.sal.common.util.Rpcs;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.DisplayString;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastDone.ToastStatus;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastDoneBuilder;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster.ToasterStatus;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.RestockToasterInput;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterBuilder;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterData;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterOutOfBreadBuilder;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterRestocked;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterRestockedBuilder;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import com.google.common.util.concurrent.Futures;
-public class OpendaylightToaster implements ToasterData, ToasterService, ToasterProviderRuntimeMXBean, AutoCloseable {
+public class OpendaylightToaster implements ToasterService, ToasterProviderRuntimeMXBean,
+ DataChangeListener, AutoCloseable {
- private static final Logger log = LoggerFactory.getLogger(OpendaylightToaster.class);
- private static final InstanceIdentifier<Toaster> toasterIID = InstanceIdentifier.builder(Toaster.class).build();
+ private static final Logger LOG = LoggerFactory.getLogger(OpendaylightToaster.class);
- private static final DisplayString toasterManufacturer = new DisplayString("Opendaylight");
- private static final DisplayString toasterModelNumber = new DisplayString("Model 1 - Binding Aware");
+ public static final InstanceIdentifier<Toaster> TOASTER_IID = InstanceIdentifier.builder(Toaster.class).build();
+
+ private static final DisplayString TOASTER_MANUFACTURER = new DisplayString("Opendaylight");
+ private static final DisplayString TOASTER_MODEL_NUMBER = new DisplayString("Model 1 - Binding Aware");
private NotificationProviderService notificationProvider;
private DataBrokerService dataProvider;
+
private final ExecutorService executor;
- private Future<RpcResult<Void>> currentTask;
+ // As you will see we are using multiple threads here. Therefore we need to be careful about concurrency.
+ // In this case we use the taskLock to provide synchronization for the current task.
+ private volatile Future<RpcResult<Void>> currentTask;
+ private final Object taskLock = new Object();
+
+ private final AtomicLong amountOfBreadInStock = new AtomicLong( 100 );
+
+ private final AtomicLong toastsMade = new AtomicLong(0);
+
+ // Thread safe holder for our darkness multiplier.
+ private final AtomicLong darknessFactor = new AtomicLong( 1000 );
public OpendaylightToaster() {
executor = Executors.newFixedThreadPool(1);
}
+ public void setNotificationProvider(NotificationProviderService salService) {
+ this.notificationProvider = salService;
+ }
+
+ public void setDataProvider(DataBrokerService salDataProvider) {
+ this.dataProvider = salDataProvider;
+ updateStatus();
+ }
+
+ /**
+ * Implemented from the AutoCloseable interface.
+ */
@Override
- public synchronized Toaster getToaster() {
- ToasterBuilder tb = new ToasterBuilder();
- tb //
- .setToasterManufacturer(toasterManufacturer) //
- .setToasterModelNumber(toasterModelNumber) //
- .setToasterStatus(currentTask == null ? ToasterStatus.Up : ToasterStatus.Down);
+ public void close() throws ExecutionException, InterruptedException {
+ // When we close this service we need to shutdown our executor!
+ executor.shutdown();
+ if (dataProvider != null) {
+ final DataModificationTransaction t = dataProvider.beginTransaction();
+ t.removeOperationalData(TOASTER_IID);
+ t.commit().get();
+ }
+ }
+
+ private Toaster buildToaster() {
+ // We don't need to synchronize on currentTask here b/c it's declared volatile and
+ // we're just doing a read.
+ boolean isUp = currentTask == null;
+
+ // note - we are simulating a device whose manufacture and model are
+ // fixed (embedded) into the hardware.
+ // This is why the manufacture and model number are hardcoded.
+ ToasterBuilder tb = new ToasterBuilder();
+ tb.setToasterManufacturer(TOASTER_MANUFACTURER).setToasterModelNumber(TOASTER_MODEL_NUMBER)
+ .setToasterStatus(isUp ? ToasterStatus.Up : ToasterStatus.Down);
return tb.build();
}
+ /**
+ * Implemented from the DataChangeListener interface.
+ */
@Override
- public synchronized Future<RpcResult<Void>> cancelToast() {
- if (currentTask != null) {
- cancelToastImpl();
+ public void onDataChanged( DataChangeEvent<InstanceIdentifier<?>, DataObject> change ) {
+ DataObject dataObject = change.getUpdatedConfigurationData().get( TOASTER_IID );
+ if( dataObject instanceof Toaster )
+ {
+ Toaster toaster = (Toaster) dataObject;
+ Long darkness = toaster.getDarknessFactor();
+ if( darkness != null )
+ {
+ darknessFactor.set( darkness );
+ }
}
- return null;
}
+ /**
+ * RestConf RPC call implemented from the ToasterService interface.
+ */
@Override
- public synchronized Future<RpcResult<Void>> makeToast(MakeToastInput input) {
- log.debug("makeToast - Received input for toast");
- logToastInput(input);
- if (currentTask != null) {
- return inProgressError();
+ public Future<RpcResult<Void>> cancelToast() {
+ synchronized (taskLock) {
+ if (currentTask != null) {
+ currentTask.cancel(true);
+ currentTask = null;
+ }
}
- currentTask = executor.submit(new MakeToastTask(input));
- updateStatus();
- return currentTask;
+ // Always return success from the cancel toast call.
+ return Futures.immediateFuture(Rpcs.<Void> getRpcResult(true, Collections.<RpcError> emptySet()));
}
- private Future<RpcResult<Void>> inProgressError() {
- RpcResult<Void> result = Rpcs.<Void> getRpcResult(false, null, Collections.<RpcError> emptySet());
- return Futures.immediateFuture(result);
- }
+ /**
+ * RestConf RPC call implemented from the ToasterService interface.
+ */
+ @Override
+ public Future<RpcResult<Void>> makeToast(MakeToastInput input) {
+ LOG.info("makeToast: " + input);
- private void cancelToastImpl() {
- currentTask.cancel(true);
- ToastDoneBuilder toastDone = new ToastDoneBuilder();
- toastDone.setToastStatus(ToastStatus.Cancelled);
- notificationProvider.publish(toastDone.build());
- }
+ synchronized (taskLock) {
+ if (currentTask != null) {
+ // return an error since we are already toasting some toast.
+ LOG.info( "Toaster is already making toast" );
- public void setNotificationProvider(NotificationProviderService salService) {
- this.notificationProvider = salService;
- }
+ RpcResult<Void> result = Rpcs.<Void> getRpcResult(false, null, Arrays.asList(
+ RpcErrors.getRpcError( null, null, null, null,
+ "Toaster is busy", null, null ) ) );
+ return Futures.immediateFuture(result);
+ }
+ else if( outOfBread() ) {
+ RpcResult<Void> result = Rpcs.<Void> getRpcResult(false, null, Arrays.asList(
+ RpcErrors.getRpcError( null, null, null, null,
+ "Toaster is out of bread", null, null ) ) );
+ return Futures.immediateFuture(result);
+ }
+ else {
+ // Notice that we are moving the actual call to another thread,
+ // allowing this thread to return immediately.
+ // The MD-SAL design encourages asynchronus programming. If the
+ // caller needs to block until the call is
+ // complete then they can leverage the blocking methods on the
+ // Future interface.
+ currentTask = executor.submit(new MakeToastTask(input));
+ }
+ }
- public void setDataProvider(DataBrokerService salDataProvider) {
- this.dataProvider = salDataProvider;
updateStatus();
+ return currentTask;
}
- private void logToastInput(MakeToastInput input) {
- String toastType = input.getToasterToastType().getName();
- String toastDoneness = input.getToasterDoneness().toString();
- log.trace("Toast: {} doneness: {}", toastType, toastDoneness);
+ /**
+ * RestConf RPC call implemented from the ToasterService interface.
+ * Restocks the bread for the toaster, resets the toastsMade counter to 0, and sends a
+ * ToasterRestocked notification.
+ */
+ @Override
+ public Future<RpcResult<java.lang.Void>> restockToaster(RestockToasterInput input) {
+ LOG.info( "restockToaster: " + input );
+
+ synchronized( taskLock ) {
+ amountOfBreadInStock.set( input.getAmountOfBreadToStock() );
+
+ if( amountOfBreadInStock.get() > 0 ) {
+ ToasterRestocked reStockedNotification =
+ new ToasterRestockedBuilder().setAmountOfBread( input.getAmountOfBreadToStock() ).build();
+ notificationProvider.publish( reStockedNotification );
+ }
+ }
+
+ return Futures.immediateFuture(Rpcs.<Void> getRpcResult(true, Collections.<RpcError> emptySet()));
}
- private final AtomicLong toastsMade = new AtomicLong(0);
+ /**
+ * JMX RPC call implemented from the ToasterProviderRuntimeMXBean interface.
+ */
+ @Override
+ public void clearToastsMade() {
+ LOG.info( "clearToastsMade" );
+ toastsMade.set( 0 );
+ }
+ /**
+ * Accesssor method implemented from the ToasterProviderRuntimeMXBean interface.
+ */
@Override
public Long getToastsMade() {
return toastsMade.get();
private void updateStatus() {
if (dataProvider != null) {
final DataModificationTransaction t = dataProvider.beginTransaction();
- t.removeOperationalData(toasterIID);
- t.putOperationalData(toasterIID, getToaster());
+ t.removeOperationalData(TOASTER_IID);
+ t.putOperationalData(TOASTER_IID, buildToaster());
try {
t.commit().get();
} catch (InterruptedException | ExecutionException e) {
- log.warn("Failed to update toaster status, operational otherwise", e);
+ LOG.warn("Failed to update toaster status, operational otherwise", e);
}
} else {
- log.trace("No data provider configured, not updating status");
+ LOG.trace("No data provider configured, not updating status");
}
}
- @Override
- public void close() throws ExecutionException, InterruptedException {
- if (dataProvider != null) {
- final DataModificationTransaction t = dataProvider.beginTransaction();
- t.removeOperationalData(toasterIID);
- t.commit().get();
- }
+ private boolean outOfBread()
+ {
+ return amountOfBreadInStock.get() == 0;
}
private class MakeToastTask implements Callable<RpcResult<Void>> {
}
@Override
- public RpcResult<Void> call() throws InterruptedException {
- Thread.sleep(1000 * toastRequest.getToasterDoneness());
+ public RpcResult<Void> call() {
+ try
+ {
+ // make toast just sleeps for n secondn per doneness level.
+ long darknessFactor = OpendaylightToaster.this.darknessFactor.get();
+ Thread.sleep(darknessFactor * toastRequest.getToasterDoneness());
- ToastDoneBuilder notifyBuilder = new ToastDoneBuilder();
- notifyBuilder.setToastStatus(ToastStatus.Done);
- notificationProvider.publish(notifyBuilder.build());
- log.debug("Toast Done");
- logToastInput(toastRequest);
+ }
+ catch( InterruptedException e ) {
+ LOG.info( "Interrupted while making the toast" );
+ }
- currentTask = null;
toastsMade.incrementAndGet();
+
+ amountOfBreadInStock.getAndDecrement();
+ if( outOfBread() ) {
+ LOG.info( "Toaster is out of bread!" );
+
+ notificationProvider.publish( new ToasterOutOfBreadBuilder().build() );
+ }
+
+ synchronized (taskLock) {
+ currentTask = null;
+ }
+
updateStatus();
+ LOG.debug("Toast done");
+
return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
}
}
prefix "toaster-provider-impl";
import config { prefix config; revision-date 2013-04-05; }
- import toaster-provider { prefix toaster-provider; revision-date 2014-01-31; }
+ import rpc-context { prefix rpcx; revision-date 2013-06-17; }
import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
description
"Initial revision.";
}
- // This is the definition of a service implementation
+ // This is the definition of the service implementation as a module identity.
identity toaster-provider-impl {
base config:module-type;
- config:provided-service toaster-provider:toaster-provider;
+
+ // Specifies the prefix for generated java classes.
config:java-name-prefix ToasterProvider;
}
+ // Augments the 'configuration' choice node under modules/module.
augment "/config:modules/config:module/config:configuration" {
case toaster-provider-impl {
when "/config:modules/config:module/config:type = 'toaster-provider-impl'";
augment "/config:modules/config:module/config:state" {
case toaster-provider-impl {
when "/config:modules/config:module/config:type = 'toaster-provider-impl'";
-
+
leaf toasts-made {
type uint32;
}
+
+ rpcx:rpc-context-instance "clear-toasts-made-rpc";
+ }
+ }
+
+ identity clear-toasts-made-rpc;
+ rpc clear-toasts-made {
+ description
+ "JMX call to clear the toasts-made counter.";
+
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance clear-toasts-made-rpc;
+ }
+ }
}
}
}
+++ /dev/null
-// vi: set smarttab et sw=4 tabstop=4:
-module toaster-provider {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider";
- prefix "toaster-provider";
-
- import config { prefix config; revision-date 2013-04-05; }
-
- description
- "This module contains the base YANG definitions for
- toaster-provider services.";
-
- revision "2014-01-31" {
- description
- "Initial revision.";
- }
-
- // This is the definition of a service
- identity toaster-provider {
-
- base "config:service-type";
-
- config:java-class "org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterData";
- }
-}
\ No newline at end of file
"This variable indicates the current state of
the toaster.";
}
+
+ leaf darknessFactor {
+ type uint32;
+ config true;
+ default 1000;
+ description
+ "The darkness factor. Basically, the number of ms to multiple the doneness value by.";
+ }
} // container toaster
rpc make-toast {
if the toaster service is disabled.";
} // rpc cancel-toast
- notification toastDone {
- description
- "Indicates that the toast in progress has completed.";
- leaf toastStatus {
- type enumeration {
- enum "done" {
- value 0;
- description "The toast is done.";
- }
- enum "cancelled" {
- value 1;
- description
- "The toast was cancelled.";
- }
- enum "error" {
- value 2;
- description
- "The toaster service was disabled or
- the toaster is broken.";
- }
+ rpc restock-toaster {
+ description
+ "Restocks the toaster with the amount of bread specified.";
+
+ input {
+ leaf amountOfBreadToStock {
+ type uint32;
+ description
+ "Indicates the amount of bread to re-stock";
+ }
}
+ }
+
+ notification toasterOutOfBread {
+ description
+ "Indicates that the toaster has run of out bread.";
+ } // notification toasterOutOfStock
+
+ notification toasterRestocked {
+ description
+ "Indicates that the toaster has run of out bread.";
+ leaf amountOfBread {
+ type uint32;
description
- "Indicates the final toast status";
+ "Indicates the amount of bread that was re-stocked";
}
- } // notification toastDone
+ } // notification toasterOutOfStock
+
} // module toaster
abstract class AbstractStatsTracker<I, K> {
private static final Logger logger = LoggerFactory.getLogger(AbstractStatsTracker.class);
-
+
private static final int WAIT_FOR_REQUEST_CYCLE = 2;
-
+
private final FutureCallback<RpcResult<? extends TransactionAware>> callback =
new FutureCallback<RpcResult<? extends TransactionAware>>() {
@Override
}
protected final InstanceIdentifierBuilder<Node> getNodeIdentifierBuilder() {
- return InstanceIdentifier.builder(getNodeIdentifier());
+ return getNodeIdentifier().builder();
}
protected final NodeRef getNodeRef() {
private FlowTableStatsTracker flowTableStats;
private int unaccountedFlowsCounter = 1;
- FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context) {
+ FlowStatsTracker(final OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context) {
super(context);
this.flowStatsService = flowStatsService;
}
- FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, FlowTableStatsTracker flowTableStats) {
+ FlowStatsTracker(final OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, final FlowTableStatsTracker flowTableStats) {
this(flowStatsService, context);
this.flowTableStats = flowTableStats;
}
@Override
- protected void cleanupSingleStat(DataModificationTransaction trans, FlowStatsEntry item) {
+ protected void cleanupSingleStat(final DataModificationTransaction trans, final FlowStatsEntry item) {
InstanceIdentifier<?> flowRef = getNodeIdentifierBuilder()
.augmentation(FlowCapableNode.class)
.child(Table.class, new TableKey(item.getTableId()))
}
@Override
- protected FlowStatsEntry updateSingleStat(DataModificationTransaction trans, FlowAndStatisticsMapList map) {
+ protected FlowStatsEntry updateSingleStat(final DataModificationTransaction trans, final FlowAndStatisticsMapList map) {
short tableId = map.getTableId();
FlowBuilder flowBuilder = new FlowBuilder();
}
this.requestAllFlowsAllTables();
-
+
}
public void requestAllFlowsAllTables() {
if (flowStatsService != null) {
}
@Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
for (Entry<InstanceIdentifier<?>, DataObject> e : change.getCreatedConfigurationData().entrySet()) {
if (Flow.class.equals(e.getKey().getTargetType())) {
final Flow flow = (Flow) e.getValue();
if (Flow.class.equals(key.getTargetType())) {
@SuppressWarnings("unchecked")
final InstanceIdentifier<Flow> flow = (InstanceIdentifier<Flow>)key;
- final InstanceIdentifier<?> del = InstanceIdentifier.builder(flow)
- .augmentation(FlowStatisticsData.class).build();
- logger.debug("Key {} triggered remove of augmentation {}", key, del);
-
- trans.removeOperationalData(del);
+ logger.debug("Key {} triggered remove of Flow from operational space.", key);
+ trans.removeOperationalData(flow);
}
}
trans.commit();
if (Group.class.equals(key.getTargetType())) {
@SuppressWarnings("unchecked")
InstanceIdentifier<Group> group = (InstanceIdentifier<Group>)key;
- InstanceIdentifier<?> del = InstanceIdentifier.builder(group).augmentation(NodeGroupDescStats.class).toInstance();
+ InstanceIdentifier<?> del = group.augmentation(NodeGroupDescStats.class);
logger.debug("Key {} triggered remove of augmentation {}", key, del);
trans.removeOperationalData(del);
if (Group.class.equals(key.getTargetType())) {
@SuppressWarnings("unchecked")
InstanceIdentifier<Group> group = (InstanceIdentifier<Group>)key;
- InstanceIdentifier<?> del = InstanceIdentifier.builder(group).augmentation(NodeGroupStatistics.class).toInstance();
+ InstanceIdentifier<?> del = group.augmentation(NodeGroupStatistics.class);
logger.debug("Key {} triggered remove of augmentation {}", key, del);
trans.removeOperationalData(del);
InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>)key;
InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
- InstanceIdentifier.builder(meter).augmentation(NodeMeterConfigStats.class).toInstance();
+ meter.augmentation(NodeMeterConfigStats.class);
trans.removeOperationalData(nodeMeterStatisticsAugmentation);
}
}
InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>)key;
InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
- InstanceIdentifier.builder(meter).augmentation(NodeMeterStatistics.class).toInstance();
+ meter.augmentation(NodeMeterStatistics.class);
trans.removeOperationalData(nodeMeterStatisticsAugmentation);
}
}
if (Queue.class.equals(key.getTargetType())) {
@SuppressWarnings("unchecked")
final InstanceIdentifier<Queue> queue = (InstanceIdentifier<Queue>)key;
- final InstanceIdentifier<?> del = InstanceIdentifier.builder(queue)
- .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).build();
+ final InstanceIdentifier<?> del = queue
+ .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class);
logger.debug("Key {} triggered remove of augmentation {}", key, del);
trans.removeOperationalData(del);
}
for (Link link : topologyData.getLink()) {
if (id.equals(link.getSource().getSourceNode()) || id.equals(link.getDestination().getDestNode())) {
- InstanceIdentifier<Link> path = InstanceIdentifier.builder(topologyPath)
- .child(Link.class, link.getKey()).build();
+ InstanceIdentifier<Link> path = topologyPath.child(Link.class, link.getKey());
transaction.removeOperationalData(path);
}
}
}
for (Link link : topologyData.getLink()) {
if (id.equals(link.getSource().getSourceTp()) || id.equals(link.getDestination().getDestTp())) {
- InstanceIdentifier<Link> path = InstanceIdentifier.builder(topologyPath)
- .child(Link.class, link.getKey()).build();
+ InstanceIdentifier<Link> path = topologyPath.child(Link.class, link.getKey());
transaction.removeOperationalData(path);
}
}
.child(Topology.class, topology).child(Link.class, link.getKey()).build();
return linkInstanceId;
}
-
+
/**
* @param txId transaction identificator
* @param future transaction result
*/
private static void listenOnTransactionState(final Object txId, Future<RpcResult<TransactionStatus>> future) {
Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future),new FutureCallback<RpcResult<TransactionStatus>>() {
-
+
@Override
public void onFailure(Throwable t) {
LOG.error("Topology export failed for Tx:{}", txId, t);
-
+
}
-
+
@Override
public void onSuccess(RpcResult<TransactionStatus> result) {
if(!result.isSuccessful()) {
*/
package org.opendaylight.controller.netconf.confignetconfconnector.exception;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
import java.util.Collections;
import java.util.Map;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
public class NetconfConfigHandlingException extends NetconfDocumentedException {
+ private static final long serialVersionUID = 1L;
public NetconfConfigHandlingException(final String message, final ErrorType errorType, final ErrorTag errorTag,
final ErrorSeverity errorSeverity) {
*/
package org.opendaylight.controller.netconf.confignetconfconnector.exception;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
import java.util.Collections;
import java.util.Map;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
public class NoTransactionFoundException extends NetconfDocumentedException {
+ private static final long serialVersionUID = 1L;
public NoTransactionFoundException(final String message, final ErrorType errorType, final ErrorTag errorTag,
final ErrorSeverity errorSeverity) {
*/
package org.opendaylight.controller.netconf.confignetconfconnector.exception;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
import java.util.Collections;
import java.util.Map;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
public class OperationNotPermittedException extends NetconfDocumentedException {
+ private static final long serialVersionUID = 1L;
public OperationNotPermittedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
final ErrorSeverity errorSeverity) {
package org.opendaylight.controller.netconf.persist.impl;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.Collections2;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.concurrent.Immutable;
+
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
-import javax.annotation.concurrent.Immutable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.TimeUnit;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Collections2;
@Immutable
public class ConfigPusher {
}
private static class NotEnoughCapabilitiesException extends Exception {
+ private static final long serialVersionUID = 1L;
+
private NotEnoughCapabilitiesException(String message, Throwable cause) {
super(message, cause);
}
</properties>
<dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-binding-it</artifactId>
- <exclusions>
- <!-- FIXME see IdentityRefNetconfTest -->
- <!-- Pax-url-aether contains guava classes e.g. ImmutableSet that clashes with guava and causes tests to fail-->
- <exclusion>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-aether</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
<artifactId>yang-test</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.ops4j.pax.tinybundles</groupId>
- <artifactId>tinybundles</artifactId>
- <version>${tinybundles.version}</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
<perCoreThreadCount>false</perCoreThreadCount>
- <classpathDependencyExcludes>
- <classpathDependencyExcludes>com.google.collections:google-collections</classpathDependencyExcludes>
- <classpathDependencyExcludes>org.ops4j.pax.url:pax-url-aether</classpathDependencyExcludes>
- </classpathDependencyExcludes>
</configuration>
<executions>
<execution>
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import javax.management.ObjectName;
import javax.xml.parsers.ParserConfigurationException;
-import junit.framework.Assert;
-
-import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
+import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
-import org.opendaylight.controller.netconf.StubUserManager;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
-import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
+import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
+import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
-import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.Session;
-
+import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
static List<ModuleFactory> getModuleFactoriesS() {
return Lists.newArrayList(new TestImplModuleFactory(), new DepTestImplModuleFactory(),
- new NetconfTestImplModuleFactory());
+ new NetconfTestImplModuleFactory(), new IdentityTestModuleFactory());
}
@Test
return netconfClient;
}
- private void startSSHServer() throws Exception {
- logger.info("Creating SSH server");
- StubUserManager um = new StubUserManager(USERNAME, PASSWORD);
- String pem;
- try (InputStream is = getClass().getResourceAsStream("/RSA.pk")) {
- pem = IOUtils.toString(is);
+ @Test
+ public void testIdRef() throws Exception {
+ NetconfMessage editId = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
+ NetconfMessage commit = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
+
+ try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) {
+ assertIsOK(netconfClient.sendMessage(editId).getDocument());
+ assertIsOK(netconfClient.sendMessage(commit).getDocument());
+
+ NetconfMessage response = netconfClient.sendMessage(getConfig);
+
+ assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("<prefix:afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</prefix:afi>"));
+ assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("<prefix:afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</prefix:afi>"));
+ assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("<prefix:safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</prefix:safi>"));
+ assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("<prefix:safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</prefix:safi>"));
+
+ } catch (Exception e) {
+ fail(Throwables.getStackTraceAsString(e));
}
- AuthProvider ap = new AuthProvider(um, pem);
- Thread sshServerThread = new Thread(NetconfSSHServer.start(10830, tcpAddress, ap));
- sshServerThread.setDaemon(true);
- sshServerThread.start();
- logger.info("SSH server on");
}
- @Test
- public void sshTest() throws Exception {
- startSSHServer();
- logger.info("creating connection");
- Connection conn = new Connection(sshAddress.getHostName(), sshAddress.getPort());
- Assert.assertNotNull(conn);
- logger.info("connection created");
- conn.connect();
- boolean isAuthenticated = conn.authenticateWithPassword(USERNAME, PASSWORD);
- assertTrue(isAuthenticated);
- logger.info("user authenticated");
- final Session sess = conn.openSession();
- sess.startSubSystem("netconf");
- logger.info("user authenticated");
- sess.getStdin().write(XmlUtil.toString(this.getConfig.getDocument()).getBytes());
-
- new Thread() {
- @Override
- public void run() {
- while (true) {
- byte[] bytes = new byte[1024];
- int c = 0;
- try {
- c = sess.getStdout().read(bytes);
- } catch (IOException e) {
- throw new IllegalStateException("IO exception while reading data on ssh bridge.");
- }
- logger.info("got data:" + bytes);
- if (c == 0) {
- break;
- }
- }
- }
- }.join();
- }
+ @Override
+ protected CodecRegistry getCodecRegistry() {
+ final IdentityCodec<?> codec = mock(IdentityCodec.class);
+ doReturn(TestIdentity1.class).when(codec).deserialize(TestIdentity1.QNAME);
+ doReturn(TestIdentity2.class).when(codec).deserialize(TestIdentity2.QNAME);
+ final CodecRegistry ret = super.getCodecRegistry();
+ doReturn(codec).when(ret).getIdentityCodec();
+ return ret;
+ }
}
+++ /dev/null
-/*
-* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
-package org.opendaylight.controller.netconf.it.pax;
-
-import static org.junit.Assert.fail;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.flowCapableModelBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAndMockitoBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles;
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.streamBundle;
-import static org.ops4j.pax.exam.CoreOptions.systemPackages;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timer;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.matchers.JUnitMatchers;
-import org.junit.runner.RunWith;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.ops4j.pax.exam.options.DefaultCompositeOption;
-import org.ops4j.pax.exam.util.Filter;
-import org.ops4j.pax.tinybundles.core.TinyBundles;
-import org.osgi.framework.Constants;
-import org.xml.sax.SAXException;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.concurrent.GlobalEventExecutor;
-
-@Ignore
-@RunWith(PaxExam.class)
-public class IdentityRefNetconfTest {
-
- public static final int CLIENT_CONNECTION_TIMEOUT_MILLIS = 15000;
-
- // Wait for controller to start
-
- // FIXME move this (pax) test to different module
- // pax jars contain guava classes that clash with real guava dependencies in non-pax tests
- //
- //@Inject
- @Filter(timeout = 60 * 1000)
- BindingAwareBroker broker;
-
- @Configuration
- public Option[] config() {
- return options(
- systemProperty("osgi.console").value("2401"),
- systemProperty("osgi.bundles.defaultStartLevel").value("4"),
- systemProperty("pax.exam.osgi.unresolved.fail").value("true"),
- systemPackages("sun.nio.ch"),
-
- testingModules(),
- loggingModules(),
- mdSalCoreBundles(),
- bindingAwareSalBundles(), configMinumumBundles(), baseModelBundles(), flowCapableModelBundles(),
- junitAndMockitoBundles(),
-
- // Classes from test-jars bundled for pax-exam test
- streamBundle(TinyBundles.bundle()
- .add(TestingNetconfClient.class)
- .add(XmlFileLoader.class)
-
- .add("/netconfMessages/editConfig_identities.xml",
- XmlFileLoader.class.getResource("/netconfMessages/editConfig_identities.xml"))
- .add("/netconfMessages/commit.xml",
- XmlFileLoader.class.getResource("/netconfMessages/commit.xml"))
- .add("/netconfMessages/getConfig.xml",
- XmlFileLoader.class.getResource("/netconfMessages/getConfig.xml"))
-
- .set(Constants.BUNDLE_SYMBOLICNAME, "TestingClient_bundle")
- .set(Constants.EXPORT_PACKAGE, "org.opendaylight.controller.netconf.client.test, " +
- "org.opendaylight.controller.netconf.util.test")
- .build(TinyBundles.withBnd())));
- }
-
- private Option loggingModules() {
- return new DefaultCompositeOption(
- mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(),
- mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(),
- mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(),
- mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(),
- mavenBundle("org.openexi", "nagasena").versionAsInProject(),
- mavenBundle("org.openexi", "nagasena-rta").versionAsInProject());
-
-
- }
-
- private Option testingModules() {
- return new DefaultCompositeOption(
- mavenBundle("org.opendaylight.controller", "yang-test").versionAsInProject());
- }
-
- private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 18383);
-
- @Test
- public void testIdRef() throws Exception {
- Preconditions.checkNotNull(broker, "Controller not initialized");
-
-
- NetconfMessage edit = xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
- NetconfMessage commit = xmlFileToNetconfMessage("netconfMessages/commit.xml");
- NetconfMessage getConfig = xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
-
- NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup();
- Timer timer = new HashedWheelTimer();
- NetconfClientDispatcherImpl clientDispatcher = new NetconfClientDispatcherImpl(nettyThreadgroup, nettyThreadgroup, timer);
- try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(tcpAddress))) {
- sendMessage(edit, netconfClient);
- sendMessage(commit, netconfClient);
- sendMessage(getConfig, netconfClient, "id-test",
- "<prefix:afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</prefix:afi>",
- "<prefix:afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</prefix:afi>",
- "<prefix:safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</prefix:safi>",
- "<prefix:safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</prefix:safi>");
-
- clientDispatcher.close();
- } catch (Exception e) {
- fail(Throwables.getStackTraceAsString(e));
- } finally {
- nettyThreadgroup.shutdownGracefully().get();
- timer.stop();
- }
- }
-
- private void sendMessage(NetconfMessage edit, TestingNetconfClient netconfClient, String... containingResponse)
- throws ExecutionException, InterruptedException, TimeoutException {
- NetconfMessage response = netconfClient.sendRequest(edit).get();
- if (containingResponse == null) {
- Assert.assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("<ok/>"));
- } else {
- for (String resp : containingResponse) {
- Assert.assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString(resp));
- }
- }
- }
-
- public static NetconfMessage xmlFileToNetconfMessage(final String fileName) throws IOException, SAXException,
- ParserConfigurationException {
- return XmlFileLoader.xmlFileToNetconfMessage(fileName);
- }
-
- public NetconfClientConfiguration getClientConfiguration(final InetSocketAddress tcpAddress) {
- final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
- b.withAddress(tcpAddress);
- b.withSessionListener(new SimpleNetconfClientSessionListener());
- b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
- CLIENT_CONNECTION_TIMEOUT_MILLIS));
- b.withConnectionTimeoutMillis(CLIENT_CONNECTION_TIMEOUT_MILLIS);
- return b.build();
- }
-}
+++ /dev/null
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
-3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
-iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
-sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
-gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
-b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
-Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
-8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
-mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
-fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
-oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
-6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
-FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
-2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
-8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
-fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
-wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
-X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
-aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
-L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
-wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
-CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
-lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
-5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
-dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
------END RSA PRIVATE KEY-----
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<persisted-snapshots>
- <snapshots>
- <snapshot>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:test:types?module=test-types&revision=2013-11-27</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:test:impl?module=config-test-impl&revision=2013-04-03</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:test?module=config-test&revision=2013-06-13</capability>
- </required-capabilities>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test:impl">prefix:impl-identity-test</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test:impl">id-test</prefix:name>
- <identities-container xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <prefix:afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</prefix:afi>
- </identities-container>
- <identities xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <prefix:safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</prefix:safi>
- <prefix:afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</prefix:afi>
- </identities>
- <identities xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <prefix:safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</prefix:safi>
- <prefix:afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</prefix:afi>
- </identities>
- <prefix:afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</prefix:afi>
- </module>
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-broker-impl</prefix:name>
- <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-notification-service</prefix:type>
- <name>ref_binding-notification-broker</name>
- </notification-service>
- <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-data-broker</prefix:type>
- <name>ref_binding-data-broker</name>
- </data-broker>
- </module>
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">runtime-mapping-singleton</prefix:name>
- </module>
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-notification-broker</prefix:name>
- </module>
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-data-broker</prefix:name>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</prefix:type>
- <name>ref_dom-broker</name>
- </dom-broker>
- <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</prefix:type>
- <name>ref_runtime-mapping-singleton</name>
- </mapping-service>
- </module>
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:logback:config">prefix:logback</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:logback:config">singleton</prefix:name>
- <console-appenders xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <threshold-filter>DEBUG</threshold-filter>
- <name>console</name>
- <encoder-pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</encoder-pattern>
- </console-appenders>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>DEBUG</level>
- <logger-name>ROOT</logger-name>
- <appenders>console</appenders>
- </loggers>
- </module>
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">yang-schema-service</prefix:name>
- </module>
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">hash-map-data-store</prefix:name>
- </module>
- <module>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</prefix:type>
- <prefix:name xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">dom-broker</prefix:name>
- <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-data-store</prefix:type>
- <name>ref_hash-map-data-store</name>
- </data-store>
- </module>
- </modules>
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:schema-service</prefix:type>
- <instance>
- <name>ref_yang-schema-service</name>
- <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-data-store</prefix:type>
- <instance>
- <name>ref_hash-map-data-store</name>
- <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</prefix:type>
- <instance>
- <name>ref_dom-broker</name>
- <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</prefix:type>
- <instance>
- <name>ref_id-test</name>
- <provider>/modules/module[type='impl-identity-test'][name='id-test']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</prefix:type>
- <instance>
- <name>ref_runtime-mapping-singleton</name>
- <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-data-consumer-broker</prefix:type>
- <instance>
- <name>ref_binding-data-broker</name>
- <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-rpc-registry</prefix:type>
- <instance>
- <name>ref_binding-broker-impl</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-notification-service</prefix:type>
- <instance>
- <name>ref_binding-notification-broker</name>
- <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</prefix:type>
- <instance>
- <name>ref_binding-broker-impl</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-notification-subscription-service</prefix:type>
- <instance>
- <name>ref_binding-notification-broker</name>
- <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
- </instance>
- </service>
- <service>
- <prefix:type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-data-broker</prefix:type>
- <instance>
- <name>ref_binding-data-broker</name>
- <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
- </instance>
- </service>
- </services>
- </data>
- </configuration>
- </snapshot>
- </snapshots>
-</persisted-snapshots>
+++ /dev/null
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <commit></commit>
-</rpc>
+++ /dev/null
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
*/
package org.opendaylight.controller.netconf.util.exception;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
import java.util.Collections;
import java.util.Map;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
public class MissingNameSpaceException extends NetconfDocumentedException {
+ private static final long serialVersionUID = 1L;
public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
- final ErrorSeverity errorSeverity) {
+ final ErrorSeverity errorSeverity) {
this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
}
public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
- final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
+ final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
super(message,errorType,errorTag,errorSeverity,errorInfo);
}
}
*/
package org.opendaylight.controller.netconf.util.exception;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
import java.util.Collections;
import java.util.Map;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
public class UnexpectedElementException extends NetconfDocumentedException {
+ private static final long serialVersionUID = 1L;
public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag,
- final ErrorSeverity errorSeverity) {
+ final ErrorSeverity errorSeverity) {
this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
}
public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag,
- final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
+ final ErrorSeverity errorSeverity, final Map<String, String> errorInfo) {
super(message,errorType,errorTag,errorSeverity,errorInfo);
}
}
*/
package org.opendaylight.controller.netconf.util.exception;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
import java.util.Collections;
import java.util.Map;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+
public class UnexpectedNamespaceException extends NetconfDocumentedException {
+ private static final long serialVersionUID = 1L;
public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
final ErrorSeverity errorSeverity) {
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.3.6</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/connectionmanager"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/containermanager"/>
</services>
<modules>
<docs docsDir="rest" title="Container Manager REST API" includeExampleXml="true" includeExampleJson="true"/>
</modules>
-</enunciate>
\ No newline at end of file
+</enunciate>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/controllermanager"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
+import org.opendaylight.controller.sal.core.Property;
+
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.opendaylight.controller.sal.core.Property;
/**
* The class describes set of properties attached to a controller
@XmlAccessorType(XmlAccessType.NONE)
public class ControllerProperties {
- @XmlElementRef
- @XmlElementWrapper
- @JsonIgnore
/**
* Set to store the controller properties
*/
+ @XmlElement(name="property")
+ @XmlElementWrapper
+ @JsonIgnore
private Set<Property> properties;
// JAXB required constructor
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/flowprogrammer"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/hosttracker"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services> </services>
<modules>
<!-- Disable doc generation -->
<docs disabled="true"/>
-
+ <swagger disabled="true"/>
<!-- Disable all the client generation tools -->
<basic-app disabled="true" />
<c disabled="true" />
<version>1.4.2-SNAPSHOT</version>
<relativePath>../../commons/opendaylight</relativePath>
</parent>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
- <tag>HEAD</tag>
- </scm>
<artifactId>northbound.client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<docs.output.dir>${project.build.directory}/rest-api-docs</docs.output.dir>
<java-client>${project.build.directory}/enunciate/build/java-client/full-client.jar</java-client>
<java-client-sources>${project.build.directory}/enunciate/build/java-client/full-client-sources.jar</java-client-sources>
- <json-client>${project.build.directory}/enunciate/build/java-client/full-json-client.jar</json-client>
- <json-client-sources>${project.build.directory}/enunciate/build/java-client/full-json-client-sources.jar</json-client-sources>
</properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>enunciate-core-annotations</artifactId>
+ </dependency>
+
+ <!-- add dependency on all northbound bundles -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>connectionmanager.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>controllermanager.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>flowprogrammer.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>forwarding.staticrouting.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>hosttracker.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>networkconfig.bridgedomain.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>networkconfig.neutron.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>statistics.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>subnets.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>switchmanager.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>topology.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>usermanager.northbound</artifactId>
+ </dependency>
+ </dependencies>
+
<build>
<plugins>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
- <version>1.5</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
<configuration>
<target>
- <taskdef resource="net/sf/antcontrib/antcontrib.properties"
- classpathref="maven.plugin.classpath" />
+ <taskdef classpathref="maven.plugin.classpath" resource="net/sf/antcontrib/antcontrib.properties"></taskdef>
<patternset id="rest.paths">
- <include name="**/target/site/wsdocs/**"/>
- <exclude name="**/java-client/**"/>
+ <include name="**/target/site/wsdocs/**"></include>
+ <exclude name="**/java-client/**"></exclude>
</patternset>
- <echo message="======== Assembling enunciate docs ========"/>
+ <echo message="======== Assembling enunciate docs ========"></echo>
<!-- cleanup existing generated files -->
- <delete dir="${docs.output.dir}"/>
- <delete file="${docs.output.dir}.zip"/>
- <mkdir dir="${docs.output.dir}"/>
+ <delete dir="${docs.output.dir}"></delete>
+ <delete file="${docs.output.dir}.zip"></delete>
+ <mkdir dir="${docs.output.dir}"></mkdir>
<!-- copy enunciate docs to stage -->
<copy todir="${docs.output.dir}">
<fileset dir="${basedir}/../../..">
- <patternset refid="rest.paths"/>
+ <patternset refid="rest.paths"></patternset>
</fileset>
- <mapper type="regexp"
- from="^(.*)/([^/]+)/target/site/wsdocs/(.*)$$"
- to="\2/\3"/>
+ <mapper from="^(.*)/([^/]+)/target/site/wsdocs/(.*)$$" to="\2/\3" type="regexp"></mapper>
</copy>
+ <!-- Remove Swagger doc link from enunciate generated index.html -->
+ <replaceregexp byline="false" match="<h2>Swagger</h2>${line.separator}\s*<p>${line.separator}.*${line.separator}\s*</p>" replace="">
+ <fileset dir="${docs.output.dir}">
+ <include name="**/index.html"></include>
+ </fileset>
+ </replaceregexp>
<!-- generate index.html -->
<!-- append header -->
- <echo file="${docs.output.dir}/index.html" append="true">
- <![CDATA[
+ <echo append="true" file="${docs.output.dir}/index.html"><![CDATA[
<html>
<head>
<title> OpenDaylight REST API Documentation </title>
<h2>OpenDaylight REST API Documentation</h2>
<p> OpenDaylight supports the following <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">Representational State Transfer (REST)</a> APIs: </p>
<h4>
- ]]>
- </echo>
- <dirset id="nbset" dir="${docs.output.dir}">
- <include name="*"/>
+ ]]></echo>
+ <dirset dir="${docs.output.dir}" id="nbset">
+ <include name="*"></include>
</dirset>
- <pathconvert pathsep="&#36;{line.separator}"
- property="nbs"
- refid="nbset"/>
- <echo file="${docs.output.dir}/index.html"
- append="true"
- message="${nbs}"/>
- <replaceregexp file="${docs.output.dir}/index.html"
- match="^\${docs.output.dir}/(.*)$"
- replace="&lt;li&gt;&lt;a href=\1/index.html&gt; \1 &lt;/a&gt;&lt;/li&gt;"
- byline="true"/>
+ <pathconvert pathsep="&#36;{line.separator}" property="nbs" refid="nbset"></pathconvert>
+ <echo append="true" file="${docs.output.dir}/index.html" message="${nbs}"></echo>
+ <replaceregexp byline="true" file="${docs.output.dir}/index.html" match="^\${docs.output.dir}/(.*)$" replace="&lt;li&gt;&lt;a href=\1/index.html&gt; \1 &lt;/a&gt;&lt;/li&gt;"></replaceregexp>
<!-- append footer -->
- <echo file="${docs.output.dir}/index.html" append="true">
- <![CDATA[
+ <echo append="true" file="${docs.output.dir}/index.html"><![CDATA[
</h4>
<i>---</i>
</body>
</html>
- ]]>
- </echo>
+ ]]></echo>
<!-- archive all the docs excluding whatever is not needed -->
- <echo message="======== Archiving enunciate docs ========"/>
+ <echo message="======== Archiving enunciate docs ========"></echo>
<zip destfile="${docs.output.dir}.zip">
- <zipfileset dir="${docs.output.dir}"/>
+ <zipfileset dir="${docs.output.dir}"></zipfileset>
</zip>
- <echo message="======== Build successful ========"/>
- <echo message="REST docs archive: ${docs.output.dir}.zip"/>
+ <echo message="======== Build successful ========"></echo>
+ <echo message="REST docs archive: ${docs.output.dir}.zip"></echo>
</target>
</configuration>
<dependencies>
<version>20020829</version>
</dependency>
</dependencies>
+ <executions>
+ <execution>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <phase>package</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>maven-enunciate-plugin</artifactId>
</plugin>
<plugin>
<executions>
<execution>
<id>attach-artifacts</id>
- <phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
+ <phase>package</phase>
<configuration>
<artifacts>
<artifact>
<type>jar</type>
<classifier>full-java-client-sources</classifier>
</artifact>
- <artifact>
- <file>${json-client}</file>
- <type>jar</type>
- <classifier>full-json-client</classifier>
- </artifact>
- <artifact>
- <file>${json-client-sources}</file>
- <type>jar</type>
- <classifier>full-json-client-sources</classifier>
- </artifact>
</artifacts>
</configuration>
</execution>
</plugin>
</plugins>
</build>
- <dependencies>
- <dependency>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>enunciate-core-annotations</artifactId>
- </dependency>
-
- <!-- add dependency on all northbound bundles -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>connectionmanager.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>controllermanager.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>flowprogrammer.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>hosttracker.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>networkconfig.bridgedomain.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>networkconfig.neutron.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>forwarding.staticrouting.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>statistics.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>subnets.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>switchmanager.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>topology.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>usermanager.northbound</artifactId>
- </dependency>
- </dependencies>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
+ </scm>
</project>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/networkconfig/bridgedomain"/>
<modules>
<docs docsDir="rest" title="Bridge Domain Configuration REST API" includeExampleXml="true" includeExampleJson="true"/>
- </modules>
+ </modules>
</enunciate>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
-<?xml version="1.0"?>\r
-<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">\r
-\r
- <services>\r
- <rest defaultRestSubcontext="/controller/nb/v2/neutron"/>\r
- </services>\r
-\r
- <modules>\r
- <docs docsDir="rest" title="OpenStack Neutron REST API" includeExampleXml="false" includeExampleJson="true"/>\r
- </modules>\r
-</enunciate>\r
+<?xml version="1.0"?>
+<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
+
+ <services>
+ <rest defaultRestSubcontext="/controller/nb/v2/neutron"/>
+ </services>
+
+ <modules>
+ <docs docsDir="rest" title="OpenStack Neutron REST API" includeExampleXml="false" includeExampleJson="true"/>
+ </modules>
+</enunciate>
<artifactId>networkconfig.neutron.northbound</artifactId>
<version>0.4.2-SNAPSHOT</version>
<packaging>bundle</packaging>
- <properties>
- <enunciate.version>1.26.2</enunciate.version>
- </properties>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.3.6</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>maven-enunciate-plugin</artifactId>
- <configuration>
- <configFile>enunciate.xml</configFile>
- </configuration>
- <executions>
- <execution>
- <goals>
- <goal>docs</goal>
- </goals>
- </execution>
- </executions>
</plugin>
</plugins>
</build>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/staticroute"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/statistics"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/subnetservice"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/switchmanager"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.Property;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
/**
* The class describes set of properties attached to a node connector
*/
public class NodeConnectorProperties {
@XmlElement
private NodeConnector nodeconnector;
- @XmlElementRef
+
+ @XmlElement(name="property")
@XmlElementWrapper
@JsonIgnore
private Set<Property> properties;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.Property;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
/**
* The class describes set of properties attached to a node
*/
public class NodeProperties {
@XmlElement
private Node node;
- @XmlElementRef
+
+ @XmlElement(name="property")
@XmlElementWrapper
@JsonIgnore
private Set<Property> properties;
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/topology"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
import org.opendaylight.controller.sal.core.Edge;
import org.opendaylight.controller.sal.core.Property;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class EdgeProperties {
@XmlElement
private Edge edge;
- @XmlElementRef
+
+ @XmlElement(name="property")
@XmlElementWrapper
@JsonIgnore
private Set<Property> properties;
<?xml version="1.0"?>
<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
<services>
<rest defaultRestSubcontext="/controller/nb/v2/usermanager"/>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.Timer;
+import java.util.TimerTask;
import org.opendaylight.controller.clustering.services.CacheConfigException;
import org.opendaylight.controller.clustering.services.CacheExistException;
private ISwitchManager switchManager;
private IDataPacketService dataPacketService;
+ /**
+ * Ip packets that are punted may not have their destination known by hostTracker at the time it
+ * is presented to SimpleForwardingImpl. Instead of dropping the packet, we will keep it around
+ * for a 'little' while, to accommodate any transients. See bug 590 for more details.
+ */
+ private class PendingPacketData {
+ private final static byte MAX_AGE = 2;
+
+ public final IPv4 pkt;
+ public final NodeConnector incomingNodeConnector;
+ private byte age;
+
+ public PendingPacketData(IPv4 pkt, NodeConnector incomingNodeConnector) {
+ this.pkt = pkt;
+ this.incomingNodeConnector = incomingNodeConnector;
+ this.age = 0;
+ }
+ boolean bumpAgeAndCheckIfTooOld() { return ++age > MAX_AGE; }
+ }
+ private static final int MAX_PENDING_PACKET_DESTINATIONS = 64;
+ private ConcurrentMap<InetAddress, PendingPacketData> pendingPacketDestinations;
+ private Timer pendingPacketsAgerTimer;
+
+ private class PendingPacketsAgerTimerHandler extends TimerTask {
+ @Override
+ public void run() {
+ if (pendingPacketDestinations == null) {
+ return;
+ }
+ try {
+ Iterator<ConcurrentMap.Entry<InetAddress, PendingPacketData>> iterator =
+ pendingPacketDestinations.entrySet().iterator();
+ while (iterator.hasNext()) {
+ ConcurrentHashMap.Entry<InetAddress, PendingPacketData> entry = iterator.next();
+ InetAddress dIP = entry.getKey();
+ PendingPacketData pendingPacketData = entry.getValue();
+
+ if (pendingPacketData.bumpAgeAndCheckIfTooOld()) {
+ iterator.remove(); // safe to remove while iterating...
+ log.debug("Pending packet for {} has been aged out", dIP);
+ } else {
+ /** Replace the entry for a key only if currently mapped to some value.
+ * This will protect the concurrent map against a race where this thread
+ * would be re-adding an entry that just got taken out.
+ */
+ pendingPacketDestinations.replace(dIP, pendingPacketData);
+ }
+ }
+ } catch (IllegalStateException e) {
+ log.warn("IllegalStateException Received by PendingPacketsAgerTimerHandler from: {}",
+ e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Add punted packet to pendingPackets
+ */
+ private void addToPendingPackets(InetAddress dIP, IPv4 pkt, NodeConnector incomingNodeConnector) {
+ if (pendingPacketDestinations.size() >= MAX_PENDING_PACKET_DESTINATIONS) {
+ log.info("Will not pend packet for {}: Too many destinations", dIP);
+ return;
+ }
+
+ /** TODO: The current implementation allows for up to 1 pending packet per InetAddress.
+ * This limitation is done for sake of simplicity. A potential enhancement could be to use a
+ * ConcurrentMultiMap instead of ConcurrentMap.
+ */
+ if (pendingPacketDestinations.containsKey(dIP)) {
+ log.trace("Will not pend packet for {}: Already have a packet pending", dIP);
+ return;
+ }
+
+ PendingPacketData pendingPacketData = new PendingPacketData(pkt, incomingNodeConnector);
+ pendingPacketDestinations.put(dIP, pendingPacketData);
+ log.debug("Pending packet for {}", dIP);
+ }
+
+ /**
+ * Send punted packet to given destination. This is invoked when there is a certain level of
+ * hope that the destination is known by hostTracker.
+ */
+ private void sendPendingPacket(InetAddress dIP) {
+ PendingPacketData pendingPacketData = pendingPacketDestinations.get(dIP);
+ if (pendingPacketData != null) {
+ handlePuntedIPPacket(pendingPacketData.pkt, pendingPacketData.incomingNodeConnector, false);
+ log.trace("Packet for {} is no longer pending", dIP);
+ pendingPacketDestinations.remove(dIP);
+ }
+ }
+
/**
* Return codes from the programming of the perHost rules in HW
*/
public void startUp() {
allocateCaches();
retrieveCaches();
+ nonClusterObjectCreate();
+ }
+
+ public void nonClusterObjectCreate() {
+ pendingPacketDestinations = new ConcurrentHashMap<InetAddress, PendingPacketData>();
+
+ /* Pending Packets Ager Timer to go off every 6 seconds to implement pending packet aging */
+ pendingPacketsAgerTimer = new Timer();
+ pendingPacketsAgerTimer.schedule(new PendingPacketsAgerTimerHandler(), 6000, 6000);
}
/**
Set<Node> switches = preparePerHostRules(host);
if (switches != null) {
installPerHostRules(host, switches);
+
+ // Green light for sending pending packet to this host. Safe to call if there are none.
+ sendPendingPacket(host.getNetworkAddress());
}
}
*
*/
void stop() {
+ pendingPacketsAgerTimer.cancel();
+ pendingPacketDestinations.clear();
}
public void setSwitchManager(ISwitchManager switchManager) {
Object nextPak = formattedPak.getPayload();
if (nextPak instanceof IPv4) {
log.trace("Handle punted IP packet: {}", formattedPak);
- handlePuntedIPPacket((IPv4) nextPak, inPkt.getIncomingNodeConnector());
+ handlePuntedIPPacket((IPv4) nextPak, inPkt.getIncomingNodeConnector(), true);
}
}
return PacketResult.IGNORED;
}
- private void handlePuntedIPPacket(IPv4 pkt, NodeConnector incomingNodeConnector) {
+ private void handlePuntedIPPacket(IPv4 pkt, NodeConnector incomingNodeConnector, boolean allowAddPending) {
InetAddress dIP = NetUtils.getInetAddress(pkt.getDestinationAddress());
if (dIP == null || hostTracker == null) {
log.debug("Invalid param(s) in handlePuntedIPPacket.. DestIP: {}. hostTracker: {}", dIP, hostTracker);
rp.setOutgoingNodeConnector(nc);
this.dataPacketService.transmitDataPacket(rp);
}
-
+ } else if (allowAddPending) {
+ // If we made it here, let's hang on to the punted packet, with hopes that its destination
+ // will become available soon.
+ addToPendingPackets(dIP, pkt, incomingNodeConnector);
+ } else {
+ log.warn("Dropping punted IP packet received at {} to Host {}", incomingNodeConnector, dIP);
}
}
}
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
org.springframework.security.core.userdetails,
javax.xml.bind.annotation</Import-Package>
<Export-Package>org.opendaylight.controller.usermanager,</Export-Package>
- <Bundle-Activator></Bundle-Activator>
</instructions>
<manifestLocation>${project.basedir}/META-INF</manifestLocation>
</configuration>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
webconsole.product.url = http://www.opendaylight.org/
webconsole.product.image = /res/imgs/odl/logo.png
webconsole.favicon = /res/imgs/odl/favicon.ico
-
+#To disable web console authentication clear default username
+webconsole.username =
# webconsole.vendor.name = Linux Foundation
# webconsole.vendor.url = http://www.linuxfoundation.org/
# webconsole.vendor.image = /res/imgs/vendor.png
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>