.idea
xtend-gen
classes
+out/
--- /dev/null
+[gerrit]
+host=git.opendaylight.org
+port=29418
+project=controller.git
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
log.debug("Can't find subnet matching {}, drop packet", dIP);
return;
}
+ // If packet is sent to the default gw (us), ignore it for now
+ if (subnet.getNetworkAddress().equals(dIP)) {
+ log.trace("Ignore IP packet destined to default gw");
+ return;
+ }
// see if we know about the host
// Hosttracker hosts db key implementation
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jboss.jbossts.jta</groupId>
private HashSet<IListenRoleChange> roleChangeListeners;
private ViewChangedListener cacheManagerListener;
- private static String loopbackAddress = "127.0.0.1";
+ private static String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress();
// defaultTransactionTimeout is 60 seconds
private static int DEFAULT_TRANSACTION_TIMEOUT = 60;
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
private ConcurrentMap<String, ConcurrentMap<?, ?>> caches = new ConcurrentHashMap<String, ConcurrentMap<?, ?>>();
protected ClusterManagerCommon() throws UnknownHostException {
- loopbackAddress = InetAddress.getByName("127.0.0.1");
+ loopbackAddress = InetAddress.getLoopbackAddress();
}
/**
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<sonar.skippedModules>org.openflow.openflowj,net.sf.jung2</sonar.skippedModules>
<logback.version>1.0.9</logback.version>
<slf4j.version>1.7.2</slf4j.version>
- <jackson.version>1.9.8</jackson.version>
+ <jackson.version>2.3.0</jackson.version>
<spring.version>3.1.3.RELEASE</spring.version>
<spring-security.version>3.1.3.RELEASE</spring-security.version>
<spring-osgi.version>1.2.1</spring-osgi.version>
<osgi.core.version>5.0.0</osgi.core.version>
<ietf-inet-types.version>2010.09.24.2-SNAPSHOT</ietf-inet-types.version>
<ietf-yang-types.version>2010.09.24.2-SNAPSHOT</ietf-yang-types.version>
+ <ietf-topology.version>2013.10.21.0-SNAPSHOT</ietf-topology.version>
<opendaylight-l2-types.version>2013.08.27.1</opendaylight-l2-types.version>
<yang-ext.version>2013.09.07.1</yang-ext.version>
<javassist.version>3.17.1-GA</javassist.version>
<jolokia.bridge.version>0.0.1-SNAPSHOT</jolokia.bridge.version>
<netty.version>4.0.10.Final</netty.version>
<commons.io.version>2.4</commons.io.version>
- <!-- Sonar properties using jacoco to retrieve integration test results -->
- <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
- <sonar.language>java</sonar.language>
+ <bundlescanner.version>0.4.1-SNAPSHOT</bundlescanner.version>
+ <usermanager.version>0.4.1-SNAPSHOT</usermanager.version>
<forwardingrulesmanager.version>0.5.0-SNAPSHOT</forwardingrulesmanager.version>
<statisticsmanager.version>0.5.0-SNAPSHOT</statisticsmanager.version>
<clustering.services.version>0.5.0-SNAPSHOT</clustering.services.version>
+ <configuration.version>0.4.1-SNAPSHOT</configuration.version>
+ <topologymanager.version>0.4.1-SNAPSHOT</topologymanager.version>
+ <!-- Third party version -->
+ <jersey-servlet.version>1.18-SNAPSHOT</jersey-servlet.version>
+ <corsfilter.version>7.0.43-SNAPSHOT</corsfilter.version>
+ <!-- Northbound API version -->
+ <commons.northbound.version>0.4.1-SNAPSHOT</commons.northbound.version>
+ <!-- Sonar properties using jacoco to retrieve integration test results -->
+ <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+ <sonar.language>java</sonar.language>
<maven.compile.plugin.version>2.5.1</maven.compile.plugin.version>
<java.version.source>1.7</java.version.source>
<java.version.target>1.7</java.version.target>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- <version>${jackson.version}</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-base</artifactId>
<version>${jackson.version}</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-jaxrs</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-xc</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-jaxb-annotations</artifactId>
<version>${jackson.version}</version>
- </dependency>
+ </dependency>
+
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-json</artifactId>
- <version>${jersey.version}</version>
- </dependency>
+
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-all</artifactId>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>com.sun.jersey.jersey-servlet</artifactId>
- <version>1.17</version>
+ <version>${jersey-servlet.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
- <version>7.0.42</version>
+ <version>${corsfilter.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>ietf-yang-types</artifactId>
<version>${ietf-yang-types.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-topology</artifactId>
+ <version>${ietf-topology.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${switchmanager.api.version}</version>
</dependency>
<!-- equinox http service bridge -->
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- </plugin>
</plugins>
</build>
</project>
public class ValidationException extends RuntimeException {
private static final long serialVersionUID = -6072893219820274247L;
- private final Map<String, Map<String, ExceptionMessageWithStackTrace>> failedValidations;
+ private final Map<String/* module name */, Map<String/* instance name */, ExceptionMessageWithStackTrace>> failedValidations;
public ValidationException(
Map<String /* module name */, Map<String /* instance name */, ExceptionMessageWithStackTrace>> failedValidations) {
return new ValidationException(failedValidations);
}
- public Map<String, Map<String, ExceptionMessageWithStackTrace>> getFailedValidations() {
+ public Map<String/* module name */, Map<String/* instance name */, ExceptionMessageWithStackTrace>> getFailedValidations() {
return failedValidations;
}
package org.opendaylight.controller.config.manager.impl;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
import junit.framework.Assert;
import org.junit.After;
import org.mockito.Matchers;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
+import javax.management.RuntimeMBeanException;
import java.io.Closeable;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.util.Dictionary;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import static org.junit.Assert.assertEquals;
protected BundleContext mockedContext = mock(BundleContext.class);
protected ServiceRegistration<?> mockedServiceRegistration;
- protected Map<Class, BundleContextServiceRegistrationHandler> getBundleContextServiceRegistrationHandlers() {
- return Maps.newHashMap();
+ private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class);
+
+ // Default handler for OSGi service registration
+ private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() {
+ @Override
+ public void handleServiceRegistration(Object serviceInstance) {}
+ };
+
+ protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class<?> serviceType) {
+ return noopServiceRegHandler;
}
// this method should be called in @Before
protected ObjectName createTestConfigBean(
ConfigTransactionJMXClient transaction, String implementationName,
String name) throws InstanceAlreadyExistsException {
- ObjectName nameCreated = transaction.createModule(implementationName,
+ return transaction.createModule(implementationName,
name);
- return nameCreated;
}
protected void assertBeanCount(int i, String configMXBeanName) {
}
private class RegisterServiceAnswer implements Answer {
+
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
- Preconditions.checkArgument(args.length == 3);
+ Preconditions.checkArgument(args.length == 3, "Unexpected arguments size (expected 3 was %s)", args.length);
- Preconditions.checkArgument(args[0] instanceof Class);
- Class<?> serviceType = (Class<?>) args[0];
+ Object serviceTypeRaw = args[0];
Object serviceInstance = args[1];
- BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandlers()
- .get(serviceType);
+ if (serviceTypeRaw instanceof Class) {
+ Class<?> serviceType = (Class<?>) serviceTypeRaw;
+ invokeServiceHandler(serviceInstance, serviceType);
+
+ } else if(serviceTypeRaw instanceof String[]) {
+ for (String className : (String[]) serviceTypeRaw) {
+ try {
+ Class<?> serviceType = Class.forName(className);
+ invokeServiceHandler(serviceInstance, serviceType);
+ } catch (ClassNotFoundException e) {
+ logger.warn("Not handling service registration of type {} ", className, e);
+ }
+ }
+
+ } else
+ logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw);
+
+ return mockedServiceRegistration;
+ }
- Preconditions.checkArgument(serviceType.isAssignableFrom(serviceInstance.getClass()));
+ private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType) {
+ BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType);
if (serviceRegistrationHandler != null) {
serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance));
}
-
- return mockedServiceRegistration;
}
}
+
+ /**
+ * Expand inner exception wrapped by JMX
+ *
+ * @param innerObject jmx proxy which will be wrapped and returned
+ */
+ protected <T> T rethrowCause(final T innerObject) {
+
+ Object proxy = Proxy.newProxyInstance(innerObject.getClass().getClassLoader(),
+ innerObject.getClass().getInterfaces(), new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ try {
+ return method.invoke(innerObject, args);
+ } catch (InvocationTargetException e) {
+ try {
+ throw e.getTargetException();
+ } catch (RuntimeMBeanException e2) {
+ throw e2.getTargetException();
+ }
+ }
+ }
+ });
+ return (T) proxy;
+ }
+
}
<build>
<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
--- /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.persist.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.controller.config.persist.api.PropertiesProvider;
+
+public class PropertiesProviderTest implements PropertiesProvider {
+ private final Map<String,String> properties = new HashMap();
+
+ public void addProperty(String key,String value){
+ properties.put(key,value);
+ }
+ @Override
+ public String getProperty(String key) {
+ return properties.get(key);
+ }
+
+ @Override
+ public String getFullKeyForReporting(String key) {
+ return null;
+ }
+}
<artifactId>mockito-configuration</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
private static final Logger logger = LoggerFactory.getLogger(DirectoryPersister.class);
private static final Charset ENCODING = Charsets.UTF_8;
- static final String MODULES_START = "//MODULES START";
+ public static final String MODULES_START = "//MODULES START";
static final String SERVICES_START = "//SERVICES START";
static final String CAPABILITIES_START = "//CAPABILITIES START";
private final File storage;
- private final String header, middle, footer;
+ private static final String header, middle, footer;
- public DirectoryPersister(File storage) {
- checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
- this.storage = storage;
+ static {
header = readResource("header.txt");
middle = readResource("middle.txt");
footer = readResource("footer.txt");
+ }
+ public DirectoryPersister(File storage) {
+ checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
+ this.storage = storage;
}
private static String readResource(String resource) {
for (File file : sortedFiles) {
logger.trace("Adding file '{}' to combined result", file);
- final MyLineProcessor lineProcessor = new MyLineProcessor(file.getAbsolutePath());
- Files.readLines(file, ENCODING, lineProcessor);
- result.add(lineProcessor.getConfigSnapshotHolder(header, middle, footer));
+ ConfigSnapshotHolder configSnapshotHolder = loadLastConfig(file);
+ result.add(configSnapshotHolder);
}
return result;
}
+ public static ConfigSnapshotHolder loadLastConfig(File file) throws IOException {
+ final MyLineProcessor lineProcessor = new MyLineProcessor(file.getAbsolutePath());
+ Files.readLines(file, ENCODING, lineProcessor);
+ return lineProcessor.getConfigSnapshotHolder(header, middle, footer);
+ }
+
@Override
public void close() {
package org.opendaylight.controller.config.persist.storage.directory;
-import org.apache.commons.io.IOUtils;
-import org.junit.Test;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
-
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class DirectoryStorageAdapterTest {
- DirectoryPersister tested;
+ Persister tested;
@Test
public void testEmptyDirectory() throws Exception {
File folder = new File("target/emptyFolder");
folder.mkdir();
- tested = new DirectoryPersister((folder));
+
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("directoryStorage",folder.getPath());
+ DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
+ tested = dsa.instantiate(pp);
assertEquals(Collections.<ConfigSnapshotHolder>emptyList(), tested.loadLastConfigs());
try {
@Test
public void testOneFile() throws Exception {
File folder = getFolder("oneFile");
- tested = new DirectoryPersister((folder));
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("directoryStorage",folder.getPath());
+ DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
+ tested = dsa.instantiate(pp);
+
List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
assertEquals(1, results.size());
ConfigSnapshotHolder result = results.get(0);
@Test
public void testTwoFiles() throws Exception {
File folder = getFolder("twoFiles");
- tested = new DirectoryPersister((folder));
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("directoryStorage",folder.getPath());
+ DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
+ tested = dsa.instantiate(pp);
+
List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
assertEquals(2, results.size());
assertSnapshot(results.get(0), "twoFilesExpected1");
--- /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>
+ <artifactId>config-subsystem</artifactId>
+ <groupId>org.opendaylight.controller</groupId>
+ <version>0.2.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>config-persister-directory-autodetect-adapter</artifactId>
+ <name>${project.artifactId}</name>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <!-- compile dependencies -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-persister-directory-adapter</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-persister-directory-xml-adapter</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>mockito-configuration</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- workaround for creating version according to OSGi specification (major.minor.micro[.qualifier] -->
+ <plugin>
+ <groupId>org.codehaus.groovy.maven</groupId>
+ <artifactId>gmaven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source>
+ System.setProperty("osgiversion", "${project.version}".replace('-', '.'))
+ </source>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Fragment-Host>${project.groupId}.config-persister-impl;bundle-version=${osgiversion}
+ </Fragment-Host>
+ <Provide-Capability>org.opendaylight.controller.config.persister.storage.adapter
+ </Provide-Capability>
+ <Import-Package>
+ com.google.common.base,
+ com.google.common.io,
+ org.apache.commons.io,
+ org.opendaylight.controller.config.persist.api,
+ org.slf4j,
+ com.google.common.collect,
+ javax.xml.bind,
+ javax.xml.bind.annotation,
+ javax.xml.transform,
+ javax.xml.transform.stream,
+ org.eclipse.persistence.jaxb,
+ org.apache.commons.lang3
+ </Import-Package>
+ <Private-Package>
+ org.opendaylight.controller.config.persist.storage.file.xml.model,
+ org.opendaylight.controller.config.persist.storage.directory,
+ org.opendaylight.controller.config.persist.storage.directory.xml,
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
--- /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.persist.storage.directory.autodetect;
+
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.storage.directory.DirectoryPersister;
+import org.opendaylight.controller.config.persist.storage.directory.xml.XmlDirectoryPersister;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.JAXBException;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class AutodetectDirectoryPersister implements Persister {
+ private static final Logger logger = LoggerFactory.getLogger(AutodetectDirectoryPersister.class);
+
+ private final File storage;
+
+ public AutodetectDirectoryPersister(File storage) {
+ checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
+ this.storage = storage;
+ }
+
+ @Override
+ public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
+ throw new UnsupportedOperationException("This adapter is read only. Please set readonly=true on " + getClass());
+ }
+
+ @Override
+ public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
+ File[] filesArray = storage.listFiles();
+ if (filesArray == null || filesArray.length == 0) {
+ return Collections.emptyList();
+ }
+ List<File> sortedFiles = new ArrayList<>(Arrays.asList(filesArray));
+ Collections.sort(sortedFiles);
+
+ // combine all found files
+ logger.debug("Reading files in following order: {}", sortedFiles);
+
+ List<ConfigSnapshotHolder> result = new ArrayList<>();
+ for (File file : sortedFiles) {
+ logger.trace("Adding file '{}' to combined result", file);
+
+ FileType fileType = FileType.getFileType(file);
+ logger.trace("File '{}' detected as {} storage", file, fileType);
+
+ ConfigSnapshotHolder snapshot = loadLastConfig(file, fileType);
+ result.add(snapshot);
+ }
+ return result;
+ }
+
+ private ConfigSnapshotHolder loadLastConfig(File file, FileType fileType) throws IOException {
+ switch (fileType) {
+ case plaintext:
+ return DirectoryPersister.loadLastConfig(file);
+ case xml:
+ try {
+ return XmlDirectoryPersister.loadLastConfig(file);
+ } catch (JAXBException e) {
+ logger.warn("Unable to restore configuration snapshot from {}", file, e);
+ throw new IllegalStateException("Unable to restore configuration snapshot from " + file, e);
+ }
+ default:
+ throw new IllegalStateException("Unknown storage type " + fileType);
+ }
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("AutodetectDirectoryPersister{");
+ sb.append("storage=").append(storage);
+ sb.append('}');
+ return sb.toString();
+ }
+}
--- /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.persist.storage.directory.autodetect;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.api.PropertiesProvider;
+import org.opendaylight.controller.config.persist.api.StorageAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+/**
+ * StorageAdapter that retrieves initial configuration from a directory. If multiple files are present, snapshot and
+ * required capabilities will be merged together. Writing to this persister is not supported.
+ */
+public class AutodetectDirectoryStorageAdapter implements StorageAdapter {
+ private static final Logger logger = LoggerFactory.getLogger(AutodetectDirectoryStorageAdapter.class);
+
+ public static final String DIRECTORY_STORAGE_PROP = "directoryStorage";
+
+
+ @Override
+ public Persister instantiate(PropertiesProvider propertiesProvider) {
+ String fileStorageProperty = propertiesProvider.getProperty(DIRECTORY_STORAGE_PROP);
+ Preconditions.checkNotNull(fileStorageProperty, "Unable to find " + propertiesProvider.getFullKeyForReporting(DIRECTORY_STORAGE_PROP));
+ File storage = new File(fileStorageProperty);
+ logger.debug("Using {}", storage);
+ return new AutodetectDirectoryPersister(storage);
+ }
+
+}
--- /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.persist.storage.directory.autodetect;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.controller.config.persist.storage.directory.DirectoryPersister;
+import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+enum FileType {
+
+ plaintext, xml;
+
+ public static final String XML_STORAGE_FIRST_LINE = "<" + ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME + ">";
+ private static final String XML_FILE_DEFINITION_LINE = "<?xml";
+
+ static FileType getFileType(File file) {
+ String firstLine = readFirstLine(file);
+ if(isPlaintextStorage(firstLine)) {
+ return plaintext;
+ } else if(isXmlStorage(firstLine))
+ return xml;
+
+ throw new IllegalArgumentException("File " + file + " is not of permitted storage type: " + Arrays.toString(FileType.values()));
+ }
+
+ private static boolean isXmlStorage(String firstLine) {
+ boolean isXml = false;
+ isXml |= firstLine.startsWith(XML_STORAGE_FIRST_LINE);
+ isXml |= firstLine.startsWith(XML_FILE_DEFINITION_LINE);
+ return isXml;
+ }
+
+ private static boolean isPlaintextStorage(String firstLine) {
+ return firstLine.startsWith(DirectoryPersister.MODULES_START);
+
+ }
+
+ @VisibleForTesting
+ static String readFirstLine(File file) {
+ FirstLineReadingProcessor callback = new FirstLineReadingProcessor();
+ try {
+ return Files.readLines(file, Charsets.UTF_8, callback);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Unable to detect file type of file " + file, e);
+ }
+ }
+
+
+ private static class FirstLineReadingProcessor implements com.google.common.io.LineProcessor<String> {
+ private String firstNonBlankLine;
+
+ @Override
+ public boolean processLine(String line) throws IOException {
+ if(isEmptyLine(line)) {
+ return true;
+ } else {
+ firstNonBlankLine = line.trim();
+ return false;
+ }
+ }
+
+ private boolean isEmptyLine(String line) {
+ return StringUtils.isBlank(line);
+ }
+
+ @Override
+ public String getResult() {
+ return firstNonBlankLine;
+ }
+ }
+}
--- /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.persist.storage.directory.autodetect;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+
+import java.io.File;
+import java.util.List;
+
+public class AutodetectDirectoryPersisterTest {
+
+ @Test
+ public void testCombined() throws Exception {
+ File resourcePath = FileTypeTest.getResourceAsFile("/combined/1controller.txt.config");
+
+ AutodetectDirectoryPersister persister = new AutodetectDirectoryPersister(resourcePath.getParentFile());
+ List<ConfigSnapshotHolder> configs = persister.loadLastConfigs();
+
+ Assert.assertEquals(2, configs.size());
+ String snapFromTxt = configs.get(0).getConfigSnapshot();
+ org.junit.Assert.assertThat(snapFromTxt, JUnitMatchers.containsString("<config>txt</config>"));
+ org.junit.Assert.assertThat(snapFromTxt, JUnitMatchers.containsString("<service>txt</service>"));
+
+ String snapFromXml = configs.get(1).getConfigSnapshot();
+ org.junit.Assert.assertThat(snapFromXml, JUnitMatchers.containsString("<config>xml</config>"));
+
+ Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities());
+ }
+}
--- /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.persist.storage.directory.autodetect;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+
+import java.io.File;
+
+public class FileTypeTest {
+
+ @Test
+ public void testPlaintext() throws Exception {
+ File file = getResourceAsFile("/test.txt.config");
+
+ FileType type = FileType.getFileType(file);
+ Assert.assertEquals(FileType.plaintext, type);
+
+ }
+
+ @Test
+ public void testXml() throws Exception {
+ File file = getResourceAsFile("/test.xml.config");
+
+ FileType type = FileType.getFileType(file);
+ Assert.assertEquals(FileType.xml, type);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testUnknown() throws Exception {
+ File file = getResourceAsFile("/unknown.config");
+
+ try {
+ FileType.getFileType(file);
+ } catch (IllegalArgumentException e) {
+ org.junit.Assert.assertThat(e.getMessage(), JUnitMatchers.containsString("File " + file + " is not of permitted storage type"));
+ throw e;
+ }
+ }
+
+ static File getResourceAsFile(String resource) {
+ String f = FileTypeTest.class.getResource(resource).getFile();
+ return new File(f);
+ }
+
+}
--- /dev/null
+//MODULES START
+ <config>txt</config>
+//SERVICES START
+ <service>txt</service>
+//CAPABILITIES START
+cap1&rev
+cap2
+capa a
\ No newline at end of file
--- /dev/null
+<snapshot>
+ <required-capabilities>
+ <capability>cap1&rev</capability>
+ <capability>cap2</capability>
+ <capability>capa a</capability>
+ </required-capabilities>
+ <configuration>
+ <config>xml</config>
+ </configuration>
+</snapshot>
\ No newline at end of file
--- /dev/null
+//MODULES START
+configuration
\ No newline at end of file
--- /dev/null
+
+<snapshot>
\ No newline at end of file
--- /dev/null
+unknown
+file type
\ No newline at end of file
<artifactId>mockito-configuration</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
private ConfigSnapshotHolder fromXmlSnapshot(File file) {
try {
- JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
- Unmarshaller um = jaxbContext.createUnmarshaller();
-
- return asHolder((ConfigSnapshot) um.unmarshal(file));
+ return loadLastConfig(file);
} catch (JAXBException e) {
logger.warn("Unable to restore configuration snapshot from {}", file, e);
throw new IllegalStateException("Unable to restore configuration snapshot from " + file, e);
}
}
- private ConfigSnapshotHolder asHolder(final ConfigSnapshot unmarshalled) {
+ public static ConfigSnapshotHolder loadLastConfig(File file) throws JAXBException {
+ JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
+ Unmarshaller um = jaxbContext.createUnmarshaller();
+
+ return asHolder((ConfigSnapshot) um.unmarshal(file));
+ }
+
+ private static ConfigSnapshotHolder asHolder(final ConfigSnapshot unmarshalled) {
return new ConfigSnapshotHolder() {
@Override
public String getConfigSnapshot() {
package org.opendaylight.controller.config.persist.storage.directory.xml;
-import org.junit.Test;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
-
+import org.junit.Test;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class DirectoryStorageAdapterTest {
XmlDirectoryPersister tested;
+ Logger logger = LoggerFactory.getLogger(DirectoryStorageAdapterTest.class.toString());
@Test
public void testEmptyDirectory() throws Exception {
@Test
public void testOneFile() throws Exception {
File folder = getFolder("oneFile");
- tested = new XmlDirectoryPersister((folder));
+ tested = new XmlDirectoryPersister(folder);
+ logger.info("Testing : "+tested.toString());
List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
assertEquals(1, results.size());
ConfigSnapshotHolder result = results.get(0);
public void testTwoFiles() throws Exception {
File folder = getFolder("twoFiles");
tested = new XmlDirectoryPersister((folder));
+ logger.info("Testing : "+tested.toString());
List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
assertEquals(2, results.size());
<artifactId>mockito-configuration</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.io.Files;
-import org.apache.commons.lang3.StringUtils;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolderImpl;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.opendaylight.controller.config.persist.api.StorageAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolderImpl;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.api.PropertiesProvider;
+import org.opendaylight.controller.config.persist.api.StorageAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * StorageAdapter that stores configuration in a plan file.
+ * StorageAdapter that stores configuration in a plain file.
*/
public class FileStorageAdapter implements StorageAdapter, Persister {
private static final Logger logger = LoggerFactory.getLogger(FileStorageAdapter.class);
import com.google.common.base.Charsets;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
import java.io.File;
import java.nio.file.Files;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
-
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
import static junit.framework.Assert.assertFalse;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
i = 1;
}
+
+ @Test
+ public void testFileAdapterAsPersister() throws Exception {
+ FileStorageAdapter storage = new FileStorageAdapter();
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("fileStorage",file.getPath());
+ pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+
+ Persister configPersister = storage.instantiate(pp);
+ final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
+ @Override
+ public String getConfigSnapshot() {
+ return createConfig();
+ }
+
+ @Override
+ public SortedSet<String> getCapabilities() {
+ return createCaps();
+ }
+ };
+ configPersister.persistConfig(holder);
+
+ configPersister.persistConfig(holder);
+
+ Collection<String> readLines = Collections2.filter(com.google.common.io.Files.readLines(file, Charsets.UTF_8),
+ new Predicate<String>() {
+
+ @Override
+ public boolean apply(String input) {
+ if (input.equals(""))
+ return false;
+ return true;
+ }
+ });
+ assertEquals(14, readLines.size());
+
+ List<ConfigSnapshotHolder> lastConf = storage.loadLastConfigs();
+ assertEquals(1, lastConf.size());
+ ConfigSnapshotHolder configSnapshotHolder = lastConf.get(0);
+ assertEquals("<config>2</config>",
+ configSnapshotHolder.getConfigSnapshot().replaceAll("\\s", ""));
+ assertEquals(createCaps(), configSnapshotHolder.getCapabilities());
+ }
@Test
public void testFileAdapter() throws Exception {
FileStorageAdapter storage = new FileStorageAdapter();
<artifactId>mockito-configuration</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
import javax.xml.bind.annotation.XmlRootElement;
import java.util.SortedSet;
-@XmlRootElement(name = "snapshot")
+@XmlRootElement(name = ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME)
public class ConfigSnapshot {
+ public static final String SNAPSHOT_ROOT_ELEMENT_NAME = "snapshot";
+
private String configSnapshot;
private SortedSet<String> capabilities;
package org.opendaylight.controller.config.persist.storage.file.xml;
import com.google.common.base.Charsets;
-import junit.framework.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
import java.io.File;
import java.nio.file.Files;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
-
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
import static junit.framework.Assert.assertFalse;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
@Test
public void testFileAdapter() throws Exception {
XmlFileStorageAdapter storage = new XmlFileStorageAdapter();
- storage.setFileStorage(file);
- storage.setNumberOfBackups(Integer.MAX_VALUE);
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("fileStorage",file.getPath());
+ pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+ storage.instantiate(pp);
+
final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
@Override
public String getConfigSnapshot() {
@Test
public void testFileAdapterOneBackup() throws Exception {
XmlFileStorageAdapter storage = new XmlFileStorageAdapter();
- storage.setFileStorage(file);
- storage.setNumberOfBackups(1);
+
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("fileStorage",file.getPath());
+ pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+ storage.instantiate(pp);
+
final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
@Override
public String getConfigSnapshot() {
storage.persistConfig(holder);
- assertEquals(16, com.google.common.io.Files.readLines(file, Charsets.UTF_8).size());
+ assertEquals(27, com.google.common.io.Files.readLines(file, Charsets.UTF_8).size());
List<ConfigSnapshotHolder> lastConf = storage.loadLastConfigs();
assertEquals(1, lastConf.size());
<configuration>
<sources>
<source>${jmxGeneratorPath}</source>
+ <source>${salGeneratorPath}</source>
</sources>
</configuration>
</execution>
void validateBean(ObjectName configBeanON) throws ValidationException;
- void destroyConfigBean(String moduleName, String instanceName)
- throws InstanceNotFoundException;
+ @Deprecated
+ /**
+ * Use {@link #destroyModule(String, String)}
+ */
+ void destroyConfigBean(String moduleName, String instanceName) throws InstanceNotFoundException;
+
+ void destroyModule(String moduleName, String instanceName) throws InstanceNotFoundException;
void setAttribute(ObjectName on, String jmxName, Attribute attribute);
}
}
@Override
+ @Deprecated
+ /**
+ * {@inheritDoc}
+ */
public void destroyConfigBean(String moduleName, String instanceName)
throws InstanceNotFoundException {
destroyModule(ObjectNameUtil.createTransactionModuleON(
getTransactionName(), moduleName, instanceName));
}
+ @Override
+ public void destroyModule(String moduleName, String instanceName)
+ throws InstanceNotFoundException {
+ destroyModule(ObjectNameUtil.createTransactionModuleON(
+ getTransactionName(), moduleName, instanceName));
+ }
+
@Override
public void abortConfig() {
configTransactionControllerMXBeanProxy.abortConfig();
-/**
- * Generated file
-
- * Generated from: yang module name: config-test yang module local name: testing
- * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
- * Generated at: Fri Sep 27 14:06:33 CEST 2013
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
- * Do not modify this file unless it is present under src/main directory
+ * 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.yang.logback.config;
-/**
- * Generated file
-
- * Generated from: yang module name: config-test yang module local name: testing
- * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
- * Generated at: Fri Sep 27 14:06:33 CEST 2013
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
- * Do not modify this file unless it is present under src/main directory
+ * 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.yang.logback.config;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * 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.yang.netty.eventexecutor;
import javax.management.InstanceAlreadyExistsException;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * 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.yang.netty.timer;
import javax.management.InstanceAlreadyExistsException;
<module>netty-timer-config</module>
<module>config-persister-directory-adapter</module>
<module>config-persister-directory-xml-adapter</module>
+ <module>config-persister-directory-autodetect-adapter</module>
<module>yang-test-plugin</module>
+ <module>shutdown-api</module>
+ <module>shutdown-impl</module>
</modules>
<profiles>
<java.version.source>1.7</java.version.source>
<java.version.target>1.7</java.version.target>
<junit.version>4.10</junit.version>
- <maven.bundle.version>2.3.7</maven.bundle.version>
+ <maven.bundle.version>2.4.0</maven.bundle.version>
<osgi.version>5.0.0</osgi.version>
<jacoco.version>0.6.2.201302030002</jacoco.version>
<slf4j.version>1.7.2</slf4j.version>
<opendaylight.yang.version>0.5.9-SNAPSHOT</opendaylight.yang.version>
<opendaylight.binding.version>0.6.0-SNAPSHOT</opendaylight.binding.version>
<opendaylight.yangtools.version>0.1.1-SNAPSHOT</opendaylight.yangtools.version>
+ <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
</properties>
<dependencies>
<artifactId>config-persister-api</artifactId>
<version>${config.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-api</artifactId>
+ <version>${config.version}</version>
+ <type>test-jar</type>
+ </dependency>
<dependency>
<groupId>org.opendaylight.bgpcep</groupId>
<artifactId>mockito-configuration</artifactId>
<version>${config.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>shutdown-api</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+
<!-- MD-SAL -->
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- </plugin>
+
+
</plugins>
<pluginManagement>
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/sal
+ ${salGeneratorPath}
</outputBaseDir>
</generator>
<generator>
</dependency>
</dependencies>
</plugin>
+ <!-- tell eclipse about generated source folders -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${salGeneratorPath}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</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">
+ <parent>
+ <artifactId>config-plugin-parent</artifactId>
+ <groupId>org.opendaylight.controller</groupId>
+ <version>0.2.3-SNAPSHOT</version>
+ <relativePath>../config-plugin-parent</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>bundle</packaging>
+ <artifactId>shutdown-api</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.opendaylight.controller.config.shutdown,
+ org.opendaylight.controller.config.yang.shutdown
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
--- /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.shutdown;
+
+import com.google.common.base.Optional;
+
+public interface ShutdownService {
+
+ /**
+ * Shut down the server.
+ *
+ * @param inputSecret must match configured secret of the implementation
+ * @param reason Optional string to be logged while shutting down
+ */
+ void shutdown(String inputSecret, Optional<String> reason);
+}
--- /dev/null
+module shutdown {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:shutdown";
+ prefix "shutdown";
+
+ import config { prefix config; revision-date 2013-04-05; }
+
+ description
+ "This module contains the base YANG definitions for
+ shutdown service.
+
+ Copyright (c)2013 Cisco Systems, Inc. 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";
+
+ revision "2013-12-18" {
+ description
+ "Initial revision.";
+ }
+
+ identity shutdown {
+ base "config:service-type";
+ config:java-class "org.opendaylight.controller.config.shutdown.ShutdownService";
+ }
+
+}
--- /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">
+ <parent>
+ <artifactId>config-plugin-parent</artifactId>
+ <groupId>org.opendaylight.controller</groupId>
+ <version>0.2.3-SNAPSHOT</version>
+ <relativePath>../config-plugin-parent</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>bundle</packaging>
+ <artifactId>shutdown-impl</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>shutdown-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-manager</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-manager</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-util</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>mockito-configuration</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: shutdown-impl yang module local name: shutdown
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Dec 18 14:02:06 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.shutdown.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.osgi.framework.Bundle;
+
+public final class ShutdownModule extends AbstractShutdownModule {
+ private final Bundle systemBundle;
+ private final ShutdownModule nullableOldModule;
+
+ public ShutdownModule(ModuleIdentifier identifier, Bundle systemBundle) {
+ super(identifier, null);
+ singletonCheck(identifier);
+ this.systemBundle = systemBundle;
+ this.nullableOldModule = null;
+ }
+
+ public ShutdownModule(ModuleIdentifier identifier, ShutdownModule oldModule, java.lang.AutoCloseable oldInstance,
+ Bundle systemBundle) {
+ super(identifier, null, oldModule, oldInstance);
+ singletonCheck(identifier);
+ this.systemBundle = systemBundle;
+ this.nullableOldModule = oldModule;
+ }
+
+ private static void singletonCheck(ModuleIdentifier identifier) {
+ if (AbstractShutdownModuleFactory.NAME.equals(identifier.getInstanceName()) == false) {
+ throw new IllegalArgumentException("Singleton enforcement failed. Expected instance name " + AbstractShutdownModuleFactory.NAME);
+ }
+ }
+
+ @Deprecated // needed for generated code
+ public ShutdownModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver, ShutdownModule oldModule,
+ AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ throw new UnsupportedOperationException();
+ }
+
+ @Deprecated // needed for generated code
+ public ShutdownModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getSecret() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getOldSecret() {
+ throw new UnsupportedOperationException();
+ }
+
+ String getActualSecret() {
+ return super.getSecret();
+ }
+
+ String getActualOldSecret() {
+ return super.getOldSecret();
+ }
+
+ @Override
+ protected void customValidation() {
+ JmxAttributeValidationException.checkNotNull(super.getOldSecret(), oldSecretJmxAttribute);
+ JmxAttributeValidationException.checkNotNull(super.getSecret(), secretJmxAttribute);
+ if (nullableOldModule != null) {
+ // if nothing changed, remain valid
+ boolean sameAsOldModule = isSame(nullableOldModule);
+ if (sameAsOldModule == false) {
+ boolean valid = getActualOldSecret().equals(nullableOldModule.getActualSecret());
+ JmxAttributeValidationException.checkCondition(valid, "Invalid old secret", oldSecretJmxAttribute);
+ }
+ }
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new ShutdownServiceImpl(getActualSecret(), systemBundle, getRootRuntimeBeanRegistratorWrapper());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: shutdown-impl yang module local name: shutdown
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Dec 18 14:02:06 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.shutdown.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+public class ShutdownModuleFactory extends AbstractShutdownModuleFactory {
+
+ @Override
+ public org.opendaylight.controller.config.spi.Module createModule(String instanceName, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.api.DynamicMBeanWithInstance old, org.osgi.framework.BundleContext bundleContext) throws Exception {
+ org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule oldModule = null;
+ try {
+ oldModule = (org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule) old.getModule();
+ } catch(Exception e) {
+ return handleChangedClass(old);
+ }
+ org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);
+
+ module.setOldSecret(oldModule.getActualOldSecret());
+ module.setSecret(oldModule.getActualSecret());
+
+ return module;
+ }
+
+
+ public ShutdownModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+ ShutdownModule oldModule, AutoCloseable oldInstance,
+ BundleContext bundleContext) {
+ Bundle systemBundle = bundleContext.getBundle(0);
+ return new ShutdownModule(new ModuleIdentifier(NAME, instanceName), oldModule, oldInstance, systemBundle);
+ }
+
+
+ public ShutdownModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+ BundleContext bundleContext) {
+ Bundle systemBundle = bundleContext.getBundle(0);
+ return new ShutdownModule(new ModuleIdentifier(NAME, instanceName), systemBundle);
+ }
+}
--- /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.yang.shutdown.impl;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.config.shutdown.ShutdownService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ShutdownServiceImpl implements ShutdownService, AutoCloseable {
+ private final ShutdownService impl;
+ private final ShutdownRuntimeRegistration registration;
+
+ public ShutdownServiceImpl(String secret, Bundle systemBundle,
+ ShutdownRuntimeRegistrator rootRuntimeBeanRegistratorWrapper) {
+ if (secret == null) {
+ throw new IllegalArgumentException("Secret cannot be null");
+ }
+ impl = new Impl(secret, systemBundle);
+ registration = rootRuntimeBeanRegistratorWrapper.register(new MXBeanImpl(impl));
+ }
+
+ @Override
+ public void shutdown(String inputSecret, Optional<String> reason) {
+ impl.shutdown(inputSecret, reason);
+ }
+
+ @Override
+ public void close() {
+ registration.close();
+ }
+}
+
+class Impl implements ShutdownService {
+ private static final Logger logger = LoggerFactory.getLogger(Impl.class);
+ private final String secret;
+ private final Bundle systemBundle;
+
+ Impl(String secret, Bundle systemBundle) {
+ this.secret = secret;
+ this.systemBundle = systemBundle;
+ }
+
+ @Override
+ public void shutdown(String inputSecret, Optional<String> reason) {
+ logger.warn("Shutdown issued with secret {} and reason {}", inputSecret, reason);
+ try {
+ Thread.sleep(1000); // prevent brute force attack
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ logger.warn("Shutdown process interrupted", e);
+ }
+ if (this.secret.equals(inputSecret)) {
+ logger.info("Server is shutting down");
+
+ Thread stopSystemBundle = new Thread() {
+ @Override
+ public void run() {
+ try {
+ // wait so that JMX response is received
+ Thread.sleep(1000);
+ systemBundle.stop();
+ } catch (BundleException e) {
+ logger.warn("Can not stop OSGi server", e);
+ } catch (InterruptedException e) {
+ logger.warn("Shutdown process interrupted", e);
+ }
+ }
+ };
+ stopSystemBundle.start();
+
+ } else {
+ logger.warn("Unauthorized attempt to shut down server");
+ throw new IllegalArgumentException("Invalid secret");
+ }
+ }
+
+}
+
+class MXBeanImpl implements ShutdownRuntimeMXBean {
+ private final ShutdownService impl;
+
+ MXBeanImpl(ShutdownService impl) {
+ this.impl = impl;
+ }
+
+ @Override
+ public void shutdown(String inputSecret, String nullableReason) {
+ Optional<String> optionalReason;
+ if (nullableReason == null) {
+ optionalReason = Optional.absent();
+ } else {
+ optionalReason = Optional.of(nullableReason);
+ }
+ impl.shutdown(inputSecret, optionalReason);
+ }
+}
--- /dev/null
+module shutdown-impl {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl";
+ prefix "shutdown-impl";
+
+ import shutdown { prefix shutdown; revision-date 2013-12-18; }
+ import config { prefix config; revision-date 2013-04-05; }
+ import rpc-context { prefix rpcx; revision-date 2013-06-17; }
+
+ organization "Cisco Systems, Inc.";
+
+ description
+ "This module contains the base YANG definitions for
+ shutdown implementation.
+
+ Copyright (c)2013 Cisco Systems, Inc. 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";
+
+ revision "2013-12-18" {
+ description
+ "Initial revision.";
+ }
+
+ identity shutdown {
+ base config:module-type;
+ config:provided-service shutdown:shutdown;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case shutdown {
+ when "/config:modules/config:module/config:type = 'shutdown'";
+ leaf secret {
+ type string;
+ default "";
+ }
+ leaf old-secret {
+ type string;
+ default "";
+ }
+ }
+ }
+
+ augment "/config:modules/config:module/config:state" {
+ case shutdown {
+ when "/config:modules/config:module/config:type = 'shutdown'";
+ rpcx:rpc-context-instance "shutdown-rpc";
+ }
+ }
+
+ identity shutdown-rpc;
+
+ rpc shutdown {
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance shutdown-rpc;
+ }
+ }
+ leaf input-secret {
+ type string;
+ }
+ leaf reason {
+ type string;
+ }
+ }
+ }
+}
--- /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.yang.shutdown.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.ValidationException.ExceptionMessageWithStackTrace;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.osgi.framework.Bundle;
+
+import javax.management.JMX;
+import javax.management.ObjectName;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME;
+
+public class ShutdownTest extends AbstractConfigTest {
+ private final ShutdownModuleFactory factory = new ShutdownModuleFactory();
+ @Mock
+ private Bundle mockedSysBundle;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ ModuleFactoriesResolver factoriesResolver = new HardcodedModuleFactoriesResolver(mockedContext, factory);
+ super.initConfigTransactionManagerImpl(factoriesResolver);
+ doReturn(mockedSysBundle).when(mockedContext).getBundle(0);
+ mockedContext.getBundle(0);
+ doNothing().when(mockedSysBundle).stop();
+ }
+
+ @Test
+ public void testSingleton_invalidName() throws Exception {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+ try {
+ transaction.createModule(NAME, "foo");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("Singleton enforcement failed. Expected instance name shutdown", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testWithoutSecret() throws Exception {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+ transaction.createModule(NAME, NAME);
+ transaction.commit();
+ // test JMX rpc
+ ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
+ ShutdownRuntimeMXBean runtime = configRegistryClient.newMXBeanProxy(runtimeON, ShutdownRuntimeMXBean.class);
+ try {
+ runtime.shutdown("foo", null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("Invalid secret", e.getMessage());
+ }
+ runtime.shutdown("", null);
+ assertStopped();
+ }
+
+
+ @Test
+ public void testWithSecret() throws Exception {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+ ObjectName on = transaction.createModule(NAME, NAME);
+ ShutdownModuleMXBean proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
+ String secret = "secret";
+ proxy.setSecret(secret);
+ transaction.commit();
+ shutdownViaRuntimeJMX(secret);
+
+ // test old secret
+ transaction = configRegistryClient.createTransaction();
+ on = transaction.lookupConfigBean(NAME, NAME);
+ proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
+ try {
+ rethrowCause(proxy).getOldSecret();
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+ try {
+ rethrowCause(proxy).getSecret();
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+ // set secret to nothing
+ String newSecret = "newSecret";
+ proxy.setSecret(newSecret);
+ try {
+ transaction.commit();
+ fail("Old secret not provided - should fail validation");
+ } catch (ValidationException e) {
+ Map<String, Map<String, ExceptionMessageWithStackTrace>> failedValidations = e.getFailedValidations();
+ assertTrue(failedValidations.containsKey(NAME));
+ ExceptionMessageWithStackTrace exceptionMessageWithStackTrace = failedValidations.get(NAME).get(NAME);
+ assertNotNull(exceptionMessageWithStackTrace);
+ assertEquals("OldSecret Invalid old secret", exceptionMessageWithStackTrace.getMessage());
+
+ }
+ proxy.setOldSecret(secret);
+ transaction.commit();
+ shutdownViaRuntimeJMX(newSecret);
+ }
+
+ private void shutdownViaRuntimeJMX(String secret) throws Exception {
+ // test JMX rpc
+ ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
+ ShutdownRuntimeMXBean runtime = JMX.newMXBeanProxy(platformMBeanServer, runtimeON, ShutdownRuntimeMXBean.class);
+ try {
+ runtime.shutdown("", null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("Invalid secret", e.getMessage());
+ }
+ runtime.shutdown(secret, null);
+ assertStopped();
+ }
+
+
+ private void assertStopped() throws Exception {
+ Thread.sleep(2000); // happens on another thread
+ verify(mockedSysBundle).stop();
+ verifyNoMoreInteractions(mockedSysBundle);
+ reset(mockedSysBundle);
+ doNothing().when(mockedSysBundle).stop();
+ }
+}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
/**
* Generated file
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.async;\r
\r
import static org.junit.Assert.assertThat;\r
+/*
+ * 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.threadpool.eventbus;
import static org.junit.Assert.assertEquals;
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.eventbus;\r
\r
import static org.mockito.Mockito.doNothing;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.fixed;\r
\r
import org.junit.Before;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.fixed;\r
\r
import static org.mockito.Mockito.doNothing;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.flexible;\r
\r
import org.junit.Before;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.naming;\r
\r
import static org.junit.Assert.assertEquals;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.naming;\r
\r
import static org.mockito.Matchers.any;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.scheduled;\r
\r
import org.junit.Before;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.scheduled;\r
\r
import com.google.common.util.concurrent.ListenableFutureTask;\r
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.StaticLoggerBinder;
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* This class interfaces with yang-maven-plugin. Gets parsed yang modules in
* {@link SchemaContext}, and parameters form the plugin configuration, and
@Override
public Collection<File> generateSources(SchemaContext context,
- File outputBaseDir, Set<Module> yangModulesInCurrentMavenModule) {
+ File outputBaseDir, Set<Module> yangModulesInCurrentMavenModule) {
Preconditions.checkArgument(context != null, "Null context received");
Preconditions.checkArgument(outputBaseDir != null,
outputBaseDir.mkdirs();
GeneratedFilesTracker generatedFiles = new GeneratedFilesTracker();
+ // create SIE structure qNamesToSIEs
Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
- // create SIE structure qNamesToSIEs
+
+ Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
for (Module module : context.getModules()) {
String packageName = packageTranslator.getPackageName(module);
Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
- .create(module, packageName);
+ .create(module, packageName, knownSEITracker);
for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
.entrySet()) {
-
// merge value into qNamesToSIEs
if (qNamesToSIEs.containsKey(sieEntry.getKey()) == false) {
qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue());
} else {
throw new IllegalStateException(
- "Cannot add two SIE with same qname "
- + sieEntry.getValue());
+ "Cannot add two SIE with same qname "
+ + sieEntry.getValue());
}
}
if (yangModulesInCurrentMavenModule.contains(module)) {
*/
package org.opendaylight.controller.config.yangjmxgenerator;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-
import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
import org.opendaylight.yangtools.yang.model.api.UsesNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
+import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
/**
* Represents part of yang model that describes a module.
for (RpcDefinition rpc : currentModule.getRpcs()) {
ContainerSchemaNode input = rpc.getInput();
- for (UsesNode uses : input.getUses()) {
-
- if (uses.getGroupingPath().getPath().size() != 1)
- continue;
-
- // check grouping path
- QName qname = uses.getGroupingPath().getPath().get(0);
- if (false == qname
- .equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME))
- continue;
-
- for (SchemaNode refinedNode : uses.getRefines().values()) {
-
- for (UnknownSchemaNode unknownSchemaNode : refinedNode
- .getUnknownSchemaNodes()) {
- if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME
- .equals(unknownSchemaNode.getNodeType())) {
- String localIdentityName = unknownSchemaNode
- .getNodeParameter();
- QName identityQName = new QName(
- currentModule.getNamespace(),
- currentModule.getRevision(),
- localIdentityName);
- Set<RpcDefinition> rpcDefinitions = result
- .get(identityQName);
- if (rpcDefinitions == null) {
- throw new IllegalArgumentException(
- "Identity referenced by rpc not found. Identity:"
- + localIdentityName + " , rpc "
- + rpc);
+ if (input != null) {
+ for (UsesNode uses : input.getUses()) {
+
+ if (uses.getGroupingPath().getPath().size() != 1)
+ continue;
+
+ // check grouping path
+ QName qname = uses.getGroupingPath().getPath().get(0);
+ if (false == qname
+ .equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME))
+ continue;
+
+ for (SchemaNode refinedNode : uses.getRefines().values()) {
+
+ for (UnknownSchemaNode unknownSchemaNode : refinedNode
+ .getUnknownSchemaNodes()) {
+ if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME
+ .equals(unknownSchemaNode.getNodeType())) {
+ String localIdentityName = unknownSchemaNode
+ .getNodeParameter();
+ QName identityQName = new QName(
+ currentModule.getNamespace(),
+ currentModule.getRevision(),
+ localIdentityName);
+ Set<RpcDefinition> rpcDefinitions = result
+ .get(identityQName);
+ if (rpcDefinitions == null) {
+ throw new IllegalArgumentException(
+ "Identity referenced by rpc not found. Identity:"
+ + localIdentityName + " , rpc "
+ + rpc);
+ }
+ rpcDefinitions.add(rpc);
}
- rpcDefinitions.add(rpc);
}
}
-
}
}
}
*/
package org.opendaylight.controller.config.yangjmxgenerator;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.String.format;
-import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.SERVICE_TYPE_Q_NAME;
-
+import com.google.common.base.Optional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.SERVICE_TYPE_Q_NAME;
/**
* Represents identity derived from {@link ConfigConstants#SERVICE_TYPE_Q_NAME}.
* values
*/
public static Map<QName, ServiceInterfaceEntry> create(Module currentModule,
- String packageName) {
+ String packageName,Map<IdentitySchemaNode, ServiceInterfaceEntry> definedSEItracker) {
logger.debug("Generating ServiceInterfaces from {} to package {}",
currentModule.getNamespace(), packageName);
// this is a base type
created = new ServiceInterfaceEntry(identity, packageName, ModuleUtil.getQName(currentModule));
} else {
- ServiceInterfaceEntry foundBase = identitiesToSIs
+ ServiceInterfaceEntry foundBase = definedSEItracker
.get(identity.getBaseIdentity());
// derived type, did we convert the parent?
if (foundBase != null) {
Optional.of(foundBase), identity, packageName, ModuleUtil.getQName(currentModule));
}
}
+
+
if (created != null) {
created.setYangModuleName(currentModule.getName());
// TODO how to get local name
created.setYangModuleLocalname(identity.getQName()
.getLocalName());
identitiesToSIs.put(identity, created);
+ definedSEItracker.put(identity, created);
iterator.remove();
}
}
+/*
+ * 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.attribute;
import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
package org.opendaylight.controller.config.yangjmxgenerator;
import com.google.common.collect.Sets;
+import java.util.HashMap;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
import javax.management.openmbean.ArrayType;
@Before
public void setUp() {
+ Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
modulesToSIEs = ServiceInterfaceEntry.create(threadsModule,
- "packages.sis");
+ "packages.sis",identitiesToSIs);
}
@Test
public void test_jmxImplModule() {
+ Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
Map<QName, ServiceInterfaceEntry> modulesToSIEs = ServiceInterfaceEntry
- .create(threadsModule, PACKAGE_NAME);
+ .create(threadsModule, PACKAGE_NAME,identitiesToSIs);
modulesToSIEs.putAll(ServiceInterfaceEntry.create(jmxModule,
- PACKAGE_NAME));
+ PACKAGE_NAME,identitiesToSIs));
Map<String /* identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
.create(jmxImplModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl(context))
, PACKAGE_NAME);
*/
package org.opendaylight.controller.config.yangjmxgenerator;
+import java.util.HashMap;
import org.junit.Test;
import org.mockito.Mockito;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
public static final String SLEEP_RPC_OUTPUT = "ThreadState";
public static final String SLEEP_RPC_INPUT_NAME = "millis";
public static final String SLEEP_RPC_INPUT_TYPE = "Long";
+ private static final Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
@Test
public void createRuntimeBean() {
public void runtimeBeanRPCTest() {
// create service interfaces
Map<QName, ServiceInterfaceEntry> modulesToSIEs = ServiceInterfaceEntry
- .create(threadsModule, "packages.sis");
+ .create(threadsModule, "packages.sis",identitiesToSIs);
assertNotNull(modulesToSIEs);
// create MXBeans map
*/
package org.opendaylight.controller.config.yangjmxgenerator;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-
+import com.google.common.collect.Sets;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-
import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.QName;
-
-import com.google.common.collect.Sets;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
public class ServiceInterfaceEntryTest extends AbstractYangTest {
public static final String PACKAGE_NAME = "packages.sis";
private static final URI THREADS_NAMESPACE;
private static final Date THREADS_REVISION_DATE;
+
static {
try {
THREADS_NAMESPACE = new URI(ConfigConstants.CONFIG_NAMESPACE
@Test
public void testCreateFromIdentities() {
// each identity has to have a base that leads to service-type
+ Map<IdentitySchemaNode, ServiceInterfaceEntry> definedIdentities = new HashMap<>();
Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
- .create(threadsModule, PACKAGE_NAME);
+ .create(threadsModule, PACKAGE_NAME,definedIdentities);
// expected eventbus, threadfactory, threadpool,
// scheduled-threadpool,thread-rpc-context
assertThat(namesToSIEntries.size(), is(expectedSIEFileNames.size()));
yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size());
return yangStoreSnapshot;
} catch (RuntimeException e) {
- throw new YangStoreException("Unable to parse yang files from following URLs: " + multimap, e);
+ StringBuffer causeStr = new StringBuffer();
+ Throwable cause = e;
+ while (cause != null) {
+ causeStr.append(e.getMessage());
+ causeStr.append("\n");
+ cause = e.getCause();
+ }
+ throw new YangStoreException("Unable to parse yang files. \n" + causeStr.toString() +
+ "URLs: " + multimap, e);
}
}
import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
+ Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
// create SIE structure qNamesToSIEs
for (Module module : resolveSchemaContext.getModules()) {
String packageName = packageTranslator.getPackageName(module);
Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
- .create(module, packageName);
+ .create(module, packageName,knownSEITracker);
for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
.entrySet()) {
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import javax.management.InstanceAlreadyExistsException;
import javax.management.ObjectName;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
public class NetconfTestImplModuleTest extends AbstractConfigTest {
public static final String TESTING_DEP_PREFIX = "testing-dep";
}
@Test
- public void testDependencyList() throws InstanceAlreadyExistsException, ValidationException,
- ConflictingVersionException {
+ public void testDependencyList() throws Exception {
ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
ObjectName on = createInstance(transaction, instanceName, 4);
transaction.validateConfig();
- CommitStatus status = transaction.commit();
+ CommitStatus status1 = transaction.commit();
assertBeanCount(1, factory.getImplementationName());
assertBeanCount(4 + 1, DepTestImplModuleFactory.NAME);
- assertStatus(status, 1 + 4 + 1, 0, 0);
+ assertStatus(status1, 1 + 4 + 1, 0, 0);
transaction = configRegistryClient.createTransaction();
assertTestingDeps(testingDeps, 4);
transaction.abortConfig();
+
+ // check that reuse logic works - equals on list of dependencies.
+ transaction = configRegistryClient.createTransaction();
+ CommitStatus status2 = transaction.commit();
+ assertStatus(status2, 0, 0, 6);
+
+ // replace single dependency
+ transaction = configRegistryClient.createTransaction();
+ String instanceName1 = TESTING_DEP_PREFIX + 1;
+ transaction.destroyModule(DepTestImplModuleFactory.NAME, instanceName1);
+ transaction.createModule(DepTestImplModuleFactory.NAME, instanceName1);
+ CommitStatus status3 = transaction.commit();
+ assertStatus(status3, 1, 1, 4);
+
+ }
+
+ @Test
+ public void testNullCheckInListOfDependencies() throws Exception {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+
+ ObjectName on = createInstance(transaction, instanceName, 4);
+ NetconfTestImplModuleMXBean proxy = transaction.newMXBeanProxy(on, NetconfTestImplModuleMXBean.class);
+ try{
+ proxy.setTestingDeps(null);
+ fail();
+ }catch(RuntimeException e) {
+ Throwable cause = e.getCause();
+ assertNotNull(cause);
+ assertTrue("Invalid type " + cause, cause instanceof IllegalArgumentException);
+ assertEquals("Null not supported", cause.getMessage());
+ }
+ proxy.setTestingDeps(Collections.<ObjectName>emptyList());
}
private void assertTestingDeps(List<ObjectName> testingDeps, int i) {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
public Status addNode (Node node, InetAddress controller) {
if (node == null || controller == null) {
+ if (node == null) {
+ log.warn("addNode: node is null");
+ } else if (controller == null) {
+ log.error("Failed to add node {}. The controller address retrieved from clusterServices is null.", node);
+ }
return new Status(StatusCode.BADREQUEST);
}
if (isLocal(node)) {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
}
/**
- * Match Source IP Address.
+ * Match the set of these vlans with that of flowSpec's vlans.
*
- * @param flowSpec Flow Specification
+ * @param flowSpec
+ * Flow Specification
* @return true, if successful
*/
private boolean matchDlVlan(ContainerFlowConfig flowSpec) {
if (dlVlan == null || flowSpec.dlVlan == null) {
return false;
}
- return dlVlan.equals(flowSpec.dlVlan);
+
+ return this.getVlanList().equals(flowSpec.getVlanList());
}
/**
}
/**
- * Returns the vlan id number
+ * Returns the vlan id number for all vlans specified
*
- * @return the vlan id number
+ * @return the vlan id number for all vlans specified
*/
- public Short getVlanId() {
- Short vlan = 0;
+ public Set<Short> getVlanList() {
+ /*
+ * example: Vlan = "1,3,5-12"
+ * elemArray = ["1" "3" "5-12"]
+ * elem[2] = "5-12" --> limits = ["5" "12"]
+ * vlanList = [1 3 5 6 7 8 9 10 11 12]
+ */
+ Set<Short> vlanList = new HashSet<Short>();
try {
- vlan = Short.parseShort(dlVlan);
+ String[] elemArray = dlVlan.split(",");
+ for (String elem : elemArray) {
+ if (elem.contains("-")) {
+ String[] limits = elem.split("-");
+ for (short j = Short.valueOf(limits[0]); j <= Short.valueOf(limits[1]); j++) {
+ vlanList.add(Short.valueOf(j));
+ }
+ } else {
+ vlanList.add(Short.valueOf(elem));
+ }
+ }
} catch (NumberFormatException e) {
}
- return vlan;
+ return vlanList;
}
/**
if (dlVlan != null) {
short vlanId = 0;
try {
- vlanId = Short.parseShort(dlVlan);
+ String[] elemArray = dlVlan.split(",");
+ for (String elem : elemArray) {
+ if (elem.contains("-")) {
+ String[] limits = elem.split("-");
+ if (Short.parseShort(limits[0]) < 0
+ || Short.parseShort(limits[0]) >= Short.parseShort(limits[1])
+ || Short.parseShort(limits[1]) > 0xfff) {
+ return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+ }
+ } else {
+ vlanId = Short.parseShort(elem);
+ if (vlanId < 0 || vlanId > 0xfff) {
+ return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+ }
+ }
+ }
} catch (NumberFormatException e) {
return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
}
- if (vlanId < 0 || vlanId > 0xfff) {
- return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
- }
}
return new Status(StatusCode.SUCCESS);
}
/**
* Returns the matches.
- * If unidirectional flag is set, there will be only one match in the list
- * If unidirectional flag is unset there will be two matches in the list,
+ * If unidirectional flag is set, there will be only one match per vlan in the list
+ * If unidirectional flag is unset there will be two matches per vlan in the list,
* only if the specified flow has an intrinsic direction.
* For Ex. if the cFlow only has the protocol field configured, no matter
- * if unidirectional flag is set or not, only one match will be returned
+ * if unidirectional flag is set or not, only one match per vlan will be returned
* The client just has to iterate over the returned list
* @return the matches
*/
public List<Match> getMatches() {
List<Match> matches = new ArrayList<Match>();
- Match match = new Match();
if (this.dlVlan != null && !this.dlVlan.isEmpty()) {
- match.setField(MatchType.DL_VLAN, this.getVlanId());
+ for(Short vlan:getVlanList()){
+ Match match = getMatch(vlan);
+ matches.add(match);
+ }
+ }
+ else{
+ Match match = getMatch(null);
+ matches.add(match);
+ }
+
+ if (!ContainerFlowConfig.unidirectional) {
+ List<Match> forwardMatches = new ArrayList<Match>(matches);
+ for (Match match : forwardMatches) {
+ Match reverse = match.reverse();
+ if (!match.equals(reverse)) {
+ matches.add(reverse);
+ }
+ }
+ }
+
+ return matches;
+ }
+
+ private Match getMatch(Short vlan){
+ Match match = new Match();
+
+ if (vlan != null) {
+ match.setField(MatchType.DL_VLAN, vlan);
}
if (this.nwSrc != null && !this.nwSrc.trim().isEmpty()) {
String parts[] = this.nwSrc.split("/");
if (this.tpDst != null && !this.tpDst.trim().isEmpty()) {
match.setField(MatchType.TP_DST, Integer.valueOf(tpDst).shortValue());
}
-
- matches.add(match);
- if(!ContainerFlowConfig.unidirectional) {
- Match reverse = match.reverse();
- if (!match.equals(reverse)) {
- matches.add(reverse);
- }
- }
- return matches;
+ return match;
}
/*
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
+++ /dev/null
-
-#24
-<rpc message-id="101" xm
-#28
-lns="urn:ietf:params:xml:ns:
-#2
-ne
-#33
-tconf:base:1.0">
- <my-own-method
-#3
- xm
-#13
-lns="http://e
-#34
-xample.net/me/my-own/1.0">
- <my
-#8
--first-p
-#21
-arameter>14</my-first
-#26
--parameter>
- <another-p
-#23
-arameter>fred</another-
-#31
-parameter>
- </my-own-method>
- <
-#2
-/r
-#3
-pc>
-##
+++ /dev/null
-
-#22
-<rpc message-id="101"
-#24
-xmlns="urn:ietf:params:x
-#15
-ml:ns:netconf:b
-#54
-ase:1.0">
- <get-config>
- <source>
- <r
-#2
-un
-#9
-ning/>
-
-#18
- </source> <fi
-#33
-lter type="subtree">
- <top x
-#4
-mlns
-#31
-="http://example.com/schema/1.2
-#15
-/config">
-
-#19
- <users>
-
-#8
- <us
-#3
-er/
-#5
->
-
-#77
- </users>
- </top>
- </filter>
- </g
-#17
-et-config>
-</rpc>
-##
+++ /dev/null
-
-#43
-<rpc message-id="101" xmlns="urn:ietf:param
-#14
-s:xml:ns:netco
-#14
-nf:base:1.0">
-
-#26
-<get-config>
- <source>
-
-#35
- <running/>
- </source>
-
-#39
- <filter type="subtree">
- <
-#40
-top xmlns="http://example.com/schema/1.2
-#26
-/config">
- <users>
-
-#36
- <user>
- <name>f
-#56
-red</name>
- </user>
- </users>
-
-#28
- </top>
- </fil
-#1
-t
-#28
-er>
- </get-config>
- </rpc>
-##
+++ /dev/null
-
-#17
-<rpc message-id="
-#25
-101" xmlns="urn:ietf:para
-#19
-ms:xml:ns:netconf:b
-#3
-ase
-#19
-:1.0">
- <get-confi
-#61
-g>
- <source>
- <running/>
- </source>
-
-#43
- <filter type="subtree">
- <!-- requ
-#13
-est a text ve
-#22
-rsion of the configura
-#9
-tion -->
-
-#16
- <config-text
-#45
-xmlns="http://example.com/text/1.2/config"/>
-
-#22
- </filter>
- </
-#18
-get-config>
-</rpc>
-##
+++ /dev/null
-
-#43
-<rpc message-id="101" xmlns="urn:ietf:param
-#41
-s:xml:ns:netconf:base:1.0">
- <edit-confi
-#29
-g>
- <target>
- <ru
-#13
-nning/>
- <
-#4
-/tar
-#18
-get>
- <config>
-
-#41
- <top xmlns="http://example.com/schema/1
-#32
-.2/config">
- <interface>
-
-#29
- <name>Ethernet0/0</na
-#30
-me>
- <mtu>1500</mtu>
-
-#61
-</interface>
- </top>
- </config>
- </e
-#9
-dit-confi
-#9
-g>
-</rpc>
-##
+++ /dev/null
-curl http://localhost:17777/jolokia/read/org.opendaylight.controller:instanceName=fixed1,type=ConfigBean,interfaceName=testing-threadpool | jsonpp
-{
- "request": {
- "mbean": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean",
- "type": "read"
- },
- "status": 200,
- "timestamp": 1362416252,
- "value": {
- "ExportedInterfaces": [
- "testing-threadpool",
- "modifiable-threadpool"
- ],
- "ImplementationName": "fixed",
- "ThreadCount": 10,
- "TriggerNewInstanceCreation": false
- }
-}
\ No newline at end of file
+++ /dev/null
-$ curl 'http://localhost:17777/jolokia/exec/org.opendaylight.controller:type=ConfigRegistry/lookupConfigBeans()' | jsonpp
-{
- "request": {
- "mbean": "org.opendaylight.controller:type=ConfigRegistry",
- "operation": "lookupConfigBeans()",
- "type": "exec"
- },
- "status": 200,
- "timestamp": 1362417043,
- "value": [
- {
- "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=modifiable-threadpool,type=ConfigBean"
- },
- {
- "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean"
- }
- ]
-}
+++ /dev/null
-<rpc message-id="104"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <commit/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="102"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <lock>
- <target>
- <candidate/>
- </target>
- </lock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="101"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <lock>
- <target>
- <running/>
- </target>
- </lock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="103"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <default-operation>none</default-operation>
- <test-option>test-then-set</test-option>
- <error-option>stop-on-error</error-option>
- <nc:config
- xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- xmlns="uri-for-my-data-model-namespace">
- <some-existing-node>
- <my-new-node nc:operation="create">
- <my-new-leaf>7</my-new-leaf>
- </my-new-node>
- </some-existing-node>
- </nc:config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="105"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unlock>
- <target>
- <candidate/>
- </target>
- </unlock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="106"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unlock>
- <target>
- <running/>
- </target>
- </unlock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <rpc-error>
- <error-type>rpc</error-type>
- <error-tag>missing-attribute</error-tag>
- <error-severity>error</error-severity>
- <error-info>
- <bad-attribute>message-id</bad-attribute>
- <bad-element>rpc</bad-element>
- </error-info>
- </rpc-error>
-</rpc-reply>
<unit id="org.eclipse.virgo.kernel.equinox.extensions" version="3.6.0.RELEASE"/>
<unit id="org.eclipse.osgi.services" version="3.3.100.v20120522-1822"/>
<unit id="org.eclipse.virgo.util.common" version="3.6.0.RELEASE"/>
-<unit id="com.sun.jersey.json" version="1.17.0"/>
<unit id="org.eclipse.equinox.util" version="1.0.400.v20120522-2049"/>
<unit id="org.springframework.core" version="3.1.3.RELEASE"/>
<unit id="org.apache.commons.fileupload" version="1.2.2"/>
<artifactId>forwardingrules-manager</artifactId>
<version>${mdsal.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.md</groupId>
+ <artifactId>topology-lldp-discovery</artifactId>
+ <version>${mdsal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.md</groupId>
+ <artifactId>topology-manager</artifactId>
+ <version>${mdsal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-topology</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-topology</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller.md</groupId>
<artifactId>statistics-manager</artifactId>
<artifactId>config-persister-directory-xml-adapter</artifactId>
<version>${config.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-persister-directory-autodetect-adapter</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>shutdown-api</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>shutdown-impl</artifactId>
+ <version>${config.version}</version>
+ </dependency>
<!-- Netconf -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-jaxrs</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-xc</artifactId>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-base</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-jaxb-annotations</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-json</artifactId>
- <version>${jersey.version}</version>
- </dependency>
+
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-all</artifactId>
<exclude>ch.qos.logback:logback-core</exclude>
<exclude>ch.qos.logback:logback-classic</exclude>
<exclude>com.sun.jersey:jersey-core</exclude>
- <exclude>com.sun.jersey:jersey-json</exclude>
<exclude>com.sun.jersey:jersey-server</exclude>
<exclude>org.opendaylight.controller:logging.bridge</exclude>
<exclude>org.opendaylight.controller:sanitytest</exclude>
<include>ch.qos.logback:logback-core</include>
<include>ch.qos.logback:logback-classic</include>
<include>com.sun.jersey:jersey-core</include>
- <include>com.sun.jersey:jersey-json</include>
<include>com.sun.jersey:jersey-server</include>
<include>org.opendaylight.controller:logging.bridge</include>
</includes>
reference\:file\:../lib/logback-core-1.0.9.jar@1:start,\
reference\:file\:../lib/logging.bridge-0.4.1-SNAPSHOT@1:start,\
reference\:file\:../lib/jersey-core-1.17.jar@2:start,\
- reference\:file\:../lib/jersey-json-1.17.jar@2:start,\
reference\:file\:../lib/jersey-server-1.17.jar@2:start
# Netconf startup configuration
netconf.ssh.address=0.0.0.0
netconf.ssh.port=1830
+netconf.ssh.pk.path = ./configuration/RSA.pk
+
netconf.config.persister.active=1,2
# read startup configuration
-netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.DirectoryStorageAdapter
+#netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.DirectoryStorageAdapter
+#netconf.config.persister.1.properties.directoryStorage=configuration/initial/
+#netconf.config.persister.1.readonly=true
+
+netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.autodetect.AutodetectDirectoryStorageAdapter
netconf.config.persister.1.properties.directoryStorage=configuration/initial/
netconf.config.persister.1.readonly=true
netconf.config.persister.2.properties.fileStorage=configuration/current/controller.currentconfig.xml
netconf.config.persister.2.properties.numberOfBackups=1
-
yangstore.blacklist=.*controller.model.*
# Set Default start level for framework
+++ /dev/null
-//MODULES START
- <module>
- <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
- <name>global-boss-group</name>
- </module>
- <module>
- <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
- <name>global-worker-group</name>
- </module>
- <module>
- <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">netty:netty-hashed-wheel-timer</type>
- <name>global-timer</name>
- </module>
- <module>
- <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">netty:netty-global-event-executor</type>
- <name>global-event-executor</name>
- </module>
-//SERVICES START
- <service>
- <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
- <instance>
- <name>global-boss-group</name>
- <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
- </instance>
- <instance>
- <name>global-worker-group</name>
- <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
- <instance>
- <name>global-event-executor</name>
- <provider>/modules/module[type='netty-global-event-executor'][name='global-event-executor']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
- <instance>
- <name>global-timer</name>
- <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
- </instance>
- </service>
-//CAPABILITIES START
-urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&revision=2013-11-19
-urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
-urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&revision=2013-11-07
-urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&revision=2013-11-19
--- /dev/null
+<snapshot>
+ <required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&revision=2013-11-19</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&revision=2013-11-07</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&revision=2013-11-19</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>
+ <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
+ <name>global-boss-group</name>
+ </module>
+ <module>
+ <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
+ <name>global-worker-group</name>
+ </module>
+ <module>
+ <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">netty:netty-hashed-wheel-timer</type>
+ <name>global-timer</name>
+ </module>
+ <module>
+ <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">netty:netty-global-event-executor</type>
+ <name>global-event-executor</name>
+ </module>
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
+ <instance>
+ <name>global-boss-group</name>
+ <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
+ </instance>
+ <instance>
+ <name>global-worker-group</name>
+ <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
+ <instance>
+ <name>global-event-executor</name>
+ <provider>/modules/module[type='netty-global-event-executor'][name='global-event-executor']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
+ <instance>
+ <name>global-timer</name>
+ <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
+ </instance>
+ </service>
+ </services>
+ </data>
+
+ </configuration>
+</snapshot>
+++ /dev/null
-//MODULES START
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
- <name>yang-schema-service</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
- <name>hash-map-data-store</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store">prefix:dom-clustered-store-impl</type>
- <name>cluster-data-store</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
- <name>dom-broker</name>
- <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
- <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
- <name>hash-map-data-store</name>
- <!-- <name>cluster-data-store</name> -->
- </data-store>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
- <name>binding-broker-impl</name>
- <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
- <name>binding-notification-broker</name>
- </notification-service>
- <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <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>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
- <name>runtime-mapping-singleton</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
- <name>binding-notification-broker</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
- <name>binding-data-broker</name>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-broker>
- <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
- <name>runtime-mapping-singleton</name>
- </mapping-service>
- </module>
-//SERVICES START
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
- <instance>
- <name>yang-schema-service</name>
- <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
- <instance>
- <name>binding-notification-broker</name>
- <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
- <instance>
- <name>hash-map-data-store</name>
- <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
- </instance>
- <instance>
- <name>cluster-data-store</name>
- <provider>/modules/module[type='dom-clustered-store-impl'][name='cluster-data-store']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
- <instance>
- <name>binding-osgi-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
- <instance>
- <name>binding-rpc-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
- <instance>
- <name>runtime-mapping-singleton</name>
- <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
- <instance>
- <name>dom-broker</name>
- <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
- <instance>
- <name>binding-data-broker</name>
- <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
- </instance>
- </service>
-//CAPABILITIES START
-urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&revision=2013-04-09
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
-urn:ietf:params:netconf:capability:candidate:1.0
-urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
-urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
-urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
-urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
-urn:ietf:params:netconf:capability:rollback-on-error:1.0
-urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
-urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
-urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
-urn:opendaylight:params:xml:ns:yang:iana?module=iana&revision=2013-08-16
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&revision=2013-08-19
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28
--- /dev/null
+<snapshot>
+
+ <configuration>
+
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
+ <name>yang-schema-service</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
+ <name>hash-map-data-store</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store">prefix:dom-clustered-store-impl</type>
+ <name>cluster-data-store</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+ <name>dom-broker</name>
+ <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+ <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
+ <name>hash-map-data-store</name>
+ <!-- <name>cluster-data-store</name> -->
+ </data-store>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
+ <name>binding-broker-impl</name>
+ <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+ <name>binding-notification-broker</name>
+ </notification-service>
+ <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <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>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+ <name>runtime-mapping-singleton</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+ <name>binding-notification-broker</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
+ <name>binding-data-broker</name>
+ <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+ <name>dom-broker</name>
+ </dom-broker>
+ <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+ <name>runtime-mapping-singleton</name>
+ </mapping-service>
+ </module>
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <instance>
+ <name>yang-schema-service</name>
+ <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+ <instance>
+ <name>binding-notification-broker</name>
+ <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+ <instance>
+ <name>hash-map-data-store</name>
+ <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
+ </instance>
+ <instance>
+ <name>cluster-data-store</name>
+ <provider>/modules/module[type='dom-clustered-store-impl'][name='cluster-data-store']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+ <instance>
+ <name>binding-osgi-broker</name>
+ <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <instance>
+ <name>binding-rpc-broker</name>
+ <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+ <instance>
+ <name>runtime-mapping-singleton</name>
+ <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+ <instance>
+ <name>dom-broker</name>
+ <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+ <instance>
+ <name>binding-data-broker</name>
+ <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
+ </instance>
+ </service>
+
+ </services>
+ </data>
+
+ </configuration>
+
+ <required-capabilities>
+ <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>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&revision=2013-04-09</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:config?module=config&revision=2013-04-05</capability>
+ <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+ <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12</capability>
+ <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17</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:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24</capability>
+ <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
+ <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05</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:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:iana?module=iana&revision=2013-08-16</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&revision=2013-08-19</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28</capability>
+ </required-capabilities>
+</snapshot>
+
<logger name="org.opendaylight.controller" level="INFO"/>
<!-- OSGi logging bridge -->
- <logger name="org.opendaylight.controller.logging.bridge" level="WARN"/>
+ <logger name="org.opendaylight.controller.logging.bridge" level="INFO"/>
+ <logger name="org.opendaylight.controller.logging.bridge.internal" level="WARN"/>
<!-- Netty -->
<logger name="io.netty" level="WARN"/>
CLASSPATH=${CLASSPATH}:${basedir}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar
FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar
+cd $basedir
+
if [ "${stopdaemon}" -eq 1 ]; then
if [ -e "${pidfile}" ]; then
daemonpid=`cat "${pidfile}"`
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
package org.opendaylight.controller.forwardingrulesmanager;
-import java.io.Serializable;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
import org.opendaylight.controller.sal.action.Action;
import org.opendaylight.controller.sal.action.ActionType;
import org.opendaylight.controller.sal.action.Controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
/**
* Configuration Java Object which represents a flow configuration information
* for Forwarding Rules Manager.
}
Flow flow = new Flow(match, getActionList());
+
if (this.cookie != null) {
flow.setId(Long.parseLong(cookie));
}
if (this.priority != null) {
flow.setPriority(Integer.decode(this.priority).shortValue());
}
+
+
return flow;
}
}
if (flow == null) {
- return (other.flow == null) ? true : false;
+ return other.flow == null;
} else if (other.flow == null) {
return false;
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
}
}
+ /**
+ * Function called by the dependency manager before Container is Stopped and Destroyed.
+ */
+ public void containerStop() {
+ uninstallAllFlowEntries(false);
+ }
+
/**
* Function called by the dependency manager before the services exported by
* the component are unregistered, this will be followed by a "destroy ()"
*/
void stop() {
stopping = true;
- uninstallAllFlowEntries(false);
// Shutdown executor
this.executor.shutdownNow();
// Now walk all the workMonitor and wake up the one sleeping because
// staticFlowEntry should never be null.
// the null check is just an extra defensive check.
if(staticFlowEntry != null) {
- staticFlows.remove(staticFlowEntry.getKey());
+ // Modify status and update cluster cache
+ log.debug("Updating static flow configuration on async error event");
+ String status = String.format("Cannot be installed on node. reason: %s", errorString);
+ staticFlowEntry.getValue().setStatus(status);
+ refreshClusterStaticFlowsStatus(node);
}
}
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
\r
HostTracker hostTracker = null;\r
hostTracker = new HostTracker();\r
- Assert.assertFalse(hostTracker == null);\r
\r
InetAddress hostIP = InetAddress.getByName("192.168.0.8");\r
IHostId id = IPHostId.fromIP(hostIP);\r
public void testHostTracker() throws UnknownHostException {\r
HostTracker hostTracker = null;\r
hostTracker = new HostTracker();\r
- Assert.assertFalse(hostTracker == null);\r
\r
InetAddress hostIP_1 = InetAddress.getByName("192.168.0.8");\r
IHostId id1 = IPHostId.fromIP(hostIP_1);\r
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
* 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.logging.bridge.internal;
import org.osgi.service.log.LogEntry;
+
+import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Enumeration;
+
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleActivator;
import org.osgi.service.log.LogReaderService;
public class Activator implements BundleActivator {
+ private static final String UNCAUGHT_EXCEPTION_POLICY_PROP = "controller.uncaughtExceptionPolicy";
+ private static final UncaughtExceptionPolicy DEFAULT_UNCAUGHT_EXCEPTION_POLICY = UncaughtExceptionPolicy.IGNORE;
+
private LogListenerImpl listener = null;
+ private ShutdownHandler shutdownHandler = null;
private Logger log = null;
@Override
* handler will display the exceptions to OSGI console as well
* as log to file.
*/
- Thread.setDefaultUncaughtExceptionHandler(new org.opendaylight.
- controller.logging.bridge.internal.UncaughtExceptionHandler());
+ UncaughtExceptionHandler handler = DEFAULT_UNCAUGHT_EXCEPTION_POLICY;
+ final String policy = context.getProperty(UNCAUGHT_EXCEPTION_POLICY_PROP);
+ if (policy != null) {
+ try {
+ handler = UncaughtExceptionPolicy.valueOf(policy.toUpperCase());
+ } catch (IllegalArgumentException ex) {
+ log.warn("Invalid policy name \"{}\", defaulting to {}", policy, handler);
+ }
+ }
+ log.info("Setting uncaught exception policy to {}", handler);
+ Thread.setDefaultUncaughtExceptionHandler(handler);
/*
* Install the Shutdown handler. This will intercept SIGTERM signal and
* close the system bundle. This allows for a graceful closing of OSGI
* framework.
*/
-
- Runtime.getRuntime().addShutdownHook(new shutdownHandler(context));
+ shutdownHandler = new ShutdownHandler(context);
+ Runtime.getRuntime().addShutdownHook(shutdownHandler);
} else {
this.log.error("Cannot register the LogListener because "
+ "cannot retrieve LogReaderService");
LogReaderService reader = (LogReaderService) service;
reader.removeLogListener(this.listener);
}
-
+ if (this.shutdownHandler != null) {
+ Runtime.getRuntime().removeShutdownHook(this.shutdownHandler);
+ }
this.listener = null;
this.log = null;
+ this.shutdownHandler = null;
}
- private class shutdownHandler extends Thread {
+ private class ShutdownHandler extends Thread {
BundleContext bundlecontext;
- public shutdownHandler(BundleContext ctxt) {
+ public ShutdownHandler(BundleContext ctxt) {
this.bundlecontext = ctxt;
}
+++ /dev/null
-package org.opendaylight.controller.logging.bridge.internal;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
- private static Logger log = LoggerFactory.getLogger(UncaughtExceptionHandler.class);
-
- public void uncaughtException (Thread t, Throwable e) {
- log.error("Uncaught ExceptionHandler:", e);
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.logging.bridge.internal;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+enum UncaughtExceptionPolicy implements Thread.UncaughtExceptionHandler {
+ ABORT {
+ public static final int EXIT_CODE = 1;
+
+ @Override
+ public void uncaughtException(final Thread t, final Throwable e) {
+ log.error("Thread {} died because of an uncaught exception, forcing virtual machine shutdown", t, e);
+ System.exit(EXIT_CODE);
+ }
+ },
+ IGNORE {
+ @Override
+ public void uncaughtException(final Thread t, final Throwable e) {
+ log.error("Thread {} died because of an uncaught exception", t, e);
+ }
+ };
+
+ private static final Logger log = LoggerFactory.getLogger(UncaughtExceptionPolicy.class);
+}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.6.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
val ret = new HashSet<NodeConnector>();
for (nc : data.nodeConnector) {
val flowConn = nc.getAugmentation(FlowCapableNodeConnector);
- if (flowConn != null && flowConn.state == PortState.Live) {
+ if (flowConn != null && flowConn.state != null && !flowConn.state.linkDown) {
ret.add(new NodeConnector(MD_SAL_TYPE, nc.key, node));
}
}
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
+ override getConfiguredNotConnectedSwitches() {
+ return null;
}
+}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-statistics</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-topology</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.services</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ </dependency>
</dependencies>
<packaging>bundle</packaging>
package org.opendaylight.controller.sal.compatibility
-import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
-import org.opendaylight.controller.sal.core.Node
-import org.opendaylight.controller.sal.core.NodeConnector
-import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
-import org.apache.felix.dm.Component
import java.util.Arrays
-import org.opendaylight.yangtools.yang.binding.NotificationListener
import java.util.Dictionary
import java.util.Hashtable
-import org.opendaylight.controller.sal.utils.GlobalConstants
+import org.apache.felix.dm.Component
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
-import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
-import org.opendaylight.controller.sal.reader.IPluginInReadService
-import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
import org.opendaylight.controller.sal.binding.api.NotificationService
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.compatibility.topology.TopologyAdapter
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
+import org.opendaylight.controller.sal.core.Node
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
+import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService
-import org.osgi.framework.BundleContext
+import org.opendaylight.controller.sal.reader.IPluginInReadService
import org.opendaylight.controller.sal.reader.IPluginOutReadService
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
-import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService
import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.utils.GlobalConstants
+import org.opendaylight.controller.sal.utils.INodeConnectorFactory
+import org.opendaylight.controller.sal.utils.INodeFactory
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices
+import org.opendaylight.controller.sal.packet.IPluginInDataPacketService
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
+import org.osgi.framework.BundleContext
-class ComponentActivator extends ComponentActivatorAbstractBase implements BindingAwareConsumer {
+import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider
+import org.opendaylight.controller.sal.compatibility.adsal.DataPacketServiceAdapter
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+
+class ComponentActivator extends ComponentActivatorAbstractBase {
private BundleContext context;
DataPacketAdapter dataPacket = new DataPacketAdapter;
@Property
- org.opendaylight.controller.sal.utils.INodeFactory nodeFactory = new MDSalNodeFactory
+ INodeFactory nodeFactory = new MDSalNodeFactory
+
+ @Property
+ INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory
+
+ @Property
+ TopologyAdapter topology = new TopologyAdapter
+
+ @Property
+ TopologyProvider tpProvider = new TopologyProvider()
+
+ @Property
+ DataPacketServiceAdapter dataPacketService = new DataPacketServiceAdapter()
+
+
override protected init() {
- Node.NodeIDType.registerIDType(MD_SAL_TYPE, NodeKey);
- NodeConnector.NodeConnectorIDType.registerIDType(MD_SAL_TYPE, NodeConnectorKey, MD_SAL_TYPE);
+ Node.NodeIDType.registerIDType(MD_SAL_TYPE, String);
+ NodeConnector.NodeConnectorIDType.registerIDType(MD_SAL_TYPE, String, MD_SAL_TYPE);
}
override start(BundleContext context) {
}
def setBroker(BindingAwareBroker broker) {
- broker.registerConsumer(this, context)
+ broker.registerProvider(new SalCompatibilityProvider(this), context)
}
- override onSessionInitialized(ConsumerContext session) {
- val subscribe = session.getSALService(NotificationService)
-
- // Registration of Flow Service
- flow.delegate = session.getRpcService(SalFlowService)
- subscribe.registerNotificationListener(flow);
-
- // Data Packet Service
- subscribe.registerNotificationListener(inventory);
-
- // Inventory Service
- inventory.dataService = session.getSALService(DataBrokerService);
- inventory.flowStatisticsService = session.getRpcService(OpendaylightFlowStatisticsService);
- inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
-
- subscribe.registerNotificationListener(dataPacket)
-
- }
override protected getGlobalImplementations() {
- return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory)
+ return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory,topology,tpProvider)
}
override protected configureGlobalInstance(Component c, Object imp) {
configure(imp, c);
}
+ override protected getImplementations() {
+ return Arrays.asList(dataPacketService)
+ }
+
+ override protected configureInstance(Component c, Object imp, String containerName) {
+ instanceConfigure(imp, c, containerName);
+ }
+
private def dispatch configure(MDSalNodeFactory imp, Component it) {
- setInterface(org.opendaylight.controller.sal.utils.INodeFactory.name, properties);
+ setInterface(INodeFactory.name, properties);
+ }
+
+ private def dispatch configure(MDSalNodeConnectorFactory imp, Component it) {
+ setInterface(INodeConnectorFactory.name, properties);
}
private def dispatch configure(ComponentActivator imp, Component it) {
.setService(IPluginOutFlowProgrammerService) //
.setCallbacks("setFlowProgrammerPublisher", "setFlowProgrammerPublisher") //
.setRequired(false))
+
+ add(
+ createServiceDependency() //
+ .setService(IClusterGlobalServices) //
+ .setCallbacks("setClusterGlobalServices", "unsetClusterGlobalServices") //
+ .setRequired(false))
+
}
+ private def dispatch instanceConfigure(DataPacketServiceAdapter imp, Component it, String containerName) {
+ setInterface(IPluginInDataPacketService.name, properties)
+ }
+
+ private def dispatch instanceConfigure(ComponentActivator imp, Component it, String containerName) {
+ }
+
+
private def dispatch configure(InventoryAndReadAdapter imp, Component it) {
setInterface(Arrays.asList(IPluginInInventoryService.name, IPluginInReadService.name), properties)
add(
createServiceDependency() //
.setService(IPluginOutReadService) //
- .setCallbacks("setReadPublisher", "setReadPublisher") //
+ .setCallbacks("setReadPublisher", "unsetReadPublisher") //
.setRequired(false))
add(
createServiceDependency() //
.setService(IPluginOutInventoryService) //
- .setCallbacks("setInventoryPublisher", "setInventoryPublisher") //
+ .setCallbacks("setInventoryPublisher", "unsetInventoryPublisher") //
+ .setRequired(false))
+ add(
+ createServiceDependency() //
+ .setService(IDiscoveryService) //
+ .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") //
.setRequired(false))
+
+
+ }
+
+ private def dispatch configure (TopologyAdapter imp, Component it) {
+ setInterface(Arrays.asList(IPluginInTopologyService.name), properties)
add(
createServiceDependency() //
.setService(IPluginOutTopologyService) //
.setCallbacks("setTopologyPublisher", "setTopologyPublisher") //
.setRequired(false))
+ }
+
+ private def dispatch configure (TopologyProvider imp, Component it) {
add(
createServiceDependency() //
- .setService(IDiscoveryService) //
- .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") //
+ .setService(IPluginOutTopologyService) //
+ .setCallbacks("setTopologyPublisher", "setTopologyPublisher") //
.setRequired(false))
-
}
private def Dictionary<String, Object> properties() {
return props;
}
}
+package class SalCompatibilityProvider implements BindingAwareProvider {
+
+ private val ComponentActivator activator;
+
+ new(ComponentActivator cmpAct) {
+ activator = cmpAct;
+ }
+
+ override getFunctionality() {
+ // Noop
+ }
+
+ override getImplementations() {
+ // Noop
+ }
+
+
+ override onSessionInitialized(ConsumerContext session) {
+ // Noop
+ }
+
+
+ override onSessionInitiated(ProviderContext session) {
+ val it = activator
+ val subscribe = session.getSALService(NotificationService)
+
+ // Registration of Flow Service
+ flow.delegate = session.getRpcService(SalFlowService)
+ flow.dataBrokerService = session.getSALService(DataBrokerService);
+ subscribe.registerNotificationListener(flow);
+
+ // Data Packet Service
+ subscribe.registerNotificationListener(inventory);
+ dataPacketService.delegate = session.getRpcService(PacketProcessingService)
+
+ // Inventory Service
+ inventory.dataService = session.getSALService(DataBrokerService);
+ inventory.flowStatisticsService = session.getRpcService(OpendaylightFlowStatisticsService);
+ inventory.flowTableStatisticsService = session.getRpcService(OpendaylightFlowTableStatisticsService);
+ inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService);
+ inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
+ inventory.dataProviderService = session.getSALService(DataProviderService)
+ topology.dataService = session.getSALService(DataProviderService)
+ tpProvider.dataService = session.getSALService(DataProviderService)
+
+
+ tpProvider.start();
+
+ subscribe.registerNotificationListener(dataPacket)
+ }
+}
package org.opendaylight.controller.sal.compatibility
+import java.util.Map
+import java.util.UUID
import java.util.concurrent.ExecutionException
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.Future
+import java.util.EnumSet
import org.opendaylight.controller.sal.core.Node
import org.opendaylight.controller.sal.flowprogrammer.Flow
import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
import org.opendaylight.controller.sal.utils.Status
import org.opendaylight.controller.sal.utils.StatusCode
+import org.opendaylight.controller.clustering.services.CacheExistException
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices
+import org.opendaylight.controller.clustering.services.IClusterServices
+
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved
import org.opendaylight.yangtools.yang.common.RpcResult
import org.slf4j.LoggerFactory
-import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+
+
+import static extension org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*
class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowListener {
private static val LOG = LoggerFactory.getLogger(FlowProgrammerAdapter);
+ private static val CACHE_NAME = "flowprogrammeradapter.flowtoid";
@Property
private SalFlowService delegate;
+
+ @Property
+ private DataBrokerService dataBrokerService;
@Property
private IPluginOutFlowProgrammerService flowProgrammerPublisher;
+ @Property
+ private IClusterGlobalServices clusterGlobalServices;
+
+
+ @Property
+ private Map<Flow, UUID> flowToFlowId = new ConcurrentHashMap<Flow, UUID>();
+
+
override addFlow(Node node, Flow flow) {
- val input = addFlowInput(node, flow);
- val future = delegate.addFlow(input);
- try {
- val result = future.get();
- return toStatus(result); // how get status from result? conversion?
- } catch (Exception e) {
- return processException(e);
- }
+ return toFutureStatus(internalAddFlowAsync(node,flow,0));
}
override modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
- val input = updateFlowInput(node, oldFlow, newFlow);
- val future = delegate.updateFlow(input);
- try {
- val result = future.get();
- return toStatus(result);
- } catch (Exception e) {
- return processException(e);
- }
+ return toFutureStatus(internalModifyFlowAsync(node, oldFlow,newFlow,0));
}
override removeFlow(Node node, Flow flow) {
- val input = removeFlowInput(node, flow);
- val future = delegate.removeFlow(input);
-
- try {
- val result = future.get();
- return toStatus(result);
- } catch (Exception e) {
- return processException(e);
- }
+ return toFutureStatus(internalRemoveFlowAsync(node, flow,0));
}
override addFlowAsync(Node node, Flow flow, long rid) {
- val input = addFlowInput(node, flow);
- delegate.addFlow(input);
- return new Status(StatusCode.SUCCESS);
+ internalAddFlowAsync(node, flow, rid);
+ return toStatus(true);
}
override modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) {
- val input = updateFlowInput(node, oldFlow, newFlow);
- delegate.updateFlow(input);
- return new Status(StatusCode.SUCCESS);
+ internalModifyFlowAsync(node, oldFlow, newFlow, rid);
+ return toStatus(true);
}
override removeFlowAsync(Node node, Flow flow, long rid) {
- val input = removeFlowInput(node, flow);
- delegate.removeFlow(input);
- return new Status(StatusCode.SUCCESS);
+ internalRemoveFlowAsync(node, flow, rid);
+ return toStatus(true);
}
override removeAllFlows(Node node) {
- throw new UnsupportedOperationException("Not present in MD-SAL");
+ // I know this looks like a copout... but its exactly what the legacy OFplugin did
+ return new Status(StatusCode.SUCCESS);
}
override syncSendBarrierMessage(Node node) {
return null;
}
- public static def toStatus(RpcResult<?> result) {
- if (result.isSuccessful()) {
+ private static def toStatus(boolean successful) {
+ if (successful) {
return new Status(StatusCode.SUCCESS);
} else {
return new Status(StatusCode.INTERNALERROR);
}
}
+
+ public static def toStatus(RpcResult<?> result) {
+ return toStatus(result.isSuccessful());
+ }
private static dispatch def Status processException(InterruptedException e) {
LOG.error("Interruption occured during processing flow",e);
NodeExperimenterErrorNotification notification) {
// NOOP : Not supported by AD SAL
}
+
+ private def Future<RpcResult<TransactionStatus>> writeFlowAsync(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, NodeKey nodeKey){
+ val modification = this._dataBrokerService.beginTransaction();
+ val flowPath = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, nodeKey)
+ .augmentation(FlowCapableNode)
+ .child(Table, new TableKey(flow.getTableId()))
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
+ .build;
+ modification.putConfigurationData(flowPath, flow);
+ return modification.commit();
+ }
+
+ private def Future<RpcResult<TransactionStatus>> internalAddFlowAsync(Node node, Flow flow, long rid){
+ var flowId = getCache().get(flow);
+ if(flowId != null) {
+ removeFlow(node, flow);
+ return internalAddFlowAsync(node, flow, rid);
+ }
+
+ flowId = UUID.randomUUID();
+ getCache().put(flow, flowId);
+
+ return writeFlowAsync(flow.toMDFlow(flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString())));
+ }
+
+ private def Future<RpcResult<TransactionStatus>> internalModifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) {
+ val flowId = getCache().remove(oldFlow);
+ if(flowId == null){
+ throw new IllegalArgumentException("oldFlow is unknown");
+ }
+
+ getCache().put(newFlow, flowId);
+ return writeFlowAsync(newFlow.toMDFlow(flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString())));
+ }
+
+
+ private def Future<RpcResult<TransactionStatus>> internalRemoveFlowAsync(Node node, Flow adflow, long rid){
+ val flowId = getCache().remove(adflow);
+ if(flowId == null){
+ throw new IllegalArgumentException("adflow is unknown");
+ }
+ val flow = adflow.toMDFlow(flowId.toString());
+ val modification = this._dataBrokerService.beginTransaction();
+ val flowPath = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, new NodeKey(new NodeId(node.getNodeIDString())))
+ .augmentation(FlowCapableNode)
+ .child(Table, new TableKey(flow.getTableId()))
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
+ .build;
+ modification.removeConfigurationData(flowPath);
+ return modification.commit();
+ }
+
+ private def toFutureStatus(Future<RpcResult<TransactionStatus>> future){
+ try {
+ val result = future.get();
+ return toStatus(result);
+ } catch (InterruptedException e) {
+ return processException(e);
+ } catch (ExecutionException e) {
+ return processException(e);
+ } catch (Exception e){
+ processException(e);
+ }
+ return toStatus(false);
+ }
+
+ private def Map<Flow, UUID> getCache(){
+ if(clusterGlobalServices == null){
+ return new ConcurrentHashMap<Flow, UUID>();
+ }
+
+ var cache = clusterGlobalServices.getCache(CACHE_NAME);
+
+ if(cache == null) {
+ try {
+ cache = clusterGlobalServices.createCache(CACHE_NAME, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+ } catch (CacheExistException e) {
+ cache = clusterGlobalServices.getCache(CACHE_NAME);
+ }
+ }
+ return cache as Map<Flow, UUID>;
+
+ }
+
}
package org.opendaylight.controller.sal.compatibility;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
import java.net.Inet6Address;
import java.net.InetAddress;
-
import org.opendaylight.controller.sal.core.NodeConnector;
-
-
-
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.sal.match.MatchField;
import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+
import com.google.common.net.InetAddresses;
-import static org.opendaylight.controller.sal.compatibility.NodeMapping.*;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.*;
public class FromSalConversionsUtils {
}
- public static GetNodeConnectorStatisticsInput nodeConnectorStatistics(
- NodeConnector connector) {
- GetNodeConnectorStatisticsInputBuilder target = new GetNodeConnectorStatisticsInputBuilder();
-
- NodeRef nodeRef = toNodeRef(connector.getNode());
- target.setNode(nodeRef);
-
- NodeConnectorRef nodeConnectorRef = toNodeConnectorRef(connector);
- target.setNodeConnector(nodeConnectorRef);
-
- return target.build();
- }
-
+ @SuppressWarnings("unused")
private static Address addressFromAction(InetAddress inetAddress) {
String strInetAddresss = InetAddresses.toAddrString(inetAddress);
if (inetAddress instanceof Inet4Address) {
targetBuilder.setVlanMatch(vlanMatch(sourceMatch));
targetBuilder.setLayer3Match(layer3Match(sourceMatch));
targetBuilder.setLayer4Match(layer4Match(sourceMatch));
+ targetBuilder.setInPort(inPortMatch(sourceMatch));
return targetBuilder.build();
}
}
+ private static NodeConnectorId inPortMatch(Match sourceMatch) {
+ MatchField inPort = sourceMatch.getField(MatchType.IN_PORT);
+ if(inPort != null && inPort.getValue() != null && (inPort.getValue() instanceof NodeConnector)) {
+ return new NodeConnectorId(((NodeConnector) inPort.getValue()).getNodeConnectorIdAsString());
+ }
+ return null;
+ }
+
private static Layer4Match layer4Match(final Match sourceMatch) {
MatchField nwProto = sourceMatch.getField(MatchType.NW_PROTO);
Short nwProtocolSource = null;
sctpMatchBuilder.setSctpDestinationPort(new PortNumber(
destinationPort));
}
-
- return sctpMatchBuilder.build();
+ if(sourcePort != null || destinationPort != null) {
+ return sctpMatchBuilder.build();
+ }
+ return null;
}
private static Layer4Match Layer4MatchAsUdp(final Match sourceMatch) {
udpMatchBuilder.setUdpDestinationPort(new PortNumber(
destinationPort));
}
-
- return udpMatchBuilder.build();
+ if(sourcePort != null || destinationPort != null) {
+ return udpMatchBuilder.build();
+ }
+ return null;
}
private static Layer4Match Layer4MatchAsTcp(final Match sourceMatch) {
tcpMatchBuilder.setTcpDestinationPort(new PortNumber(
destinationPort));
}
-
- return tcpMatchBuilder.build();
+ if(sourcePort != null || destinationPort != null) {
+ return tcpMatchBuilder.build();
+ }
+ return null;
}
private static Integer transportPort(final Match sourceMatch,
MatchField vlan = sourceMatch.getField(MatchType.DL_VLAN);
if (vlan != null && vlan.getValue() != null) {
VlanIdBuilder vlanIDBuilder = new VlanIdBuilder();
- vlanIDBuilder.setVlanId(new VlanId((int) (NetUtils
+ vlanIDBuilder.setVlanId(new VlanId((NetUtils
.getUnsignedShort((short) vlan.getValue()))));
vlanMatchBuild.setVlanId(vlanIDBuilder.build());
}
vlanMatchBuild.setVlanPcp(new VlanPcp((short) ((byte) vlanPriority
.getValue())));
}
-
- return vlanMatchBuild.build();
+ if((vlan != null && vlan.getValue() != null) || (vlanPriority != null && vlanPriority.getValue() != null)) {
+ return vlanMatchBuild.build();
+ }
+ return null;
}
private static IpMatch ipMatch(final Match sourceMatch) {
targetIpMatchBuild.setIpProtocol((short) ((byte) protocol
.getValue()));
}
-
- return targetIpMatchBuild.build();
-
+ if((networkTos != null && networkTos.getValue() != null) || (protocol != null && protocol.getValue() != null)) {
+ return targetIpMatchBuild.build();
+ }
+ return null;
}
private static EthernetMatch ethernetMatch(final Match sourceMatch) {
final EthernetMatchBuilder targetEthMatchBuild = new EthernetMatchBuilder();
-
- EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
- .setAddress(ethernetSourceAddress(sourceMatch));
- targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
-
- EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder()
- .setAddress(ethernetDestAddress(sourceMatch));
- targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
+ if(sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) {
+ EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
+ .setAddress(ethernetSourceAddress(sourceMatch));
+ targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
+ }
+ if(sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null) {
+ EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder()
+ .setAddress(ethernetDestAddress(sourceMatch));
+ targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
+ }
final MatchField dataLinkType = sourceMatch.getField(MatchType.DL_TYPE);
if (dataLinkType != null && dataLinkType.getValue() != null) {
.setType(etherType);
targetEthMatchBuild.setEthernetType(ethType.build());
}
- return targetEthMatchBuild.build();
+ if((sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) ||
+ (sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null)||
+ dataLinkType != null ) {
+ return targetEthMatchBuild.build();
+ }
+ return null;
}
private static MacAddress ethernetSourceAddress(final Match sourceMatch) {
InetAddress inetDestAddress = null;
MatchField netDest = sourceMatch.getField(MatchType.NW_DST);
- if (netSource != null && netSource.getValue() != null) {
+ if (netDest != null && netDest.getValue() != null) {
inetDestAddress = (InetAddress) (netDest.getValue());
}
if ((inetSourceAddress instanceof Inet4Address)
- && (inetDestAddress instanceof Inet4Address)) {
+ || (inetDestAddress instanceof Inet4Address)) {
MatchField dataLinkType = sourceMatch.getField(DL_TYPE);
Short dLType = null;
if (dataLinkType != null && dataLinkType.getValue() != null) {
(Inet4Address) inetDestAddress);
}
} else if ((inetSourceAddress instanceof Inet6Address)
- && (inetDestAddress instanceof Inet6Address)) {
+ || (inetDestAddress instanceof Inet6Address)) {
return setLayer3MatchAsIpv6((Inet6Address) inetSourceAddress,
(Inet6Address) inetDestAddress);
}
private static Layer3Match setLayer3MatchAsIpv4(
final Inet4Address inetSourceAddress,
final Inet4Address inetDestAddress) {
- String inetSrcAddressString = InetAddresses
- .toAddrString(inetSourceAddress);
- String inetDstAddressString = InetAddresses
- .toAddrString(inetDestAddress);
-
Ipv4MatchBuilder layer4MatchBuild = new Ipv4MatchBuilder();
- layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString));
- layer4MatchBuild
- .setIpv4Destination(new Ipv4Prefix(inetDstAddressString));
+ if(inetSourceAddress != null) {
+ String inetSrcAddressString = InetAddresses
+ .toAddrString(inetSourceAddress);
+ layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString));
+ }
+ if(inetDestAddress != null) {
+ String inetDstAddressString = InetAddresses
+ .toAddrString(inetDestAddress);
+ layer4MatchBuild
+ .setIpv4Destination(new Ipv4Prefix(inetDstAddressString));
+ }
return layer4MatchBuild.build();
}
private static Layer3Match setLayer3MatchAsIpv6(
final Inet6Address inetSourceAddress,
final Inet6Address inetDestAddress) {
- String inetSrcAddressString = InetAddresses
- .toAddrString(inetSourceAddress);
- String inetDstAddressString = InetAddresses
- .toAddrString(inetDestAddress);
Ipv6MatchBuilder layer6MatchBuild = new Ipv6MatchBuilder();
-
- layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString));
- layer6MatchBuild
- .setIpv6Destination(new Ipv6Prefix(inetDstAddressString));
+ if(inetSourceAddress != null) {
+ String inetSrcAddressString = InetAddresses
+ .toAddrString(inetSourceAddress);
+ layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString));
+ }
+ if(inetDestAddress != null) {
+ String inetDstAddressString = InetAddresses
+ .toAddrString(inetDestAddress);
+ layer6MatchBuild
+ .setIpv6Destination(new Ipv6Prefix(inetDstAddressString));
+ }
return layer6MatchBuild.build();
}
+
+ public static boolean flowEquals(Flow statsFlow, Flow storedFlow) {
+ if (statsFlow.getClass() != storedFlow.getClass()) {
+ return false;
+ }
+ if (statsFlow.getBufferId()== null) {
+ if (storedFlow.getBufferId() != null) {
+ return false;
+ }
+ } else if(!statsFlow.getBufferId().equals(storedFlow.getBufferId())) {
+ return false;
+ }
+ if (statsFlow.getContainerName()== null) {
+ if (storedFlow.getContainerName()!= null) {
+ return false;
+ }
+ } else if(!statsFlow.getContainerName().equals(storedFlow.getContainerName())) {
+ return false;
+ }
+ if (statsFlow.getCookie()== null) {
+ if (storedFlow.getCookie()!= null) {
+ return false;
+ }
+ } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
+ return false;
+ }
+ if (statsFlow.getMatch()== null) {
+ if (storedFlow.getMatch() != null) {
+ return false;
+ }
+ } else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
+ return false;
+ }
+ if (statsFlow.getCookie()== null) {
+ if (storedFlow.getCookie()!= null) {
+ return false;
+ }
+ } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
+ return false;
+ }
+ if (statsFlow.getHardTimeout() == null) {
+ if (storedFlow.getHardTimeout() != null) {
+ return false;
+ }
+ } else if(!statsFlow.getHardTimeout().equals(storedFlow.getHardTimeout() )) {
+ return false;
+ }
+ if (statsFlow.getIdleTimeout()== null) {
+ if (storedFlow.getIdleTimeout() != null) {
+ return false;
+ }
+ } else if(!statsFlow.getIdleTimeout().equals(storedFlow.getIdleTimeout())) {
+ return false;
+ }
+ if (statsFlow.getPriority() == null) {
+ if (storedFlow.getPriority() != null) {
+ return false;
+ }
+ } else if(!statsFlow.getPriority().equals(storedFlow.getPriority())) {
+ return false;
+ }
+ if (statsFlow.getTableId() == null) {
+ if (storedFlow.getTableId() != null) {
+ return false;
+ }
+ } else if(!statsFlow.getTableId().equals(storedFlow.getTableId())) {
+ return false;
+ }
+ return true;
+ }
+
}
package org.opendaylight.controller.sal.compatibility
-import org.opendaylight.controller.sal.reader.IPluginInReadService
-import org.opendaylight.controller.sal.core.NodeConnector
+import java.util.ArrayList
+import java.util.Collections
+import java.util.List
+import java.util.Set
+import java.util.concurrent.CopyOnWriteArrayList;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.Edge
import org.opendaylight.controller.sal.core.Node
-import org.opendaylight.controller.sal.flowprogrammer.Flow
import org.opendaylight.controller.sal.core.NodeTable
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
-
-import static extension org.opendaylight.controller.sal.common.util.Arguments.*
-import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.flowprogrammer.Flow
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
+import org.opendaylight.controller.sal.reader.FlowOnNode
+import org.opendaylight.controller.sal.reader.IPluginInReadService
+import org.opendaylight.controller.sal.reader.IPluginOutReadService
+import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
+import org.opendaylight.controller.sal.reader.NodeDescription
+import org.opendaylight.controller.sal.reader.NodeTableStatistics
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
-import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
-import org.opendaylight.controller.sal.reader.FlowOnNode
-import org.opendaylight.controller.sal.reader.NodeDescription
-import org.slf4j.LoggerFactory
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsInputBuilder
-import java.util.ArrayList
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsInputBuilder
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
-import java.util.Collections
-import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.controller.sal.topology.IPluginInTopologyService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener
-import org.opendaylight.controller.sal.core.Edge
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.slf4j.LoggerFactory
-class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInReadService, IPluginInInventoryService, OpendaylightInventoryListener, FlowTopologyDiscoveryListener {
+import static extension org.opendaylight.controller.sal.common.util.Arguments.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import java.util.concurrent.ConcurrentHashMap
+import java.util.Map
+
+class InventoryAndReadAdapter implements IPluginInReadService,
+ IPluginInInventoryService,
+ OpendaylightInventoryListener,
+ OpendaylightFlowStatisticsListener,
+ OpendaylightFlowTableStatisticsListener,
+ OpendaylightPortStatisticsListener {
private static val LOG = LoggerFactory.getLogger(InventoryAndReadAdapter);
+ private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
@Property
DataBrokerService dataService;
@Property
- OpendaylightFlowStatisticsService flowStatisticsService;
+ DataProviderService dataProviderService;
@Property
- IPluginOutInventoryService inventoryPublisher;
+ OpendaylightFlowStatisticsService flowStatisticsService;
@Property
- IPluginOutTopologyService topologyPublisher;
+ OpendaylightPortStatisticsService nodeConnectorStatisticsService;
@Property
- IDiscoveryService discoveryPublisher;
+ OpendaylightFlowTableStatisticsService flowTableStatisticsService;
@Property
FlowTopologyDiscoveryService topologyDiscovery;
+
+ @Property
+ List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
+
+ @Property
+ List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
+
+ def setInventoryPublisher(IPluginOutInventoryService listener){
+ inventoryPublisher.add(listener);
+ }
+
+ def unsetInventoryPublisher(IPluginOutInventoryService listener){
+ inventoryPublisher.remove(listener);
+ }
- override getTransmitRate(NodeConnector connector) {
+ def setReadPublisher(IPluginOutReadService listener) {
+ statisticsPublisher.add(listener);
+ }
+
+ def unsetReadPublisher (IPluginOutReadService listener) {
+ if( listener != null)
+ statisticsPublisher.remove(listener);
+ }
+
+ protected def startChange() {
+ return dataProviderService.beginTransaction;
+ }
+
+ override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) {
val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
return nodeConnector.currentSpeed
}
override readAllFlow(Node node, boolean cached) {
- val input = new GetAllFlowStatisticsInputBuilder;
- input.setNode(node.toNodeRef);
- val result = flowStatisticsService.getAllFlowStatistics(input.build)
- val statistics = result.get.result;
val output = new ArrayList<FlowOnNode>();
- for (stat : statistics.flowStatistics) {
- // FIXME: Create FlowOnNode
- }
+ val tableRef = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+ .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
+
+ val it = this.startChange();
+
+ val table= it.readConfigurationData(tableRef) as Table;
+
+ if(table != null){
+ LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+
+ for(flow : table.flow){
+
+ val adsalFlow = ToSalConversionsUtils.toFlow(flow);
+ val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
+
+ if(statsFromDataStore != null){
+ val it = new FlowOnNode(adsalFlow);
+ byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
+ packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
+ durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
+ durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
+
+ output.add(it);
+ }
+ }
+ }
+
+ //TODO (main): Shell we send request to the switch? It will make async request to the switch.
+ // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
+ // If we assume that md-sal statistics manager will always be running, then its not required
+ // But if not, then sending request will collect the latest data for adaptor atleast.
+ val input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
+ input.setNode(node.toNodeRef);
+ flowStatisticsService.getAllFlowsStatisticsFromAllFlowTables(input.build)
+
return output;
}
override readAllNodeConnector(Node node, boolean cached) {
- val input = new GetAllNodeConnectorStatisticsInputBuilder();
+
+ val ret = new ArrayList<NodeConnectorStatistics>();
+ val nodeRef = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+ .toInstance();
+
+ val provider = this.startChange();
+
+ val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+
+ if(dsNode != null){
+
+ for (dsNodeConnector : dsNode.nodeConnector){
+ val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+ .child(NodeConnector, dsNodeConnector.key)
+ .toInstance();
+
+ val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
+
+ if(nodeConnectorFromDS != null){
+ val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
+
+ ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
+ }
+ }
+ }
+
+ //TODO: Refer TODO (main)
+ val input = new GetAllNodeConnectorsStatisticsInputBuilder();
input.setNode(node.toNodeRef);
- val result = flowStatisticsService.getAllNodeConnectorStatistics(input.build());
- val statistics = result.get.result.nodeConnectorStatistics;
- val ret = new ArrayList<NodeConnectorStatistics>();
- for (stat : statistics) {
- ret.add(stat.toNodeConnectorStatistics())
- }
+ nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
return ret;
}
override readAllNodeTable(Node node, boolean cached) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ val ret = new ArrayList<NodeTableStatistics>();
+
+ val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
+
+ if(dsFlowCapableNode != null){
+
+ for (table : dsFlowCapableNode.table){
+
+ val tableStats = table.getAugmentation(FlowTableStatisticsData);
+
+ if(tableStats != null){
+ ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
+ }
+ }
+ }
+
+ //TODO: Refer TODO (main)
+ val input = new GetFlowTablesStatisticsInputBuilder();
+ input.setNode(node.toNodeRef);
+ flowTableStatisticsService.getFlowTablesStatistics(input.build);
+ return ret;
}
override readDescription(Node node, boolean cached) {
- val capableNode = readFlowCapableNode(node.toNodeRef)
-
- val it = new NodeDescription()
- manufacturer = capableNode.manufacturer
- serialNumber = capableNode.serialNumber
- software = capableNode.software
- description = capableNode.description
-
- return it;
+ return toNodeDescription(node.toNodeRef);
+ }
+
+ override readFlow(Node node, Flow targetFlow, boolean cached) {
+ var FlowOnNode ret= null;
+
+ val tableRef = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+ .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
+
+ val it = this.startChange();
+
+ val table= it.readConfigurationData(tableRef) as Table;
+
+ if(table != null){
+ LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+
+ for(mdsalFlow : table.flow){
+ if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
+ val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
+
+ if(statsFromDataStore != null){
+ LOG.debug("Found matching flow in the data store flow table ");
+ val it = new FlowOnNode(targetFlow);
+ byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
+ packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
+ durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
+ durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
+
+ ret = it;
+ }
+ }
+ }
+ }
+
+ //TODO: Refer TODO (main)
+ val input = new GetFlowStatisticsFromFlowTableInputBuilder;
+ input.setNode(node.toNodeRef);
+ input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
+ flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
+
+ return ret;
+
}
- override readFlow(Node node, Flow flow, boolean cached) {
- val input = flowStatisticsInput(node, flow);
- val output = flowStatisticsService.getFlowStatistics(input);
-
- try {
- val statistics = output.get().getResult();
- if (statistics != null) {
- val it = new FlowOnNode(flow);
- byteCount = statistics.byteCount.value.longValue
- durationNanoseconds = statistics.duration.getNanosecond().getValue().intValue();
- durationSeconds = statistics.duration.getSecond().getValue().intValue();
- packetCount = statistics.getPacketCount().getValue().longValue();
- return it;
- }
- } catch (Exception e) {
- LOG.error("Read flow not processed", e);
- }
- return null;
+ override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
+ var NodeConnectorStatistics nodeConnectorStatistics = null;
+
+ val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
+ .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
+ .toInstance();
+ val provider = this.startChange();
+
+ val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
+
+ if(nodeConnectorFromDS != null){
+ val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
+ if(nodeConnectorStatsFromDs != null) {
+ nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
+ InventoryMapping.toNodeKey(connector.node).id,
+ InventoryMapping.toNodeConnectorKey(connector).id);
+ }
+ }
+
+ //TODO: Refer TODO (main)
+ val input = new GetNodeConnectorStatisticsInputBuilder();
+ input.setNode(connector.node.toNodeRef);
+ input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
+ nodeConnectorStatisticsService.getNodeConnectorStatistics(input.build());
+ return nodeConnectorStatistics;
}
- override readNodeConnector(NodeConnector connector, boolean cached) {
-
- val getNodeConnectorStatisticsInput = FromSalConversionsUtils.nodeConnectorStatistics(connector);
- val future = flowStatisticsService.getNodeConnectorStatistics(getNodeConnectorStatisticsInput);
- try {
- val rpcResult = future.get();
- val output = rpcResult.getResult();
-
- if (output != null) {
- return output.toNodeConnectorStatistics;
- }
- } catch (Exception e) {
- LOG.error("Read node connector not processed", e);
- }
-
- return null;
+ override readNodeTable(NodeTable nodeTable, boolean cached) {
+ var NodeTableStatistics nodeStats = null
+
+ val tableRef = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
+ .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
+
+ val it = this.startChange();
+
+ val table= it.readConfigurationData(tableRef) as Table;
+
+ if(table != null){
+ val tableStats = table.getAugmentation(FlowTableStatisticsData);
+
+ if(tableStats != null){
+ nodeStats = toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
+ }
+ }
+
+ //TODO: Refer TODO (main)
+ val input = new GetFlowTablesStatisticsInputBuilder();
+ input.setNode(nodeTable.node.toNodeRef);
+ flowTableStatisticsService.getFlowTablesStatistics(input.build);
+
+ return nodeStats;
}
override onNodeConnectorRemoved(NodeConnectorRemoved update) {
override onNodeRemoved(NodeRemoved notification) {
val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
- val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
- inventoryPublisher.updateNode(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
+ publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
}
override onNodeConnectorUpdated(NodeConnectorUpdated update) {
- val properties = new java.util.HashSet<org.opendaylight.controller.sal.core.Property>();
-
-
- val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = update.nodeConnectorRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
var updateType = UpdateType.CHANGED;
- if ( this._dataService.readOperationalData(identifier) == null ){
+ if ( this._dataService.readOperationalData(update.nodeConnectorRef.value as InstanceIdentifier<? extends DataObject>) == null ){
updateType = UpdateType.ADDED;
}
var nodeConnector = update.nodeConnectorRef.toADNodeConnector
-
- properties.add(new org.opendaylight.controller.sal.core.Name(nodeConnector.ID.toString()));
-
- inventoryPublisher.updateNodeConnector(nodeConnector , updateType , properties);
+ publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
}
override onNodeUpdated(NodeUpdated notification) {
- val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
- val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
+ val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value as InstanceIdentifier<? extends DataObject>;
var updateType = UpdateType.CHANGED;
if ( this._dataService.readOperationalData(identifier) == null ){
updateType = UpdateType.ADDED;
}
- inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, properties);
+ publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
+
+ //Notify the listeners of IPluginOutReadService
+
+ for (statsPublisher : statisticsPublisher){
+ val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+ statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,toNodeDescription(notification.nodeRef));
+ }
}
override getNodeProps() {
-
- // FIXME: Read from MD-SAL inventory service
- return null;
+ val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
+
+ val nodes = readAllMDNodes()
+ for (node : nodes.node ) {
+ val fcn = node.getAugmentation(FlowCapableNode)
+ if(fcn != null) {
+ val perNodeProps = fcn.toADNodeProperties(node.id)
+ val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
+ if(perNodeProps != null ) {
+ for(perNodeProp : perNodeProps) {
+ perNodePropMap.put(perNodeProp.name,perNodeProp)
+ }
+ }
+ props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
+ }
+ }
+ return props;
}
-
- override getNodeConnectorProps(Boolean refresh) {
-
- // FIXME: Read from MD-SAL Invcentory Service
- return null;
+
+ private def readAllMDNodes() {
+ val nodesRef = InstanceIdentifier.builder(Nodes)
+ .toInstance
+ val reader = TypeSafeDataReader.forReader(dataService)
+ return reader.readOperationalData(nodesRef)
+ }
+
+ private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
+ val nodeRef = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
+ .toInstance
+ val reader = TypeSafeDataReader.forReader(dataService)
+ return reader.readOperationalData(nodeRef).nodeConnector
}
- override readNodeTable(NodeTable table, boolean cached) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ override getNodeConnectorProps(Boolean refresh) {
+ // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary
+ // data store to refresh from
+ val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
+ val nodes = readAllMDNodes()
+ for (node : nodes.node) {
+ val ncs = node.readAllMDNodeConnectors
+ if(ncs != null) {
+ for( nc : ncs ) {
+ val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
+ if(fcnc != null) {
+ val ncps = fcnc.toADNodeConnectorProperties
+ val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
+ if(ncps != null) {
+ for(p : ncps) {
+ ncpsm.put(p.name,p)
+ }
+ }
+ props.put(nc.id.toADNodeConnector(node.id),ncpsm)
+ }
+ }
+ }
+ }
+ return props
}
private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
val node = dataObject.checkInstanceOf(
- org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector);
+ NodeConnector);
return node.getAugmentation(FlowCapableNodeConnector);
}
- private static def toNodeConnectorStatistics(
- org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics output) {
- val it = new NodeConnectorStatistics
-
- collisionCount = output.getCollisionCount().longValue();
- receiveCRCErrorCount = output.getReceiveCrcError().longValue();
- receiveFrameErrorCount = output.getReceiveFrameError().longValue();
- receiveOverRunErrorCount = output.getReceiveOverRunError().longValue();
+ private def toNodeConnectorStatistics(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
+
+ val it = new NodeConnectorStatistics();
+
+ receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
+ transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
+
+ receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
+ transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
+
+ receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
+ transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
+
+ receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
+ transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
+
+ receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
+ receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
+ receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
+ collisionCount = nodeConnectorStatistics.collisionCount.longValue;
+
+ val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
+ .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
+
+ nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
+
+ return it;
+ }
- receiveDropCount = output.getReceiveDrops().longValue();
- receiveErrorCount = output.getReceiveErrors().longValue();
- receivePacketCount = output.getPackets().getReceived().longValue();
- receiveByteCount = output.getBytes().getReceived().longValue();
+ private def toNodeTableStatistics(
+ FlowTableStatistics tableStats,
+ Short tableId,Node node){
+ var it = new NodeTableStatistics();
+
+ activeCount = tableStats.activeFlows.value.intValue;
+ lookupCount = tableStats.packetsLookedUp.value.intValue;
+ matchedCount = tableStats.packetsMatched.value.intValue;
+ name = tableId.toString;
+ nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
+ return it;
+ }
+
+ private def toNodeDescription(NodeRef nodeRef){
+ val capableNode = readFlowCapableNode(nodeRef);
- transmitDropCount = output.getTransmitDrops().longValue();
- transmitErrorCount = output.getTransmitErrors().longValue();
- transmitPacketCount = output.getPackets().getTransmitted().longValue();
- transmitByteCount = output.getBytes().getTransmitted().longValue();
+ val it = new NodeDescription()
+ manufacturer = capableNode.manufacturer
+ serialNumber = capableNode.serialNumber
+ software = capableNode.software
+ description = capableNode.description
+
return it;
- }
-
- override sollicitRefresh() {
- topologyDiscovery.solicitRefresh
- }
-
- override onLinkDiscovered(LinkDiscovered notification) {
- val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.ADDED);
- discoveryPublisher.notifyEdge(notification.toADEdge,UpdateType.ADDED,Collections.emptySet());
- topologyPublisher.edgeUpdate(Collections.singletonList(update))
- }
-
- override onLinkOverutilized(LinkOverutilized notification) {
- topologyPublisher.edgeOverUtilized(notification.toADEdge)
- }
-
- override onLinkRemoved(LinkRemoved notification) {
- val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.REMOVED);
- topologyPublisher.edgeUpdate(Collections.singletonList(update))
- }
-
- override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
- topologyPublisher.edgeUtilBackToNormal(notification.toADEdge)
- }
+ }
def Edge toADEdge(Link link) {
new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
}
-
+
+ /*
+ * OpendaylightFlowStatisticsListener interface implementation
+ */
+ override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
+ //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
+ }
+
+ override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
+
+ val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
+
+ for(flowStats : notification.flowAndStatisticsMapList){
+ if(flowStats.tableId == 0)
+ adsalFlowsStatistics.add(toFlowOnNode(flowStats));
+ }
+
+ for (statsPublisher : statisticsPublisher){
+ val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+ statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
+ }
+
+ }
+ /*
+ * OpendaylightFlowTableStatisticsListener interface implementation
+ */
+ override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
+ var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
+
+ for(stats : notification.flowTableAndStatisticsMap){
+ if (stats.tableId.value == 0){
+ val it = new NodeTableStatistics();
+ activeCount = stats.activeFlows.value.intValue;
+ lookupCount = stats.packetsLookedUp.value.longValue;
+ matchedCount = stats.packetsMatched.value.longValue;
+
+ adsalFlowTableStatistics.add(it);
+ }
+ }
+ for (statsPublisher : statisticsPublisher){
+ val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+ statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
+ }
+ }
+
+ /*
+ * OpendaylightPortStatisticsUpdate interface implementation
+ */
+ override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
+
+ val adsalPortStatistics = new ArrayList<NodeConnectorStatistics>();
+
+ for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
+ adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
+ }
+
+ for (statsPublisher : statisticsPublisher){
+ val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+ statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
+ }
+
+ }
+
+ private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap){
+
+ val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap));
+
+ byteCount = flowAndStatsMap.byteCount.value.longValue;
+ packetCount = flowAndStatsMap.packetCount.value.longValue;
+ durationSeconds = flowAndStatsMap.duration.second.value.intValue;
+ durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
+
+ return it;
+ }
+
+ override getConfiguredNotConnectedNodes() {
+ return Collections.emptySet();
+ }
+
+
+ private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+ for( publisher : inventoryPublisher){
+ publisher.updateNode(node, updateType, properties);
+ }
+ }
+
+ private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+ for( publisher : inventoryPublisher){
+ publisher.updateNodeConnector(nodeConnector, updateType, properties);
+ }
+ }
}
import java.net.Inet4Address
import java.net.Inet6Address
import java.util.ArrayList
-import java.util.List
import org.opendaylight.controller.sal.action.Controller
import org.opendaylight.controller.sal.action.Drop
import org.opendaylight.controller.sal.action.Flood
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsInputBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.hw.path.action._case.HwPathActionBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.loopback.action._case.LoopbackActionBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathActionCaseBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId
public class MDFlowMapping {
}
instructions = targetActions.toApplyInstruction();
match = sourceFlow.match.toMatch();
+ tableId = new Integer(0).shortValue
return it.build();
}
+ public static def toMDFlow(Flow sourceFlow, String flowId) {
+ if (sourceFlow == null)
+ throw new IllegalArgumentException();
+ val it = new FlowBuilder();
+ hardTimeout = sourceFlow.hardTimeout as int
+ idleTimeout = sourceFlow.idleTimeout as int
+ cookie = BigInteger.valueOf(sourceFlow.id)
+ priority = sourceFlow.priority as int
+ id = new FlowId(flowId)
+
+ val sourceActions = sourceFlow.actions;
+ val targetActions = new ArrayList<Action>();
+ for (sourceAction : sourceActions) {
+ targetActions.add(sourceAction.toAction());
+ }
+ instructions = targetActions.toApplyInstruction();
+ match = sourceFlow.match.toMatch();
+ tableId = new Integer(0).shortValue
+ return it.build();
+ }
+
public static def Instructions toApplyInstruction(ArrayList<Action> actions) {
val it = new InstructionsBuilder;
val applyActions = new InstructionBuilder;
applyActions.instruction = new ApplyActionsCaseBuilder().setApplyActions(new ApplyActionsBuilder().setAction(actions).build()).build()
+ applyActions.setOrder(new Integer(0))
instruction = Collections.<Instruction>singletonList(applyActions.build)
return it.build;
}
- public static def flowStatisticsInput(Node sourceNode, Flow sourceFlow) {
- val source = flowAdded(sourceFlow);
- val it = new GetFlowStatisticsInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow);
- node = sourceNode.toNodeRef();
- return it.build();
- }
-
public static def removeFlowInput(Node sourceNode, Flow sourceFlow) {
val source = flowAdded(sourceFlow);
val it = new RemoveFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow);
+ node = sourceNode.toNodeRef()
return it.build();
}
public static def addFlowInput(Node sourceNode, Flow sourceFlow) {
val source = flowAdded(sourceFlow);
val it = new AddFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow);
+ it.setNode(sourceNode.toNodeRef)
return it.build();
}
}
public static def Uri toUri(NodeConnector connector) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ return new NodeConnectorId(connector.ID as String);
}
public static def MacAddress toMacAddress(byte[] bytes) {
}
return new MacAddress(sb.toString());
}
+
+ public static def toMDSalflow(Flow sourceFlow) {
+ if (sourceFlow == null)
+ throw new IllegalArgumentException();
+ val it = new FlowBuilder();
+
+ hardTimeout = sourceFlow.hardTimeout as int
+ idleTimeout = sourceFlow.idleTimeout as int
+ cookie = BigInteger.valueOf(sourceFlow.id)
+ priority = sourceFlow.priority as int
+
+ val sourceActions = sourceFlow.actions;
+ val targetActions = new ArrayList<Action>();
+ for (sourceAction : sourceActions) {
+ targetActions.add(sourceAction.toAction());
+ }
+ instructions = targetActions.toApplyInstruction();
+ match = sourceFlow.match.toMatch();
+ return it.build();
+ }
+
}
--- /dev/null
+package org.opendaylight.controller.sal.compatibility;
+
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.INodeConnectorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MDSalNodeConnectorFactory implements INodeConnectorFactory{
+ private Logger logger = LoggerFactory.getLogger(MDSalNodeConnectorFactory.class);
+
+ @Override
+ public NodeConnector fromStringNoNode(String type, String id, Node node) {
+ try {
+ return new NodeConnector(type, id, node);
+ } catch (ConstructionException e) {
+ logger.error("Could not construct NodeConnector", e);
+ }
+ return null;
+
+ }
+}
import org.opendaylight.controller.sal.core.ConstructionException;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.utils.INodeFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public Node fromString(String type, String id) {
try {
- return new Node(type, new NodeKey(new NodeId(id)));
+ return new Node(type, id);
} catch (ConstructionException e) {
logger.error("Could not construct Node", e);
}
import static com.google.common.base.Preconditions.*;
import static extension org.opendaylight.controller.sal.common.util.Arguments.*;
+import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
import org.opendaylight.controller.sal.core.ConstructionException
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures
+import org.opendaylight.controller.sal.core.Bandwidth
+import org.opendaylight.controller.sal.core.AdvertisedBandwidth
+import org.opendaylight.controller.sal.core.SupportedBandwidth
+import org.opendaylight.controller.sal.core.PeerBandwidth
+import org.opendaylight.controller.sal.core.Name
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig
+import org.opendaylight.controller.sal.core.Config
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.State
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
+import java.util.HashSet
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated
+import org.opendaylight.controller.sal.core.Tables
+import java.util.List
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability
+import org.opendaylight.controller.sal.core.Buffers
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityFlowStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityTableStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityIpReasm
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityPortStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityStp
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityQueueStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityArpMatchIp
+import org.opendaylight.controller.sal.core.Capabilities
+import org.opendaylight.controller.sal.core.MacAddress
+import java.util.Date
+import org.opendaylight.controller.sal.core.TimeStamp
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
public class NodeMapping {
}
public static def toADNode(InstanceIdentifier<?> node) throws ConstructionException {
+ return node.toNodeId.toADNode
+ }
+
+ public static def toADNode(NodeId id) {
+ return new Node(MD_SAL_TYPE, id.toADNodeId);
+ }
+
+ public static def toNodeId(InstanceIdentifier<?> node) {
checkNotNull(node);
checkNotNull(node.getPath());
checkArgument(node.getPath().size() >= 2);
val arg = node.getPath().get(1);
val item = arg.checkInstanceOf(IdentifiableItem);
val nodeKey = item.getKey().checkInstanceOf(NodeKey);
- return new Node(MD_SAL_TYPE, nodeKey);
+ return nodeKey.id
+ }
+
+ public static def toADNodeId(NodeId nodeId) {
+ checkNotNull(nodeId);
+ return nodeId.value
}
public static def toADNodeConnector(NodeConnectorRef source) throws ConstructionException {
checkNotNull(source);
val InstanceIdentifier<?> path = checkNotNull(source.getValue());
- val node = path.toADNode();
checkArgument(path.path.size() >= 3);
val arg = path.getPath().get(2);
val item = arg.checkInstanceOf(IdentifiableItem);
val connectorKey = item.getKey().checkInstanceOf(NodeConnectorKey);
- return new NodeConnector(MD_SAL_TYPE, connectorKey, node);
+ return connectorKey.id.toADNodeConnector(path.toNodeId)
+ }
+
+ public static def toADNodeConnector(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId ncid,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nid) {
+ return new NodeConnector(ncid.toNodeConnectorType(nid),
+ ncid.toADNodeConnectorId(nid), nid.toADNode);
+ }
+
+ public static def toNodeConnectorType(NodeConnectorId ncId, NodeId nodeId) {
+ if (ncId.equals(nodeId.toLocalNodeConnectorId)) {
+ return NodeConnector.NodeConnectorIDType.SWSTACK
+ } else if (ncId.equals(nodeId.toNormalNodeConnectorId)) {
+ return NodeConnector.NodeConnectorIDType.HWPATH
+ } else if (ncId.equals(nodeId.toControllerNodeConnectorId)) {
+ return NodeConnector.NodeConnectorIDType.CONTROLLER
+ }
+ return MD_SAL_TYPE
+ }
+
+ public static def toADNodeConnectorId(NodeConnectorId nodeConnectorId, NodeId nodeId) {
+ if (nodeConnectorId.equals(nodeId.toLocalNodeConnectorId) ||
+ nodeConnectorId.equals(nodeId.toNormalNodeConnectorId) ||
+ nodeConnectorId.equals(nodeId.toControllerNodeConnectorId)) {
+ return NodeConnector.SPECIALNODECONNECTORID
+ }
+ return nodeConnectorId.value
+ }
+
+ public static def toControllerNodeConnectorId(NodeId node) {
+ return new NodeConnectorId(node.value + ":" + 4294967293L)
+ }
+
+ public static def toLocalNodeConnectorId(NodeId node) {
+ return new NodeConnectorId(node.value + ":" + 4294967294L)
+ }
+
+ public static def toNormalNodeConnectorId(NodeId node) {
+ return new NodeConnectorId(node.value + ":" + 4294967290L)
}
public static def toNodeRef(Node node) {
checkArgument(MD_SAL_TYPE.equals(node.getType()));
- val nodeKey = node.ID.checkInstanceOf(NodeKey);
+ var nodeId = node.ID.checkInstanceOf(String)
+ val nodeKey = new NodeKey(new NodeId(nodeId));
val nodePath = InstanceIdentifier.builder().node(Nodes).child(NODE_CLASS, nodeKey).toInstance();
return new NodeRef(nodePath);
}
public static def toNodeConnectorRef(NodeConnector nodeConnector) {
val node = nodeConnector.node.toNodeRef();
val nodePath = node.getValue() as InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node>
- val connectorKey = nodeConnector.ID.checkInstanceOf(NodeConnectorKey);
+ var NodeConnectorId nodeConnectorId
+ if (nodeConnector.ID.equals(NodeConnector.SPECIALNODECONNECTORID)) {
+ if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.SWSTACK)) {
+ nodeConnectorId = nodePath.toNodeId.toLocalNodeConnectorId
+ } else if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.HWPATH)) {
+ nodeConnectorId = nodePath.toNodeId.toNormalNodeConnectorId
+ } else if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.CONTROLLER)) {
+ nodeConnectorId = nodePath.toNodeId.toControllerNodeConnectorId
+ }
+ } else {
+ nodeConnectorId = new NodeConnectorId(nodeConnector.ID.checkInstanceOf(String))
+ }
+ val connectorKey = new NodeConnectorKey(nodeConnectorId);
val path = InstanceIdentifier.builder(nodePath).child(NODECONNECTOR_CLASS, connectorKey).toInstance();
return new NodeConnectorRef(path);
}
return toADNode(node.getValue());
}
+ public static def toADNodeConnectorProperties(NodeConnectorUpdated nc) {
+ val fcncu = nc.getAugmentation(FlowCapableNodeConnectorUpdated)
+ if (fcncu != null) {
+ return fcncu.toADNodeConnectorProperties
+ }
+ return new HashSet<org.opendaylight.controller.sal.core.Property>();
+ }
+
+ public static def toADNodeConnectorProperties(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector nc) {
+ val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
+ if (fcnc != null) {
+ return fcnc.toADNodeConnectorProperties
+ }
+ return new HashSet<org.opendaylight.controller.sal.core.Property>();
+ }
+
+ public static def toADNodeConnectorProperties(FlowNodeConnector fcncu) {
+ val props = new HashSet<org.opendaylight.controller.sal.core.Property>();
+ if (fcncu != null) {
+ if (fcncu.currentFeature != null && fcncu.currentFeature.toAdBandwidth != null) {
+ props.add(fcncu.currentFeature.toAdBandwidth)
+ }
+ if (fcncu.advertisedFeatures != null && fcncu.advertisedFeatures.toAdAdvertizedBandwidth != null) {
+ props.add(fcncu.advertisedFeatures.toAdAdvertizedBandwidth)
+ }
+ if (fcncu.supported != null && fcncu.supported.toAdSupportedBandwidth != null) {
+ props.add(fcncu.supported.toAdSupportedBandwidth)
+ }
+ if (fcncu.peerFeatures != null && fcncu.peerFeatures.toAdPeerBandwidth != null) {
+ props.add(fcncu.peerFeatures.toAdPeerBandwidth)
+ }
+ if (fcncu.name != null && fcncu.name.toAdName != null) {
+ props.add(fcncu.name.toAdName)
+ }
+ if (fcncu.configuration != null && fcncu.configuration.toAdConfig != null) {
+ props.add(fcncu.configuration.toAdConfig)
+ }
+ if (fcncu.state != null && fcncu.state.toAdState != null) {
+ props.add(fcncu.state.toAdState)
+ }
+ }
+ return props
+ }
+
+ public static def toAdName(String name) {
+ return new Name(name)
+ }
+
+ public static def toAdConfig(PortConfig pc) {
+ var Config config;
+ if (pc.PORTDOWN) {
+ config = new Config(Config.ADMIN_DOWN)
+ } else {
+ config = new Config(Config.ADMIN_UP)
+ }
+ return config
+ }
+
+ public static def toAdState(State s) {
+ var org.opendaylight.controller.sal.core.State state
+ if (s.linkDown) {
+ state = new org.opendaylight.controller.sal.core.State(org.opendaylight.controller.sal.core.State.EDGE_DOWN)
+ } else {
+ state = new org.opendaylight.controller.sal.core.State(org.opendaylight.controller.sal.core.State.EDGE_UP)
+ }
+ return state
+ }
+
+ public static def toAdBandwidth(PortFeatures pf) {
+ var Bandwidth bw = null
+ if (pf.is_10mbHd || pf.is_10mbFd) {
+ bw = new Bandwidth(Bandwidth.BW10Mbps)
+ } else if (pf.is_100mbHd || pf.is_100mbFd) {
+ bw = new Bandwidth(Bandwidth.BW100Mbps)
+ } else if (pf.is_1gbHd || pf.is_1gbFd) {
+ bw = new Bandwidth(Bandwidth.BW1Gbps)
+ } else if (pf.is_1gbFd) {
+ bw = new Bandwidth(Bandwidth.BW10Gbps)
+ } else if (pf.is_10gbFd) {
+ bw = new Bandwidth(Bandwidth.BW10Gbps)
+ } else if (pf.is_40gbFd) {
+ bw = new Bandwidth(Bandwidth.BW40Gbps)
+ } else if (pf.is_100gbFd) {
+ bw = new Bandwidth(Bandwidth.BW100Gbps)
+ } else if (pf.is_1tbFd) {
+ bw = new Bandwidth(Bandwidth.BW1Tbps)
+ }
+ return bw;
+ }
+
+ public static def toAdAdvertizedBandwidth(PortFeatures pf) {
+ var AdvertisedBandwidth abw
+ val bw = pf.toAdBandwidth
+ if (bw != null) {
+ abw = new AdvertisedBandwidth(bw.value)
+ }
+ return abw
+ }
+
+ public static def toAdSupportedBandwidth(PortFeatures pf) {
+ var SupportedBandwidth sbw
+ val bw = pf.toAdBandwidth
+ if (bw != null) {
+ sbw = new SupportedBandwidth(bw.value)
+ }
+ return sbw
+ }
+
+ public static def toAdPeerBandwidth(PortFeatures pf) {
+ var PeerBandwidth pbw
+ val bw = pf.toAdBandwidth
+ if (bw != null) {
+ pbw = new PeerBandwidth(bw.value)
+ }
+ return pbw
+ }
+
+ public static def toADNodeProperties(NodeUpdated nu) {
+ val fcnu = nu.getAugmentation(FlowCapableNodeUpdated)
+ if (fcnu != null) {
+ return fcnu.toADNodeProperties(nu.id)
+ }
+ return new HashSet<org.opendaylight.controller.sal.core.Property>();
+
+ }
+
+ public static def toADNodeProperties(FlowNode fcnu, NodeId id) {
+ val props = new HashSet<org.opendaylight.controller.sal.core.Property>();
+ if (fcnu != null) {
+ props.add(toADTimestamp)
+
+ // props.add(fcnu.supportedActions.toADActions) - TODO
+ if (id != null) {
+ props.add(id.toADMacAddress)
+ }
+ if (fcnu.switchFeatures != null) {
+ if (fcnu.switchFeatures.maxTables != null) {
+ props.add(fcnu.switchFeatures.maxTables.toADTables)
+ }
+ if (fcnu.switchFeatures.capabilities != null) {
+ props.add(fcnu.switchFeatures.capabilities.toADCapabiliities)
+ }
+ if (fcnu.switchFeatures.maxBuffers != null) {
+ props.add(fcnu.switchFeatures.maxBuffers.toADBuffers)
+ }
+ }
+ }
+ return props;
+ }
+
+ public static def toADTimestamp() {
+ val date = new Date();
+ val timestamp = new TimeStamp(date.time, "connectedSince")
+ return timestamp;
+ }
+
+ public static def toADMacAddress(NodeId id) {
+ return new MacAddress(Long.parseLong(id.value.replaceAll("openflow:", "")).longValue.bytesFromDpid)
+ }
+
+ public static def toADTables(Short tables) {
+ return new Tables(tables.byteValue)
+ }
+
+ public static def toADCapabiliities(List<Class<? extends FeatureCapability>> capabilities) {
+ var int b
+ for (capability : capabilities) {
+ if (capability.equals(FlowFeatureCapabilityFlowStats)) {
+ b = Capabilities.CapabilitiesType.FLOW_STATS_CAPABILITY.value.bitwiseOr(b)
+ } else if (capability.equals(FlowFeatureCapabilityTableStats)) {
+ b = Capabilities.CapabilitiesType.TABLE_STATS_CAPABILITY.value.bitwiseOr(b)
+ } else if (capability.equals(FlowFeatureCapabilityPortStats)) {
+ b = Capabilities.CapabilitiesType.PORT_STATS_CAPABILITY.value.bitwiseOr(b)
+ } else if (capability.equals(FlowFeatureCapabilityStp)) {
+ b = Capabilities.CapabilitiesType.STP_CAPABILITY.value.bitwiseOr(b)
+ } else if (capability.equals(FlowFeatureCapabilityIpReasm)) {
+ b = Capabilities.CapabilitiesType.IP_REASSEM_CAPABILITY.value.bitwiseOr(b)
+ } else if (capability.equals(FlowFeatureCapabilityQueueStats)) {
+ b = Capabilities.CapabilitiesType.QUEUE_STATS_CAPABILITY.value.bitwiseOr(b)
+ } else if (capability.equals(FlowFeatureCapabilityArpMatchIp)) {
+ b = Capabilities.CapabilitiesType.ARP_MATCH_IP_CAPABILITY.value.bitwiseOr(b)
+ }
+ }
+ return new Capabilities(b)
+ }
+
+ public static def toADBuffers(Long buffers) {
+ return new Buffers(buffers.intValue)
+ }
+
}
package org.opendaylight.controller.sal.compatibility;
-import com.google.common.net.InetAddresses;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
+import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
+import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
+import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
+import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN;
+import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN_PR;
+import static org.opendaylight.controller.sal.match.MatchType.NW_DST;
+import static org.opendaylight.controller.sal.match.MatchType.NW_PROTO;
+import static org.opendaylight.controller.sal.match.MatchType.NW_SRC;
+import static org.opendaylight.controller.sal.match.MatchType.NW_TOS;
+import static org.opendaylight.controller.sal.match.MatchType.TP_DST;
+import static org.opendaylight.controller.sal.match.MatchType.TP_SRC;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.opendaylight.controller.sal.action.Controller;
import org.opendaylight.controller.sal.action.Drop;
import org.opendaylight.controller.sal.action.SetVlanId;
import org.opendaylight.controller.sal.action.SetVlanPcp;
import org.opendaylight.controller.sal.action.SwPath;
+import org.opendaylight.controller.sal.core.Capabilities;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.ActionList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanId;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
-import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
-import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
-import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
-import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN;
-import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN_PR;
-import static org.opendaylight.controller.sal.match.MatchType.NW_DST;
-import static org.opendaylight.controller.sal.match.MatchType.NW_PROTO;
-import static org.opendaylight.controller.sal.match.MatchType.NW_SRC;
-import static org.opendaylight.controller.sal.match.MatchType.NW_TOS;
-import static org.opendaylight.controller.sal.match.MatchType.TP_DST;
-import static org.opendaylight.controller.sal.match.MatchType.TP_SRC;
+import com.google.common.net.InetAddresses;
public class ToSalConversionsUtils {
private static void fillFromArp(Match target, ArpMatch source) {
Ipv4Prefix sourceAddress = source.getArpSourceTransportAddress();
if (sourceAddress != null) {
- target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null);
+ target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
}
Ipv4Prefix destAddress = source.getArpTargetTransportAddress();
if (destAddress != null) {
- target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null);
+ target.setField(NW_DST, inetAddressFrom(destAddress), null);
}
ArpSourceHardwareAddress sourceHwAddress = source.getArpSourceHardwareAddress();
if (sourceHwAddress != null) {
private static void fillFromIpv6(Match target, Ipv6Match source) {
Ipv6Prefix sourceAddress = source.getIpv6Source();
if (sourceAddress != null) {
- target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null);
+ target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
}
Ipv6Prefix destAddress = source.getIpv6Destination();
if (destAddress != null) {
- target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null);
+ target.setField(NW_DST, inetAddressFrom(destAddress), null);
}
}
private static void fillFromIpv4(Match target, Ipv4Match source) {
Ipv4Prefix sourceAddress = source.getIpv4Source();
if (sourceAddress != null) {
- target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null);
+ target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
}
Ipv4Prefix destAddress = source.getIpv4Destination();
if (destAddress != null) {
- target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null);
+ target.setField(NW_DST, inetAddressFrom(destAddress), null);
}
}
}
}
- private static byte[] bytesFrom(MacAddress address) {
+ public static byte[] bytesFrom(MacAddress address) {
String[] mac = address.getValue().split(":");
byte[] macAddress = new byte[6]; // mac.length == 6 bytes
for (int i = 0; i < mac.length; i++) {
}
return macAddress;
}
+
+ public static byte[] bytesFromDpid(long dpid) {
+ byte[] mac = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ for (short i = 0; i < 6; i++) {
+ mac[5 - i] = (byte) dpid;
+ dpid >>= 8;
+ }
+
+ return mac;
+ }
}
import org.opendaylight.controller.sal.compatibility.NodeMapping;
import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.packet.RawPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
private TransmitPacketInput toTransmitPacketInput(RawPacket rawPacket) {
TransmitPacketInputBuilder builderTPIB = new TransmitPacketInputBuilder();
- NodeConnectorRef egress = NodeMapping.toNodeConnectorRef(rawPacket.getOutgoingNodeConnector());
- NodeConnectorRef ingress = NodeMapping.toNodeConnectorRef(rawPacket.getIncomingNodeConnector());
+ builderTPIB.setNode(NodeMapping.toNodeRef(rawPacket.getOutgoingNodeConnector().getNode()));
+
+ NodeConnectorRef egress = rawPacket.getOutgoingNodeConnector() == null ? null :
+ NodeMapping.toNodeConnectorRef(rawPacket.getOutgoingNodeConnector());
+ NodeConnectorRef ingress = rawPacket.getIncomingNodeConnector() == null ? null :
+ NodeMapping.toNodeConnectorRef(rawPacket.getIncomingNodeConnector());
byte[] payload = rawPacket.getPacketData();
builderTPIB.setEgress(egress);
return builderTPIB.build();
}
+ public PacketProcessingService getDelegate() {
+ return delegate;
+ }
+
+ public void setDelegate(PacketProcessingService delegate) {
+ this.delegate = delegate;
+ }
+
+
+
}
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.common.util.Futures;
import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils;
+import org.opendaylight.controller.sal.compatibility.InventoryMapping;
import org.opendaylight.controller.sal.compatibility.NodeMapping;
import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
import org.opendaylight.controller.sal.core.ConstructionException;
import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
import org.opendaylight.controller.sal.reader.NodeDescription;
import org.opendaylight.controller.sal.reader.NodeTableStatistics;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter64;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowTableStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowTableStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowTableStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.NodeConnectorStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.flow.statistics.output.FlowStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.flow.statistics.output.FlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.statistics.Duration;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.statistics.DurationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Bytes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Packets;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, IReadServiceListener {
+public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, IReadServiceListener{
private static final Logger LOG = LoggerFactory.getLogger(FlowStatisticsAdapter.class);
private IReadService readDelegate;
private NotificationProviderService notifier;
@Override
- public Future<RpcResult<GetAllFlowStatisticsOutput>> getAllFlowStatistics(GetAllFlowStatisticsInput input) {
- GetAllFlowStatisticsOutput rpcResultType = null;
- boolean rpcResultBool = false;
-
- try {
- Node adNode = NodeMapping.toADNode(input.getNode());
- List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
- List<FlowStatistics> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
- GetAllFlowStatisticsOutputBuilder builder = new GetAllFlowStatisticsOutputBuilder();
- rpcResultType = builder.setFlowStatistics(flowsStatistics).build();
- rpcResultBool = true;
- } catch (ConstructionException e) {
- LOG.error(e.getMessage());
- }
+ public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
+ GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
+ //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and
+ // generating aggregate flow statistics out of those individual flow stats.
+ return null;
+ }
- return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
+ @Override
+ public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
+ GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
+ //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and
+ // generating aggregate flow statistics out of those individual flow stats.
+ return null;
}
@Override
- public Future<RpcResult<GetAllNodeConnectorStatisticsOutput>> getAllNodeConnectorStatistics(
- GetAllNodeConnectorStatisticsInput input) {
- GetAllNodeConnectorStatisticsOutput rpcResultType = null;
+ public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
+ GetAllFlowStatisticsFromFlowTableInput input) {
+ GetAllFlowStatisticsFromFlowTableOutput rpcResultType = null;
boolean rpcResultBool = false;
try {
Node adNode = NodeMapping.toADNode(input.getNode());
- List<NodeConnectorStatistics> nodesConnectorStatistics = readDelegate.readNodeConnectors(adNode);
- List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics> odNodesConnectorStatistics;
- odNodesConnectorStatistics = toOdNodesConnectorStatistics(nodesConnectorStatistics);
- GetAllNodeConnectorStatisticsOutputBuilder builder = new GetAllNodeConnectorStatisticsOutputBuilder();
- rpcResultType = builder.setNodeConnectorStatistics(odNodesConnectorStatistics).build();
+ List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
+ List<FlowAndStatisticsMapList> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
+ GetAllFlowStatisticsFromFlowTableOutputBuilder builder = new GetAllFlowStatisticsFromFlowTableOutputBuilder();
+ builder.setTransactionId(new TransactionId(new BigInteger("0")));
+ rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
+
rpcResultBool = true;
} catch (ConstructionException e) {
LOG.error(e.getMessage());
return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
}
+ /**
+ * Essentially this API will return the same result as getAllFlowStatisticsFromFlowTable
+ */
@Override
- public Future<RpcResult<GetFlowStatisticsOutput>> getFlowStatistics(GetFlowStatisticsInput input) {
- GetFlowStatisticsOutput rpcResultType = null;
+ public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
+ GetAllFlowsStatisticsFromAllFlowTablesInput input) {
+
+ GetAllFlowsStatisticsFromAllFlowTablesOutput rpcResultType = null;
boolean rpcResultBool = false;
try {
- Node node = NodeMapping.toADNode(input.getNode());
- Flow flow = ToSalConversionsUtils.toFlow(input);
- FlowOnNode readFlow = readDelegate.readFlow(node, flow);
- FlowStatistics flowOnNodeToFlowStatistics = toOdFlowStatistics(readFlow);
- rpcResultType = new GetFlowStatisticsOutputBuilder(flowOnNodeToFlowStatistics).build();
+ Node adNode = NodeMapping.toADNode(input.getNode());
+ List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
+ List<FlowAndStatisticsMapList> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
+ GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder builder = new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder();
+ builder.setTransactionId(new TransactionId(new BigInteger("0")));
+ rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
+
rpcResultBool = true;
} catch (ConstructionException e) {
LOG.error(e.getMessage());
}
@Override
- public Future<RpcResult<GetFlowTableStatisticsOutput>> getFlowTableStatistics(GetFlowTableStatisticsInput input) {
- GetFlowTableStatisticsOutput rpcResultType = null;
+ public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
+ GetFlowStatisticsFromFlowTableInput input) {
+ GetFlowStatisticsFromFlowTableOutput rpcResultType = null;
boolean rpcResultBool = false;
try {
Node node = NodeMapping.toADNode(input.getNode());
- List<NodeTableStatistics> nodesTable = readDelegate.readNodeTable(node);
- NodeTableStatistics nodeTable = null;
- if (!nodesTable.isEmpty()) {
- nodeTable = nodesTable.get(0);
- rpcResultType = toOdTableStatistics(nodeTable);
- rpcResultBool = true;
- }
- } catch (ConstructionException e) {
- LOG.error(e.getMessage());
- }
-
- return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
- }
-
- @Override
- public Future<RpcResult<GetNodeConnectorStatisticsOutput>> getNodeConnectorStatistics(
- GetNodeConnectorStatisticsInput input) {
- GetNodeConnectorStatisticsOutput rpcResultType = null;
- boolean rpcResultBool = false;
-
- NodeConnectorRef nodeConnector = input.getNodeConnector();
- try {
- NodeConnectorStatistics nodeConnectorStats = readDelegate.readNodeConnector(NodeMapping
- .toADNodeConnector(nodeConnector));
- org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics odNodeConnectorStatistics = toOdNodeConnectorStatistics(nodeConnectorStats);
- rpcResultType = new GetNodeConnectorStatisticsOutputBuilder(odNodeConnectorStatistics).build();
+ Flow flow = ToSalConversionsUtils.toFlow(input);
+ FlowOnNode readFlow = readDelegate.readFlow(node, flow);
+ List<FlowAndStatisticsMapList> flowOnNodeToFlowStatistics = new ArrayList<FlowAndStatisticsMapList>();
+ flowOnNodeToFlowStatistics.add(toOdFlowStatistics(readFlow));
+ rpcResultType = new GetFlowStatisticsFromFlowTableOutputBuilder().setFlowAndStatisticsMapList(flowOnNodeToFlowStatistics).build();
rpcResultBool = true;
} catch (ConstructionException e) {
LOG.error(e.getMessage());
}
@Override
- public void descriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) {
-
- // TODO which *StatisticsUpdated interface should be used?
-
+ public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList) {
+ List<FlowAndStatisticsMapList> flowStatistics = toOdFlowsStatistics(flowStatsList);
+ FlowsStatisticsUpdateBuilder flowsStatisticsUpdateBuilder = new FlowsStatisticsUpdateBuilder();
+ flowsStatisticsUpdateBuilder.setFlowAndStatisticsMapList(flowStatistics);
+ flowsStatisticsUpdateBuilder.setMoreReplies(false);
+ flowsStatisticsUpdateBuilder.setTransactionId(null);
+ flowsStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
+ notifier.publish(flowsStatisticsUpdateBuilder.build());
}
@Override
public void nodeConnectorStatisticsUpdated(Node node, List<NodeConnectorStatistics> ncStatsList) {
- for (NodeConnectorStatistics ndConStats : ncStatsList) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics odNodeConnectorStatistics;
- odNodeConnectorStatistics = toOdNodeConnectorStatistics(ndConStats);
- NodeConnectorStatisticsUpdatedBuilder statisticsBuilder = new NodeConnectorStatisticsUpdatedBuilder(
- odNodeConnectorStatistics);
- notifier.publish(statisticsBuilder.build());
- }
- }
-
- @Override
- public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList) {
- for (FlowOnNode flowOnNode : flowStatsList) {
- FlowStatistics flowStatistics = toOdFlowStatistics(flowOnNode);
- FlowStatisticsUpdatedBuilder statisticsBuilder = new FlowStatisticsUpdatedBuilder(flowStatistics);
- notifier.publish(statisticsBuilder.build());
- }
+ NodeConnectorStatisticsUpdateBuilder nodeConnectorStatisticsUpdateBuilder = new NodeConnectorStatisticsUpdateBuilder();
+ List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatistics = toOdNodeConnectorStatistics(ncStatsList);
+
+ nodeConnectorStatisticsUpdateBuilder.setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatistics);
+ nodeConnectorStatisticsUpdateBuilder.setMoreReplies(false);
+ nodeConnectorStatisticsUpdateBuilder.setTransactionId(null);
+ nodeConnectorStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
+ notifier.publish(nodeConnectorStatisticsUpdateBuilder.build());
}
@Override
public void nodeTableStatisticsUpdated(Node node, List<NodeTableStatistics> tableStatsList) {
- // TODO : Not implemented by AD-SAL.
+
+ FlowTableStatisticsUpdateBuilder flowTableStatisticsUpdateBuilder = new FlowTableStatisticsUpdateBuilder();
+
+ List<FlowTableAndStatisticsMap> flowTableStatistics = toOdFlowTableStatistics(tableStatsList);
+ flowTableStatisticsUpdateBuilder.setFlowTableAndStatisticsMap(flowTableStatistics);
+ flowTableStatisticsUpdateBuilder.setMoreReplies(false);
+ flowTableStatisticsUpdateBuilder.setTransactionId(null);
+ flowTableStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
+ notifier.publish(flowTableStatisticsUpdateBuilder.build());
+}
+
+ @Override
+ public void descriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) {
+ // TODO which *StatisticsUpdated interface should be used?
+
}
- private List<FlowStatistics> toOdFlowsStatistics(List<FlowOnNode> flowsOnNode) {
- List<FlowStatistics> flowsStatistics = new ArrayList<>();
+ private List<FlowAndStatisticsMapList> toOdFlowsStatistics(List<FlowOnNode> flowsOnNode) {
+ List<FlowAndStatisticsMapList> flowsStatistics = new ArrayList<>();
for (FlowOnNode flowOnNode : flowsOnNode) {
flowsStatistics.add(toOdFlowStatistics(flowOnNode));
}
return flowsStatistics;
}
- private FlowStatistics toOdFlowStatistics(FlowOnNode flowOnNode) {
- FlowStatisticsBuilder builder = new FlowStatisticsBuilder();
+ private FlowAndStatisticsMapList toOdFlowStatistics(FlowOnNode flowOnNode) {
+ FlowAndStatisticsMapListBuilder builder = new FlowAndStatisticsMapListBuilder();
builder.setByteCount(toCounter64(flowOnNode.getByteCount()));
builder.setPacketCount(toCounter64(flowOnNode.getPacketCount()));
builder.setDuration(extractDuration(flowOnNode));
-
+ builder.setMatch(FromSalConversionsUtils.toMatch(flowOnNode.getFlow().getMatch()));
+ builder.setPriority((int)flowOnNode.getFlow().getPriority());
+ builder.setHardTimeout((int)flowOnNode.getFlow().getHardTimeout());
+ builder.setIdleTimeout((int)flowOnNode.getFlow().getIdleTimeout());
+ //TODO: actions to instruction conversion
+ builder.setInstructions(null);
return builder.build();
}
- private Duration extractDuration(FlowOnNode flowOnNode) {
+ private org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.Duration extractDuration(FlowOnNode flowOnNode) {
DurationBuilder builder = new DurationBuilder();
- builder.setNanosecond(toCounter64(flowOnNode.getDurationNanoseconds()));
- builder.setSecond(toCounter64(flowOnNode.getDurationSeconds()));
+ builder.setNanosecond(new Counter32((long)flowOnNode.getDurationNanoseconds()));
+ builder.setSecond(new Counter32((long)flowOnNode.getDurationSeconds()));
return builder.build();
}
return new Counter64(byteCountBigInt);
}
- private Counter64 toCounter64(int num) {
- String byteCountStr = String.valueOf(num);
- BigInteger byteCountBigInt = new BigInteger(byteCountStr);
- return new Counter64(byteCountBigInt);
- }
-
- private List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics> toOdNodesConnectorStatistics(
- List<NodeConnectorStatistics> nodesConnectorStatistics) {
- List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics> odNodesConnectorStatistics = new ArrayList<>();
- for (NodeConnectorStatistics nodeConnectorStatistics : nodesConnectorStatistics) {
- odNodesConnectorStatistics.add(toOdNodeConnectorStatistics(nodeConnectorStatistics));
+ private List<FlowTableAndStatisticsMap> toOdFlowTableStatistics(List<NodeTableStatistics> tableStatsList) {
+
+ List<FlowTableAndStatisticsMap> flowTableStatsMap = new ArrayList<FlowTableAndStatisticsMap>();
+ for (NodeTableStatistics nodeTableStatistics : tableStatsList) {
+ FlowTableAndStatisticsMapBuilder flowTableAndStatisticsMapBuilder = new FlowTableAndStatisticsMapBuilder();
+ flowTableAndStatisticsMapBuilder.setActiveFlows(new Counter32((long) nodeTableStatistics.getActiveCount()));
+ flowTableAndStatisticsMapBuilder.setPacketsLookedUp(toCounter64(nodeTableStatistics.getLookupCount()));
+ flowTableAndStatisticsMapBuilder.setPacketsMatched(toCounter64(nodeTableStatistics.getMatchedCount()));
+ flowTableAndStatisticsMapBuilder.setActiveFlows(new Counter32((long) nodeTableStatistics.getActiveCount()));
+ flowTableAndStatisticsMapBuilder.setTableId(new TableId((short)nodeTableStatistics.getNodeTable().getID()));
+ flowTableStatsMap.add(flowTableAndStatisticsMapBuilder.build());
}
- return odNodesConnectorStatistics;
+
+ return flowTableStatsMap;
}
- private org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics toOdNodeConnectorStatistics(
- NodeConnectorStatistics ndConStats) {
- NodeConnectorStatisticsBuilder builder = new NodeConnectorStatisticsBuilder();
-
- builder.setBytes(extractBytes(ndConStats));
- builder.setCollisionCount(toBI(ndConStats.getCollisionCount()));
- builder.setDuration(null);
- builder.setPackets(extractPackets(ndConStats));
- builder.setReceiveCrcError(toBI(ndConStats.getReceiveCRCErrorCount()));
- builder.setReceiveDrops(toBI(ndConStats.getReceiveDropCount()));
- builder.setReceiveErrors(toBI(ndConStats.getReceiveErrorCount()));
- builder.setReceiveFrameError(toBI(ndConStats.getReceiveFrameErrorCount()));
- builder.setReceiveOverRunError(toBI(ndConStats.getReceiveOverRunErrorCount()));
- builder.setTransmitDrops(toBI(ndConStats.getTransmitDropCount()));
- builder.setTransmitErrors(toBI(ndConStats.getTransmitErrorCount()));
-
- return builder.build();
+ private List<NodeConnectorStatisticsAndPortNumberMap> toOdNodeConnectorStatistics(
+ List<NodeConnectorStatistics> ncStatsList) {
+ List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsList = new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
+ for(NodeConnectorStatistics ofNodeConnectorStatistics : ncStatsList){
+ NodeConnectorStatisticsAndPortNumberMapBuilder nodeConnectorStatisticsAndPortNumberMapBuilder = new NodeConnectorStatisticsAndPortNumberMapBuilder();
+
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setBytes(extractBytes(ofNodeConnectorStatistics));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setCollisionCount(toBI(ofNodeConnectorStatistics.getCollisionCount()));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setDuration(null);
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setPackets(extractPackets(ofNodeConnectorStatistics));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveCrcError(toBI(ofNodeConnectorStatistics.getReceiveCRCErrorCount()));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveDrops(toBI(ofNodeConnectorStatistics.getReceiveDropCount()));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveErrors(toBI(ofNodeConnectorStatistics.getReceiveErrorCount()));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveFrameError(toBI(ofNodeConnectorStatistics.getReceiveFrameErrorCount()));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveOverRunError(toBI(ofNodeConnectorStatistics.getReceiveOverRunErrorCount()));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitDrops(toBI(ofNodeConnectorStatistics.getTransmitDropCount()));
+ nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitErrors(toBI(ofNodeConnectorStatistics.getTransmitErrorCount()));
+ nodeConnectorStatisticsList.add(nodeConnectorStatisticsAndPortNumberMapBuilder.build());
+ }
+
+ return nodeConnectorStatisticsList;
}
private BigInteger toBI(long num) {
return builder.build();
}
- private GetFlowTableStatisticsOutput toOdTableStatistics(NodeTableStatistics nodeTable) {
- GetFlowTableStatisticsOutputBuilder builder = new GetFlowTableStatisticsOutputBuilder();
-
- builder.setActive(toCounter64(nodeTable.getActiveCount()));
- builder.setLookup(toCounter64(nodeTable.getLookupCount()));
- builder.setMatched(toCounter64(nodeTable.getMatchedCount()));
-
- return builder.build();
- }
-
- @Override
- public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
- GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
- GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
- GetAllFlowStatisticsFromFlowTableInput input) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
- GetAllFlowsStatisticsFromAllFlowTablesInput input) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
- GetFlowStatisticsFromFlowTableInput input) {
- // TODO Auto-generated method stub
- return null;
- }
-
}
--- /dev/null
+package org.opendaylight.controller.sal.compatibility.topology
+
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+
+import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
+
+class TopologyAdapter implements IPluginInTopologyService {
+
+ @Property
+ DataProviderService dataService;
+
+ @Property
+ IPluginOutTopologyService topologyPublisher;
+
+ override sollicitRefresh() {
+ val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,new TopologyKey(new TopologyId("flow:1"))).toInstance;
+ val reader = TypeSafeDataReader.forReader(dataService)
+ val topology = reader.readOperationalData(path)
+ topologyPublisher.edgeUpdate(topology.toADEdgeUpdates(reader))
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.compatibility.topology
+
+import com.google.common.collect.FluentIterable
+import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
+import org.slf4j.LoggerFactory
+
+class TopologyCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+ static val LOG = LoggerFactory.getLogger(TopologyCommitHandler);
+ @Property
+ IPluginOutTopologyService topologyPublisher;
+
+ @Property
+ DataProviderService dataService;
+
+ new(DataProviderService dataService) {
+ _topologyPublisher = topologyPublisher
+ _dataService = dataService
+ }
+
+ override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+ val msg = new CopyOnWriteArrayList<TopoEdgeUpdate>()
+ try {
+ val reader = TypeSafeDataReader.forReader(dataService)
+ val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, new TopologyKey(new TopologyId("flow:1"))).toInstance
+ val topology = reader.readOperationalData(topologyPath)
+ val adds = FluentIterable.from(modification.createdOperationalData.entrySet)
+ .filter[value instanceof Link]
+ .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)]
+ .toList
+ val updates = FluentIterable.from(modification.updatedOperationalData.entrySet)
+ .filter[!modification.createdOperationalData.containsKey(key) && (value instanceof Link)]
+ .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] // Evidently the ADSAL does not expect edge 'CHANGED"
+ .toList
+ val removes = FluentIterable.from(modification.removedOperationalData)
+ .transform[reader.readOperationalData(it as InstanceIdentifier<DataObject>)]
+ .filter[it instanceof Link]
+ .transform[(it as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.REMOVED,reader)]
+ .toList
+ msg.addAll(adds)
+ msg.addAll(updates)
+ msg.addAll(removes)
+ } catch (Exception e) {
+ LOG.error("Exception caught",e)
+ }
+ return new TopologyTransaction(modification,topologyPublisher,dataService,msg)
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.compatibility.topology
+
+import com.google.common.collect.FluentIterable
+import java.util.Collections
+import java.util.List
+import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.sal.core.ConstructionException
+import org.opendaylight.controller.sal.core.Edge
+import org.opendaylight.controller.sal.core.Node
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+
+import static com.google.common.base.Preconditions.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
+
+class TopologyMapping {
+
+ private new() {
+ throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
+ }
+
+ public static def toADEdgeUpdates(Topology topology,TypeSafeDataReader reader) {
+ val List<TopoEdgeUpdate> result = new CopyOnWriteArrayList<TopoEdgeUpdate>()
+ return FluentIterable.from(topology.link).transform[toAdEdge(topology).toTopoEdgeUpdate(reader)].copyInto(result)
+ }
+
+ public static def toAdEdge(Link link,Topology topology) {
+ val adSrc = link.source.sourceTp.toADNodeConnector(link.source.sourceNode)
+ val adDst = link.destination.destTp.toADNodeConnector(link.destination.destNode)
+ return new Edge(adSrc,adDst);
+ }
+
+ public static def toTopoEdgeUpdate(Edge e,TypeSafeDataReader reader) {
+ return toTopoEdgeUpdate(e,UpdateType.ADDED,reader)
+ }
+
+ public static def toTopoEdgeUpdate(Edge e,UpdateType type,TypeSafeDataReader reader) {
+ return new TopoEdgeUpdate(e,e.toAdEdgeProperties(reader),type)
+ }
+
+ public static def toAdEdgeProperties(Edge e,TypeSafeDataReader reader) {
+ val nc = reader.readOperationalData(e.tailNodeConnector.toNodeConnectorRef.value as InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector>)
+ return nc.toADNodeConnectorProperties
+ }
+
+ public static def toADNodeId(NodeId nodeId) {
+ checkNotNull(nodeId);
+ return nodeId.value
+ }
+ public static def toADNodeConnector(TpId source,NodeId nodeId) throws ConstructionException {
+ checkNotNull(source);
+ return new NodeConnector(MD_SAL_TYPE,source.toADNodeConnectorId,nodeId.toADNode)
+ }
+
+ public static def toADNodeConnectorId(TpId nodeConnectorId) {
+ return nodeConnectorId.value
+ }
+
+ public static def toADNode(NodeId nodeId) {
+ checkNotNull(nodeId);
+ return new Node(MD_SAL_TYPE,nodeId.toADNodeId);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.compatibility.topology
+
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+import org.slf4j.LoggerFactory
+
+class TopologyProvider implements AutoCloseable{
+ static val LOG = LoggerFactory.getLogger(TopologyProvider);
+ TopologyCommitHandler commitHandler
+
+ @Property
+ IPluginOutTopologyService topologyPublisher;
+
+ @Property
+ DataProviderService dataService;
+
+ Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
+
+ def void start() {
+ commitHandler = new TopologyCommitHandler(dataService)
+ commitHandler.setTopologyPublisher(topologyPublisher)
+ val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(NetworkTopology)
+ .child(Topology,new TopologyKey(new TopologyId("flow:1")))
+ .child(Link)
+ .toInstance();
+ commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
+ LOG.info("TopologyProvider started")
+ }
+
+ override close() throws Exception {
+ commitHandlerRegistration.close
+ }
+
+ def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) {
+ _topologyPublisher = topologyPublisher;
+ commitHandler.setTopologyPublisher(topologyPublisher);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.compatibility.topology
+
+import java.util.Collections
+import java.util.List
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.slf4j.LoggerFactory
+
+class TopologyTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
+ static val LOG = LoggerFactory.getLogger(TopologyTransaction);
+ @Property
+ val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+
+ @Property
+ IPluginOutTopologyService topologyPublisher;
+
+ @Property
+ DataProviderService dataService;
+ @Property
+ List<TopoEdgeUpdate> edgeUpdates;
+
+ new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,IPluginOutTopologyService topologyPublisher,
+ DataProviderService dataService,List<TopoEdgeUpdate> edgeUpdates) {
+ _modification = modification;
+ _topologyPublisher = topologyPublisher
+ _dataService = dataService
+ _edgeUpdates = edgeUpdates
+ }
+ override finish() throws IllegalStateException {
+
+ if(topologyPublisher != null && _edgeUpdates != null && !edgeUpdates.empty) {
+ topologyPublisher.edgeUpdate(edgeUpdates)
+ }
+
+ return new RpcResultTo()
+ }
+
+ override getModification() {
+ return _modification;
+ }
+
+ override rollback() throws IllegalStateException {
+ // NOOP
+ }
+}
+class RpcResultTo implements RpcResult<Void> {
+
+ override getErrors() {
+ return Collections.emptySet
+ }
+
+ override getResult() {
+ return null;
+ }
+
+ override isSuccessful() {
+ return true;
+ }
+
+}
\ No newline at end of file
import org.opendaylight.yangtools.yang.binding.DataObject
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
class FlowTransaction extends AbstractTransaction {
@Property
- val SalFlowService salFlowService;
+ val SalFlowService salFlowService;
+
new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalFlowService salFlowService) {
- super(modification)
+ super(modification)
_salFlowService = salFlowService;
}
val tableInstanceId = instanceId.firstIdentifierOf(Table);
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new RemoveFlowInputBuilder(flow);
+ builder.setFlowRef(new FlowRef(instanceId));
builder.setNode(new NodeRef(nodeInstanceId));
builder.setFlowTable(new FlowTableRef(tableInstanceId));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
_salFlowService.removeFlow(builder.build());
}
}
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new UpdateFlowInputBuilder();
builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setFlowRef(new FlowRef(instanceId));
val ufb = new UpdatedFlowBuilder(updatedFlow);
builder.setUpdatedFlow((ufb.build()));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
val ofb = new OriginalFlowBuilder(originalFlow);
builder.setOriginalFlow(ofb.build());
_salFlowService.updateFlow(builder.build());
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new AddFlowInputBuilder(flow);
builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
+ builder.setFlowRef(new FlowRef(instanceId));
builder.setFlowTable(new FlowTableRef(tableInstanceId));
_salFlowService.addFlow(builder.build());
}
import org.opendaylight.controller.frm.AbstractTransaction
import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
import org.opendaylight.yangtools.yang.binding.DataObject
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
class GroupTransaction extends AbstractTransaction {
@Property
val SalGroupService groupService;
-
+
new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalGroupService groupService) {
- super(modification)
+ super(modification)
_groupService = groupService;
}
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new RemoveGroupInputBuilder(group);
builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
+ builder.setGroupRef(new GroupRef(instanceId));
_groupService.removeGroup(builder.build());
}
}
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new UpdateGroupInputBuilder();
builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setGroupRef(new GroupRef(instanceId));
val ufb = new UpdatedGroupBuilder(updatedGroup);
builder.setUpdatedGroup((ufb.build()));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
val ofb = new OriginalGroupBuilder(originalGroup);
builder.setOriginalGroup(ofb.build());
_groupService.updateGroup(builder.build());
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new AddGroupInputBuilder(group);
builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setGroupRef(new GroupRef(instanceId));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
_groupService.addGroup(builder.build());
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter
import org.opendaylight.yangtools.yang.binding.DataObject
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
class MeterTransaction extends AbstractTransaction {
@Property
val SalMeterService salMeterService;
-
+
new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalMeterService salMeterService) {
- super(modification)
+ super(modification)
_salMeterService = salMeterService;
}
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new RemoveMeterInputBuilder(meter);
builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setMeterRef(new MeterRef(instanceId));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
_salMeterService.removeMeter(builder.build());
}
}
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new UpdateMeterInputBuilder();
builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setMeterRef(new MeterRef(instanceId));
val ufb = new UpdatedMeterBuilder(updatedMeter);
builder.setUpdatedMeter((ufb.build()));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
val ofb = new OriginalMeterBuilder(originalMeter);
builder.setOriginalMeter(ofb.build());
_salMeterService.updateMeter(builder.build());
val nodeInstanceId = instanceId.firstIdentifierOf(Node);
val builder = new AddMeterInputBuilder(meter);
builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setMeterRef(new MeterRef(instanceId));
+ builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
_salMeterService.addMeter(builder.build());
}
}
// Check path
val it = manager.startChange()
- removeRuntimeData(ref.value as InstanceIdentifier<? extends DataObject>);
+ removeOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
commit()
}
data.addAugmentation(FlowCapableNodeConnector, augment)
}
- putRuntimeData(ref.value as InstanceIdentifier<NodeConnector>, data.build());
+ putOperationalData(ref.value as InstanceIdentifier<NodeConnector>, data.build());
commit()
}
val ref = node.nodeRef;
val it = manager.startChange()
- removeRuntimeData(ref.value as InstanceIdentifier<? extends DataObject>);
+ removeOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
commit()
}
data.addAugmentation(FlowCapableNode, augment)
}
- putRuntimeData(ref.value as InstanceIdentifier<Node>, data.build())
+ putOperationalData(ref.value as InstanceIdentifier<Node>, data.build())
commit()
}
}
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.0</version>
+ <version>2013.08.27.1</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>model-inventory</artifactId>
+ <version>${project.version}</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
description "Check chaining for loops and delete";
}
+ typedef group-ref {
+ type instance-identifier;
+ }
+
grouping group {
leaf group-type {
type string;
}
- leaf install {
- type boolean;
- }
-
leaf barrier {
type boolean;
}
import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
import opendaylight-l2-types {prefix l2t;revision-date "2013-08-27";}
+ import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
revision "2013-10-26" {
description "Initial revision of macth types";
grouping match {
leaf in-port {
- type uint32;
+ type inv:node-connector-id;
}
leaf in-phy-port {
- type uint32;
+ type inv:node-connector-id;
}
container "metadata" {
}
}
+ typedef meter-ref {
+ type instance-identifier;
+ }
+
grouping meter {
leaf flags {
leaf meter-id {
type meter-id;
- }
+ }
- leaf install {
+ leaf barrier {
type boolean;
}
+
leaf meter-name {
type string;
}
}
leaf max-length {
- type uint16 {
- range "0..65294";
- }
+ type uint16;
}
}
}
case controller-action-case {
container controller-action {
leaf max-length {
- type uint16 {
- range "0..65294";
- }
+ type uint16;
}
}
}
description "Initial revision of flow service";
}
+ typedef flow-ref {
+ type instance-identifier;
+ }
+
typedef output-port-values {
type enumeration {
enum MAX {
}
}
- typedef port-state {
- type enumeration {
- enum link-down;
- enum blocked;
- enum live;
+ grouping port-state {
+ leaf link-down {
+ type boolean;
+ }
+ leaf blocked {
+ type boolean;
+ }
+ leaf live {
+ type boolean;
}
}
description "Human readable name of the port";
}
- leaf state {
- type port-state;
- description "Bit map of OFPPS-* flags";
+ container state {
+ uses port-state;
+ description "Description of state of port";
}
leaf current-feature {
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.0</version>
+ <version>2013.08.27.1</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.0</version>
+ <version>2013.08.27.1</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
prefix type;
import opendaylight-inventory {prefix inv; revision-date "2013-08-19";}
+ import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
import yang-ext {prefix ext; revision-date "2013-07-09";}
revision "2013-11-03" {
typedef transaction-id {
type uint64;
}
+ // This refers to MD-SAL transaction reference.
+ grouping transaction-metadata {
+ leaf transaction-uri {
+ type inet:uri;
+ }
+ }
grouping transaction-aware {
leaf transaction-id {
}
typedef flow-id {
- type uint32; // Note: This doesn't really belong here, and not sure if unint32 is right
+ type inet:uri;
}
grouping tables {
rpc add-flow {
input {
- uses node-flow;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf flow-ref {
+ type types:flow-ref;
+ }
+ uses node-flow;
}
output {
uses tr:transaction-aware;
rpc remove-flow {
input {
- uses node-flow;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf flow-ref {
+ type types:flow-ref;
+ }
+ uses node-flow;
}
output {
uses tr:transaction-aware;
rpc update-flow {
input {
- uses flow-update;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf flow-ref {
+ type types:flow-ref;
+ }
+ uses flow-update;
}
output {
uses tr:transaction-aware;
}
notification flow-added {
+ uses tr:transaction-metadata;
+ leaf flow-ref {
+ type types:flow-ref;
+ }
uses node-flow;
uses tr:transaction-aware;
}
notification flow-updated {
+ uses tr:transaction-metadata;
+ leaf flow-ref {
+ type types:flow-ref;
+ }
uses node-flow;
- uses tr:transaction-aware;
+ uses tr:transaction-aware;
}
notification flow-removed {
+ uses tr:transaction-metadata;
+ leaf flow-ref {
+ type types:flow-ref;
+ }
uses node-flow;
uses tr:transaction-aware;
}
notification node-error-notification {
uses error:error-message;
uses tr:transaction-aware;
+ uses tr:transaction-metadata;
}
notification node-experimenter-error-notification {
rpc add-group {
input {
- uses node-group;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf group-ref {
+ type group-type:group-ref;
+ }
+ uses node-group;
}
output {
uses tr:transaction-aware;
rpc remove-group {
input {
- uses node-group;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf group-ref {
+ type group-type:group-ref;
+ }
+ uses node-group;
}
output {
uses tr:transaction-aware;
rpc update-group {
input {
- uses group-update;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf group-ref {
+ type group-type:group-ref;
+ }
+ uses group-update;
}
output {
uses tr:transaction-aware;
}
notification group-added {
+ uses tr:transaction-metadata;
+ leaf group-ref {
+ type group-type:group-ref;
+ }
uses node-group;
uses tr:transaction-aware;
}
notification group-updated {
+ uses tr:transaction-metadata;
+ leaf group-ref {
+ type group-type:group-ref;
+ }
uses node-group;
uses tr:transaction-aware;
}
notification group-removed {
+ uses tr:transaction-metadata;
+ leaf group-ref {
+ type group-type:group-ref;
+ }
uses node-group;
uses tr:transaction-aware;
}
rpc add-meter {
input {
- uses node-meter;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf meter-ref {
+ type meter-type:meter-ref;
+ }
+ uses node-meter;
}
output {
uses tr:transaction-aware;
rpc remove-meter {
input {
- uses node-meter;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf meter-ref {
+ type meter-type:meter-ref;
+ }
+
+ uses node-meter;
}
output {
uses tr:transaction-aware;
rpc update-meter {
input {
- uses meter-update;
- uses tr:transaction-aware;
+ uses tr:transaction-metadata;
+ leaf meter-ref {
+ type meter-type:meter-ref;
+ }
+
+ uses meter-update;
}
output {
uses tr:transaction-aware;
}
notification meter-added {
+ uses tr:transaction-metadata;
+ leaf meter-ref {
+ type meter-type:meter-ref;
+ }
uses node-meter;
uses tr:transaction-aware;
}
notification meter-updated {
+ uses tr:transaction-metadata;
+ leaf meter-ref {
+ type meter-type:meter-ref;
+ }
uses node-meter;
uses tr:transaction-aware;
}
notification meter-removed {
+ uses tr:transaction-metadata;
+ leaf meter-ref {
+ type meter-type:meter-ref;
+ }
uses node-meter;
uses tr:transaction-aware;
}
import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
import ietf-yang-types {prefix yang;revision-date "2010-09-24";}
import opendaylight-l2-types {prefix types;revision-date "2013-08-27";}
+ import opendaylight-match-types {prefix match-type;revision-date "2013-10-26";}
+ import opendaylight-table-types {prefix table-type;revision-date "2013-10-26";}
revision "2013-07-09" {
description "";
}
}
+ identity packet-in-reason {
+ description "Base identity for all the available packet in reason";
+ }
+
+ identity no-match {
+ base packet-in-reason;
+ description "No matching flow in the classifier";
+ }
+
+ identity send-to-controller {
+ base packet-in-reason;
+ description "Explicit instruction to send packet to controller";
+ }
+
+ identity invalid-ttl {
+ base packet-in-reason;
+ description "Packet with invalid TTL";
+ }
notification packet-received {
leaf cookie {
type cookie;
}
+
+ leaf table-id {
+ type table-type:table-id;
+ }
+
+ leaf packet-in-reason {
+ type identityref {
+ base packet-in-reason;
+ }
+ }
+
+ container match {
+ uses match-type:match;
+ }
+
uses raw-packet;
}
uses raw-packet;
}
}
-}
\ No newline at end of file
+}
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27-SNAPSHOT</version>
+ <version>2013.08.27.1-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
import flow-node-inventory {prefix flow-node;revision-date "2013-08-19";}
import flow-capable-transaction {prefix tr;}
import sal-flow {prefix flow;}
+ import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
revision "2013-08-19" {
typedef flow-id {
description "flow id";
- type yang:counter32;
+ type inet:uri;
}
grouping flow-and-statistics-map-list {
}
}
- // RPC calls to fetch flow statistics
+ // RPC calls to fetch aggregate flow statistics
rpc get-aggregate-flow-statistics-from-flow-table-for-all-flows {
description "Fetch aggregate statistics for all the flows present in the specific flow table of the switch";
input {
uses stat-types:aggregate-flow-statistics;
uses tr:transaction-aware;
}
-
- //Keeping flow statistics RPC call for backward compatibility for sal-compatibility layer --START
- rpc get-flow-statistics {
- input {
- uses inv:node-context-ref;
- uses flow-types:flow;
- }
- output {
- uses flow-types:flow-statistics;
- }
- }
-
- rpc get-all-flow-statistics {
- input {
- uses inv:node-context-ref;
- }
- output {
- list flow-statistics {
- uses flow-types:flow-statistics;
- }
- }
- }
-
- notification flow-statistics-updated {
- uses flow-types:flow-statistics;
- }
-
- //Keeping flow statistics RPC call for backward compatibility for sal-compatibility layer --END
-
- //RPC call to fetch node connector statistics
- rpc get-node-connector-statistics {
- input {
- uses inv:node-context-ref;
- leaf node-connector {
- type inv:node-connector-ref;
- }
- }
- output {
- uses stat-types:node-connector-statistics;
- }
- }
-
- rpc get-all-node-connector-statistics {
- input {
- uses inv:node-context-ref;
- }
- output {
- list node-connector-statistics {
- uses stat-types:node-connector-statistics;
- }
- }
- }
-
- rpc get-flow-table-statistics {
- input {
- uses inv:node-context-ref;
- }
- output {
- uses flow-types:flow-table-statistics;
- }
- }
-
- notification flow-table-statistics-updated {
- leaf flow-table {
- type flow:flow-table-ref;
- }
- uses flow-types:flow-table-statistics;
- }
-
- notification node-connector-statistics-updated {
- uses stat-types:node-connector-statistics;
- }
}
import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
import opendaylight-group-types {prefix group-types;revision-date "2013-10-18";}
import flow-capable-transaction {prefix tr;}
+ import flow-node-inventory {prefix fni;}
contact
"Anilkumar Vishnoi
}
}
- augment "/inv:nodes/inv:node/group-types:group" {
+ augment "/inv:nodes/inv:node/fni:group" {
ext:augment-identifier "node-group-statistics";
uses group-statistics;
}
}
// RPC calls
- rpc get-all-ports-statistics {
- description "Get statistics for all the ports from the node";
+ rpc get-all-node-connectors-statistics {
+ description "Get statistics for all node connectors from the node";
input {
uses inv:node-context-ref;
}
output {
- uses stat-types:node-connector-statistics;
+ uses node-connector-statistics-and-port-number-map;
uses tr:transaction-aware;
}
}
- rpc get-port-statistics {
- description "Get statistics for given port from the node";
+ rpc get-node-connector-statistics {
+ description "Get statistics for given node connector from the node";
input {
uses inv:node-context-ref;
leaf node-connector-id {
}
}
- //Notification for port statistics update
+ //Notification for node connector statistics update
grouping node-connector-statistics-and-port-number-map {
- description "List of flow and statistics map";
+ description "List of map - node connectors and their statistics";
list node-connector-statistics-and-port-number-map {
key "node-connector-id";
leaf node-connector-id {
}
}
- notification port-statistics-update {
+ notification node-connector-statistics-update {
leaf moreReplies {
type boolean;
}
--- /dev/null
+module netconf-node-inventory {
+ namespace "urn:opendaylight:netconf-node-inventory";
+ prefix "netinv";
+
+ import opendaylight-inventory { prefix inv; revision-date "2013-08-19";}
+ import yang-ext {prefix ext; revision-date "2013-07-09";}
+
+ revision "2014-01-08" {
+ description "Initial revision of Inventory model";
+ }
+
+ grouping netconf-node-fields {
+ leaf-list initial-capability {
+ type string;
+ }
+
+ leaf-list current-capability {
+ type string;
+ }
+ }
+
+ augment /inv:nodes/inv:node {
+ ext:augment-identifier "netconf-node";
+
+ uses netconf-node-fields;
+ }
+}
\ No newline at end of file
<packaging>bundle</packaging>
<dependencies>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-inventory</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-topology</artifactId>
- <version>2013.07.12.2-SNAPSHOT</version>
- </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-inventory</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-topology</artifactId>
+ <version>2013.10.21.0-SNAPSHOT</version>
+ </dependency>
</dependencies>
</project>
import ietf-inet-types { prefix "inet"; }
import opendaylight-inventory {prefix "inv";}
import opendaylight-topology {prefix "odt";}
- import network-topology {prefix "topo";}
+ import network-topology {prefix "topo"; revision-date "2013-07-12"; }
organization "TBD";
augment "/topo:network-topology/topo:topology/topo:node" {
ext:augment-identifier "inventory-node";
- uses inv:node-context-ref;
+ leaf inventory-node-ref {
+ type inv:node-ref;
+ }
}
augment "/topo:network-topology/topo:topology/topo:node/topo:termination-point" {
ext:augment-identifier "inventory-node-connector";
- leaf node-connector {
+ leaf inventory-node-connector-ref {
ext:context-reference "inv:node-connector-context";
type inv:node-connector-ref;
}
}
-}
\ No newline at end of file
+}
import yang-ext { prefix "ext"; }
import ietf-inet-types { prefix "inet"; }
import opendaylight-inventory {prefix "inv";}
- import network-topology {prefix "topo";}
+ import network-topology {prefix "topo"; revision-date "2013-07-12"; }
organization "TBD";
import yang-ext { prefix "ext"; }
import ietf-inet-types { prefix "inet"; }
- import network-topology {prefix "topo";}
+ import network-topology {prefix "topo"; revision-date "2013-07-12"; }
import opendaylight-topology {prefix "odl";}
organization "TBD";
ext:augment-identifier "aggregated-node";
uses aggregate-node;
}
-}
\ No newline at end of file
+}
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <bundle.plugin.version>2.3.7</bundle.plugin.version>
+ <bundle.plugin.version>2.4.0</bundle.plugin.version>
</properties>
<modules>
<configuration>
<instructions>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
- <Import-Package>*,org.opendaylight.yangtools.yang.binding.annotations</Import-Package>
+ <Import-Package>org.opendaylight.yangtools.yang.binding.annotations, *</Import-Package>
</instructions>
</configuration>
</plugin>
<codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
<outputBaseDir>target/site/models</outputBaseDir>
</generator>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.yangtools.yang.wadl.generator.maven.WadlGenerator</codeGeneratorClass>
+ <outputBaseDir>target/site/models</outputBaseDir>
+ </generator>
</codeGenerators>
<inspectDependencies>true</inspectDependencies>
</configuration>
<module>inventory-manager</module>
<module>statistics-manager</module>
+ <module>topology-manager</module>
<module>forwardingrules-manager</module>
+ <module>topology-lldp-discovery</module>
<!-- Compability Packages -->
<module>compatibility</module>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
</Export-Package>
<Import-Package>
com.sun.jersey.spi.container.servlet,
- org.codehaus.jackson.annotate,
+ com.fasterxml.jackson.annotation,
javax.ws.rs,
javax.ws.rs.core,
javax.xml.bind,
* version of RpcServices
*
*/
-public interface RpcConsumerRegistry {
+public interface RpcConsumerRegistry extends BindingAwareService {
/**
* Returns a session specific instance (implementation) of requested
* YANG module implentation / service provided by consumer.
package org.opendaylight.controller.sal.binding.api;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
/**
- * Interface defining provider's access to the Rpc Registry
- * which could be used to register their implementations of service to the MD-SAL.
+ * Interface defining provider's access to the Rpc Registry which could be used
+ * to register their implementations of service to the MD-SAL.
*
* @author ttkacik
- *
+ *
*/
-public interface RpcProviderRegistry extends RpcConsumerRegistry {
+public interface RpcProviderRegistry extends //
+ RpcConsumerRegistry, //
+ RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
/**
* Registers an global RpcService implementation.
*
/**
*
- * Register an Routed RpcService where routing is determined on annotated (in YANG model)
- * context-reference and value of annotated leaf.
+ * Register an Routed RpcService where routing is determined on annotated
+ * (in YANG model) context-reference and value of annotated leaf.
*
- * @param type Type of RpcService, use generated interface class, not your implementation clas
- * @param implementation Implementation of RpcService
- * @return Registration object for routed Rpc which could be used to close an
+ * @param type
+ * Type of RpcService, use generated interface class, not your
+ * implementation clas
+ * @param implementation
+ * Implementation of RpcService
+ * @return Registration object for routed Rpc which could be used to close
+ * an
*
* @throws IllegalStateException
*/
package org.opendaylight.controller.sal.binding.api.mount;
+import java.util.EventListener;
+
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
/**
- * Provider MountProviderService, this version allows access to MD-SAL
- * services specific for this mountpoint and registration / provision of
- * interfaces for mount point.
+ * Provider MountProviderService, this version allows access to MD-SAL services
+ * specific for this mountpoint and registration / provision of interfaces for
+ * mount point.
*
* @author ttkacik
*
*/
-public interface MountProviderService extends MountInstance {
+public interface MountProviderService extends MountService {
+
+ @Override
+ public MountProviderInstance getMountPoint(InstanceIdentifier<?> path);
MountProviderInstance createMountPoint(InstanceIdentifier<?> path);
+
+ MountProviderInstance createOrGetMountPoint(InstanceIdentifier<?> path);
+
+ ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+
+ public interface MountProvisionListener extends EventListener {
+
+ void onMountPointCreated(InstanceIdentifier<?> path);
+
+ void onMountPointRemoved(InstanceIdentifier<?> path);
+
+ }
}
-package org.opendaylight.controller.sal.binding.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
* 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.binding.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
import java.util.Set;
-package org.opendaylight.controller.sal.binding.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.RpcService;
* 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.binding.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
import java.util.Map;
<artifactId>sal-binding-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
/**\r
-* Generated file\r
+ * Generated file\r
\r
-* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl\r
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator\r
-* Generated at: Wed Nov 20 17:33:01 CET 2013\r
-*\r
-* Do not modify this file unless it is present under src/main directory\r
-*/\r
+ * Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl\r
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator\r
+ * Generated at: Wed Nov 20 17:33:01 CET 2013\r
+ *\r
+ * Do not modify this file unless it is present under src/main directory\r
+ */\r
package org.opendaylight.controller.config.yang.md.sal.binding.impl;\r
\r
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;\r
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardingUtils;\r
import org.osgi.framework.BundleContext;\r
\r
-import com.google.common.base.Preconditions;\r
+import com.google.common.util.concurrent.MoreExecutors;\r
\r
/**\r
*\r
*/\r
-public final class BindingBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {\r
+public final class BindingBrokerImplModule extends\r
+ org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {\r
\r
private BundleContext bundleContext;\r
\r
- public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
+ public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
super(identifier, dependencyResolver);\r
}\r
\r
- public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
+ public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,\r
+ BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
super(identifier, dependencyResolver, oldModule, oldInstance);\r
}\r
\r
@Override\r
- public void validate(){\r
+ public void validate() {\r
super.validate();\r
}\r
\r
@Override\r
public java.lang.AutoCloseable createInstance() {\r
- BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getIdentifier().getInstanceName(),getBundleContext());\r
- broker.setDataBroker(getDataBrokerDependency());\r
- broker.setNotifyBroker(getNotificationServiceDependency());\r
+\r
+ RootBindingAwareBroker broker;\r
+ if (DomForwardingUtils.isDomForwardedBroker(getDataBrokerDependency())) {\r
+ broker = createForwardedBroker();\r
+ } else {\r
+ broker = createStandaloneBroker();\r
+ }\r
broker.start();\r
return broker;\r
}\r
\r
+ private RootBindingAwareBroker createStandaloneBroker() {\r
+ RootBindingAwareBroker broker = new RootBindingAwareBroker(getIdentifier().getInstanceName());\r
+\r
+ broker.setDataBroker(getDataBrokerDependency());\r
+ broker.setNotificationBroker(getNotificationServiceDependency());\r
+ broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
+ return broker;\r
+ }\r
+\r
+ private RootBindingAwareBroker createForwardedBroker() {\r
+ DomForwardedBindingBrokerImpl broker = new DomForwardedBindingBrokerImpl(getIdentifier().getInstanceName());\r
+\r
+ broker.setDataBroker(getDataBrokerDependency());\r
+ broker.setNotificationBroker(getNotificationServiceDependency());\r
+ broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
+\r
+ broker.getMountManager().setDataCommitExecutor(SingletonHolder.getDefaultCommitExecutor());\r
+ broker.getMountManager().setNotificationExecutor(SingletonHolder.getDefaultNotificationExecutor());\r
+\r
+\r
+ DomForwardingUtils.reuseForwardingFrom(broker, broker.getDataBroker());\r
+ broker.startForwarding();\r
+ return broker;\r
+ }\r
+\r
public BundleContext getBundleContext() {\r
return bundleContext;\r
}\r
import java.util.concurrent.Executors;\r
import java.util.concurrent.ScheduledExecutorService;\r
\r
-import org.opendaylight.controller.config.yang.md.sal.binding.statistics.DataBrokerRuntimeMXBeanImpl;\r
import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;\r
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl;\r
import org.opendaylight.controller.sal.core.api.Broker;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
import org.opendaylight.controller.sal.core.api.data.DataProviderService;\r
import org.opendaylight.yangtools.yang.binding.DataObject;\r
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
\r
@Override\r
public java.lang.AutoCloseable createInstance() {\r
- DataBrokerRuntimeMXBeanImpl dataBindingBroker = new DataBrokerRuntimeMXBeanImpl();\r
+ RootDataBrokerImpl dataBindingBroker;\r
\r
- // FIXME: obtain via dependency management\r
- ExecutorService executor = Executors.newCachedThreadPool();\r
- ExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);\r
- dataBindingBroker.setExecutor(listeningExecutor);\r
-\r
- Broker domBroker = getDomBrokerDependency();\r
- BindingIndependentMappingService mappingService = getMappingServiceDependency();\r
\r
- if (domBroker != null && mappingService != null) {\r
- BindingIndependentConnector runtimeMapping = new BindingIndependentConnector();\r
- runtimeMapping.setMappingService(mappingService);\r
- runtimeMapping.setBaDataService(dataBindingBroker);\r
- domBroker.registerProvider(runtimeMapping, getBundleContext());\r
+ ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();\r
+ \r
+ if (getDomBrokerDependency() != null && getMappingServiceDependency() != null) {\r
+ \r
+ dataBindingBroker = createDomConnectedBroker(listeningExecutor);\r
+ } else {\r
+ dataBindingBroker = createStandAloneBroker(listeningExecutor);\r
}\r
- getRootRuntimeBeanRegistratorWrapper().register(dataBindingBroker);\r
+ dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper());\r
+\r
return dataBindingBroker;\r
}\r
+ private RootDataBrokerImpl createStandAloneBroker(ExecutorService listeningExecutor) {\r
+ RootDataBrokerImpl broker = new RootDataBrokerImpl();\r
+ broker.setExecutor(listeningExecutor);\r
+ return broker;\r
+ }\r
+\r
+ private RootDataBrokerImpl createDomConnectedBroker(ExecutorService listeningExecutor) {\r
+ DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl();\r
+ forwardedBroker.setExecutor(listeningExecutor);\r
+ BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(getMappingServiceDependency());\r
+ getDomBrokerDependency().registerProvider(forwardedBroker, getBundleContext());\r
+ ProviderSession domContext = forwardedBroker.getDomProviderContext();\r
+ forwardedBroker.setConnector(connector);\r
+ forwardedBroker.setDomProviderContext(domContext);\r
+ forwardedBroker.startForwarding();\r
+ return forwardedBroker;\r
+ }\r
\r
public BundleContext getBundleContext() {\r
return bundleContext;\r
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
import com.google.common.util.concurrent.ListeningExecutorService;
@Override
public java.lang.AutoCloseable createInstance() {
- ExecutorService executor = Executors.newFixedThreadPool(5);
- ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+ ListeningExecutorService listeningExecutor = SingletonHolder.getDefaultNotificationExecutor();
NotificationBrokerImpl broker = new NotificationBrokerImpl(listeningExecutor);
return broker;
}
+++ /dev/null
-package org.opendaylight.controller.config.yang.md.sal.binding.statistics;\r
-\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
-import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;\r
-\r
-public class DataBrokerRuntimeMXBeanImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
- \r
- private final Transactions transactions = new Transactions();\r
- private final Data data = new Data();\r
- \r
- public Transactions getTransactions() {\r
- transactions.setCreated(getCreatedTransactionsCount().get());\r
- transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
- transactions.setSuccessful(getFinishedTransactionsCount().get());\r
- transactions.setFailed(getFailedTransactionsCount().get());\r
- return transactions;\r
- }\r
-\r
- @Override\r
- public Data getData() {\r
- transactions.setCreated(getCreatedTransactionsCount().get());\r
- transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
- transactions.setSuccessful(getFinishedTransactionsCount().get());\r
- transactions.setFailed(getFailedTransactionsCount().get());\r
- data.setTransactions(transactions);\r
- return data;\r
- }\r
-}\r
*/
package org.opendaylight.controller.sal.binding.codegen;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import java.util.Set;
import java.util.HashMap;
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.RpcImplementation;
import org.opendaylight.controller.md.sal.common.api.routing.MutableRoutingTable;
@Override
public void unregisterPath(Class<? extends BaseIdentity> context, InstanceIdentifier<?> path) {
routingTables.get(context).removeRoute(path, getInstance());
-
}
@Override
package org.opendaylight.controller.sal.binding.codegen.impl;
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
package org.opendaylight.controller.sal.binding.codegen.impl;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
import javassist.ClassPool;
public class SingletonHolder {
- public static final ClassPool CLASS_POOL = new ClassPool();
- public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(CLASS_POOL);
+ public static final ClassPool CLASS_POOL = new ClassPool();
+ public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(
+ CLASS_POOL);
public static final RuntimeCodeGenerator RPC_GENERATOR = RPC_GENERATOR_IMPL;
public static final NotificationInvokerFactory INVOKER_FACTORY = RPC_GENERATOR_IMPL.getInvokerFactory();
+ private static ListeningExecutorService NOTIFICATION_EXECUTOR = null;
+ private static ListeningExecutorService COMMIT_EXECUTOR = null;
+
+ public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() {
+ if (NOTIFICATION_EXECUTOR == null) {
+ NOTIFICATION_EXECUTOR = createNamedExecutor("md-sal-binding-notification-%d");
+ }
+ return NOTIFICATION_EXECUTOR;
+ }
+
+ public static synchronized final ListeningExecutorService getDefaultCommitExecutor() {
+ if (COMMIT_EXECUTOR == null) {
+ COMMIT_EXECUTOR = createNamedExecutor("md-sal-binding-commit-%d");
+ }
+
+ return COMMIT_EXECUTOR;
+ }
+
+ private static ListeningExecutorService createNamedExecutor(String format) {
+ ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat(format).build();
+ ExecutorService executor = Executors.newCachedThreadPool(factory);
+ return MoreExecutors.listeningDecorator(executor);
+
+ }
+
}
package org.opendaylight.controller.sal.binding.dom.serializer.api;
import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.Node;
@Override
public ValueWithQName<A> deserialize(Node<?> input);
+
+ public QName getAugmentationQName();
}
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.controller.sal.binding.dom.serializer.api.IdentifierCodec;
+import org.opendaylight.yangtools.yang.binding.DataObject;
public interface CodecRegistry {
void bindingClassEncountered(Class<?> cls);
void putPathToClass(List<QName> names, Class<?> cls);
+
+ public abstract QName getQNameForAugmentation(Class<?> cls);
}
import com.google.common.collect.ImmutableList
import org.opendaylight.yangtools.yang.binding.Augmentation
import java.util.concurrent.ConcurrentHashMap
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections
class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
private static val LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl);
val CodecRegistry codecRegistry;
- val Map<Class<?>,QName> classToQName = new WeakHashMap;
val Map<Class<?>, Map<List<QName>, Class<?>>> classToPreviousAugment = new WeakHashMap;
public new(CodecRegistry registry) {
previousAugmentation = null;
} else {
- previousQName = resolveQname(baArg.type);
+ previousQName = codecRegistry.getQNameForAugmentation(baArg.type as Class);
previousAugmentation = baArg.type;
}
}
private def dispatch PathArgument serializePathArgument(Item argument, QName previousQname) {
val type = argument.type;
- val qname = resolveQname(type);
+ val qname = BindingReflections.findQName(type);
if(previousQname == null) {
return new NodeIdentifier(qname);
}
val Map<QName,Object> predicates = new HashMap();
val type = argument.type;
val keyCodec = codecRegistry.getIdentifierCodecForIdentifiable(type);
- val qname = resolveQname(type);
+ val qname = BindingReflections.findQName(type);
val combinedInput = new ValueWithQName(previousQname,argument.key)
val compositeOutput = keyCodec.serialize(combinedInput as ValueWithQName);
for(outputValue :compositeOutput.value) {
}
return new NodeIdentifierWithPredicates(QName.create(previousQname,qname.localName),predicates);
}
-
- def resolveQname(Class<?> class1) {
- val qname = classToQName.get(class1);
- if(qname !== null) {
- return qname;
- }
- val qnameField = class1.getField("QNAME");
- val qnameValue = qnameField.get(null) as QName;
- classToQName.put(class1,qnameValue);
- return qnameValue;
- }
}
\ No newline at end of file
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.Node;
}
return codec;
}
+
+ @Override
+ public QName getQNameForAugmentation(Class<?> cls) {
+ checkArgument(Augmentation.class.isAssignableFrom(cls));
+ return getCodecForAugmentation((Class<? extends Augmentation>)cls).getAugmentationQName();
+ }
private static Class<? extends Augmentable<?>> getAugmentableArgumentFrom(
final Class<? extends Augmentation<?>> augmentation) {
Delegator<BindingCodec> {
private BindingCodec delegate;
+ private QName augmentationQName;
public AugmentationCodecWrapper(BindingCodec<Map<QName, Object>, Object> rawCodec) {
this.delegate = rawCodec;
+ this.augmentationQName = BindingReflections.findQName(rawCodec.getClass());
}
@Override
Object rawCodecValue = getDelegate().deserialize((Map<QName, Object>) input);
return new ValueWithQName<T>(input.getNodeType(), (T) rawCodecValue);
}
+
+ @Override
+ public QName getAugmentationQName() {
+ return augmentationQName;
+ }
}
private class IdentityCompositeCodec implements IdentitityCodec {
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
-import org.osgi.framework.BundleContext
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.slf4j.LoggerFactory
-
-class BindingAwareBrokerImpl extends RpcProviderRegistryImpl implements BindingAwareBroker, AutoCloseable {
- private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
-
- private InstanceIdentifier<? extends DataObject> root = InstanceIdentifier.builder().toInstance();
-
- @Property
- private var NotificationProviderService notifyBroker
-
- @Property
- private var DataProviderService dataBroker
-
- @Property
- var BundleContext brokerBundleContext
-
- public new(String name,BundleContext bundleContext) {
- super(name);
- _brokerBundleContext = bundleContext;
- }
-
- def start() {
- log.info("Starting MD-SAL: Binding Aware Broker");
- }
-
-
-
- override registerConsumer(BindingAwareConsumer consumer, BundleContext bundleCtx) {
- val ctx = consumer.createContext(bundleCtx)
- consumer.onSessionInitialized(ctx)
- return ctx
- }
-
- override registerProvider(BindingAwareProvider provider, BundleContext bundleCtx) {
- val ctx = provider.createContext(bundleCtx)
- provider.onSessionInitialized(ctx)
- provider.onSessionInitiated(ctx as ProviderContext)
- return ctx
- }
-
- private def createContext(BindingAwareConsumer consumer, BundleContext consumerCtx) {
- new OsgiConsumerContext(consumerCtx, this)
- }
-
- private def createContext(BindingAwareProvider provider, BundleContext providerCtx) {
- new OsgiProviderContext(providerCtx, this)
- }
-
- override <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> registerRouteChangeListener(L listener) {
- super.<L>registerRouteChangeListener(listener)
- }
-
- override close() throws Exception {
-
- }
-}
\ No newline at end of file
import java.util.Set;
import java.util.concurrent.Future;\r
import java.util.concurrent.atomic.AtomicLong;\r
-
+\r
import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;\r
import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;\r
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;\r
import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
import org.opendaylight.yangtools.yang.binding.DataObject;\r
import org.opendaylight.yangtools.yang.binding.DataRoot;\r
+import org.opendaylight.yangtools.yang.binding.Identifiable;\r
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
import org.opendaylight.yangtools.yang.common.RpcResult;\r
\r
\r
-public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements\r
- DataProviderService, AutoCloseable {\r
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> //\r
+ implements DataProviderService, AutoCloseable {\r
\r
private final AtomicLong nextTransaction = new AtomicLong();\r
private final AtomicLong createdTransactionsCount = new AtomicLong();\r
return true;
}
}
-
return false;
}\r
}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+public class MountPointManagerImpl implements MountProviderService {
+
+ public final Logger LOG = LoggerFactory.getLogger(MountPointManagerImpl.class);
+
+ private final ConcurrentMap<InstanceIdentifier<?>, BindingMountPointImpl> mountPoints;
+ private final ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create();
+
+ private ListeningExecutorService notificationExecutor;
+ private ListeningExecutorService dataCommitExecutor;
+
+ public MountPointManagerImpl() {
+ mountPoints = new ConcurrentHashMap<>();
+ }
+
+ public ListeningExecutorService getNotificationExecutor() {
+ return notificationExecutor;
+ }
+
+ public void setNotificationExecutor(ListeningExecutorService notificationExecutor) {
+ this.notificationExecutor = notificationExecutor;
+ }
+
+ public ListeningExecutorService getDataCommitExecutor() {
+ return dataCommitExecutor;
+ }
+
+ public void setDataCommitExecutor(ListeningExecutorService dataCommitExecutor) {
+ this.dataCommitExecutor = dataCommitExecutor;
+ }
+
+ @Override
+ public synchronized BindingMountPointImpl createMountPoint(InstanceIdentifier<?> path) {
+ BindingMountPointImpl potential = mountPoints.get(path);
+ if (potential != null) {
+ throw new IllegalStateException("Mount point already exists.");
+ }
+ return createOrGetMountPointImpl(path);
+ }
+
+ @Override
+ public BindingMountPointImpl createOrGetMountPoint(InstanceIdentifier<?> path) {
+ BindingMountPointImpl potential = getMountPoint(path);
+ if (potential != null) {
+ return potential;
+ }
+ return createOrGetMountPointImpl(path);
+ }
+
+ @Override
+ public BindingMountPointImpl getMountPoint(InstanceIdentifier<?> path) {
+ return mountPoints.get(path);
+ }
+
+ private synchronized BindingMountPointImpl createOrGetMountPointImpl(InstanceIdentifier<?> path) {
+ BindingMountPointImpl potential = getMountPoint(path);
+ if (potential != null) {
+ return potential;
+ }
+ RpcProviderRegistryImpl rpcRegistry = new RpcProviderRegistryImpl("mount");
+ NotificationBrokerImpl notificationBroker = new NotificationBrokerImpl();
+ notificationBroker.setExecutor(getNotificationExecutor());
+ DataBrokerImpl dataBroker = new DataBrokerImpl();
+ dataBroker.setExecutor(getDataCommitExecutor());
+ BindingMountPointImpl mountInstance = new BindingMountPointImpl(path, rpcRegistry, notificationBroker,
+ dataBroker);
+ mountPoints.putIfAbsent(path, mountInstance);
+ notifyMountPointCreated(path);
+ return mountInstance;
+ }
+
+ private void notifyMountPointCreated(InstanceIdentifier<?> path) {
+ for (ListenerRegistration<MountProvisionListener> listener : listeners) {
+ try {
+ listener.getInstance().onMountPointCreated(path);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener.", e);
+ }
+ }
+ }
+
+ @Override
+ public ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener) {
+ return listeners.register(listener);
+ }
+
+ public class BindingMountPointImpl extends
+ AbstractBindingSalProviderInstance<DataBrokerImpl, NotificationBrokerImpl, RpcProviderRegistryImpl>
+ implements MountProviderInstance {
+
+ private InstanceIdentifier<?> identifier;
+
+ public BindingMountPointImpl(org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> identifier,
+ RpcProviderRegistryImpl rpcRegistry, NotificationBrokerImpl notificationBroker,
+ DataBrokerImpl dataBroker) {
+ super(rpcRegistry, notificationBroker, dataBroker);
+ this.identifier = identifier;
+ }
+
+ @Override
+ public InstanceIdentifier<?> getIdentifier() {
+ return this.identifier;
+ }
+ }
+}
import org.opendaylight.yangtools.concepts.ListenerRegistration\r
import org.opendaylight.yangtools.concepts.Registration\r
import org.opendaylight.yangtools.yang.binding.Notification\r
-import org.slf4j.LoggerFactory\rimport org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder
-
+import org.slf4j.LoggerFactory\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder\r
+\r
class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {\r
\r
val Multimap<Class<? extends Notification>, NotificationListener<?>> listeners;\r
\r
private static val log = LoggerFactory.getLogger(NotifyTask);\r
\r
+ @SuppressWarnings("rawtypes")\r
val NotificationListener listener;\r
val Notification notification;\r
\r
override call() {\r
+ //Only logging the complete notification in debug mode\r
try {\r
- log.info("Delivering notification {} to {}",notification,listener);\r
+ if(log.isDebugEnabled){\r
+ log.debug("Delivering notification {} to {}",notification,listener);\r
+ } else {\r
+ log.info("Delivering notification {} to {}",notification.class.name,listener);\r
+ }\r
listener.onNotification(notification);\r
- log.info("Notification delivered {} to {}",notification,listener);\r
+ if(log.isDebugEnabled){\r
+ log.debug("Notification delivered {} to {}",notification,listener);\r
+ } else {\r
+ log.info("Notification delivered {} to {}",notification.class.name,listener);\r
+ }\r
} catch (Exception e) {\r
log.error("Unhandled exception thrown by listener: {}", listener, e);\r
}\r
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareService;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.LoggerFactory
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*
-
-class OsgiConsumerContext implements ConsumerContext {
-
- static val log = LoggerFactory.getLogger(OsgiConsumerContext)
- protected val BundleContext bundleContext;
- protected val BindingAwareBrokerImpl broker;
-
- new(BundleContext ctx, BindingAwareBrokerImpl broker) {
- this.bundleContext = ctx;
- this.broker = broker;
- }
-
- override def <T extends BindingAwareService> getSALService(Class<T> service) {
-
- // SAL Services are global
- var ref = bundleContext.getServiceReference(service);
- return bundleContext.getService(ref) as T;
- }
-
- override def <T extends RpcService> T getRpcService(Class<T> module) {
- try {
-
- val services = bundleContext.getServiceReferences(module, getProxyFilter());
-
- // Proxy service found / using first implementation
- // FIXME: Add advanced logic to retrieve service with right set of models
- if (false == services.empty) {
- val ref = services.iterator().next() as ServiceReference<T>;
- return bundleContext.getService(ref) as T;
- } else {
- return broker.getRpcService(module);
- }
- } catch (InvalidSyntaxException e) {
- log.error("Created filter was invalid:", e.message, e)
- }
- return null;
-
- }
-
- private def getProxyFilter() {
- return '''(«SAL_SERVICE_TYPE»=«SAL_SERVICE_TYPE_CONSUMER_PROXY»)'''
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl;
-
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.osgi.framework.BundleContext;
-
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*;
-import static extension org.opendaylight.controller.sal.binding.impl.osgi.PropertiesUtils.*;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality
-import static com.google.common.base.Preconditions.*
-
-class OsgiProviderContext extends OsgiConsumerContext implements ProviderContext {
-
- @Property
- val Map<Class<? extends RpcService>, RpcRegistration<? extends RpcService>> registeredServices
-
- new(BundleContext ctx, BindingAwareBrokerImpl broker) {
- super(ctx, broker);
- _registeredServices = new HashMap();
- }
-
- override <T extends RpcService> addRpcImplementation(Class<T> type, T implementation) {
- val salReg = broker.addRpcImplementation(type, implementation)
- registeredServices.put(type, salReg)
- return salReg;
- }
-
- override <T extends RpcService> addRoutedRpcImplementation(Class<T> type, T implementation) throws IllegalStateException {
- val salReg = broker.addRoutedRpcImplementation(type, implementation)
- registeredServices.put(type, salReg)
- return salReg;
- }
-
- override registerFunctionality(ProviderFunctionality functionality) {
- // NOOP for now
- }
-
- override unregisterFunctionality(ProviderFunctionality functionality) {
- // NOOP for now
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
+import org.opendaylight.controller.md.sal.binding.util.BindingContextUtils;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.NotificationService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountService;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Mutable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableClassToInstanceMap;
+
+public class RootBindingAwareBroker implements //
+ Mutable, //
+ Identifiable<String>, //
+ BindingAwareBroker, AutoCloseable,
+ RpcProviderRegistry {
+
+ private final static Logger LOG = LoggerFactory.getLogger(RootBindingAwareBroker.class);
+
+ RootSalInstance controllerRoot;
+
+ private final String identifier;
+
+ private RpcProviderRegistry rpcBroker;
+
+ private NotificationProviderService notificationBroker;
+
+ private DataProviderService dataBroker;
+
+ private MountPointManagerImpl mountManager;
+
+ public MountPointManagerImpl getMountManager() {
+ return mountManager;
+ }
+
+ public void setMountManager(MountPointManagerImpl mountManager) {
+ this.mountManager = mountManager;
+ }
+
+ private ImmutableClassToInstanceMap<BindingAwareService> supportedConsumerServices;
+
+ private ImmutableClassToInstanceMap<BindingAwareService> supportedProviderServices;
+
+ public RootBindingAwareBroker(String instanceName) {
+ this.identifier = instanceName;
+ mountManager = new MountPointManagerImpl();
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public RootSalInstance getRoot() {
+ return controllerRoot;
+ }
+
+ public DataProviderService getDataBroker() {
+ return this.dataBroker;
+ }
+
+ public NotificationProviderService getNotificationBroker() {
+ return this.notificationBroker;
+ }
+
+ public RpcProviderRegistry getRpcProviderRegistry() {
+ return this.rpcBroker;
+ }
+
+ public RpcProviderRegistry getRpcBroker() {
+ return rpcBroker;
+ }
+
+ public void setRpcBroker(RpcProviderRegistry rpcBroker) {
+ this.rpcBroker = rpcBroker;
+ }
+
+ public void setNotificationBroker(NotificationProviderService notificationBroker) {
+ this.notificationBroker = notificationBroker;
+ }
+
+ public void setDataBroker(DataProviderService dataBroker) {
+ this.dataBroker = dataBroker;
+ }
+
+ public void start() {
+ checkState(controllerRoot == null, "Binding Aware Broker was already started.");
+ LOG.info("Starting Binding Aware Broker: {}", identifier);
+
+ controllerRoot = new RootSalInstance(getRpcProviderRegistry(), getNotificationBroker(), getDataBroker());
+
+
+ supportedConsumerServices = ImmutableClassToInstanceMap.<BindingAwareService> builder()
+ .put(NotificationService.class, getRoot()) //
+ .put(DataBrokerService.class, getRoot()) //
+ .put(RpcConsumerRegistry.class, getRoot()) //
+ .put(MountService.class, mountManager).build();
+
+ supportedProviderServices = ImmutableClassToInstanceMap.<BindingAwareService> builder()
+ .putAll(supportedConsumerServices)
+ .put(NotificationProviderService.class, getRoot()) //
+ .put(DataProviderService.class, getRoot()) //
+ .put(RpcProviderRegistry.class, getRoot()) //
+ .put(MountProviderService.class, mountManager).build();
+ }
+
+ @Override
+ public ConsumerContext registerConsumer(BindingAwareConsumer consumer, BundleContext ctx) {
+ checkState(supportedConsumerServices != null, "Broker is not initialized.");
+ return BindingContextUtils.createConsumerContextAndInitialize(consumer, supportedConsumerServices);
+ }
+
+ @Override
+ public ProviderContext registerProvider(BindingAwareProvider provider, BundleContext ctx) {
+ checkState(supportedProviderServices != null, "Broker is not initialized.");
+ return BindingContextUtils.createProviderContextAndInitialize(provider, supportedProviderServices);
+ }
+
+ @Override
+ public void close() throws Exception {
+ // FIXME: Close all sessions
+ }
+
+ @Override
+ public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getRoot().addRoutedRpcImplementation(type, implementation);
+ }
+
+ @Override
+ public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getRoot().addRpcImplementation(type, implementation);
+ }
+
+ @Override
+ public <T extends RpcService> T getRpcService(Class<T> module) {
+ return getRoot().getRpcService(module);
+ }
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+ L arg0) {
+ return getRoot().registerRouteChangeListener(arg0);
+ }
+
+
+ public class RootSalInstance extends
+ AbstractBindingSalProviderInstance<DataProviderService, NotificationProviderService, RpcProviderRegistry> {
+
+ public RootSalInstance(RpcProviderRegistry rpcRegistry, NotificationProviderService notificationBroker,
+ DataProviderService dataBroker) {
+ super(rpcRegistry, notificationBroker, dataBroker);
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl;\r
+\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistration;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistrator;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
+\r
+public class RootDataBrokerImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
+\r
+ private final Transactions transactions = new Transactions();\r
+ private final Data data = new Data();\r
+ private BindingIndependentConnector bindingIndependentConnector;\r
+ private DataBrokerImplRuntimeRegistration runtimeBeanRegistration;\r
+\r
+ public BindingIndependentConnector getBindingIndependentConnector() {\r
+ return bindingIndependentConnector;\r
+ }\r
+\r
+ public Transactions getTransactions() {\r
+ transactions.setCreated(getCreatedTransactionsCount().get());\r
+ transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
+ transactions.setSuccessful(getFinishedTransactionsCount().get());\r
+ transactions.setFailed(getFailedTransactionsCount().get());\r
+ return transactions;\r
+ }\r
+\r
+ @Override\r
+ public Data getData() {\r
+ data.setTransactions(getTransactions());\r
+ return data;\r
+ }\r
+\r
+ public void setBindingIndependentConnector(BindingIndependentConnector runtimeMapping) {\r
+ this.bindingIndependentConnector = runtimeMapping;\r
+ }\r
+\r
+ public void registerRuntimeBean(DataBrokerImplRuntimeRegistrator rootRegistrator) {\r
+ runtimeBeanRegistration = rootRegistrator.register(this);\r
+ }\r
+\r
+}\r
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper;
import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+
+public class BindingDomConnectorDeployer {
+
+ private static BindingIndependentMappingService mappingService;
+
+ public static BindingIndependentConnector tryToDeployConnector(RootBindingAwareBroker baBroker,
+ ProviderSession domSession) {
+ checkNotNull(baBroker);
+ checkNotNull(domSession);
+ BindingIndependentConnector connector = createConnector(mappingService);
+ return connector;
+ }
+
+ public static BindingIndependentConnector createConnector(BindingIndependentMappingService mappingService) {
+ BindingIndependentConnector connector = new BindingIndependentConnector();
+ connector.setMappingService(mappingService);
+ return connector;
+ }
+
+ public static BindingIndependentConnector createConnector(BindingIndependentConnector source) {
+ BindingIndependentConnector connector = new BindingIndependentConnector();
+ connector.setMappingService(source.getMappingService());
+ return connector;
+ }
+
+ public static void startDataForwarding(BindingIndependentConnector connector, DataProviderService baService,
+ ProviderSession domContext) {
+ startDataForwarding(connector, baService,
+ domContext.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
+ }
+
+ public static void startRpcForwarding(BindingIndependentConnector connector,
+ RpcProviderRegistry rpcProviderRegistry, ProviderSession domProviderContext) {
+ startRpcForwarding(connector, rpcProviderRegistry, domProviderContext.getService(RpcProvisionRegistry.class));
+
+ }
+
+ public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService provider,ProviderSession domProviderContext) {
+ startNotificationForwarding(connector, provider, domProviderContext.getService(NotificationPublishService.class));
+ }
+
+ public static void startRpcForwarding(BindingIndependentConnector connector, RpcProviderRegistry baService,
+ RpcProvisionRegistry domService) {
+ if (connector.isRpcForwarding()) {
+ return;
+ }
+
+ connector.setDomRpcRegistry(domService);
+ connector.setBindingRpcRegistry(baService);
+ connector.startRpcForwarding();
+ }
+
+ public static void startDataForwarding(BindingIndependentConnector connector, DataProviderService baService,
+ org.opendaylight.controller.sal.core.api.data.DataProviderService domService) {
+ if (connector.isDataForwarding()) {
+ return;
+ }
+
+ connector.setBindingDataService(baService);
+ connector.setDomDataService(domService);
+ connector.startDataForwarding();
+ }
+
+ public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService baService, NotificationPublishService domService) {
+ if(connector.isNotificationForwarding()) {
+ return;
+ }
+
+ // FIXME
+ }
+
+ //
+ // public static BindingIndependentMappingService getGlobalMappingService()
+ // {
+ // return mappingService;
+ // }
+ //
+ // protected static BindingIndependentMappingService
+ // setGlobalMappingService(BindingIndependentMappingService service) {
+ // mappingService= service;
+ // return mappingService;
+ // }
+ //
+ // public static BindingIndependentConnector
+ // tryToDeployConnector(MountProviderInstance baMount,MountProvisionInstance
+ // domMount) {
+ //
+ //
+ // return null;
+ // }
+
+}
package org.opendaylight.controller.sal.binding.impl.connect.dom;
import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-
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.DataCommitHandler;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
import org.opendaylight.controller.sal.common.util.Rpcs;
import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.RpcInput;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.opendaylight.yangtools.yang.common.QName;
import com.google.common.collect.ImmutableSet;
import static com.google.common.base.Preconditions.*;
-import static org.opendaylight.yangtools.concepts.util.ClassLoaderUtils.*;
public class BindingIndependentConnector implements //
RuntimeDataProvider, //
private Registration<DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>> biCommitHandlerRegistration;
private RpcProvisionRegistry biRpcRegistry;
- private RpcProviderRegistryImpl baRpcRegistry;
+ private RpcProviderRegistry baRpcRegistry;
private ListenerRegistration<DomToBindingRpcForwardingManager> domToBindingRpcManager;
// private ListenerRegistration<BindingToDomRpcForwardingManager>
};
+ private Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> baDataReaderRegistration;
+
+ private boolean rpcForwarding = false;
+
+ private boolean dataForwarding = false;
+
+ private boolean notificationForwarding = false;
+
@Override
public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
try {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
-
CompositeNode result = biDataService.readOperationalData(biPath);
- Class<? extends DataObject> targetType = path.getTargetType();
-
- if (Augmentation.class.isAssignableFrom(targetType)) {
- path = mappingService.fromDataDom(biPath);
- Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
- DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
- if (parentTo instanceof Augmentable<?>) {
- return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
- }
-
- }
- return mappingService.dataObjectFromDataDom(path, result);
-
+ return potentialAugmentationRead(path,biPath,result);
} catch (DeserializationException e) {
throw new IllegalStateException(e);
}
}
+ private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException {
+ Class<? extends DataObject> targetType = path.getTargetType();
+ if (Augmentation.class.isAssignableFrom(targetType)) {
+ path = mappingService.fromDataDom(biPath);
+ Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
+ DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
+ if (parentTo instanceof Augmentable<?>) {
+ return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
+ }
+ }
+ return mappingService.dataObjectFromDataDom(path, result);
+ }
+
@Override
public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
try {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
CompositeNode result = biDataService.readConfigurationData(biPath);
- return mappingService.dataObjectFromDataDom(path, result);
+ return potentialAugmentationRead(path,biPath,result);
} catch (DeserializationException e) {
throw new IllegalStateException(e);
}
return biDataService;
}
- public void setBiDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
+ protected void setDomDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
this.biDataService = biDataService;
}
return baDataService;
}
- public void setBaDataService(DataProviderService baDataService) {
+ protected void setBindingDataService(DataProviderService baDataService) {
this.baDataService = baDataService;
}
return baRpcRegistry;
}
- public void setRpcRegistry(RpcProviderRegistryImpl rpcRegistry) {
+ protected void setBindingRpcRegistry(RpcProviderRegistry rpcRegistry) {
this.baRpcRegistry = rpcRegistry;
}
- public void start() {
- baDataService.registerDataReader(ROOT, this);
+ public void startDataForwarding() {
+ checkState(!dataForwarding, "Connector is already forwarding data.");
+ baDataReaderRegistration = baDataService.registerDataReader(ROOT, this);
baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler);
biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
-
- if (baRpcRegistry != null && biRpcRegistry != null) {
+ dataForwarding = true;
+ }
+
+ public void startRpcForwarding() {
+ if (baRpcRegistry != null && biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher<?, ?>) {
+ checkState(!rpcForwarding,"Connector is already forwarding RPCs");
domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager());
-
+ rpcForwarding = true;
}
}
+
+ public void startNotificationForwarding() {
+ checkState(!notificationForwarding, "Connector is already forwarding notifications.");
+ notificationForwarding = true;
+ }
- public void setMappingService(BindingIndependentMappingService mappingService) {
+ protected void setMappingService(BindingIndependentMappingService mappingService) {
this.mappingService = mappingService;
}
@Override
public void onSessionInitiated(ProviderSession session) {
- setBiDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
- start();
+ setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
+ setDomRpcRegistry(session.getService(RpcProvisionRegistry.class));
+
}
public <T extends RpcService> void onRpcRouterCreated(Class<T> serviceType, RpcRouter<T> router) {
*/
if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
- return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction);
+ return CommitHandlerTransactions.allwaysSuccessfulTransaction(bindingTransaction);
}
DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
* duplicating data.
*/
if (domOpenedTransactions.containsKey(identifier)) {
- return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction);
+ return CommitHandlerTransactions.allwaysSuccessfulTransaction(domTransaction);
}
org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
@SuppressWarnings("rawtypes")
private WeakReference<Class> outputClass;
+ @SuppressWarnings({ "rawtypes", "unchecked" })
public DefaultInvocationStrategy(Method targetMethod, Class<?> outputClass,
Class<? extends DataContainer> inputClass) {
super(targetMethod);
}
public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
+ @SuppressWarnings("unchecked")
Future<RpcResult<Void>> result = (Future<RpcResult<Void>>) targetMethod.invoke(rpcService);
RpcResult<Void> bindingResult = result.get();
return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors());
}
+ }
+
+ public boolean isRpcForwarding() {
+ return rpcForwarding;
+ }
+
+ public boolean isDataForwarding() {
+ return dataForwarding;
+ }
+
+ public boolean isNotificationForwarding() {
+ // TODO Auto-generated method stub
+ return notificationForwarding;
+ }
+ public BindingIndependentMappingService getMappingService() {
+ return mappingService;
}
}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class BindingIndependentMountPointForwarder {
+
+ private MountProvisionService domMountService;
+ private MountProviderService baMountService;
+ private BindingIndependentMappingService mappingService;
+
+ private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager();
+ private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager();
+
+ private ConcurrentMap<InstanceIdentifier<?>, BindingIndependentConnector> connectors;
+ private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded;
+ private ListenerRegistration<MountProvisionListener> domListenerRegistration;
+ private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> baListenerRegistration;
+
+ public MountProvisionService getDomMountService() {
+ return domMountService;
+ }
+
+ public void setDomMountService(MountProvisionService domMountService) {
+ this.domMountService = domMountService;
+ }
+
+ public void start() {
+ if(domMountService != null && baMountService != null) {
+ domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager);
+ baListenerRegistration = baMountService.registerProvisionListener(bindingForwardingManager);
+ }
+ }
+
+ private void tryToDeployConnector(InstanceIdentifier<?> baPath,
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath);
+ if(previous != null) {
+ return;
+ }
+ MountProviderInstance baMountPoint = baMountService.getMountPoint(baPath);
+ MountProvisionInstance domMountPoint = domMountService.getMountPoint(biPath);
+ BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint);
+ connectors.put(baPath, connector);
+ connector.startDataForwarding();
+ connector.startRpcForwarding();
+ connector.startNotificationForwarding();
+ }
+
+ private BindingIndependentConnector createForwarder(InstanceIdentifier<?> path, MountProviderInstance baMountPoint,
+ MountProvisionInstance domMountPoint) {
+ BindingIndependentConnector connector = new BindingIndependentConnector();
+
+ connector.setBindingDataService(baMountPoint);
+ connector.setBindingRpcRegistry(baMountPoint);
+ //connector.setBindingNotificationBroker(baMountPoint);
+
+ connector.setDomDataService(domMountPoint);
+ connector.setDomRpcRegistry(domMountPoint);
+ //connector.setDomNotificationBroker(domMountPoint);
+ return connector;
+ }
+
+ public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
+ InstanceIdentifier<?> baPath;
+ try {
+ baPath = mappingService.fromDataDom(domPath);
+ BindingIndependentConnector potentialConnector = connectors.get(baPath);
+ if(potentialConnector != null) {
+ return;
+ }
+ tryToDeployConnector(baPath,domPath);
+ } catch (DeserializationException e) {
+
+ }
+ }
+
+ public synchronized void tryToDeployBindingForwarder(InstanceIdentifier<?> baPath) {
+ BindingIndependentConnector potentialConnector =connectors.get(baPath);
+ if(potentialConnector != null) {
+ return;
+ }
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(baPath);
+ tryToDeployConnector(baPath, domPath);
+ }
+
+ public synchronized void undeployBindingForwarder(InstanceIdentifier<?> baPath) {
+ // FIXME: Implement closeMountPoint
+ }
+
+ public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+ // FIXME: Implement closeMountPoint
+ }
+
+ private class DomMountPointForwardingManager implements MountProvisionListener {
+
+ @Override
+ public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+ tryToDeployDomForwarder(path);
+ }
+
+ @Override
+ public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+ undeployDomForwarder(path);
+ }
+ }
+
+ private class BindingMountPointForwardingManager implements
+ org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener {
+
+ @Override
+ public void onMountPointCreated(InstanceIdentifier<?> path) {
+ tryToDeployBindingForwarder(path);
+ }
+
+ @Override
+ public void onMountPointRemoved(InstanceIdentifier<?> path) {
+ undeployBindingForwarder(path);
+ }
+ }
+}
+++ /dev/null
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
-
-public class BindingIndependentRpcConnector {
-
-}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implements DomForwardedBroker {
+
+ private ProviderSession domProviderContext;
+ private BindingIndependentConnector connector;
+
+ private MountProvisionService domMountService;
+
+ private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager();
+ private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager();
+
+ private ConcurrentMap<InstanceIdentifier<?>, BindingIndependentConnector> connectors = new ConcurrentHashMap<>();
+ private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded = new ConcurrentHashMap<>();
+ private ListenerRegistration<MountProvisionListener> domListenerRegistration;
+ private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> baListenerRegistration;
+
+
+ public DomForwardedBindingBrokerImpl(String instanceName) {
+ super(instanceName);
+ }
+
+ @Override
+ public BindingIndependentConnector getConnector() {
+ return connector;
+ }
+
+ @Override
+ public ProviderSession getDomProviderContext() {
+ return domProviderContext;
+ }
+
+ @Override
+ public void setConnector(BindingIndependentConnector connector) {
+ this.connector = connector;
+ }
+
+ @Override
+ public void setDomProviderContext(ProviderSession domProviderContext) {
+ this.domProviderContext = domProviderContext;
+ }
+
+ @Override
+ public void startForwarding() {
+ BindingDomConnectorDeployer.startDataForwarding(getConnector(), getDataBroker(), getDomProviderContext());
+ BindingDomConnectorDeployer.startRpcForwarding(getConnector(), getRpcProviderRegistry(),
+ getDomProviderContext());
+ BindingDomConnectorDeployer.startNotificationForwarding(getConnector(), getNotificationBroker(),
+ getDomProviderContext());
+ startMountpointForwarding();
+ }
+
+ private void startMountpointForwarding() {
+ domMountService = getDomProviderContext().getService(MountProvisionService.class);
+ if (domMountService != null && getMountManager() != null) {
+ domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager);
+ baListenerRegistration = getMountManager().registerProvisionListener(bindingForwardingManager);
+ }
+ }
+
+ public MountProvisionService getDomMountService() {
+ return domMountService;
+ }
+
+ public void setDomMountService(MountProvisionService domMountService) {
+ this.domMountService = domMountService;
+ }
+
+ private void tryToDeployConnector(InstanceIdentifier<?> baPath,
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath);
+ if (previous != null) {
+ return;
+ }
+ MountProviderInstance baMountPoint = getMountManager().createOrGetMountPoint(baPath);
+ MountProvisionInstance domMountPoint = domMountService.createOrGetMountPoint(biPath);
+ BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint);
+ connectors.put(baPath, connector);
+ }
+
+ private BindingIndependentConnector createForwarder(InstanceIdentifier<?> path, MountProviderInstance baMountPoint,
+ MountProvisionInstance domMountPoint) {
+ BindingIndependentConnector mountConnector = BindingDomConnectorDeployer.createConnector(getConnector());
+
+ BindingDomConnectorDeployer.startDataForwarding(mountConnector, baMountPoint, domMountPoint);
+ BindingDomConnectorDeployer.startRpcForwarding(mountConnector, baMountPoint, domMountPoint);
+ BindingDomConnectorDeployer.startNotificationForwarding(mountConnector, baMountPoint, domMountPoint);
+ // connector.setDomNotificationBroker(domMountPoint);
+ return connector;
+ }
+
+ public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
+ InstanceIdentifier<?> baPath;
+ try {
+ baPath = connector.getMappingService().fromDataDom(domPath);
+ BindingIndependentConnector potentialConnector = connectors.get(baPath);
+ if (potentialConnector != null) {
+ return;
+ }
+ tryToDeployConnector(baPath, domPath);
+ } catch (DeserializationException e) {
+
+ }
+ }
+
+ public synchronized void tryToDeployBindingForwarder(InstanceIdentifier<?> baPath) {
+ BindingIndependentConnector potentialConnector = connectors.get(baPath);
+ if (potentialConnector != null) {
+ return;
+ }
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = connector.getMappingService().toDataDom(baPath);
+ tryToDeployConnector(baPath, domPath);
+ }
+
+ public synchronized void undeployBindingForwarder(InstanceIdentifier<?> baPath) {
+ // FIXME: Implement closeMountPoint
+ }
+
+ public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+ // FIXME: Implement closeMountPoint
+ }
+
+ private class DomMountPointForwardingManager implements MountProvisionListener {
+
+ @Override
+ public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+ tryToDeployDomForwarder(path);
+ }
+
+ @Override
+ public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+ undeployDomForwarder(path);
+ }
+ }
+
+ private class BindingMountPointForwardingManager implements
+ org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener {
+
+ @Override
+ public void onMountPointCreated(InstanceIdentifier<?> path) {
+ tryToDeployBindingForwarder(path);
+ }
+
+ @Override
+ public void onMountPointRemoved(InstanceIdentifier<?> path) {
+ undeployBindingForwarder(path);
+ }
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+
+interface DomForwardedBroker {
+
+ public BindingIndependentConnector getConnector();
+
+ public void setConnector(BindingIndependentConnector connector);
+
+ public void setDomProviderContext(ProviderSession domProviderContext);
+
+ public ProviderSession getDomProviderContext();
+
+ void startForwarding();
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+
+public class DomForwardedDataBrokerImpl extends RootDataBrokerImpl implements Provider, DomForwardedBroker {
+
+ private BindingIndependentConnector connector;
+ private ProviderSession domProviderContext;
+
+ public void setConnector(BindingIndependentConnector connector) {
+ this.connector = connector;
+ }
+
+ @Override
+ public void onSessionInitiated(ProviderSession session) {
+ this.setDomProviderContext(session);
+ }
+
+ @Override
+ public Collection<ProviderFunctionality> getProviderFunctionality() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public BindingIndependentConnector getConnector() {
+ return connector;
+ }
+
+ @Override
+ public ProviderSession getDomProviderContext() {
+ return domProviderContext;
+ }
+
+ public void setDomProviderContext(ProviderSession domProviderContext) {
+ this.domProviderContext = domProviderContext;
+ }
+
+ @Override
+ public void startForwarding() {
+ BindingDomConnectorDeployer.startDataForwarding(getConnector(), this, getDomProviderContext());
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import com.google.common.base.Preconditions;
+
+public class DomForwardingUtils {
+
+ public static boolean isDomForwardedBroker(Object obj) {
+ return obj instanceof DomForwardedBroker;
+ }
+
+ public static void reuseForwardingFrom(Object target,Object source) {
+ Preconditions.checkArgument(isDomForwardedBroker(source));
+ Preconditions.checkArgument(isDomForwardedBroker(target));
+ DomForwardedBroker forwardedSource = (DomForwardedBroker) source;
+ DomForwardedBroker forwardedTarget = (DomForwardedBroker) target;
+ reuseForwardingFrom(forwardedTarget, forwardedSource);
+
+ }
+
+ private static void reuseForwardingFrom(DomForwardedBroker target, DomForwardedBroker source) {
+ target.setConnector(source.getConnector());
+ target.setDomProviderContext(source.getDomProviderContext());
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl.osgi
-
-class Constants {
-
- private new() {
- }
-
- public static val SAL_SERVICE_TYPE = "salServiceType"
- public static val SAL_SERVICE_TYPE_CONSUMER_PROXY = "consumerProxy"
- public static val SAL_SERVICE_TYPE_PROVIDER = "provider"
- public static val SAL_SERVICE_TYPE_CONNECTOR = "connector"
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl.osgi
-
-import java.util.Hashtable
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*
-
-class PropertiesUtils {
-
- private new() {
- }
-
- static def setSalServiceType(Hashtable<String, String> properties, String value) {
- properties.put(SAL_SERVICE_TYPE, value)
- return properties
- }
-
- static def getSalServiceType(Hashtable<String, String> properties) {
- return properties.get(SAL_SERVICE_TYPE)
- }
-
- static def newProperties() {
- new Hashtable<String, String>()
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl.osgi;
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.sal.binding.spi;
-
-public class RoutingContext {
-
-}
config:required-identity sal:binding-notification-service;
}
}
- }
+ }
}
}
-
+
augment "/config:modules/config:module/config:configuration" {
case binding-data-broker {
when "/config:modules/config:module/config:type = 'binding-data-broker'";
}
}
}
+
container mapping-service {
uses config:service-ref {
refine type {
import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.*;
import org.opendaylight.controller.sal.binding.api.NotificationListener;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
import org.opendaylight.controller.sal.binding.test.mock.BarListener;
import org.opendaylight.controller.sal.binding.test.mock.BarUpdate;
import org.opendaylight.controller.sal.binding.test.mock.CompositeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.Future;
import javassist.ClassPool;
+import org.eclipse.xtext.xbase.lib.Pure;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;
import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.BrokerService;
import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
import org.opendaylight.controller.sal.core.api.data.DataStore;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
+import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl;
import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.slf4j.LoggerFactory;
import com.google.common.base.Predicate;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import static com.google.common.base.Preconditions.*;
public class BindingTestContext implements AutoCloseable {
-
-
+
public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
.builder().toInstance();
private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
-
+
private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
-
-
- private BindingAwareBrokerImpl baBrokerImpl;
+
+ private DomForwardedBindingBrokerImpl baBrokerImpl;
private DataBrokerImpl baDataImpl;
private NotificationBrokerImpl baNotifyImpl;
- private BindingIndependentConnector baConnectDataServiceImpl;
+ private BindingIndependentConnector baConnectImpl;
private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
private BrokerImpl biBrokerImpl;
private DataStoreStatsWrapper dataStoreStats;
private DataStore dataStore;
-
private boolean dataStoreStatisticsEnabled = false;
-
+
private final ListeningExecutorService executor;
private final ClassPool classPool;
private final boolean startWithSchema;
-
+ private MountPointManagerImpl biMountImpl;
+
protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) {
this.executor = executor;
this.classPool = classPool;
rawDataStore = new HashMapDataStore();
schemaAwareDataStore = new SchemaAwareDataStoreAdapter();
schemaAwareDataStore.changeDelegate(rawDataStore);
- if(dataStoreStatisticsEnabled) {
- dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
- dataStore = dataStoreStats;
+ if (dataStoreStatisticsEnabled) {
+ dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
+ dataStore = dataStoreStats;
} else {
dataStore = schemaAwareDataStore;
}
-
+
biDataImpl.registerConfigurationReader(TREE_ROOT, dataStore);
biDataImpl.registerOperationalReader(TREE_ROOT, dataStore);
biDataImpl.registerCommitHandler(TREE_ROOT, dataStore);
}
-
+
public void startDomDataBroker() {
- checkState(executor != null,"Executor needs to be set");
+ checkState(executor != null, "Executor needs to be set");
biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
biDataImpl.setExecutor(executor);
}
-
+
public void startBindingDataBroker() {
- checkState(executor != null,"Executor needs to be set");
+ checkState(executor != null, "Executor needs to be set");
baDataImpl = new DataBrokerImpl();
baDataImpl.setExecutor(executor);
}
-
+
public void startBindingBroker() {
- checkState(executor != null,"Executor needs to be set");
- checkState(baDataImpl != null,"Binding Data Broker must be started");
+ checkState(executor != null, "Executor needs to be set");
+ checkState(baDataImpl != null, "Binding Data Broker must be started");
checkState(baNotifyImpl != null, "Notification Service must be started");
- baBrokerImpl = new BindingAwareBrokerImpl("test",null);
-
+ baBrokerImpl = new DomForwardedBindingBrokerImpl("test");
+
+ baBrokerImpl.getMountManager().setDataCommitExecutor(executor);
+ baBrokerImpl.getMountManager().setNotificationExecutor(executor);
+ baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test"));
baBrokerImpl.setDataBroker(baDataImpl);
- baBrokerImpl.setNotifyBroker(baNotifyImpl);
-
+ baBrokerImpl.setNotificationBroker(baNotifyImpl);
baBrokerImpl.start();
}
-
- public void startBindingToDomDataConnector() {
- checkState(baDataImpl != null,"Binding Data Broker needs to be started");
- checkState(biDataImpl != null,"DOM Data Broker needs to be started.");
- checkState(mappingServiceImpl != null,"DOM Mapping Service needs to be started.");
- baConnectDataServiceImpl = new BindingIndependentConnector();
- baConnectDataServiceImpl.setRpcRegistry(baBrokerImpl);
- baConnectDataServiceImpl.setDomRpcRegistry(getDomRpcRegistry());
- baConnectDataServiceImpl.setBaDataService(baDataImpl);
- baConnectDataServiceImpl.setBiDataService(biDataImpl);
- baConnectDataServiceImpl.setMappingService(mappingServiceImpl);
- baConnectDataServiceImpl.start();
+
+ public void startForwarding() {
+ checkState(baDataImpl != null, "Binding Data Broker needs to be started");
+ checkState(biDataImpl != null, "DOM Data Broker needs to be started.");
+ checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started.");
+
+ baConnectImpl = BindingDomConnectorDeployer.createConnector(getBindingToDomMappingService());
+ baConnectImpl.setDomRpcRegistry(getDomRpcRegistry());
+ baBrokerImpl.setConnector(baConnectImpl);
+ baBrokerImpl.setDomProviderContext(createMockContext());
+ baBrokerImpl.startForwarding();
}
-
+
+ private ProviderSession createMockContext() {
+ // TODO Auto-generated method stub
+ final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
+ .<BrokerService> builder()
+ //
+ .put(org.opendaylight.controller.sal.core.api.data.DataProviderService.class, biDataImpl) //
+ .put(RpcProvisionRegistry.class, biBrokerImpl.getRouter()) //
+ .put(MountProvisionService.class, biMountImpl) //
+ .build();
+
+ return new ProviderSession() {
+
+ @Override
+ public Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends BrokerService> T getService(Class<T> service) {
+ return domBrokerServices.getInstance(service);
+ }
+
+ @Override
+ public boolean isClosed() {
+ return false;
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return null;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
+ RpcRegistrationListener listener) {
+ return null;
+ }
+
+ @Override
+ public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException {
+ return null;
+ }
+
+ @Override
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ return null;
+ }
+
+ @Override
+ public RoutedRpcRegistration addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ return null;
+ }
+ };
+ }
+
public void startBindingToDomMappingService() {
- checkState(classPool != null,"ClassPool needs to be present");
+ checkState(classPool != null, "ClassPool needs to be present");
mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
mappingServiceImpl.setPool(classPool);
mappingServiceImpl.start(null);
}
-
-
+
public void updateYangSchema(String[] files) {
SchemaContext context = getContext(files);
- if(schemaAwareDataStore != null) {
+ if (schemaAwareDataStore != null) {
schemaAwareDataStore.onGlobalContextUpdated(context);
}
- if(mappingServiceImpl != null) {
+ if (mappingServiceImpl != null) {
mappingServiceImpl.onGlobalContextUpdated(context);
}
}
-
-
+
public static String[] getAllYangFilesOnClasspath() {
Predicate<String> predicate = new Predicate<String>() {
@Override
Set<String> result = reflection.getResources(predicate);
return (String[]) result.toArray(new String[result.size()]);
}
-
+
private static SchemaContext getContext(String[] yangFiles) {
ClassLoader loader = BindingTestContext.class.getClassLoader();
List<InputStream> streams = new ArrayList<>();
Set<Module> modules = parser.parseYangModelsFromStreams(streams);
return parser.resolveSchemaContext(modules);
}
-
+
public void start() {
startBindingDataBroker();
startBindingNotificationBroker();
startDomDataBroker();
startDomDataStore();
startDomBroker();
+ startDomMountPoint();
startBindingToDomMappingService();
- startBindingToDomDataConnector();
- if(startWithSchema) {
+ startForwarding();
+ if (startWithSchema) {
loadYangSchemaFromClasspath();
}
}
+ private void startDomMountPoint() {
+ biMountImpl = new MountPointManagerImpl();
+ biMountImpl.setDataBroker(getDomDataBroker());
+ }
+
private void startDomBroker() {
checkState(executor != null);
biBrokerImpl = new BrokerImpl();
public void startBindingNotificationBroker() {
checkState(executor != null);
baNotifyImpl = new NotificationBrokerImpl(executor);
-
+
}
public void loadYangSchemaFromClasspath() {
}
public void logDataStoreStatistics() {
- if(dataStoreStats == null) {
+ if (dataStoreStats == null) {
return;
}
-
+
LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(),
dataStoreStats.getConfigurationReadAverageTime());
}
public RpcProviderRegistry getBindingRpcRegistry() {
- return baBrokerImpl;
+ return baBrokerImpl.getRoot();
}
public RpcProvisionRegistry getDomRpcRegistry() {
- if(biBrokerImpl == null) {
+ if (biBrokerImpl == null) {
return null;
}
return biBrokerImpl.getRouter();
}
-
+
public RpcImplementation getDomRpcInvoker() {
return biBrokerImpl.getRouter();
}
-
+
@Override
public void close() throws Exception {
-
+
+ }
+
+ public MountProviderService getBindingMountProviderService() {
+ return baBrokerImpl.getMountManager();
+ }
+
+ public MountProvisionService getDomMountProviderService() {
+ return biMountImpl;
}
}
package org.opendaylight.controller.sal.binding.test.bugfix;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+import com.google.common.collect.ImmutableSet;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
public class FlagsSerializationTest extends AbstractDataServiceTest {
private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
- private static final long FLOW_ID = 1234;
+ private static final String FLOW_ID = "1234";
private static final short TABLE_ID = (short)0;
private static final String NODE_ID = "node:1";
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.supported.actions.ActionType;
assertBindingIndependentVersion(NODE_INSTANCE_ID_BI);
testNodeRemove();
}
+
+ @Test
+ public void putNodeWithAugmentation() throws Exception {
+
+ NodeBuilder nodeBuilder = new NodeBuilder();
+ nodeBuilder.setId(new NodeId(NODE_ID));
+ nodeBuilder.setKey(NODE_KEY);
+ FlowCapableNodeBuilder fnub = new FlowCapableNodeBuilder();
+ fnub.setHardware("Hardware Foo");
+ fnub.setManufacturer("Manufacturer Foo");
+ fnub.setSerialNumber("Serial Foo");
+ fnub.setDescription("Description Foo");
+ fnub.setSoftware("JUnit emulated");
+ FlowCapableNode fnu = fnub.build();
+
+ nodeBuilder.addAugmentation(FlowCapableNode.class, fnu);
+ DataModificationTransaction baseTransaction = baDataService.beginTransaction();
+ baseTransaction.putOperationalData(NODE_INSTANCE_ID_BA, nodeBuilder.build());
+ RpcResult<TransactionStatus> result = baseTransaction.commit().get();
+ assertEquals(TransactionStatus.COMMITED, result.getResult());
+
+ FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance());
+ assertNotNull(readedAugmentation);
+ assertEquals(fnu.getHardware(), readedAugmentation.getHardware());
+
+ testPutNodeConnectorWithAugmentation();
+ testNodeRemove();
+ }
+ 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();
+
+ NodeConnectorBuilder nc = new NodeConnectorBuilder();
+ nc.setKey(ncKey);
+
+ FlowCapableNodeConnectorBuilder fncb = new FlowCapableNodeConnectorBuilder();
+ fncb.setName("Baz");
+ nc.addAugmentation(FlowCapableNodeConnector.class, fncb.build());
+
+ DataModificationTransaction baseTransaction = baDataService.beginTransaction();
+ baseTransaction.putOperationalData(ncPath, nc.build());
+ RpcResult<TransactionStatus> result = baseTransaction.commit().get();
+ assertEquals(TransactionStatus.COMMITED, result.getResult());
+
+ FlowCapableNodeConnector readedAugmentation = (FlowCapableNodeConnector) baDataService.readOperationalData(ncAugmentPath);
+ assertNotNull(readedAugmentation);
+ assertEquals(fncb.getName(), readedAugmentation.getName());
+ }
+
private void testNodeRemove() throws Exception {
DataModificationTransaction transaction = baDataService.beginTransaction();
transaction.removeOperationalData(NODE_INSTANCE_ID_BA);
package org.opendaylight.controller.sal.binding.test.connect.dom;
-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 java.util.concurrent.Future;
-
+import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.CommitHandlersTransactions;
+import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import com.google.common.collect.ImmutableMap;
+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;
public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
private static final QName TABLE_ID_QNAME = QName.create(Table.QNAME, "id");
private static final String NODE_ID = "node:1";
- private static final FlowId FLOW_ID = new FlowId(1234L);
+ private static final FlowId FLOW_ID = new FlowId("1234");
private static final Short TABLE_ID = Short.valueOf((short) 0);
private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
modificationCapture = modification;
- return CommitHandlersTransactions.allwaysSuccessfulTransaction(modification);
+ return CommitHandlerTransactions.allwaysSuccessfulTransaction(modification);
}
};
--- /dev/null
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.management.Notification;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
+import org.opendaylight.controller.sal.binding.test.util.BindingTestContext;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class CrossBrokerMountPointTest {
+
+ private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+ private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
+ private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
+ private static final QName TABLE_ID_QNAME = QName.create(Table.QNAME, "id");
+
+ private static final String NODE_ID = "node:1";
+
+ private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
+
+ private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
+ NODE_ID);
+
+ private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
+ .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) //
+ .child(Group.class, GROUP_KEY) //
+ .augmentation(NodeGroupStatistics.class) //
+ .child(GroupStatistics.class) //
+ .toInstance();
+
+ private static final QName AUGMENTED_GROUP_STATISTICS = QName.create(NodeGroupStatistics.QNAME,
+ GroupStatistics.QNAME.getLocalName());
+
+ private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+ .node(Nodes.QNAME) //
+ .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
+ .toInstance();
+
+ private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier GROUP_STATISTICS_ID_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+ //
+ .builder(NODE_INSTANCE_ID_BI)
+ .nodeWithKey(QName.create(FlowCapableNode.QNAME, "group"), QName.create(FlowCapableNode.QNAME, "group-id"),
+ 0L).node(AUGMENTED_GROUP_STATISTICS).toInstance();
+
+ private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
+
+ private BindingTestContext testContext;
+ private MountProviderService bindingMountPointService;
+ private MountProvisionService domMountPointService;
+
+ @Before
+ public void setup() {
+ BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
+ testFactory.setExecutor(MoreExecutors.sameThreadExecutor());
+ testFactory.setStartWithParsedSchema(true);
+ testContext = testFactory.getTestContext();
+
+ testContext.start();
+ bindingMountPointService = testContext.getBindingMountProviderService();
+ domMountPointService = testContext.getDomMountProviderService();
+
+ // biRpcInvoker = testContext.getDomRpcInvoker();
+ assertNotNull(bindingMountPointService);
+ assertNotNull(domMountPointService);
+
+ // flowService = MessageCapturingFlowService.create(baRpcRegistry);
+ }
+
+ @Test
+ public void testMountPoint() {
+
+ testContext.getBindingDataBroker().readOperationalData(NODE_INSTANCE_ID_BA);
+
+ MountProvisionInstance domMountPoint = domMountPointService.createMountPoint(NODE_INSTANCE_ID_BI);
+ assertNotNull(domMountPoint);
+ MountProviderInstance bindingMountPoint = bindingMountPointService.getMountPoint(NODE_INSTANCE_ID_BA);
+ assertNotNull(bindingMountPoint);
+
+ final BigInteger packetCount = BigInteger.valueOf(500L);
+
+
+ DataReader<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> simpleReader = new DataReader<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>() {
+
+ @Override
+ public CompositeNode readConfigurationData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) {
+ return null;
+ }
+
+
+ @Override
+ public CompositeNode readOperationalData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) {
+ if (arg0.equals(GROUP_STATISTICS_ID_BI)) {
+ ImmutableCompositeNode data = ImmutableCompositeNode
+ .builder()
+ .setQName(AUGMENTED_GROUP_STATISTICS)
+ .addLeaf(QName.create(AUGMENTED_GROUP_STATISTICS, "packet-count"), packetCount) //
+ .toInstance();
+
+ return data;
+ }
+ return null;
+ }
+
+ };
+ domMountPoint.registerOperationalReader(NODE_INSTANCE_ID_BI, simpleReader);
+
+ GroupStatistics data = (GroupStatistics) bindingMountPoint.readOperationalData(GROUP_STATISTICS_ID_BA);
+ assertNotNull(data);
+ assertEquals(packetCount,data.getPacketCount().getValue());
+ }
+}
mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), // //
mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(), //
mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), // //
+ mavenBundle(CONTROLLER, "sal-binding-util").versionAsInProject(), //
mavenBundle("org.javassist", "javassist").versionAsInProject(), // //
mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), // //
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.NotificationService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.binding.RpcService;
public class NoficationTest extends AbstractTest {
* The registration of the Consumer 2. SalFlowListener is registered
* registered as notification listener.
*/
- BindingAwareConsumer consumer2 = new BindingAwareConsumer() {
+ BindingAwareProvider provider = new BindingAwareProvider() {
+
@Override
- public void onSessionInitialized(ConsumerContext session) {
+ public void onSessionInitiated(ProviderContext session) {
listener2Reg = session.getSALService(NotificationProviderService.class).registerNotificationListener(
listener2);
}
+
+ @Override
+ public void onSessionInitialized(ConsumerContext session) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Collection<? extends RpcService> getImplementations() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Collection<? extends ProviderFunctionality> getFunctionality() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
};
// registerConsumer method calls onSessionInitialized method above
- broker.registerConsumer(consumer2, getBundleContext());
+ broker.registerProvider(provider, getBundleContext());
/**
* 3 notifications are published
<artifactId>sal-binding-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.dependencymanager</artifactId>
- <version>3.1.0</version>
- </dependency>
</dependencies>
</project>
--- /dev/null
+package org.opendaylight.controller.md.sal.binding.util;
+
+import java.util.concurrent.Future;
+import java.util.zip.Checksum;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.NotificationListener;
+import org.opendaylight.controller.sal.binding.api.NotificationService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.mount.MountInstance;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataRoot;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractBindingSalConsumerInstance<D extends DataBrokerService, N extends NotificationService, R extends RpcConsumerRegistry> //
+ implements //
+ RpcConsumerRegistry, //
+ NotificationService, //
+ DataBrokerService {
+
+ private final R rpcRegistry;
+ private final N notificationBroker;
+ private final D dataBroker;
+
+ protected final R getRpcRegistry() {
+ return rpcRegistry;
+ }
+
+ protected final N getNotificationBroker() {
+ return notificationBroker;
+ }
+
+ protected final D getDataBroker() {
+ return dataBroker;
+ }
+
+ protected final R getRpcRegistryChecked() {
+ Preconditions.checkState(rpcRegistry != null,"Rpc Registry is not available.");
+ return rpcRegistry;
+ }
+
+ protected final N getNotificationBrokerChecked() {
+ Preconditions.checkState(notificationBroker != null,"Notification Broker is not available.");
+ return notificationBroker;
+ }
+
+ protected final D getDataBrokerChecked() {
+ Preconditions.checkState(dataBroker != null, "Data Broker is not available");
+ return dataBroker;
+ }
+
+
+ protected AbstractBindingSalConsumerInstance(R rpcRegistry, N notificationBroker, D dataBroker) {
+ this.rpcRegistry = rpcRegistry;
+ this.notificationBroker = notificationBroker;
+ this.dataBroker = dataBroker;
+ }
+
+ public <T extends RpcService> T getRpcService(Class<T> module) {
+ return getRpcRegistryChecked().getRpcService(module);
+ }
+
+ @Deprecated
+ public <T extends Notification> void addNotificationListener(Class<T> notificationType,
+ NotificationListener<T> listener) {
+ getNotificationBrokerChecked().addNotificationListener(notificationType, listener);
+ }
+
+ @Deprecated
+ public void addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+ getNotificationBrokerChecked().addNotificationListener(listener);
+ }
+
+ @Deprecated
+ public void removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+ getNotificationBrokerChecked().removeNotificationListener(listener);
+ }
+
+ @Deprecated
+ public <T extends Notification> void removeNotificationListener(Class<T> notificationType,
+ NotificationListener<T> listener) {
+ getNotificationBrokerChecked().removeNotificationListener(notificationType, listener);
+ }
+
+ public <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(
+ Class<T> notificationType, NotificationListener<T> listener) {
+ return getNotificationBrokerChecked().registerNotificationListener(notificationType, listener);
+ }
+
+ public Registration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
+ org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+ return getNotificationBrokerChecked().registerNotificationListener(listener);
+ }
+
+ @Deprecated
+ public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
+ return getDataBrokerChecked().getData(store, rootType);
+ }
+
+ @Deprecated
+ public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
+ return getDataBrokerChecked().getData(store, filter);
+ }
+
+ @Deprecated
+ public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
+ return getDataBrokerChecked().getCandidateData(store, rootType);
+ }
+
+ @Deprecated
+ public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
+ return getDataBrokerChecked().getCandidateData(store, filter);
+ }
+
+ @Deprecated
+ public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
+ return getDataBrokerChecked().editCandidateData(store, changeSet);
+ }
+
+ @Deprecated
+ public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
+ return getDataBrokerChecked().commit(store);
+ }
+
+ @Deprecated
+ public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
+ return getDataBrokerChecked().getData(data);
+ }
+
+ @Deprecated
+ public DataObject getConfigurationData(InstanceIdentifier<?> data) {
+ return getDataBrokerChecked().getConfigurationData(data);
+ }
+
+ public DataModificationTransaction beginTransaction() {
+ return getDataBrokerChecked().beginTransaction();
+ }
+
+ @Deprecated
+ public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
+ getDataBrokerChecked().registerChangeListener(path, changeListener);
+ }
+
+ @Deprecated
+ public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
+ DataChangeListener changeListener) {
+ getDataBrokerChecked().unregisterChangeListener(path, changeListener);
+ }
+
+ @Deprecated
+ public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+ return getDataBrokerChecked().readConfigurationData(path);
+ }
+
+ public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+ return getDataBrokerChecked().readOperationalData(path);
+ }
+
+ @Deprecated
+ public ListenerRegistration<DataChangeListener> registerDataChangeListener(
+ InstanceIdentifier<? extends DataObject> path, DataChangeListener listener) {
+ return getDataBrokerChecked().registerDataChangeListener(path, listener);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.binding.util;
+
+import java.util.concurrent.ExecutorService;
+
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public abstract class AbstractBindingSalProviderInstance<D extends DataProviderService, N extends NotificationProviderService, R extends RpcProviderRegistry> //
+ extends AbstractBindingSalConsumerInstance<D, N, R> //
+ implements //
+ DataProviderService, //
+ RpcProviderRegistry, //
+ NotificationProviderService {
+
+ public AbstractBindingSalProviderInstance(R rpcRegistry, N notificationBroker,
+ D dataBroker) {
+ super(rpcRegistry, notificationBroker, dataBroker);
+ }
+
+ @Override
+ public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerDataReader(
+ InstanceIdentifier<? extends DataObject> path,
+ DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
+ return getDataBrokerChecked().registerDataReader(path, reader);
+ }
+
+ @Override
+ public Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> registerCommitHandler(
+ InstanceIdentifier<? extends DataObject> path,
+ DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
+ return getDataBrokerChecked().registerCommitHandler(path, commitHandler);
+ }
+
+ @Override
+ public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>>> registerCommitHandlerListener(
+ RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>> commitHandlerListener) {
+ return getDataBrokerChecked().registerCommitHandlerListener(commitHandlerListener);
+ }
+
+ @Override
+ public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getRpcRegistryChecked().addRpcImplementation(type, implementation);
+ }
+
+ @Override
+ public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getRpcRegistryChecked().addRoutedRpcImplementation(type, implementation);
+ }
+
+ @Override
+ @Deprecated
+ public void notify(Notification notification) {
+ getNotificationBrokerChecked().notify(notification);
+ }
+
+ @Override
+ @Deprecated
+ public void notify(Notification notification, ExecutorService service) {
+ getNotificationBrokerChecked().notify(notification, service);
+ }
+
+ @Override
+ public void publish(Notification notification) {
+ getNotificationBrokerChecked().publish(notification);
+ }
+
+ @Override
+ public void publish(Notification notification, ExecutorService service) {
+ getNotificationBrokerChecked().publish(notification, service);
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+ L listener) {
+ return getRpcRegistryChecked().registerRouteChangeListener(listener);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.binding.util;
+
+import java.awt.image.SinglePixelPackedSampleModel;
+
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+import static com.google.common.base.Preconditions.*;
+
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.MutableClassToInstanceMap;
+
+public class BindingContextUtils {
+
+ public static ConsumerContext createConsumerContext(BindingAwareConsumer consumer,
+ ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ checkNotNull(consumer,"Consumer should not be null");
+ checkNotNull(serviceProvider,"Service map should not be null");
+ return new SingleConsumerContextImpl(serviceProvider);
+ }
+
+ public static ProviderContext createProviderContext(BindingAwareProvider provider,
+ ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ checkNotNull(provider,"Provider should not be null");
+ checkNotNull(serviceProvider,"Service map should not be null");
+ return new SingleProviderContextImpl(serviceProvider);
+ }
+
+ public static ConsumerContext createConsumerContextAndInitialize(BindingAwareConsumer consumer,
+ ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ ConsumerContext context = createConsumerContext(consumer, serviceProvider);
+ consumer.onSessionInitialized(context);
+ return context;
+ }
+
+ public static ProviderContext createProviderContextAndInitialize(BindingAwareProvider provider,
+ ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ ProviderContext context = createProviderContext(provider, serviceProvider);
+ provider.onSessionInitiated(context);
+ return context;
+ }
+
+ public static <T extends BindingAwareService> T createContextProxyOrReturnService(Class<T> service, T instance) {
+ // FIXME: Create Proxy
+ return instance;
+ }
+
+ private static class SingleConsumerContextImpl implements ConsumerContext, AutoCloseable {
+
+ private ClassToInstanceMap<BindingAwareService> alreadyRetrievedServices;
+ private ClassToInstanceMap<BindingAwareService> serviceProvider;
+
+ public SingleConsumerContextImpl(ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ this.alreadyRetrievedServices = MutableClassToInstanceMap.create();
+ this.serviceProvider = serviceProvider;
+ }
+
+ @Override
+ public final <T extends RpcService> T getRpcService(Class<T> module) {
+ return getSALService(RpcConsumerRegistry.class).getRpcService(module);
+ }
+
+ @Override
+ public final <T extends BindingAwareService> T getSALService(Class<T> service) {
+ checkNotNull(service,"Service class should not be null.");
+ T potential = alreadyRetrievedServices.getInstance(service);
+ if(potential != null) {
+ return potential;
+ }
+ return tryToRetrieveSalService(service);
+ }
+
+ private synchronized <T extends BindingAwareService> T tryToRetrieveSalService(Class<T> service) {
+ final T potential = alreadyRetrievedServices.getInstance(service);
+ if(potential != null) {
+ return potential;
+ }
+ final T requested = serviceProvider.getInstance(service);
+ if(requested == null) {
+ throw new IllegalArgumentException("Requested service "+service.getName() +" is not available.");
+ }
+ final T retrieved = BindingContextUtils.createContextProxyOrReturnService(service,requested);
+ alreadyRetrievedServices.put(service, retrieved);
+ return retrieved;
+ }
+
+ @Override
+ public final void close() throws Exception {
+ alreadyRetrievedServices = null;
+ serviceProvider = null;
+ }
+ }
+
+ private static class SingleProviderContextImpl extends SingleConsumerContextImpl implements ProviderContext {
+
+ public SingleProviderContextImpl(ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ super(serviceProvider);
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+ L listener) {
+ return getSALService(RpcProviderRegistry.class).registerRouteChangeListener(listener);
+ }
+
+ @Override
+ public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type,
+ T implementation) throws IllegalStateException {
+ return getSALService(RpcProviderRegistry.class).addRoutedRpcImplementation(type, implementation);
+ }
+
+ @Override
+ public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getSALService(RpcProviderRegistry.class).addRpcImplementation(type, implementation);
+ }
+
+ @Deprecated
+ @Override
+ public void registerFunctionality(ProviderFunctionality functionality) {
+ // NOOP
+ }
+
+ @Deprecated
+ @Override
+ public void unregisterFunctionality(ProviderFunctionality functionality) {
+ // NOOP
+ }
+ }
+}
public final class TypeSafeDataReader {
-
- private final DataReader<InstanceIdentifier<?>,DataObject> delegate;
-
-
-
+ private final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate;
+
public DataReader<InstanceIdentifier<?>, DataObject> getDelegate() {
return delegate;
}
-
- public TypeSafeDataReader(DataReader<InstanceIdentifier<?>, DataObject> delegate) {
+ public TypeSafeDataReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
this.delegate = delegate;
}
-
@SuppressWarnings("unchecked")
public <D extends DataObject> D readConfigurationData(InstanceIdentifier<D> path) {
return (D) delegate.readConfigurationData(path);
}
-
-
+
@SuppressWarnings("unchecked")
- public <D extends DataObject> D readOperationalData(InstanceIdentifier<D> path) {
+ public <D extends DataObject> D readOperationalData(InstanceIdentifier<D> path) {
return (D) delegate.readOperationalData(path);
}
-
- public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<?>, DataObject> delegate) {
+
+ public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
return new TypeSafeDataReader(delegate);
}
}
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
</dependencies>
<packaging>bundle</packaging>
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.common.util;
public class Arguments {
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
+package org.opendaylight.controller.sal.common.util;
import java.util.Collections;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
-import org.opendaylight.controller.sal.common.util.Rpcs;
import org.opendaylight.yangtools.concepts.Path;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
-public class CommitHandlersTransactions {
+public class CommitHandlerTransactions {
private static class AllwaysSuccessfulTransaction<P extends Path<P>,D> implements DataCommitTransaction<P, D> {
}
}
-
public static final <P extends Path<P>,D> AllwaysSuccessfulTransaction<P, D> allwaysSuccessfulTransaction(DataModification<P, D> modification) {
return new AllwaysSuccessfulTransaction<>(modification);
}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.common.util;
import java.util.concurrent.ExecutionException;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
import org.opendaylight.yangtools.yang.common.QName;
-public interface RpcProvisionRegistry {
+public interface RpcProvisionRegistry extends BrokerService {
/**
* Registers an implementation of the rpc.
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.controller.sal.core.api.mount;
import java.util.concurrent.Future;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public interface MountInstance extends NotificationService, DataBrokerService {
+public interface MountInstance extends //
+ NotificationService, //
+ DataBrokerService {
Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input);
+
+ SchemaContext getSchemaContext();
}
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
import org.opendaylight.controller.sal.core.api.data.DataProviderService;
import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
public interface MountProvisionInstance extends //
MountInstance,//
RpcProvisionRegistry,//
DataProviderService {
+ void setSchemaContext(SchemaContext optional);
+
}
package org.opendaylight.controller.sal.core.api.mount;
+import java.util.EventListener;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
public interface MountProvisionService extends MountService {
MountProvisionInstance createMountPoint(InstanceIdentifier path);
MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path);
+
+ ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+
+ public interface MountProvisionListener extends EventListener {
+
+ void onMountPointCreated(InstanceIdentifier path);
+
+ void onMountPointRemoved(InstanceIdentifier path);
+
+ }
}
<artifactId>sal-common-impl</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-impl</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-core-spi</artifactId>
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker;
+
+public class $ModuleInfo {
+
+
+}
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import com.google.common.util.concurrent.MoreExecutors;
+
public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, CompositeNode, DataChangeListener> implements
DataProviderService, AutoCloseable {
public DataBrokerImpl() {
setDataReadRouter(new DataReaderRouter());
+ setExecutor(MoreExecutors.sameThreadExecutor());
}
public AtomicLong getCreatedTransactionsCount() {
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
public class MountPointImpl implements MountProvisionInstance {
private final RpcRouter rpcs;
- private final DataReaderRouter dataReader;
+ private final DataBrokerImpl dataReader;
private final NotificationRouter notificationRouter;
private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
private final InstanceIdentifier mountPath;
+ private SchemaContext schemaContext;
+
public MountPointImpl(InstanceIdentifier path) {
this.mountPath = path;
rpcs = new RpcRouterImpl("");
- dataReader = new DataReaderRouter();
+ dataReader = new DataBrokerImpl();
notificationRouter = new NotificationRouterImpl();
readWrapper = new ReadWrapper();
}
@Override
public DataModificationTransaction beginTransaction() {
- // TODO Auto-generated method stub
- return null;
+ return dataReader.beginTransaction();
}
@Override
public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
DataChangeListener listener) {
- // TODO Auto-generated method stub
- return null;
+ return dataReader.registerDataChangeListener(path, listener);
}
@Override
@Override
public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
- // TODO Auto-generated method stub
- return null;
+ return dataReader.registerCommitHandler(path, commitHandler);
}
@Override
// NOOP
}
+ public SchemaContext getSchemaContext() {
+ return schemaContext;
+ }
+
+ public void setSchemaContext(SchemaContext schemaContext) {
+ this.schemaContext = schemaContext;
+ }
+
class ReadWrapper implements DataReader<InstanceIdentifier, CompositeNode> {
@Override
public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
- // TODO Auto-generated method stub
- return null;
+ return dataReader.registerCommitHandlerListener(commitHandlerListener);
}
}
import java.util.concurrent.ConcurrentHashMap
import static com.google.common.base.Preconditions.*;
import org.opendaylight.controller.sal.core.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry
class MountPointManagerImpl implements MountProvisionService {
@Property
DataProviderService dataBroker;
+ val ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create()
+
ConcurrentMap<InstanceIdentifier,MountPointImpl> mounts = new ConcurrentHashMap();
override createMountPoint(InstanceIdentifier path) {
val mount = new MountPointImpl(path);
registerMountPoint(mount);
mounts.put(path,mount);
+ notifyMountCreated(path);
return mount;
}
+ def notifyMountCreated(InstanceIdentifier identifier) {
+ for(listener : listeners) {
+ listener.instance.onMountPointCreated(identifier);
+ }
+ }
+
def registerMountPoint(MountPointImpl impl) {
dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
}
+ override registerProvisionListener(MountProvisionListener listener) {
+ listeners.register(listener)
+ }
+
override createOrGetMountPoint(InstanceIdentifier path) {
val mount = mounts.get(path);
import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.osgi.framework.ServiceReference;
public MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path) {
return getDelegate().createOrGetMountPoint(path);
}
+
+ @Override
+ public ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener) {
+ return getDelegate().registerProvisionListener(listener);
+ }
}
// TODO Auto-generated constructor stub
}
- @Override
public YangNode getParent() {
// TODO Auto-generated method stub
return null;
<scope>test</scope>
<version>${netconf.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-test</artifactId>
- <scope>test</scope>
- <version>${netconf.version}</version>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>config-manager</artifactId>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>ietf-netconf-monitoring</artifactId>
+ <version>0.2.3-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>ietf-inet-types</artifactId>
import io.netty.channel.EventLoopGroup;
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 javax.net.ssl.SSLContext;
import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+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 static com.google.common.base.Preconditions.*;
public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
{
+ private static ExecutorService GLOBAL_PROCESSING_EXECUTOR = null;
+ private static AbstractCachingSchemaSourceProvider<String, InputStream> GLOBAL_NETCONF_SOURCE_PROVIDER = null;
private BundleContext bundleContext;
public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
} else {
addressValue = getAddress().getIpv6Address().getValue();
}
-
*/
ReconnectStrategy strategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null,
Long.valueOf(connectionAttempts), null);
-
- device.setStrategy(strategy);
+ device.setReconnectStrategy(strategy);
InetAddress addr = InetAddresses.forString(addressValue);
InetSocketAddress socketAddress = new InetSocketAddress(addr , getPort().intValue());
+
+
+ device.setProcessingExecutor(getGlobalProcessingExecutor());
+
device.setSocketAddress(socketAddress);
+ device.setEventExecutor(getEventExecutorDependency());
+ device.setDispatcher(createDispatcher());
+ device.setSchemaSourceProvider(getGlobalNetconfSchemaProvider(bundleContext));
+ getDomRegistryDependency().registerProvider(device, bundleContext);
+ device.start();
+ return device;
+ }
+
+ private ExecutorService getGlobalProcessingExecutor() {
+ if(GLOBAL_PROCESSING_EXECUTOR == null) {
+
+ GLOBAL_PROCESSING_EXECUTOR = Executors.newCachedThreadPool();
+
+ }
+ return GLOBAL_PROCESSING_EXECUTOR;
+ }
+
+ private synchronized AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider(BundleContext bundleContext) {
+ if(GLOBAL_NETCONF_SOURCE_PROVIDER == null) {
+ String storageFile = "cache/schema";
+// File directory = bundleContext.getDataFile(storageFile);
+ File directory = new File("cache/schema");
+ SchemaSourceProvider<String> defaultProvider = SchemaSourceProviders.noopProvider();
+ GLOBAL_NETCONF_SOURCE_PROVIDER = FilesystemSchemaCachingProvider.createFromStringSourceProvider(defaultProvider, directory);
+ }
+ return GLOBAL_NETCONF_SOURCE_PROVIDER;
+ }
+
+ private NetconfClientDispatcher createDispatcher() {
EventLoopGroup bossGroup = getBossThreadGroupDependency();
EventLoopGroup workerGroup = getWorkerThreadGroupDependency();
- NetconfClientDispatcher dispatcher = null;
if(getTcpOnly()) {
- dispatcher = new NetconfClientDispatcher( bossGroup, workerGroup);
+ return new NetconfClientDispatcher( bossGroup, workerGroup);
} else {
AuthenticationHandler authHandler = new LoginPassword(getUsername(),getPassword());
- dispatcher = new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup);
+ return new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup);
}
- getDomRegistryDependency().registerProvider(device, bundleContext);
-
- device.start(dispatcher);
- return device;
}
public void setBundleContext(BundleContext bundleContext) {
package org.opendaylight.controller.sal.connect.netconf
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.netconf.client.NetconfClient
-import org.opendaylight.controller.sal.core.api.RpcImplementation
-import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import com.google.common.base.Optional
+import com.google.common.collect.FluentIterable
+import io.netty.util.concurrent.EventExecutor
+import java.io.InputStream
import java.net.InetSocketAddress
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.api.SimpleNode
-import org.opendaylight.yangtools.yang.common.QName
+import java.net.URI
import java.util.Collections
+import java.util.List
+import java.util.Set
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Future
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.controller.netconf.api.NetconfMessage
+import org.opendaylight.controller.netconf.client.NetconfClient
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.controller.sal.core.api.Provider
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
-import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
+import org.opendaylight.controller.sal.core.api.Provider
+import org.opendaylight.controller.sal.core.api.RpcImplementation
import org.opendaylight.controller.sal.core.api.data.DataBrokerService
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+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.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
+import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
+import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
-class NetconfDevice implements
- Provider, //
- DataReader<InstanceIdentifier, CompositeNode>, //
- DataCommitHandler<InstanceIdentifier, CompositeNode>, //
- RpcImplementation, //
- AutoCloseable {
+import static com.google.common.base.Preconditions.*
+import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*
+
+import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import org.opendaylight.controller.netconf.util.xml.XmlUtil
+
+class NetconfDevice implements Provider, //
+DataReader<InstanceIdentifier, CompositeNode>, //
+DataCommitHandler<InstanceIdentifier, CompositeNode>, //
+RpcImplementation, //
+AutoCloseable {
var NetconfClient client;
@Property
var MountProvisionInstance mountInstance;
+ @Property
+ var EventExecutor eventExecutor;
+
+ @Property
+ var ExecutorService processingExecutor;
+
@Property
var InstanceIdentifier path;
@Property
- var ReconnectStrategy strategy;
+ var ReconnectStrategy reconnectStrategy;
+
+ @Property
+ var AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider;
+
+ @Property
+ private NetconfDeviceSchemaContextProvider deviceContextProvider
+
+ protected val Logger logger
Registration<DataReader<InstanceIdentifier, CompositeNode>> operReaderReg
Registration<DataReader<InstanceIdentifier, CompositeNode>> confReaderReg
Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> commitHandlerReg
-
+
val String name
MountProvisionService mountService
-
-
+
+ int messegeRetryCount = 5;
+
+ int messageTimeoutCount = 5 * 1000;
+
+ Set<QName> cachedCapabilities
+
+ @Property
+ var NetconfClientDispatcher dispatcher
+
+ static val InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance();
+
+ @Property
+ var SchemaSourceProvider<InputStream> remoteSourceProvider
+
public new(String name) {
this.name = name;
+ this.logger = LoggerFactory.getLogger(NetconfDevice.name + "#" + name);
this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE,
Collections.singletonMap(INVENTORY_ID, name)).toInstance;
}
- def start(NetconfClientDispatcher dispatcher) {
- client = NetconfClient.clientFor(name, socketAddress, strategy, dispatcher);
- confReaderReg = mountInstance.registerConfigurationReader(path, this);
- operReaderReg = mountInstance.registerOperationalReader(path, this);
- //commitHandlerReg = mountInstance.registerCommitHandler(path,this);
+ def start() {
+ checkState(dispatcher != null, "Dispatcher must be set.");
+ checkState(schemaSourceProvider != null, "Schema Source Provider must be set.")
+ checkState(eventExecutor != null, "Event executor must be set.");
+
+ val listener = new NetconfDeviceListener(this, eventExecutor);
+ val task = startClientTask(dispatcher, listener)
+ if (mountInstance != null) {
+ confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this);
+ operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this);
+ commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this)
+ }
+ return processingExecutor.submit(task) as Future<Void>;
+
+ //commitHandlerReg = mountInstance.registerCommitHandler(path,this);
+ }
+
+ def Optional<SchemaContext> getSchemaContext() {
+ if (deviceContextProvider == null) {
+ return Optional.absent();
+ }
+ return deviceContextProvider.currentContext;
+ }
+
+ private def Runnable startClientTask(NetconfClientDispatcher dispatcher, NetconfDeviceListener listener) {
+
+ return [ |
+ logger.info("Starting Netconf Client on: {}", socketAddress);
+ client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener);
+ logger.debug("Initial capabilities {}", initialCapabilities);
+ var SchemaSourceProvider<String> delegate;
+ if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) {
+ delegate = new NetconfRemoteSchemaSourceProvider(this);
+ } else if(client.capabilities.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.namespace.toString)) {
+ delegate = new NetconfRemoteSchemaSourceProvider(this);
+ } else {
+ logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress);
+ delegate = SchemaSourceProviders.<String>noopProvider();
+ }
+ remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate);
+ deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider);
+ deviceContextProvider.createContextFromCapabilities(initialCapabilities);
+ if (mountInstance != null && schemaContext.isPresent) {
+ mountInstance.schemaContext = schemaContext.get();
+ }
+ ]
}
override readConfigurationData(InstanceIdentifier path) {
- val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
+ val result = invokeRpc(NETCONF_GET_CONFIG_QNAME,
+ wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
return data?.findNode(path) as CompositeNode;
}
Collections.emptySet;
}
+ def createSubscription(String streamName) {
+ val it = ImmutableCompositeNode.builder()
+ QName = NETCONF_CREATE_SUBSCRIPTION_QNAME
+ addLeaf("stream", streamName);
+ invokeRpc(QName, toInstance())
+ }
+
override invokeRpc(QName rpc, CompositeNode input) {
- val message = rpc.toRpcMessage(input);
- val result = client.sendMessage(message);
- return result.toRpcResult();
+ try {
+ val message = rpc.toRpcMessage(input,schemaContext);
+ val result = sendMessageImpl(message, messegeRetryCount, messageTimeoutCount);
+ return result.toRpcResult(rpc, schemaContext);
+
+ } catch (Exception e) {
+ logger.error("Rpc was not processed correctly.", e)
+ throw e;
+ }
+ }
+
+ def NetconfMessage sendMessageImpl(NetconfMessage message, int retryCount, int timeout) {
+ logger.debug("Send message {}",XmlUtil.toString(message.document))
+ val result = client.sendMessage(message, retryCount, timeout);
+ NetconfMapping.checkValidReply(message, result)
+ return result;
}
override getProviderFunctionality() {
override onSessionInitiated(ProviderSession session) {
val dataBroker = session.getService(DataBrokerService);
-
-
-
+
val transaction = dataBroker.beginTransaction
- if(transaction.operationalNodeNotExisting) {
- transaction.putOperationalData(path,nodeWithId)
+ if (transaction.operationalNodeNotExisting) {
+ transaction.putOperationalData(path, nodeWithId)
}
- if(transaction.configurationNodeNotExisting) {
- transaction.putConfigurationData(path,nodeWithId)
+ if (transaction.configurationNodeNotExisting) {
+ transaction.putConfigurationData(path, nodeWithId)
}
transaction.commit().get();
mountService = session.getService(MountProvisionService);
- mountInstance = mountService.createOrGetMountPoint(path);
+ mountInstance = mountService?.createOrGetMountPoint(path);
}
-
+
def getNodeWithId() {
- val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name);
- return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id));
+ val id = new SimpleNodeTOImpl(INVENTORY_ID, null, name);
+ return new CompositeNodeTOImpl(INVENTORY_NODE, null, Collections.singletonList(id));
}
-
+
def boolean configurationNodeNotExisting(DataModificationTransaction transaction) {
return null === transaction.readConfigurationData(path);
}
-
+
def boolean operationalNodeNotExisting(DataModificationTransaction transaction) {
return null === transaction.readOperationalData(path);
}
- def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
+ static def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
var Node<?> current = node;
for (arg : identifier.path) {
return null;
} else if (current instanceof CompositeNode) {
val currentComposite = (current as CompositeNode);
-
+
current = currentComposite.getFirstCompositeByName(arg.nodeType);
- if (current == null) {
+ if(current == null) {
+ current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision());
+ }
+ if(current == null) {
current = currentComposite.getFirstSimpleByName(arg.nodeType);
}
if (current == null) {
+ current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision());
+ } if (current == null) {
return null;
}
}
}
override requestCommit(DataModification<InstanceIdentifier, CompositeNode> modification) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ val twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(this, modification);
+ twoPhaseCommit.prepare()
+ return twoPhaseCommit;
+ }
+
+ def getInitialCapabilities() {
+ val capabilities = client?.capabilities;
+ if (capabilities == null) {
+ return null;
+ }
+ if (cachedCapabilities == null) {
+ cachedCapabilities = FluentIterable.from(capabilities).filter[
+ contains("?") && contains("module=") && contains("revision=")].transform [
+ val parts = split("\\?");
+ val namespace = parts.get(0);
+ val queryParams = FluentIterable.from(parts.get(1).split("&"));
+ var revision = queryParams.findFirst[startsWith("revision=")]?.replaceAll("revision=", "");
+ val moduleName = queryParams.findFirst[startsWith("module=")]?.replaceAll("module=", "");
+ if (revision === null) {
+ logger.warn("Netconf device was not reporting revision correctly, trying to get amp;revision=");
+ revision = queryParams.findFirst[startsWith("&revision=")]?.replaceAll("revision=", "");
+ if (revision != null) {
+ logger.warn("Netconf device returned revision incorectly escaped for {}", it)
+ }
+ }
+ if (revision == null) {
+ return QName.create(URI.create(namespace), null, moduleName);
+ }
+ return QName.create(namespace, revision, moduleName);
+ ].toSet();
+ }
+ return cachedCapabilities;
}
override close() {
}
}
+
+package class NetconfDeviceSchemaContextProvider {
+
+ @Property
+ val NetconfDevice device;
+
+ @Property
+ val SchemaSourceProvider<InputStream> sourceProvider;
+
+ @Property
+ var Optional<SchemaContext> currentContext;
+
+ new(NetconfDevice device, SchemaSourceProvider<InputStream> sourceProvider) {
+ _device = device
+ _sourceProvider = sourceProvider
+ _currentContext = Optional.absent();
+ }
+
+ def createContextFromCapabilities(Iterable<QName> capabilities) {
+ val sourceContext = YangSourceContext.createFrom(capabilities, sourceProvider)
+ if (!sourceContext.missingSources.empty) {
+ device.logger.warn("Sources for following models are missing {}", sourceContext.missingSources);
+ }
+ device.logger.debug("Trying to create schema context from {}", sourceContext.validSources)
+ val modelsToParse = YangSourceContext.getValidInputStreams(sourceContext);
+ if (!sourceContext.validSources.empty) {
+ val schemaContext = tryToCreateContext(modelsToParse);
+ currentContext = Optional.fromNullable(schemaContext);
+ } else {
+ currentContext = Optional.absent();
+ }
+ if (currentContext.present) {
+ device.logger.debug("Schema context successfully created.");
+ }
+
+ }
+
+ def SchemaContext tryToCreateContext(List<InputStream> modelsToParse) {
+ val parser = new YangParserImpl();
+ try {
+
+ val models = parser.parseYangModelsFromStreams(modelsToParse);
+ val result = parser.resolveSchemaContext(models);
+ return result;
+ } catch (Exception e) {
+ device.logger.debug("Error occured during parsing YANG schemas", e);
+ return null;
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import com.google.common.base.Objects;
+
+import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.concurrent.Promise;
+
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.NetconfMapping;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.w3c.dom.Document;
+
+@SuppressWarnings("all")
+class NetconfDeviceListener extends NetconfClientSessionListener {
+ private final NetconfDevice device;
+ private final EventExecutor eventExecutor;
+
+ public NetconfDeviceListener(final NetconfDevice device, final EventExecutor eventExecutor) {
+ this.device = device;
+ this.eventExecutor = eventExecutor;
+ }
+
+ private Promise<NetconfMessage> messagePromise;
+ private ConcurrentMap<String, Promise<NetconfMessage>> promisedMessages;
+
+ private final ReentrantLock promiseLock = new ReentrantLock();
+
+ public void onMessage(final NetconfClientSession session, final NetconfMessage message) {
+ if (isNotification(message)) {
+ this.onNotification(session, message);
+ } else {
+ try {
+ this.promiseLock.lock();
+ boolean _notEquals = (!Objects.equal(this.messagePromise, null));
+ if (_notEquals) {
+ this.device.logger.debug("Setting promised reply {} with message {}", this.messagePromise, message);
+ this.messagePromise.setSuccess(message);
+ this.messagePromise = null;
+ }
+ } finally {
+ this.promiseLock.unlock();
+ }
+ }
+ }
+
+ /**
+ * Method intended to customize notification processing.
+ *
+ * @param session
+ * {@see
+ * NetconfClientSessionListener#onMessage(NetconfClientSession,
+ * NetconfMessage)}
+ * @param message
+ * {@see
+ * NetconfClientSessionListener#onMessage(NetconfClientSession,
+ * NetconfMessage)}
+ */
+ public void onNotification(final NetconfClientSession session, final NetconfMessage message) {
+ this.device.logger.debug("Received NETCONF notification.", message);
+ CompositeNode _notificationBody = null;
+ CompositeNode _compositeNode = null;
+ if (message != null) {
+ _compositeNode = NetconfMapping.toCompositeNode(message,device.getSchemaContext());
+ }
+ if (_compositeNode != null) {
+ _notificationBody = NetconfDeviceListener.getNotificationBody(_compositeNode);
+ }
+ final CompositeNode domNotification = _notificationBody;
+ boolean _notEquals = (!Objects.equal(domNotification, null));
+ if (_notEquals) {
+ MountProvisionInstance _mountInstance = null;
+ if (this.device != null) {
+ _mountInstance = this.device.getMountInstance();
+ }
+ if (_mountInstance != null) {
+ _mountInstance.publish(domNotification);
+ }
+ }
+ }
+
+ private static CompositeNode getNotificationBody(final CompositeNode node) {
+ List<Node<? extends Object>> _children = node.getChildren();
+ for (final Node<? extends Object> child : _children) {
+ if ((child instanceof CompositeNode)) {
+ return ((CompositeNode) child);
+ }
+ }
+ return null;
+ }
+
+ public NetconfMessage getLastMessage(final int attempts, final int attemptMsDelay) throws InterruptedException {
+ final Promise<NetconfMessage> promise = this.promiseReply();
+ this.device.logger.debug("Waiting for reply {}", promise);
+ int _plus = (attempts * attemptMsDelay);
+ final boolean messageAvailable = promise.await(_plus);
+ if (messageAvailable) {
+ try {
+ try {
+ return promise.get();
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ } catch (final Throwable _t) {
+ if (_t instanceof ExecutionException) {
+ final ExecutionException e = (ExecutionException) _t;
+ IllegalStateException _illegalStateException = new IllegalStateException(e);
+ throw _illegalStateException;
+ } else {
+ throw Exceptions.sneakyThrow(_t);
+ }
+ }
+ }
+ String _plus_1 = ("Unsuccessful after " + Integer.valueOf(attempts));
+ String _plus_2 = (_plus_1 + " attempts.");
+ IllegalStateException _illegalStateException_1 = new IllegalStateException(_plus_2);
+ throw _illegalStateException_1;
+ }
+
+ public synchronized Promise<NetconfMessage> promiseReply() {
+ this.device.logger.debug("Promising reply.");
+ this.promiseLock.lock();
+ try {
+ boolean _equals = Objects.equal(this.messagePromise, null);
+ if (_equals) {
+ Promise<NetconfMessage> _newPromise = this.eventExecutor.<NetconfMessage> newPromise();
+ this.messagePromise = _newPromise;
+ return this.messagePromise;
+ }
+ return this.messagePromise;
+ } finally {
+ this.promiseLock.unlock();
+ }
+ }
+
+ public boolean isNotification(final NetconfMessage message) {
+ Document _document = message.getDocument();
+ final XmlElement xmle = XmlElement.fromDomDocument(_document);
+ String _name = xmle.getName();
+ return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(_name);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*;
+
+public class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<InstanceIdentifier, CompositeNode> {
+
+ private NetconfDevice device;
+ private final DataModification<InstanceIdentifier, CompositeNode> modification;
+ private boolean candidateSupported = true;
+
+ public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device,
+ DataModification<InstanceIdentifier, CompositeNode> modification) {
+ super();
+ this.device = device;
+ this.modification = modification;
+ }
+
+ public void prepare() {
+ for (InstanceIdentifier toRemove : modification.getRemovedConfigurationData()) {
+ sendRemove(toRemove);
+ }
+ for(Entry<InstanceIdentifier, CompositeNode> toUpdate : modification.getUpdatedConfigurationData().entrySet()) {
+ sendMerge(toUpdate.getKey(),toUpdate.getValue());
+ }
+
+ }
+
+ private void sendMerge(InstanceIdentifier key, CompositeNode value) {
+ sendEditRpc(createEditStructure(key, Optional.<String>absent(), Optional.of(value)));
+ }
+
+ private void sendRemove(InstanceIdentifier toRemove) {
+ sendEditRpc(createEditStructure(toRemove, Optional.of("remove"), Optional.<CompositeNode> absent()));
+ }
+
+ private void sendEditRpc(CompositeNode editStructure) {
+ CompositeNodeBuilder<ImmutableCompositeNode> builder = configurationRpcBuilder();
+ builder.setQName(NETCONF_EDIT_CONFIG_QNAME);
+ builder.add(editStructure);
+
+ RpcResult<CompositeNode> rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance());
+ Preconditions.checkState(rpcResult.isSuccessful(),"Rpc Result was unsuccessful");
+
+ }
+
+ private CompositeNodeBuilder<ImmutableCompositeNode> configurationRpcBuilder() {
+ CompositeNodeBuilder<ImmutableCompositeNode> ret = ImmutableCompositeNode.builder();
+
+ Node<?> targetNode;
+ if(candidateSupported) {
+ targetNode = ImmutableCompositeNode.create(NETCONF_CANDIDATE_QNAME, ImmutableList.<Node<?>>of());
+ } else {
+ targetNode = ImmutableCompositeNode.create(NETCONF_RUNNING_QNAME, ImmutableList.<Node<?>>of());
+ }
+ Node<?> targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.<Node<?>>of(targetNode));
+ ret.add(targetWrapperNode);
+ return ret;
+ }
+
+ private CompositeNode createEditStructure(InstanceIdentifier dataPath, Optional<String> action,
+ Optional<CompositeNode> lastChildOverride) {
+ List<PathArgument> path = dataPath.getPath();
+ List<PathArgument> reversed = Lists.reverse(path);
+ CompositeNode previous = null;
+ boolean isLast = true;
+ for (PathArgument arg : reversed) {
+ CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
+ builder.setQName(arg.getNodeType());
+ Map<QName, Object> predicates = Collections.emptyMap();
+ if (arg instanceof NodeIdentifierWithPredicates) {
+ predicates = ((NodeIdentifierWithPredicates) arg).getKeyValues();
+ }
+ for (Entry<QName, Object> entry : predicates.entrySet()) {
+ builder.addLeaf(entry.getKey(), entry.getValue());
+ }
+
+ if (isLast) {
+ if (action.isPresent()) {
+ builder.setAttribute(NETCONF_ACTION_QNAME, action.get());
+ }
+ if (lastChildOverride.isPresent()) {
+ List<Node<?>> children = lastChildOverride.get().getChildren();
+ for(Node<?> child : children) {
+ if(!predicates.containsKey(child.getKey())) {
+ builder.add(child);
+ }
+ }
+
+ }
+ } else {
+ builder.add(previous);
+ }
+ previous = builder.toInstance();
+ isLast = false;
+ }
+ return ImmutableCompositeNode.create(NETCONF_CONFIG_QNAME, ImmutableList.<Node<?>>of(previous));
+ }
+
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ CompositeNodeBuilder<ImmutableCompositeNode> commitInput = ImmutableCompositeNode.builder();
+ commitInput.setQName(NETCONF_COMMIT_QNAME);
+ RpcResult<?> rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance());
+ return (RpcResult<Void>) rpcResult;
+ }
+
+ @Override
+ public DataModification<InstanceIdentifier, CompositeNode> getModification() {
+ return this.modification;
+ }
+
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
import org.opendaylight.controller.sal.common.util.Rpcs
import java.util.List
import com.google.common.collect.ImmutableList
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import com.google.common.base.Preconditions
+import com.google.common.base.Optional
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils
class NetconfMapping {
public static val NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0")
- public static val NETCONF_QNAME = new QName(NETCONF_URI,null,"netconf");
- public static val NETCONF_RPC_QNAME = new QName(NETCONF_QNAME,"rpc");
- public static val NETCONF_GET_QNAME = new QName(NETCONF_QNAME,"get");
- public static val NETCONF_GET_CONFIG_QNAME = new QName(NETCONF_QNAME,"get-config");
- public static val NETCONF_SOURCE_QNAME = new QName(NETCONF_QNAME,"source");
- public static val NETCONF_RUNNING_QNAME = new QName(NETCONF_QNAME,"running");
- public static val NETCONF_RPC_REPLY_QNAME = new QName(NETCONF_QNAME,"rpc-reply");
- public static val NETCONF_OK_QNAME = new QName(NETCONF_QNAME,"ok");
- public static val NETCONF_DATA_QNAME = new QName(NETCONF_QNAME,"data");
+ public static val NETCONF_MONITORING_URI = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"
+ public static val NETCONF_NOTIFICATION_URI = URI.create("urn:ietf:params:xml:ns:netconf:notification:1.0")
- static List<Node<?>> RUNNING = Collections.<Node<?>>singletonList(new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME,null,null));
- public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME,null,RUNNING);
-
- static val messageId = new AtomicInteger(0);
-
+ public static val NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf");
+ public static val NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc");
+ public static val NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get");
+ public static val NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter");
+ public static val NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
+ public static val NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
+ public static val NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config");
+ public static val NETCONF_DELETE_CONFIG_QNAME = QName.create(NETCONF_QNAME, "delete-config");
+ public static val NETCONF_ACTION_QNAME = QName.create(NETCONF_QNAME, "action");
+ public static val NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit");
+
+ public static val NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config");
+ public static val NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
+ public static val NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target");
+
+ public static val NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate");
+ public static val NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
+
+
+ public static val NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
+ public static val NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok");
+ public static val NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
+ public static val NETCONF_CREATE_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"create-subscription");
+ public static val NETCONF_CANCEL_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"cancel-subscription");
+ public static val IETF_NETCONF_MONITORING_MODULE = QName.create(NETCONF_MONITORING_URI, "2010-10-04","ietf-netconf-monitoring");
+ static List<Node<?>> RUNNING = Collections.<Node<?>>singletonList(
+ new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME, null, null));
+ public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME, null, RUNNING);
+ static val messageId = new AtomicInteger(0);
static def Node<?> toFilterStructure(InstanceIdentifier identifier) {
var Node<?> previous = null;
- for (component : identifier.path.reverse) {
+ if(identifier.path.empty) {
+ return null;
+ }
+
+ for (component : identifier.path.reverseView) {
val Node<?> current = component.toNode(previous);
previous = current;
}
- return previous;
+ return filter("subtree",previous);
}
-
+
static def dispatch Node<?> toNode(NodeIdentifierWithPredicates argument, Node<?> node) {
val list = new ArrayList<Node<?>>();
- for( arg : argument.keyValues.entrySet) {
- list.add = new SimpleNodeTOImpl(arg.key,null,arg.value);
+ for (arg : argument.keyValues.entrySet) {
+ list.add = new SimpleNodeTOImpl(arg.key, null, arg.value);
}
- return new CompositeNodeTOImpl(argument.nodeType,null,list)
+ return new CompositeNodeTOImpl(argument.nodeType, null, list)
}
-
+
static def dispatch Node<?> toNode(PathArgument argument, Node<?> node) {
- if(node != null) {
- return new CompositeNodeTOImpl(argument.nodeType,null,Collections.singletonList(node));
+ if (node != null) {
+ return new CompositeNodeTOImpl(argument.nodeType, null, Collections.singletonList(node));
} else {
- return new SimpleNodeTOImpl(argument.nodeType,null,null);
+ return new SimpleNodeTOImpl(argument.nodeType, null, null);
}
}
- static def CompositeNode toCompositeNode(NetconfMessage message) {
- return message.toRpcResult().result;
+ static def CompositeNode toCompositeNode(NetconfMessage message,Optional<SchemaContext> ctx) {
+ return null//message.toRpcResult().result;
}
- static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node) {
- val rpcPayload = wrap(NETCONF_RPC_QNAME,node);
+ static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node,Optional<SchemaContext> ctx) {
+ val rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node));
val w3cPayload = NodeUtils.buildShadowDomTree(rpcPayload);
- w3cPayload.documentElement.setAttribute("message-id","m-"+ messageId.andIncrement);
+ w3cPayload.documentElement.setAttribute("message-id", "m-" + messageId.andIncrement);
return new NetconfMessage(w3cPayload);
}
+
+ def static flattenInput(CompositeNode node) {
+ val inputQName = QName.create(node.nodeType,"input");
+ val input = node.getFirstCompositeByName(inputQName);
+ if(input == null) return node;
+ if(input instanceof CompositeNode) {
+
+ val nodes = ImmutableList.builder() //
+ .addAll(input.children) //
+ .addAll(node.children.filter[nodeType != inputQName]) //
+ .build()
+ return ImmutableCompositeNode.create(node.nodeType,nodes);
+ }
+
+ }
- static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message) {
- val rawRpc = message.document.toCompositeNode() as CompositeNode;
+ static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message,QName rpc,Optional<SchemaContext> context) {
+ var CompositeNode rawRpc;
+ if(context.present) {
+ if(isDataRetrievalReply(rpc)) {
+
+ val xmlData = message.document.dataSubtree
+ val dataNodes = XmlDocumentUtils.toDomNodes(xmlData,Optional.of(context.get.dataDefinitions))
+
+ val it = ImmutableCompositeNode.builder()
+ setQName(NETCONF_RPC_REPLY_QNAME)
+ add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME,dataNodes));
+
+ rawRpc = it.toInstance;
+ //sys(xmlData)
+ } else {
+ val rpcSchema = context.get.operations.findFirst[QName == rpc]
+ rawRpc = message.document.toCompositeNode() as CompositeNode;
+ }
+
+
+
+ } else {
+ rawRpc = message.document.toCompositeNode() as CompositeNode;
+ }
//rawRpc.
-
- return Rpcs.getRpcResult(true,rawRpc,Collections.emptySet());
+ return Rpcs.getRpcResult(true, rawRpc, Collections.emptySet());
}
+ def static Element getDataSubtree(Document doc) {
+ doc.getElementsByTagNameNS(NETCONF_URI.toString,"data").item(0) as Element
+ }
- static def wrap(QName name,Node<?> node) {
- if(node != null) {
- return new CompositeNodeTOImpl(name,null,Collections.singletonList(node));
- }
- else {
- return new CompositeNodeTOImpl(name,null,Collections.emptyList());
+ def static boolean isDataRetrievalReply(QName it) {
+ return NETCONF_URI == namespace && ( localName == NETCONF_GET_CONFIG_QNAME.localName || localName == NETCONF_GET_QNAME.localName)
+ }
+
+ static def wrap(QName name, Node<?> node) {
+ if (node != null) {
+ return new CompositeNodeTOImpl(name, null, Collections.singletonList(node));
+ } else {
+ return new CompositeNodeTOImpl(name, null, Collections.emptyList());
}
}
-
- static def wrap(QName name,Node<?> additional,Node<?> node) {
- if(node != null) {
- return new CompositeNodeTOImpl(name,null,ImmutableList.of(additional,node));
+
+ static def wrap(QName name, Node<?> additional, Node<?> node) {
+ if (node != null) {
+ return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node));
+ } else {
+ return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional));
}
- else {
- return new CompositeNodeTOImpl(name,null,ImmutableList.of(additional));
+ }
+
+ static def filter(String type, Node<?> node) {
+ val it = ImmutableCompositeNode.builder(); //
+ setQName(NETCONF_FILTER_QNAME);
+ setAttribute(NETCONF_TYPE_QNAME,type);
+ if (node != null) {
+ return add(node).toInstance();
+ } else {
+ return toInstance();
}
}
-
-
+
public static def Node<?> toCompositeNode(Document document) {
- return XmlDocumentUtils.toCompositeNode(document) as Node<?>
+ return XmlDocumentUtils.toDomNode(document) as Node<?>
}
+
+ public static def checkValidReply(NetconfMessage input, NetconfMessage output) {
+ val inputMsgId = input.document.documentElement.getAttribute("message-id")
+ val outputMsgId = output.document.documentElement.getAttribute("message-id")
+ Preconditions.checkState(inputMsgId == outputMsgId,"Rpc request and reply message IDs must be same.");
+
+ }
+
}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String> {
+
+ public static final QName IETF_NETCONF_MONITORING = QName.create(
+ "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
+ public static final QName GET_SCHEMA_QNAME = QName.create(IETF_NETCONF_MONITORING, "get-schema");
+ public static final QName GET_DATA_QNAME = QName.create(IETF_NETCONF_MONITORING, "data");
+
+ NetconfDevice device;
+
+ public NetconfRemoteSchemaSourceProvider(NetconfDevice device) {
+ super();
+ this.device = device;
+ }
+
+ @Override
+ public Optional<String> getSchemaSource(String moduleName, Optional<String> revision) {
+ CompositeNodeBuilder<ImmutableCompositeNode> request = ImmutableCompositeNode.builder(); //
+ request.setQName(GET_SCHEMA_QNAME) //
+ .addLeaf("format", "yang") //
+ .addLeaf("identifier", moduleName); //
+ if (revision.isPresent()) {
+ request.addLeaf("version", revision.get());
+ }
+
+ device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision);
+ RpcResult<CompositeNode> schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance());
+ if (schemaReply.isSuccessful()) {
+ String schemaBody = getSchemaFromRpc(schemaReply.getResult());
+ if (schemaBody != null) {
+ device.logger.info("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision);
+ return Optional.of(schemaBody);
+ }
+ }
+ device.logger.info("YANG shcema was not successfully retrieved.");
+ return Optional.absent();
+ }
+
+ private String getSchemaFromRpc(CompositeNode result) {
+ if (result == null) {
+ return null;
+ }
+ SimpleNode<?> simpleNode = result.getFirstSimpleByName(GET_DATA_QNAME.withoutRevision());
+ Object potential = simpleNode.getValue();
+ if (potential instanceof String) {
+ return (String) potential;
+ }
+ return null;
+ }
+
+ public static final boolean isSupportedFor(Set<QName> capabilities) {
+ return capabilities.contains(IETF_NETCONF_MONITORING);
+ }
+}
+++ /dev/null
-package org.opendaylight.controller.sal.connect.netconf;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-public class XmlDocumentUtils {
-
- public static CompositeNode toCompositeNode(Document doc) {
- return (CompositeNode) toCompositeNode(doc.getDocumentElement());
- }
-
- private static Node<?> toCompositeNode(Element element) {
- String orgNamespace = element.getNamespaceURI();
- URI biNamespace = null;
- if (orgNamespace != null) {
- biNamespace = URI.create(orgNamespace);
- }
- QName qname = new QName(biNamespace, element.getLocalName());
-
- List<Node<?>> values = new ArrayList<>();
- NodeList nodes = element.getChildNodes();
- boolean isSimpleObject = false;
- String value = null;
- for (int i = 0; i < nodes.getLength(); i++) {
- org.w3c.dom.Node child = nodes.item(i);
- if (child instanceof Element) {
- isSimpleObject = false;
- values.add(toCompositeNode((Element) child));
- }
- if (!isSimpleObject && child instanceof org.w3c.dom.Text) {
- value = element.getTextContent();
- if (value.matches(".*\\w.*")) {
- isSimpleObject = true;
- break;
- }
- }
- }
-
- if (isSimpleObject) {
- return new SimpleNodeTOImpl<>(qname, null, value);
- }
- return new CompositeNodeTOImpl(qname, null, values);
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+import java.io.StringReader;
+
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ *
+ *
+ */
+public class YangModelInputStreamAdapter extends InputStream implements Delegator<InputStream> {
+
+ final String source;
+ final QName moduleIdentifier;
+ final InputStream delegate;
+
+
+
+ private YangModelInputStreamAdapter(String source, QName moduleIdentifier, InputStream delegate) {
+ super();
+ this.source = source;
+ this.moduleIdentifier = moduleIdentifier;
+ this.delegate = delegate;
+ }
+
+ public int read() throws IOException {
+ return delegate.read();
+ }
+
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ public int read(byte[] b) throws IOException {
+ return delegate.read(b);
+ }
+
+ public boolean equals(Object obj) {
+ return delegate.equals(obj);
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ return delegate.read(b, off, len);
+ }
+
+ public long skip(long n) throws IOException {
+ return delegate.skip(n);
+ }
+
+ public int available() throws IOException {
+ return delegate.available();
+ }
+
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ public void mark(int readlimit) {
+ delegate.mark(readlimit);
+ }
+
+ public void reset() throws IOException {
+ delegate.reset();
+ }
+
+ public boolean markSupported() {
+ return delegate.markSupported();
+ }
+
+ @Override
+ public InputStream getDelegate() {
+ return delegate;
+ }
+
+ @Override
+ public String toString() {
+ return "YangModelInputStreamAdapter [moduleIdentifier=" + moduleIdentifier + ", delegate=" + delegate + "]";
+ }
+
+ public static YangModelInputStreamAdapter create(QName name, String module) {
+ InputStream stringInput = new StringBufferInputStream(module);
+ return new YangModelInputStreamAdapter(null, name, stringInput );
+ }
+}
}
}
}
+
+ container event-executor {
+ uses config:service-ref {
+ refine type {
+ config:required-identity netty:netty-event-executor;
+ }
+ }
+ }
}
}
}
\ No newline at end of file
<properties>
<zeromq.version>0.3.1</zeromq.version>
- <jackson.version>1.9.8</jackson.version>
+ <jackson.version>2.3.0</jackson.version>
<stax.version>1.0.1</stax.version>
</properties>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-impl</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
<!-- Third Party -->
<dependency>
<groupId> org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
<dependency>
<groupId>stax</groupId>
<artifactId>stax-api</artifactId>
*/
package org.opendaylight.controller.sal.connector.remoterpc.dto;
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.map.ObjectMapper;
+import java.io.Serializable;
+import java.net.URI;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
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;
-import java.net.URI;
-
public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>,Serializable {
transient ObjectMapper mapper = new ObjectMapper();
package org.opendaylight.controller.sal.connector.remoterpc;
-import org.codehaus.jackson.JsonParseException;
+import java.net.URI;
+
+import com.fasterxml.jackson.core.JsonParseException;
import org.junit.Assert;
import org.junit.Test;
import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.net.URI;
-
public class RouteIdentifierImplTest {
Logger _logger = LoggerFactory.getLogger(RouteIdentifierImplTest.class);
</scm>
<properties>
+ <jackson.version>2.3.0</jackson.version>
<exam.version>3.0.0</exam.version>
<url.version>1.5.0</url.version>
<config.version>0.2.3-SNAPSHOT</config.version>
</dependency>
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- <version>1.9.2</version>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- <version>1.9.2</version>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${jackson.version}</version>
</dependency>
+
<dependency>
<groupId>org.zeromq</groupId>
<artifactId>jeromq</artifactId>
<version>0.3.1</version>
</dependency>
+
<dependency>
<groupId>org.opendaylight.yangtools.thirdparty</groupId>
<artifactId>xtend-lib-osgi</artifactId>
mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
mavenBundle("com.google.guava", "guava").versionAsInProject(), //
mavenBundle("org.zeromq", "jeromq").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(),
//routingtable dependencies
systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
// List framework bundles
<artifactId>yang-data-impl</artifactId>
<version>${yang.version}</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-model-util</artifactId>
<version>${yang.version}</version>
<version>2.4</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-model-util</artifactId>
- <version>0.5.9-SNAPSHOT</version>
- </dependency>
</dependencies>
<build>
*/
package org.opendaylight.controller.sal.rest.api;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+ @Consumes({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+ Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
+ @POST
+ @Path("/operations/{identifier}")
+ @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+ Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+ public StructuredData invokeRpc(@PathParam("identifier") String identifier);
+
@GET
@Path("/config/{identifier:.+}")
@Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public StructuredData readConfigurationData(@PathParam("identifier") String identifier);
-
- @POST
- @Path("/config/{identifier:.+}")
+
+ @GET
+ @Path("/operational/{identifier:.+}")
@Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
- public Response createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+ public StructuredData readOperationalData(@PathParam("identifier") String identifier);
@PUT
@Path("/config/{identifier:.+}")
- @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ @Consumes({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
- @GET
- @Path("/operational/{identifier:.+}")
- @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ @POST
+ @Path("/config/{identifier:.+}")
+ @Consumes({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
- public StructuredData readOperationalData(@PathParam("identifier") String identifier);
+ public Response createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+
+ @POST
+ @Path("/config")
+ @Consumes({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+ public Response createConfigurationData(CompositeNode payload);
+
+ @DELETE
+ @Path("/config/{identifier:.+}")
+ public Response deleteConfigurationData(@PathParam("identifier") String identifier);
}
package org.opendaylight.controller.sal.rest.api;
+import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@Deprecated
@POST
@Path("/datastore/{identifier:.+}")
- @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+ @Consumes({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
@Deprecated
@PUT
@Path("/datastore/{identifier:.+}")
- @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+ @Consumes({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
private final Set<ListSchemaNode> foundLists = new HashSet<>();
- private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
+ private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
Preconditions.checkNotNull(writer);
TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
+ if (node.getValue() == null && !(baseType instanceof EmptyTypeDefinition)) {
+ logger.debug("While generationg JSON output null value was found for type "
+ + baseType.getClass().getSimpleName() + ".");
+ }
+
// TODO check InstanceIdentifierTypeDefinition
if (baseType instanceof IdentityrefTypeDefinition) {
if (node.getValue() instanceof QName) {
IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(baseType).serialize(node.getValue());
IdentityValue valueFromDTO = valueDTO.getValuesWithNamespaces().get(0);
- String moduleName = ControllerContext.getInstance().findModuleByNamespace(URI.create(valueFromDTO.getNamespace()));
+ String moduleName = ControllerContext.getInstance().findModuleNameByNamespace(
+ URI.create(valueFromDTO.getNamespace()));
writer.value(moduleName + ":" + valueFromDTO.getValue());
} else {
logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
- + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+ + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is "
+ + node.getValue().getClass());
writer.value(String.valueOf(node.getValue()));
}
} else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition
import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
SchemaService schemaService = session.getService(SchemaService.class);
listenerRegistration = schemaService.registerSchemaServiceListener(ControllerContext.getInstance());
ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext());
+ ControllerContext.getInstance().setMountService(session.getService(MountService.class));
}
@Override
package org.opendaylight.controller.sal.rest.impl;
-import java.util.Set;
-
import javax.activation.UnsupportedDataTypeException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.controller.sal.restconf.impl.RestCodec;
-import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.YangNode;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.Leafref;
import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
+import com.google.common.base.Optional;
public class XmlMapper {
-
- private final Logger logger = LoggerFactory.getLogger(XmlMapper.class);
+ private static final LeafrefCodecImpl LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl(
+ Optional.<LeafrefTypeDefinition> absent());
- public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException {
- Preconditions.checkNotNull(data);
- Preconditions.checkNotNull(schema);
+ private static class LeafrefCodecImpl extends TypeDefinitionAwareCodec<Object, LeafrefTypeDefinition> implements
+ LeafrefCodec<String> {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- Document doc = null;
- try {
- DocumentBuilder bob = dbf.newDocumentBuilder();
- doc = bob.newDocument();
- } catch (ParserConfigurationException e) {
- return null;
+ protected LeafrefCodecImpl(Optional<LeafrefTypeDefinition> typeDef) {
+ super(typeDef, Object.class);
}
- if (schema instanceof ContainerSchemaNode || schema instanceof ListSchemaNode) {
- doc.appendChild(translateToXmlAndReturnRootElement(doc, data, schema));
- return doc;
- } else {
- throw new UnsupportedDataTypeException(
- "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
+ @Override
+ public String serialize(Object data) {
+ return String.valueOf(data);
}
- }
- private Element translateToXmlAndReturnRootElement(Document doc, Node<?> data, YangNode schema)
- throws UnsupportedDataTypeException {
- QName dataType = data.getNodeType();
- Element itemEl = doc.createElementNS(dataType.getNamespace().toString(), dataType.getLocalName());
- if (data instanceof SimpleNode<?>) {
- if (schema instanceof LeafListSchemaNode) {
- writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafListSchemaNode) schema).getType(), (DataSchemaNode) schema);
- } else if (schema instanceof LeafSchemaNode) {
- writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafSchemaNode) schema).getType(), (DataSchemaNode) schema);
- } else {
- Object value = data.getValue();
- if (value != null) {
- itemEl.setTextContent(String.valueOf(value));
- }
- }
- } else { // CompositeNode
- for (Node<?> child : ((CompositeNode) data).getChildren()) {
- DataSchemaNode childSchema = null;
- if(schema != null){
- childSchema = findFirstSchemaForNode(child, ((DataNodeContainer) schema).getChildNodes());
- if (logger.isDebugEnabled()) {
- if (childSchema == null) {
- logger.debug("Probably the data node \"" + ((child == null) ? "" : child.getNodeType().getLocalName())
- + "\" is not conform to schema");
- }
- }
- }
- itemEl.appendChild(translateToXmlAndReturnRootElement(doc, child, childSchema));
- }
+ @Override
+ public Object deserialize(String data) {
+ return data;
}
- return itemEl;
}
- private void writeValueOfNodeByType(Element element, SimpleNode<?> node, TypeDefinition<?> type, DataSchemaNode schema) {
-
- TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
+ private static class XmlCodecProviderImpl implements XmlCodecProvider {
+ @Override
+ public TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codecFor(TypeDefinition<?> baseType) {
+ TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codec = TypeDefinitionAwareCodec
+ .from(baseType);
- if (baseType instanceof IdentityrefTypeDefinition) {
- if (node.getValue() instanceof QName) {
- IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue());
- IdentityValue value = valueDTO.getValuesWithNamespaces().get(0);
- String prefix = "x";
- if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
- prefix = value.getPrefix();
+ if (codec == null) {
+ if (baseType instanceof Leafref) {
+ return LEAFREF_DEFAULT_CODEC;
}
- element.setAttribute("xmlns:" + prefix, value.getNamespace());
- element.setTextContent(prefix + ":" + value.getValue());
- } else {
- logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
- + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
- element.setTextContent(String.valueOf(node.getValue()));
- }
- } else {
- if (node.getValue() != null) {
- String value = String.valueOf(RestCodec.from(baseType).serialize(node.getValue()));
- if (value.equals("null")) {
- value = String.valueOf(node.getValue());
- }
- element.setTextContent(value);
}
+ return codec;
}
}
- private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
- if (dataSchemaNode != null && node != null) {
- for (DataSchemaNode dsn : dataSchemaNode) {
- if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
- return dsn;
- } else if (dsn instanceof ChoiceNode) {
- for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
- DataSchemaNode foundDsn = findFirstSchemaForNode(node, choiceCase.getChildNodes());
- if (foundDsn != null) {
- return foundDsn;
- }
- }
- }
- }
- }
- return null;
- }
+ private static final XmlCodecProvider XML_CODEC_PROVIDER_IMPL = new XmlCodecProviderImpl();
+ public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException {
+ return XmlDocumentUtils.toDocument(data, schema, XML_CODEC_PROVIDER_IMPL);
+ }
}
import org.opendaylight.yangtools.yang.data.api.CompositeNode
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
override readConfigurationData(InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Configuration via Restconf: {}",path)
+ LOG.info("Read Configuration via Restconf: {}", path)
return dataService.readConfigurationData(path);
}
+
+ def readConfigurationDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+ checkPreconditions
+ LOG.info("Read Configuration via Restconf: {}", path)
+ return mountPoint.readConfigurationData(path);
+ }
override readOperationalData(InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Operational via Restconf: {}",path)
+ LOG.info("Read Operational via Restconf: {}", path)
return dataService.readOperationalData(path);
}
+
+ def readOperationalDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+ checkPreconditions
+ LOG.info("Read Operational via Restconf: {}", path)
+ return mountPoint.readOperationalData(path);
+ }
def RpcResult<CompositeNode> invokeRpc(QName type, CompositeNode payload) {
checkPreconditions
def commitConfigurationDataPut(InstanceIdentifier path, CompositeNode payload) {
checkPreconditions
val transaction = dataService.beginTransaction;
+ LOG.info("Put Configuration via Restconf: {}", path)
+ transaction.putConfigurationData(path, payload);
+ return transaction.commit
+ }
+
+ def commitConfigurationDataPutBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
+ checkPreconditions
+ val transaction = mountPoint.beginTransaction;
+ LOG.info("Put Configuration via Restconf: {}", path)
+ transaction.putConfigurationData(path, payload);
+ return transaction.commit
+ }
+
+ def commitConfigurationDataPost(InstanceIdentifier path, CompositeNode payload) {
+ checkPreconditions
+ val transaction = dataService.beginTransaction;
+ transaction.putConfigurationData(path, payload);
+ if (payload == transaction.createdConfigurationData.get(path)) {
+ LOG.info("Post Configuration via Restconf: {}", path)
+ return transaction.commit
+ }
+ LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+ return null;
+ }
+
+ def commitConfigurationDataPostBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
+ checkPreconditions
+ val transaction = mountPoint.beginTransaction;
transaction.putConfigurationData(path, payload);
- return transaction.commit()
+ if (payload == transaction.createdConfigurationData.get(path)) {
+ LOG.info("Post Configuration via Restconf: {}", path)
+ return transaction.commit
+ }
+ LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+ return null;
}
- def commitOperationalDataPut(InstanceIdentifier path, CompositeNode payload) {
+ def commitConfigurationDataDelete(InstanceIdentifier path) {
checkPreconditions
val transaction = dataService.beginTransaction;
- transaction.putOperationalData(path, payload);
- return transaction.commit()
+ transaction.removeConfigurationData(path)
+ return transaction.commit
}
+ def commitConfigurationDataDeleteBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+ checkPreconditions
+ val transaction = mountPoint.beginTransaction;
+ transaction.removeConfigurationData(path)
+ return transaction.commit
+ }
+
}
Preconditions.checkState(compositeNode == null, "Data can be inconsistent.");
return Collections.unmodifiableList(values);
}
+
+ @Override
+ public boolean isChangeAllowed() {
+ return compositeNode == null ? true : false;
+ }
@Override
public CompositeNode unwrap() {
public Set<java.util.Map.Entry<QName, List<Node<?>>>> entrySet() {
return unwrap().entrySet();
}
+
}
import java.util.List
import java.util.Map
import java.util.concurrent.ConcurrentHashMap
-import javax.ws.rs.core.Response
import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.controller.sal.core.api.mount.MountService
import org.opendaylight.controller.sal.rest.impl.RestUtil
import org.opendaylight.controller.sal.rest.impl.RestconfProvider
import org.opendaylight.yangtools.yang.common.QName
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.Module
import org.opendaylight.yangtools.yang.model.api.RpcDefinition
import org.opendaylight.yangtools.yang.model.api.SchemaContext
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
import org.slf4j.LoggerFactory
import static com.google.common.base.Preconditions.*
+import static javax.ws.rs.core.Response.Status.*
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
class ControllerContext implements SchemaServiceListener {
val static LOG = LoggerFactory.getLogger(ControllerContext)
val static ControllerContext INSTANCE = new ControllerContext
val static NULL_VALUE = "null"
+ val static MOUNT_MODULE = "yang-ext"
+ val static MOUNT_NODE = "mount"
+ val static MOUNT = "yang-ext:mount"
- var SchemaContext schemas;
+ @Property
+ var SchemaContext globalSchema;
+
+ @Property
+ var MountService mountService;
private val BiMap<URI, String> uriToModuleName = HashBiMap.create();
private val Map<String, URI> moduleNameToUri = uriToModuleName.inverse();
}
private def void checkPreconditions() {
- if (schemas === null) {
- throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
+ if (globalSchema === null) {
+ throw new ResponseException(SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
}
}
}
public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) {
- val ret = InstanceIdentifier.builder();
+ checkPreconditions
val pathArgs = restconfInstance.split("/");
if (pathArgs.empty) {
return null;
if (pathArgs.head.empty) {
pathArgs.remove(0)
}
- val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule);
- if (schemaNode === null) {
- return null
+ val startModule = pathArgs.head.toModuleName();
+ if (startModule === null) {
+ throw new ResponseException(BAD_REQUEST, "First node in URI has to be in format \"moduleName:nodeName\"")
}
- return new InstanceIdWithSchemaNode(ret.toInstance, schemaNode)
- }
-
- private def findModule(String restconfInstance) {
- checkPreconditions
- checkNotNull(restconfInstance);
- val pathArgs = restconfInstance.split("/");
- if (pathArgs.empty) {
- return null;
+ val iiWithSchemaNode = collectPathArguments(InstanceIdentifier.builder(), pathArgs,
+ globalSchema.getLatestModule(startModule), null);
+ if (iiWithSchemaNode === null) {
+ throw new ResponseException(BAD_REQUEST, "URI has bad format")
}
- val modulWithFirstYangStatement = pathArgs.filter[s|s.contains(":")].head
- val startModule = modulWithFirstYangStatement.toModuleName();
- return getLatestModule(startModule)
+ return iiWithSchemaNode
}
- def getLatestModule(String moduleName) {
- checkPreconditions
+ private def getLatestModule(SchemaContext schema, String moduleName) {
+ checkArgument(schema !== null);
checkArgument(moduleName !== null && !moduleName.empty)
- val modules = schemas.modules.filter[m|m.name == moduleName]
+ val modules = schema.modules.filter[m|m.name == moduleName]
+ return modules.filterLatestModule
+ }
+
+ private def filterLatestModule(Iterable<Module> modules) {
var latestModule = modules.head
for (module : modules) {
if (module.revision.after(latestModule.revision)) {
}
return latestModule
}
+
+ def findModuleByName(String moduleName) {
+ checkPreconditions
+ checkArgument(moduleName !== null && !moduleName.empty)
+ return globalSchema.getLatestModule(moduleName)
+ }
+
+ def findModuleByName(MountInstance mountPoint, String moduleName) {
+ checkArgument(moduleName !== null && mountPoint !== null)
+ val mountPointSchema = mountPoint.schemaContext;
+ return mountPointSchema?.getLatestModule(moduleName);
+ }
+
+ def findModuleByNamespace(URI namespace) {
+ checkPreconditions
+ val moduleSchemas = globalSchema.findModuleByNamespace(namespace)
+ return moduleSchemas?.filterLatestModule
+ }
+
+ def findModuleByNamespace(MountInstance mountPoint, URI namespace) {
+ checkArgument(namespace !== null && mountPoint !== null)
+ val mountPointSchema = mountPoint.schemaContext;
+ val moduleSchemas = mountPointSchema?.findModuleByNamespace(namespace)
+ return moduleSchemas?.filterLatestModule
+ }
def String toFullRestconfIdentifier(InstanceIdentifier path) {
checkPreconditions
val elements = path.path;
val ret = new StringBuilder();
val startQName = elements.get(0).nodeType;
- val initialModule = schemas.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision)
+ val initialModule = globalSchema.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision)
var node = initialModule as DataSchemaNode;
for (element : elements) {
node = node.childByQName(element.nodeType);
throw new IllegalArgumentException("Conversion of generic path argument is not supported");
}
- def findModuleByNamespace(URI namespace) {
+ def findModuleNameByNamespace(URI namespace) {
checkPreconditions
var module = uriToModuleName.get(namespace)
if (module === null) {
- val moduleSchemas = schemas.findModuleByNamespace(namespace);
+ val moduleSchemas = globalSchema.findModuleByNamespace(namespace);
if(moduleSchemas === null) return null
- var latestModule = moduleSchemas.head
- for (m : moduleSchemas) {
- if (m.revision.after(latestModule.revision)) {
- latestModule = m
- }
- }
+ var latestModule = moduleSchemas.filterLatestModule
if(latestModule === null) return null
uriToModuleName.put(namespace, latestModule.name)
module = latestModule.name;
return module
}
- def findNamespaceByModule(String module) {
+ def findNamespaceByModuleName(String module) {
var namespace = moduleNameToUri.get(module)
if (namespace === null) {
- val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)]
- var latestModule = moduleSchemas.head
- for (m : moduleSchemas) {
- if (m.revision.after(latestModule.revision)) {
- latestModule = m
- }
- }
+ var latestModule = globalSchema.getLatestModule(module)
if(latestModule === null) return null
namespace = latestModule.namespace
uriToModuleName.put(namespace, latestModule.name)
checkPreconditions
var module = uriToModuleName.get(qname.namespace)
if (module === null) {
- val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
+ val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
if(moduleSchema === null) throw new IllegalArgumentException()
uriToModuleName.put(qname.namespace, moduleSchema.name)
module = moduleSchema.name;
if(object === null) return "";
return URLEncoder.encode(object.toString)
}
-
- private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
- DataNodeContainer parentNode) {
+
+ private def InstanceIdWithSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
+ DataNodeContainer parentNode, MountInstance mountPoint) {
checkNotNull(strings)
if (parentNode === null) {
return null;
}
if (strings.empty) {
- return parentNode as DataSchemaNode;
+ return new InstanceIdWithSchemaNode(builder.toInstance, parentNode as DataSchemaNode, mountPoint)
}
- val nodeRef = strings.head;
-
- val nodeName = nodeRef.toNodeName();
- val targetNode = parentNode.getDataChildByName(nodeName);
- if (targetNode === null) {
- val children = parentNode.childNodes
- for (child : children) {
- if (child instanceof ChoiceNode) {
- val choice = child as ChoiceNode
- for (caze : choice.cases) {
- val result = builder.collectPathArguments(strings, caze as DataNodeContainer);
- if (result !== null)
- return result
- }
+
+ val nodeName = strings.head.toNodeName
+ val moduleName = strings.head.toModuleName
+ var DataSchemaNode targetNode = null
+ if (!moduleName.nullOrEmpty) {
+ // if it is mount point
+ if (moduleName == MOUNT_MODULE && nodeName == MOUNT_NODE) {
+ if (mountPoint !== null) {
+ throw new ResponseException(BAD_REQUEST, "Restconf supports just one mount point in URI.")
+ }
+
+ if (mountService === null) {
+ throw new ResponseException(SERVICE_UNAVAILABLE, "MountService was not found. "
+ + "Finding behind mount points does not work."
+ )
+ }
+
+ val partialPath = builder.toInstance;
+ val mount = mountService.getMountPoint(partialPath)
+ if (mount === null) {
+ LOG.debug("Instance identifier to missing mount point: {}", partialPath)
+ throw new ResponseException(BAD_REQUEST, "Mount point does not exist.")
+ }
+
+ val mountPointSchema = mount.schemaContext;
+ if (mountPointSchema === null) {
+ throw new ResponseException(BAD_REQUEST, "Mount point does not contain any schema with modules.")
}
+
+ if (strings.size == 1) { // any data node is not behind mount point
+ return new InstanceIdWithSchemaNode(InstanceIdentifier.builder().toInstance, mountPointSchema, mount)
+ }
+
+ val moduleNameBehindMountPoint = strings.get(1).toModuleName()
+ if (moduleNameBehindMountPoint === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "First node after mount point in URI has to be in format \"moduleName:nodeName\"")
+ }
+
+ val moduleBehindMountPoint = mountPointSchema.getLatestModule(moduleNameBehindMountPoint)
+ if (moduleBehindMountPoint === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.")
+ }
+
+ return collectPathArguments(InstanceIdentifier.builder(), strings.subList(1, strings.size),
+ moduleBehindMountPoint, mount);
+ }
+
+ var Module module = null;
+ if (mountPoint === null) {
+ module = globalSchema.getLatestModule(moduleName)
+ if (module === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "URI has bad format. \"" + moduleName + "\" module does not exist.")
+ }
+ } else {
+ module = mountPoint.schemaContext?.getLatestModule(moduleName)
+ if (module === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.")
+ }
+ }
+ targetNode = parentNode.findInstanceDataChild(nodeName, module.namespace)
+ if (targetNode === null) {
+ throw new ResponseException(BAD_REQUEST, "URI has bad format. Possible reasons:\n" +
+ "1. \"" + strings.head + "\" was not found in parent data node.\n" +
+ "2. \"" + strings.head + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + strings.head + "\".")
+ }
+ } else { // string without module name
+ targetNode = parentNode.findInstanceDataChild(nodeName, null)
+ if (targetNode === null) {
+ throw new ResponseException(BAD_REQUEST, "URI has bad format. \"" + nodeName + "\" was not found in parent data node.\n")
}
- return null
- }
- if (targetNode instanceof ChoiceNode) {
- return null
}
-
+
// Number of consumed elements
var consumed = 1;
if (targetNode instanceof ListSchemaNode) {
// every key has to be filled
if ((strings.length - consumed) < keysSize) {
- return null;
+ throw new ResponseException(BAD_REQUEST,"Missing key for list \"" + listNode.QName.localName + "\".")
}
val uriKeyValues = strings.subList(consumed, consumed + keysSize);
val keyValues = new HashMap<QName, Object>();
// key value cannot be NULL
if (uriKeyValue.equals(NULL_VALUE)) {
- return null
+ throw new ResponseException(BAD_REQUEST, "URI has bad format. List \"" + listNode.QName.localName
+ + "\" cannot contain \"null\" value as a key."
+ )
}
keyValues.addKeyValue(listNode.getDataChildByName(key), uriKeyValue);
i = i + 1;
}
if (targetNode instanceof DataNodeContainer) {
val remaining = strings.subList(consumed, strings.length);
- val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer);
+ val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer, mountPoint);
return result
}
- return targetNode
+ return new InstanceIdWithSchemaNode(builder.toInstance, targetNode, mountPoint)
+ }
+
+ def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name, URI moduleNamespace) {
+ var DataSchemaNode potentialNode = null
+ if (moduleNamespace === null) {
+ potentialNode = container.getDataChildByName(name);
+ } else {
+ potentialNode = container.childNodes.filter[n|n.QName.localName == name && n.QName.namespace == moduleNamespace].head
+ }
+
+ if (potentialNode.instantiatedDataSchema) {
+ return potentialNode;
+ }
+ val allCases = container.childNodes.filter(ChoiceNode).map[cases].flatten
+ for (caze : allCases) {
+ potentialNode = caze.findInstanceDataChild(name, moduleNamespace);
+ if (potentialNode !== null) {
+ return potentialNode;
+ }
+ }
+ return null;
+ }
+
+ static def boolean isInstantiatedDataSchema(DataSchemaNode node) {
+ switch node {
+ LeafSchemaNode: return true
+ LeafListSchemaNode: return true
+ ContainerSchemaNode: return true
+ ListSchemaNode: return true
+ default: return false
+ }
}
private def void addKeyValue(HashMap<QName, Object> map, DataSchemaNode node, String uriValue) {
map.put(node.QName, decoded);
}
- private def String toModuleName(String str) {
+ private static def String toModuleName(String str) {
checkNotNull(str)
if (str.contains(":")) {
val args = str.split(":");
- checkArgument(args.size === 2);
- return args.get(0);
- } else {
- return null;
+ if (args.size === 2) {
+ return args.get(0);
+ }
}
+ return null;
}
private def String toNodeName(String str) {
if (str.contains(":")) {
val args = str.split(":");
- checkArgument(args.size === 2);
- return args.get(1);
- } else {
- return str;
+ if (args.size === 2) {
+ return args.get(1);
+ }
}
+ return str;
}
private def QName toQName(String name) {
val module = name.toModuleName;
val node = name.toNodeName;
- val namespace = FluentIterable.from(schemas.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) //
+ val namespace = FluentIterable.from(globalSchema.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) //
.transform[QName.create(namespace,revision,it.name)].findFirst[module == localName]
;
return QName.create(namespace,node);
}
override onGlobalContextUpdated(SchemaContext context) {
- this.schemas = context;
+ this.globalSchema = context;
for (operation : context.operations) {
val qname = operation.QName;
qnameToRpc.put(qname, operation);
this.namespace = namespace;
}
+ @Override
+ public boolean isChangeAllowed() {
+ return unwrapped == null ? true : false;
+ }
+
@Override
public Node<?> unwrap() {
if (unwrapped == null) {
package org.opendaylight.controller.sal.restconf.impl;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
private final InstanceIdentifier instanceIdentifier;
private final DataSchemaNode schemaNode;
+ private final MountInstance mountPoint;
- public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode) {
+ public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, MountInstance mountPoint) {
this.instanceIdentifier = instanceIdentifier;
this.schemaNode = schemaNode;
+ this.mountPoint = mountPoint;
}
public InstanceIdentifier getInstanceIdentifier() {
return schemaNode;
}
+ public MountInstance getMountPoint() {
+ return mountPoint;
+ }
+
}
T unwrap();
+ boolean isChangeAllowed();
+
URI getNamespace();
void setNamespace(URI namespace);
private RestCodec() {
}
-
+
public static final Codec<Object, Object> from(TypeDefinition<?> typeDefinition) {
return new ObjectCodec(typeDefinition);
}
-
+
@SuppressWarnings("rawtypes")
public static final class ObjectCodec implements Codec<Object, Object> {
private final Logger logger = LoggerFactory.getLogger(RestCodec.class);
-
+
public static final Codec IDENTITYREF_DEFAULT_CODEC = new IdentityrefCodecImpl();
public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl();
private ObjectCodec(TypeDefinition<?> typeDefinition) {
type = RestUtil.resolveBaseTypeFrom(typeDefinition);
}
-
+
@SuppressWarnings("unchecked")
@Override
public Object deserialize(Object input) {
} else if (type instanceof LeafrefTypeDefinition) {
return LEAFREF_DEFAULT_CODEC.deserialize(input);
} else {
- TypeDefinitionAwareCodec<Object,? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec.from(type);
+ TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
+ .from(type);
if (typeAwarecodec != null) {
return typeAwarecodec.deserialize(String.valueOf(input));
} else {
- logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet.");
+ logger.debug("Codec for type \"" + type.getQName().getLocalName()
+ + "\" is not implemented yet.");
return null;
}
}
- } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
- logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e);
+ } catch (ClassCastException e) { // TODO remove this catch when
+ // everyone use codecs
+ logger.error(
+ "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
+ e);
return input;
}
}
} else if (type instanceof LeafrefTypeDefinition) {
return LEAFREF_DEFAULT_CODEC.serialize(input);
} else {
- TypeDefinitionAwareCodec<Object,? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec.from(type);
+ TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
+ .from(type);
if (typeAwarecodec != null) {
return typeAwarecodec.serialize(input);
} else {
- logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet.");
+ logger.debug("Codec for type \"" + type.getQName().getLocalName()
+ + "\" is not implemented yet.");
return null;
}
}
- } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
- logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e);
+ } catch (ClassCastException e) { // TODO remove this catch when
+ // everyone use codecs
+ logger.error(
+ "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
+ e);
return input;
}
}
-
+
}
-
+
public static class IdentityrefCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
@Override
public QName deserialize(IdentityValuesDTO data) {
IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
String namespace = valueWithNamespace.getNamespace();
- URI validNamespace = ControllerContext.getInstance().findNamespaceByModule(namespace);
+ URI validNamespace = ControllerContext.getInstance().findNamespaceByModuleName(namespace);
if (validNamespace == null) {
validNamespace = URI.create(namespace);
}
}
}
-
+
public static class LeafrefCodecImpl implements LeafrefCodec<String> {
@Override
public Object deserialize(String data) {
return data;
}
-
+
}
-
+
}
package org.opendaylight.controller.sal.restconf.impl
+import com.google.common.base.Preconditions
+import java.net.URI
import java.util.ArrayList
+import java.util.HashMap
import java.util.List
import java.util.Set
import javax.ws.rs.core.Response
import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
import org.opendaylight.controller.sal.rest.api.RestconfService
import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.RpcResult
import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder
import org.opendaylight.yangtools.yang.data.api.Node
import org.opendaylight.yangtools.yang.data.impl.NodeFactory
import org.opendaylight.yangtools.yang.model.api.ChoiceNode
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.Module
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
import org.opendaylight.yangtools.yang.model.api.TypeDefinition
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
return null;
}
- override readData(String identifier) {
- val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
- return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
- }
-
- override createConfigurationData(String identifier, CompositeNode payload) {
- val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val value = normalizeNode(payload, identifierWithSchemaNode.schemaNode)
- val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier, value).get();
- switch status.result {
- case TransactionStatus.COMMITED: Response.status(NO_CONTENT).build
- default: Response.status(INTERNAL_SERVER_ERROR).build
- }
+ override invokeRpc(String identifier, CompositeNode payload) {
+ return callRpc(identifier.rpcDefinition, payload)
}
-
- override updateConfigurationData(String identifier, CompositeNode payload) {
- val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val value = normalizeNode(payload, identifierWithSchemaNode.schemaNode)
- val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier, value).get();
- switch status.result {
- case TransactionStatus.COMMITED: Response.status(OK).build
- default: Response.status(INTERNAL_SERVER_ERROR).build
- }
+
+ override invokeRpc(String identifier) {
+ return callRpc(identifier.rpcDefinition, null)
}
-
- override invokeRpc(String identifier, CompositeNode payload) {
- val rpc = identifier.rpcDefinition
+
+ private def StructuredData callRpc(RpcDefinition rpc, CompositeNode payload) {
if (rpc === null) {
throw new ResponseException(NOT_FOUND, "RPC does not exist.");
}
- val value = normalizeNode(payload, rpc.input)
- val List<Node<?>> input = new ArrayList
- input.add(value)
- val rpcRequest = NodeFactory.createMutableCompositeNode(rpc.QName, null, input, null, null)
+ var CompositeNode rpcRequest;
+ if (payload === null) {
+ rpcRequest = NodeFactory.createMutableCompositeNode(rpc.QName, null, null, null, null)
+ } else {
+ val value = normalizeNode(payload, rpc.input, null)
+ val List<Node<?>> input = new ArrayList
+ input.add(value)
+ rpcRequest = NodeFactory.createMutableCompositeNode(rpc.QName, null, input, null, null)
+ }
val rpcResult = broker.invokeRpc(rpc.QName, rpcRequest);
if (!rpcResult.successful) {
throw new ResponseException(INTERNAL_SERVER_ERROR, "Operation failed")
return new StructuredData(rpcResult.result, rpc.output)
}
+ override readData(String identifier) {
+ val iiWithData = identifier.toInstanceIdentifier
+ var CompositeNode data = null;
+ if (iiWithData.mountPoint !== null) {
+ data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.instanceIdentifier)
+ } else {
+ data = broker.readOperationalData(iiWithData.getInstanceIdentifier);
+ }
+ return new StructuredData(data, iiWithData.schemaNode)
+ }
+
override readConfigurationData(String identifier) {
- val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val data = broker.readConfigurationData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
- return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+ val iiWithData = identifier.toInstanceIdentifier
+ var CompositeNode data = null;
+ if (iiWithData.mountPoint !== null) {
+ data = broker.readConfigurationDataBehindMountPoint(iiWithData.mountPoint, iiWithData.getInstanceIdentifier)
+ } else {
+ data = broker.readConfigurationData(iiWithData.getInstanceIdentifier);
+ }
+ return new StructuredData(data, iiWithData.schemaNode)
}
override readOperationalData(String identifier) {
- val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
- return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+ val iiWithData = identifier.toInstanceIdentifier
+ var CompositeNode data = null;
+ if (iiWithData.mountPoint !== null) {
+ data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.getInstanceIdentifier)
+ } else {
+ data = broker.readOperationalData(iiWithData.getInstanceIdentifier);
+ }
+ return new StructuredData(data, iiWithData.schemaNode)
}
override updateConfigurationDataLegacy(String identifier, CompositeNode payload) {
updateConfigurationData(identifier, payload);
}
+ override updateConfigurationData(String identifier, CompositeNode payload) {
+ val iiWithData = identifier.toInstanceIdentifier
+ val value = normalizeNode(payload, iiWithData.schemaNode, iiWithData.mountPoint)
+ var RpcResult<TransactionStatus> status = null
+ if (iiWithData.mountPoint !== null) {
+ status = broker.commitConfigurationDataPutBehindMountPoint(iiWithData.mountPoint,
+ iiWithData.instanceIdentifier, value).get()
+ } else {
+ status = broker.commitConfigurationDataPut(iiWithData.instanceIdentifier, value).get();
+ }
+ switch status.result {
+ case TransactionStatus.COMMITED: Response.status(OK).build
+ default: Response.status(INTERNAL_SERVER_ERROR).build
+ }
+ }
+
override createConfigurationDataLegacy(String identifier, CompositeNode payload) {
createConfigurationData(identifier, payload);
}
- private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
- val identifierWithSchemaNode = identifier.toInstanceIdentifier
- if (identifierWithSchemaNode === null) {
- throw new ResponseException(BAD_REQUEST, "URI has bad format");
+ override createConfigurationData(String identifier, CompositeNode payload) {
+ if (payload.namespace === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)");
+ }
+ val uncompleteInstIdWithData = identifier.toInstanceIdentifier
+ val schemaNode = uncompleteInstIdWithData.mountPoint.findModule(payload)?.getSchemaChildNode(payload)
+ val value = normalizeNode(payload, schemaNode, uncompleteInstIdWithData.mountPoint)
+ val completeInstIdWithData = uncompleteInstIdWithData.addLastIdentifierFromData(value, schemaNode)
+ var RpcResult<TransactionStatus> status = null
+ if (completeInstIdWithData.mountPoint !== null) {
+ status = broker.commitConfigurationDataPostBehindMountPoint(completeInstIdWithData.mountPoint,
+ completeInstIdWithData.instanceIdentifier, value)?.get();
+ } else {
+ status = broker.commitConfigurationDataPost(completeInstIdWithData.instanceIdentifier, value)?.get();
+ }
+ if (status === null) {
+ return Response.status(ACCEPTED).build
+ }
+ switch status.result {
+ case TransactionStatus.COMMITED: Response.status(NO_CONTENT).build
+ default: Response.status(INTERNAL_SERVER_ERROR).build
+ }
+ }
+
+ override createConfigurationData(CompositeNode payload) {
+ if (payload.namespace === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)");
+ }
+ val schemaNode = findModule(null, payload)?.getSchemaChildNode(payload)
+ val value = normalizeNode(payload, schemaNode, null)
+ val iiWithData = addLastIdentifierFromData(null, value, schemaNode)
+ var RpcResult<TransactionStatus> status = null
+ if (iiWithData.mountPoint !== null) {
+ status = broker.commitConfigurationDataPostBehindMountPoint(iiWithData.mountPoint,
+ iiWithData.instanceIdentifier, value)?.get();
+ } else {
+ status = broker.commitConfigurationDataPost(iiWithData.instanceIdentifier, value)?.get();
+ }
+ if (status === null) {
+ return Response.status(ACCEPTED).build
+ }
+ switch status.result {
+ case TransactionStatus.COMMITED: Response.status(NO_CONTENT).build
+ default: Response.status(INTERNAL_SERVER_ERROR).build
+ }
+ }
+
+ override deleteConfigurationData(String identifier) {
+ val iiWithData = identifier.toInstanceIdentifier
+ var RpcResult<TransactionStatus> status = null
+ if (iiWithData.mountPoint !== null) {
+ status = broker.commitConfigurationDataDeleteBehindMountPoint(iiWithData.mountPoint,
+ iiWithData.getInstanceIdentifier).get;
+ } else {
+ status = broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier).get;
+ }
+ switch status.result {
+ case TransactionStatus.COMMITED: Response.status(OK).build
+ default: Response.status(INTERNAL_SERVER_ERROR).build
+ }
+ }
+
+ private def dispatch URI namespace(CompositeNode data) {
+ return data.nodeType.namespace
+ }
+
+ private def dispatch URI namespace(CompositeNodeWrapper data) {
+ return data.namespace
+ }
+
+ private def dispatch Module findModule(MountInstance mountPoint, CompositeNode data) {
+ if (mountPoint !== null) {
+ return mountPoint.findModuleByNamespace(data.nodeType.namespace)
+ } else {
+ return findModuleByNamespace(data.nodeType.namespace)
}
- return identifierWithSchemaNode
}
- private def CompositeNode normalizeNode(CompositeNode node, DataSchemaNode schema) {
+ private def dispatch Module findModule(MountInstance mountPoint, CompositeNodeWrapper data) {
+ Preconditions.checkNotNull(data.namespace)
+ var Module module = null;
+ if (mountPoint !== null) {
+ module = mountPoint.findModuleByNamespace(data.namespace) // namespace from XML
+ if (module === null) {
+ module = mountPoint.findModuleByName(data.namespace.toString) // namespace (module name) from JSON
+ }
+ } else {
+ module = data.namespace.findModuleByNamespace // namespace from XML
+ if (module === null) {
+ module = data.namespace.toString.findModuleByName // namespace (module name) from JSON
+ }
+ }
+ return module
+ }
+
+ private def dispatch DataSchemaNode getSchemaChildNode(DataNodeContainer parentSchemaNode, CompositeNode data) {
+ return parentSchemaNode?.getDataChildByName(data.nodeType.localName)
+ }
+
+ private def dispatch DataSchemaNode getSchemaChildNode(DataNodeContainer parentSchemaNode, CompositeNodeWrapper data) {
+ return parentSchemaNode?.getDataChildByName(data.localName)
+ }
+
+ private def InstanceIdWithSchemaNode addLastIdentifierFromData(InstanceIdWithSchemaNode identifierWithSchemaNode,
+ CompositeNode data, DataSchemaNode schemaOfData) {
+ val iiOriginal = identifierWithSchemaNode?.instanceIdentifier
+ var InstanceIdentifierBuilder iiBuilder = null
+ if (iiOriginal === null) {
+ iiBuilder = InstanceIdentifier.builder
+ } else {
+ iiBuilder = InstanceIdentifier.builder(iiOriginal)
+ }
+
+ if (schemaOfData instanceof ListSchemaNode) {
+ iiBuilder.nodeWithKey(schemaOfData.QName, (schemaOfData as ListSchemaNode).resolveKeysFromData(data))
+ } else {
+ iiBuilder.node(schemaOfData.QName)
+ }
+ return new InstanceIdWithSchemaNode(iiBuilder.toInstance, schemaOfData, identifierWithSchemaNode?.mountPoint)
+ }
+
+ private def resolveKeysFromData(ListSchemaNode listNode, CompositeNode dataNode) {
+ val keyValues = new HashMap<QName, Object>();
+ for (key : listNode.keyDefinition) {
+ val dataNodeKeyValueObject = dataNode.getSimpleNodesByName(key.localName)?.head?.value
+ if (dataNodeKeyValueObject === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "Data contains list \"" + dataNode.nodeType.localName + "\" which does not contain key: \"" +
+ key.localName + "\"")
+ }
+ keyValues.put(key, dataNodeKeyValueObject);
+ }
+ return keyValues
+ }
+
+ private def CompositeNode normalizeNode(CompositeNode node, DataSchemaNode schema, MountInstance mountPoint) {
+ if (schema === null) {
+ throw new ResponseException(INTERNAL_SERVER_ERROR, "Data schema node was not found for " + node?.nodeType?.localName)
+ }
+ if (!(schema instanceof DataNodeContainer)) {
+ throw new ResponseException(BAD_REQUEST, "Root element has to be container or list yang datatype.");
+ }
if (node instanceof CompositeNodeWrapper) {
- normalizeNode(node as CompositeNodeWrapper, schema, null)
+ if ((node as CompositeNodeWrapper).changeAllowed) {
+ normalizeNode(node as CompositeNodeWrapper, schema, null, mountPoint)
+ }
return (node as CompositeNodeWrapper).unwrap()
}
return node
}
- private def void normalizeNode(NodeWrapper<?> nodeBuilder, DataSchemaNode schema, QName previousAugment) {
+ private def void normalizeNode(NodeWrapper<?> nodeBuilder, DataSchemaNode schema, QName previousAugment,
+ MountInstance mountPoint) {
if (schema === null) {
throw new ResponseException(BAD_REQUEST,
- "Data has bad format\n" + nodeBuilder.localName + " does not exist in yang schema.");
+ "Data has bad format.\n\"" + nodeBuilder.localName + "\" does not exist in yang schema.");
}
var validQName = schema.QName
var currentAugment = previousAugment;
} else if (previousAugment !== null && schema.QName.namespace !== previousAugment.namespace) {
validQName = QName.create(currentAugment, schema.QName.localName);
}
- val moduleName = controllerContext.findModuleByNamespace(validQName.namespace);
+ var String moduleName = null;
+ if (mountPoint === null) {
+ moduleName = controllerContext.findModuleNameByNamespace(validQName.namespace);
+ } else {
+ moduleName = mountPoint.findModuleByNamespace(validQName.namespace)?.name
+ }
if (nodeBuilder.namespace === null || nodeBuilder.namespace == validQName.namespace ||
nodeBuilder.namespace.toString == moduleName) {
nodeBuilder.qname = validQName
} else {
throw new ResponseException(BAD_REQUEST,
- "Data has bad format\nIf data is in XML format then namespace for " + nodeBuilder.localName +
- " should be " + schema.QName.namespace + ".\n If data is in Json format then module name for " +
- nodeBuilder.localName + " should be " + moduleName + ".");
+ "Data has bad format.\nIf data is in XML format then namespace for \"" + nodeBuilder.localName +
+ "\" should be \"" + schema.QName.namespace + "\".\nIf data is in Json format then module name for \"" +
+ nodeBuilder.localName + "\" should be \"" + moduleName + "\".");
}
if (nodeBuilder instanceof CompositeNodeWrapper) {
for (child : children) {
normalizeNode(child,
findFirstSchemaByLocalName(child.localName, (schema as DataNodeContainer).childNodes),
- currentAugment)
+ currentAugment, mountPoint)
}
if(schema instanceof ListSchemaNode) {
val listKeys = (schema as ListSchemaNode).keyDefinition
}
if (!foundKey) {
throw new ResponseException(BAD_REQUEST,
- "Missing key \"" + listKey.localName + "\" of list \"" + schema.QName.localName + "\"")
+ "Missing key in URI \"" + listKey.localName + "\" of list \"" + schema.QName.localName + "\"")
}
}
}
this.namespace = namespace;
}
+ @Override
+ public boolean isChangeAllowed() {
+ return simpleNode == null ? true : false;
+ }
+
@Override
public SimpleNode<Object> unwrap() {
if (simpleNode == null) {
package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;
import java.util.Set;
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.structures.*;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Cont;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Lf;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.LfLst;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Lst;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.LstItem;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
-public class ToJsonBasicYangTypesTest {
+public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/cnsn-to-json/simple-yang-types", 1, "simple-yang-types", "cont1");
+ }
/**
* Test of json output when as input are specified composite node with empty
*/
@Test
public void compositeNodeAndYangWithJsonReaderEmptyDataTest() {
- String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(prepareCompositeNodeWithEmpties(),
- "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
- verifyJsonOutputForEmpty(jsonOutput);
+ CompositeNode compositeNode = prepareCompositeNodeWithEmpties();
+ TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+ String jsonOutput = null;
+ try {
+ jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+ StructuredDataToJsonProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ }
+
+ verifyJsonOutputForEmptyData(jsonOutput);
}
/**
*/
@Test
public void xmlAndYangTypesWithJsonReaderTest() {
- String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
- TestUtils.loadCompositeNode("/cnsn-to-json/simple-yang-types/xml/data.xml"),
- "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-yang-types/xml/data.xml",
+ XmlToCompositeNodeProvider.INSTANCE);
+ TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+ String jsonOutput = null;
+ try {
+ jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+ StructuredDataToJsonProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ }
+
verifyJsonOutput(jsonOutput);
}
- private void verifyJsonOutputForEmpty(String jsonOutput) {
+ private void verifyJsonOutputForEmptyData(String jsonOutput) {
+ assertNotNull(jsonOutput);
StringReader strReader = new StringReader(jsonOutput);
JsonReader jReader = new JsonReader(strReader);
}
private void verifyJsonOutput(String jsonOutput) {
+ assertNotNull(jsonOutput);
StringReader strReader = new StringReader(jsonOutput);
JsonReader jReader = new JsonReader(strReader);
import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
+public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
@BeforeClass
public static void initialization() {
}
private void testWrapper(String xmlPath, String pathToSchemaNode) {
- CompositeNode compNode = TestUtils.loadCompositeNode(xmlPath);
- TestUtils.normalizeCompositeNode(compNode, modules, dataSchemaNode, pathToSchemaNode);
+ CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, XmlToCompositeNodeProvider.INSTANCE);
+ TestUtils.normalizeCompositeNode(compNode, modules, pathToSchemaNode);
try {
- TestUtils.writeCompNodeWithSchemaContextToJson(compNode, modules, dataSchemaNode);
+ TestUtils.writeCompNodeWithSchemaContextToOutput(compNode, modules, dataSchemaNode,
+ StructuredDataToJsonProvider.INSTANCE);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.StringReader;
-import java.math.BigDecimal;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import javax.ws.rs.WebApplicationException;
-import javax.xml.bind.DatatypeConverter;
+import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
-public class ToJsonBasicDataTypesTest {
+public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/cnsn-to-json/simple-data-types");
+ }
@Test
public void simpleYangDataTest() {
- String jsonOutput = "";
- CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/simple-data-types/xml/data.xml");
- Set<Module> modules = TestUtils.resolveModules("/cnsn-to-json/simple-data-types");
- assertEquals(1, modules.size());
- Module module = TestUtils.resolveModule(null, modules);
- assertNotNull(module);
- DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
- assertNotNull(dataSchemaNode);
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml",
+ XmlToCompositeNodeProvider.INSTANCE);
- TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "simple-data-types:cont");
+ String jsonOutput = null;
+
+ TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
try {
- jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
+ jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+ StructuredDataToJsonProvider.INSTANCE);
} catch (WebApplicationException | IOException e) {
- assertTrue(false); // shouldn't get here
}
+ assertNotNull(jsonOutput);
- System.out.println(jsonOutput);
verifyJsonOutput(jsonOutput);
}
- private CompositeNode prepareData() {
- MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
- ModifyAction.CREATE, null);
-
- List<Node<?>> childNodes = new ArrayList<>();
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Min"), cont, (byte) -128,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Max"), cont, (byte) 127,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Min"), cont, (short) -32768,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Max"), cont, (short) 32767,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Min"), cont,
- (int) -2147483648, ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Max"), cont, (int) 2147483647,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Min"), cont, new Long(
- "-9223372036854775807"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Max"), cont, new Long(
- "9223372036854775807"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint8Max"), cont, (short) 255,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint16Max"), cont, (int) 65535,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint32Max"), cont, new Long(
- "4294967295"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr"), cont, "lfstr",
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr1"), cont, "",
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool1"), cont, Boolean.TRUE,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool2"), cont, Boolean.FALSE,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal1"), cont, new BigDecimal(
- "43.32"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal2"), cont, new BigDecimal(
- "-0.43"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal3"), cont, new BigDecimal(
- "43"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal4"), cont, new BigDecimal(
- "43E3"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal6"), cont, new BigDecimal(
- "33.12345"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfenum"), cont, "enum3",
- ModifyAction.CREATE, null));
-
- HashSet<String> bits = new HashSet<String>();
- bits.add("bit3");
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbits"), cont, bits,
- ModifyAction.CREATE, null));
-
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbinary"), cont, DatatypeConverter
- .parseBase64Binary("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfempty"), cont, null,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion1"), cont, (int) 324,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion2"), cont, new BigDecimal(
- "33.3"), ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion3"), cont, "55",
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion4"), cont, Boolean.TRUE,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion5"), cont, "true",
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion6"), cont, "false",
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion7"), cont, null,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion8"), cont, "",
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion9"), cont, "",
- ModifyAction.CREATE, null));
-
- HashSet<String> bits2 = new HashSet<String>();
- bits2.add("bt1");
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion10"), cont, bits2,
- ModifyAction.CREATE, null));
-
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion11"), cont, (short) 33,
- ModifyAction.CREATE, null));
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion12"), cont, Boolean.FALSE,
- ModifyAction.CREATE, null));
- try {
- childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("identityref1"), cont, new QName(
- new URI("simple:data:types"), "iden"), ModifyAction.CREATE, null));
- } catch (URISyntaxException e) {
- }
-
- cont.getChildren().addAll(childNodes);
-
- cont.init();
-
- return cont;
- }
-
private void verifyJsonOutput(String jsonOutput) {
StringReader strReader = new StringReader(jsonOutput);
JsonReader jReader = new JsonReader(strReader);
private void jsonReadContElements(JsonReader jReader) throws IOException {
jReader.beginObject();
List<String> loadedLfs = new ArrayList<>();
- boolean exceptForDecimal5Raised = false;
boolean enumChecked = false;
boolean bitsChecked = false;
boolean lfdecimal6Checked = false;
boolean lfbool2Checked = false;
boolean lfstrChecked = false;
boolean lfbinaryChecked = false;
- // boolean lfref1Checked = false;
boolean lfemptyChecked = false;
boolean lfstr1Checked = false;
boolean lfidentityrefChecked = false;
try {
peek = jReader.peek();
} catch (IOException e) {
- if (keyName.equals("lfdecimal5")) {
- exceptForDecimal5Raised = true;
- } else {
- assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
- }
+ assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
}
if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) {
import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
+public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
@BeforeClass
public static void initialization() {
public void identityrefToJsonTest() {
String json = null;
try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), modules, dataSchemaNode);
+ QName valueAsQname = TestUtils.buildQName("name_test", "identityref:module", "2013-12-2");
+ json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(valueAsQname), modules,
+ dataSchemaNode, StructuredDataToJsonProvider.INSTANCE);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
assertTrue(mtch.matches());
}
- private CompositeNode prepareCompositeNode() {
+ @Test
+ public void identityrefToJsonWithoutQNameTest() {
+ String json = null;
+ try {
+ String value = "not q name value";
+ json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(value), modules,
+ dataSchemaNode, StructuredDataToJsonProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ // shouldn't end here
+ assertTrue(false);
+ }
+ System.out.println(json);
+ assertNotNull(json);
+ Pattern ptrn = Pattern.compile(".*\"lf1\"\\p{Space}*:\\p{Space}*\"not q name value\".*", Pattern.DOTALL);
+ Matcher mtch = ptrn.matcher(json);
+
+ assertTrue(mtch.matches());
+ }
+
+ private CompositeNode prepareCompositeNode(Object value) {
MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
ModifyAction.CREATE, null);
MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1"), cont, null,
ModifyAction.CREATE, null);
cont.getChildren().add(cont1);
- MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1,
- TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"), ModifyAction.CREATE, null);
+ MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1, value,
+ ModifyAction.CREATE, null);
+
cont1.getChildren().add(lf1);
cont1.init();
cont.init();
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import javax.activation.UnsupportedDataTypeException;
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.YangNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToJsonIncorrectTopLevelTest extends YangAndXmlAndDataSchemaLoader {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonIncorrectTopLevelTest.class);
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/cnsn-to-json/simple-data-types");
+ }
+
+ private class IncorrectDataSchema implements DataSchemaNode, DataNodeContainer {
+
+ @Override
+ public String getDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public SchemaPath getPath() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public QName getQName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getReference() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Status getStatus() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Set<DataSchemaNode> getChildNodes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public DataSchemaNode getDataChildByName(QName arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public DataSchemaNode getDataChildByName(String arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Set<GroupingDefinition> getGroupings() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Set<TypeDefinition<?>> getTypeDefinitions() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Set<UsesNode> getUses() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ConstraintDefinition getConstraints() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isAddedByUses() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isAugmenting() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isConfiguration() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ }
+
+ @Test
+ public void incorrectTopLevelElementTest() {
+
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", XmlToCompositeNodeProvider.INSTANCE);
+ DataSchemaNode incorrectDataSchema = null;
+ incorrectDataSchema = new IncorrectDataSchema();
+
+ TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
+
+ boolean exceptionRaised = false;
+ try {
+ TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, incorrectDataSchema,
+ StructuredDataToJsonProvider.INSTANCE);
+ } catch (UnsupportedDataTypeException e) {
+ exceptionRaised = true;
+ } catch (WebApplicationException | IOException e) {
+ LOG.error("WebApplicationException or IOException was raised");
+ }
+
+ assertTrue(exceptionRaised);
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+/**
+ *
+ * All tests are commented now because leafref isn't supported now
+ *
+ */
+
+public class CnSnToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialization() {
+ dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont");
+ }
+
+ @Test
+ public void leafrefAbsolutePathToExistingLeafTest() {
+ String json = toJson("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml");
+ validateJson(".*\"lf3\":\\p{Blank}*\"true\".*", json);
+ }
+
+ @Test
+ public void leafrefRelativePathToExistingLeafTest() {
+ String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml");
+ validateJson(".*\"lf2\":\\p{Blank}*\"121\".*", json);
+ }
+
+ /**
+ * Tests case when reference to not existing element is present. In this
+ * case value from single node is printed as string.
+ */
+ @Test
+ public void leafrefToNonExistingLeafTest() {
+ String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml");
+ validateJson(".*\"lf5\":\\p{Blank}*\"137\".*", json);
+ }
+
+ /**
+ * Tests case when non leaf element is referenced. In this case value from
+ * single node is printed as string.
+ */
+ @Test
+ public void leafrefToNotLeafTest() {
+ String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml");
+ validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*", json);
+ }
+
+ /**
+ * Tests case when leaflist element is refers to leaf.
+ */
+ @Test
+ public void leafrefFromLeafListToLeafTest() {
+ String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml");
+ validateJson(
+ ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*\"345\",\\p{Space}*\"346\",\\p{Space}*\"347\".*",
+ json);
+ }
+
+ /**
+ * Tests case when leaflist element is refers to leaf.
+ */
+ @Test
+ public void leafrefFromLeafrefToLeafrefTest() {
+ String json = toJson("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml");
+ validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*\"200\".*", json);
+ }
+
+ private void validateJson(String regex, String value) {
+ assertNotNull(value);
+ Pattern ptrn = Pattern.compile(regex, Pattern.DOTALL);
+ Matcher mtch = ptrn.matcher(value);
+ assertTrue(mtch.matches());
+ }
+
+ private String toJson(String xmlDataPath) {
+ try {
+ CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlDataPath, XmlToCompositeNodeProvider.INSTANCE);
+ TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+ return TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+ StructuredDataToJsonProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ }
+ return "";
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.*;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLoader {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonNotExistingLeafTypeTest.class);
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/cnsn-to-json/simple-data-types");
+ }
+
+ // FIXME
+ @Ignore
+ @Test
+ public void incorrectTopLevelElementTest() {
+
+ String jsonOutput = null;
+ try {
+ jsonOutput = TestUtils
+ .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
+ (Set<Module>) Collections.EMPTY_SET, prepareDataSchemaNode(),
+ StructuredDataToJsonProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ LOG.error("WebApplicationException or IOException was raised");
+ }
+ assertNotNull(jsonOutput);
+ assertTrue(jsonOutput.contains("\"lf1\": \"\""));
+ }
+
+ private CompositeNode prepareCompositeNode() {
+ MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+ TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null);
+ MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(
+ TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null);
+ cont.getChildren().add(lf1);
+ cont.init();
+ return cont;
+ }
+
+ private DataSchemaNode prepareDataSchemaNode() {
+ ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont",
+ "simple:uri", "2012-12-17"), null);
+ LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1",
+ "simple:uri", "2012-12-17"), null);
+ leafBuild.setType(new DummyType());
+ leafBuild.setConfiguration(true);
+
+ contBuild.addChildNode(leafBuild);
+ return contBuild.build();
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/cnsn-to-json/augmentation", 5, "yang", "cont");
+ }
+
+ /**
+ * Test of json output when as input are specified composite node with empty
+ * data + YANG file
+ */
+ @Test
+ public void augmentedElementsToJson() {
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/augmentation/xml/data.xml",
+ XmlToCompositeNodeProvider.INSTANCE);
+ TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+ String jsonOutput = null;
+ try {
+ jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+ StructuredDataToJsonProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ }
+ assertNotNull(jsonOutput);
+
+ assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\""));
+ assertTrue(jsonOutput.contains("\"augment-container:cont1\": {"));
+ assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\""));
+ assertTrue(jsonOutput.contains("\"augment-list:lst1\": ["));
+ assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\""));
+ assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\""));
+ assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": ["));
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+ }
+
+ @Test
+ public void dataFromSeveralModulesToJsonTest() throws WebApplicationException, IOException, URISyntaxException {
+ SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
+ String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext,
+ StructuredDataToJsonProvider.INSTANCE);
+
+// String output =
+// String.format("\"data\" : {\n" +
+// "\t\"cont_m1\" : {\n" +
+// "\t\t\"lf1_m1\" : \"lf1 m1 value\"\n" +
+// "\t}\n" +
+// "\t\"cont_m2\" : {\n" +
+// "\t\t\"lf1_m2\" : \"lf1 m2 value\"\n" +
+// "\t}\n" +
+// "}");
+
+ StringBuilder regex = new StringBuilder();
+ regex.append("^");
+
+ regex.append(".*\"data\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+
+ regex.append(".*\"contB_m1\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+ regex.append(".*\\}");
+
+ regex.append(".*\"cont_m1\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+ regex.append(".*\\}");
+
+ regex.append(".*\"contB_m2\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+ regex.append(".*\\}");
+
+ regex.append(".*\"cont_m2\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+ regex.append(".*\\}");
+
+ regex.append(".*\\}");
+
+ regex.append(".*");
+ regex.append("$");
+
+ Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
+ Matcher matcher = ptrn.matcher(output);
+
+ assertTrue(matcher.find());
+
+ }
+
+ private CompositeNode prepareCnSn() throws URISyntaxException {
+ CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data");
+
+ URI uriModule1 = new URI("module:one");
+ CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1");
+ SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value");
+ cont_m1.addValue(lf1_m1);
+ CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1");
+
+ data.addValue(contB_m1);
+ data.addValue(cont_m1);
+
+ URI uriModule2 = new URI("module:two");
+ CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2");
+ SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value");
+ cont_m2.addValue(lf1_m2);
+ CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2");
+ data.addValue(contB_m2);
+ data.addValue(cont_m2);
+ return data;
+ }
+
+}
+++ /dev/null
-package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.regex.Matcher;
-
-import javax.ws.rs.WebApplicationException;
-
-import org.junit.*;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-
-/**
- *
- * All tests are commented now because leafref isn't supported now
- *
- */
-
-public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
-
- @BeforeClass
- public static void initialization() {
- dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont");
- }
-
- @Ignore
- @Test
- public void leafrefAbsolutePathToExistingLeafTest() {
- String json = null;
- try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml"),
- modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- assertNotNull(json);
- java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf3\":\\p{Blank}*true.*",
- java.util.regex.Pattern.DOTALL);
- Matcher mtch = ptrn.matcher(json);
- assertTrue(mtch.matches());
- }
-
- @Ignore
- @Test
- public void leafrefRelativePathToExistingLeafTest() {
- String json = null;
- try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml"),
- modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- assertNotNull(json);
- java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf2\":\\p{Blank}*121.*",
- java.util.regex.Pattern.DOTALL);
- Matcher mtch = ptrn.matcher(json);
- assertTrue(mtch.matches());
- }
-
- /**
- * Tests case when reference to not existing element is present. In this
- * case value from single node is printed as string.
- */
- @Ignore
- @Test
- public void leafrefToNonExistingLeafTest() {
- String json = null;
- try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml"),
- modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- assertNotNull(json);
- java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf5\":\\p{Blank}*\"137\".*",
- java.util.regex.Pattern.DOTALL);
- Matcher mtch = ptrn.matcher(json);
- assertTrue(mtch.matches());
- }
-
- /**
- * Tests case when non leaf element is referenced. In this case value from
- * single node is printed as string.
- */
- @Ignore
- @Test
- public void leafrefToNotLeafTest() {
- String json = null;
- try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml"), modules,
- dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- assertNotNull(json);
- java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(
- ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*",
- java.util.regex.Pattern.DOTALL);
- Matcher mtch = ptrn.matcher(json);
- assertTrue(mtch.matches());
- }
-
- /**
- * Tests case when leaflist element is refers to leaf.
- */
- @Ignore
- @Test
- public void leafrefFromLeafListToLeafTest() {
- String json = null;
- try {
- json = TestUtils
- .writeCompNodeWithSchemaContextToJson(
- TestUtils
- .loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"),
- modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- assertNotNull(json);
- java.util.regex.Pattern ptrn = java.util.regex.Pattern
- .compile(
- ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*345,\\p{Space}*346,\\p{Space}*347.*",
- java.util.regex.Pattern.DOTALL);
- Matcher mtch = ptrn.matcher(json);
- assertTrue(mtch.matches());
- }
-
- /**
- * Tests case when leaflist element is refers to leaf.
- */
- @Ignore
- @Test
- public void leafrefFromLeafrefToLeafrefTest() {
- String json = null;
- try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml"), modules,
- dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- assertNotNull(json);
- java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(
- ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*200.*", java.util.regex.Pattern.DOTALL);
- Matcher mtch = ptrn.matcher(json);
- assertTrue(mtch.matches());
- }
-
-}
+++ /dev/null
-package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-public class ToJsonWithAugmentTest {
-
- /**
- * Test of json output when as input are specified composite node with empty
- * data + YANG file
- */
- @Test
- public void augmentedElementsToJson() {
-
- CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/augmentation/xml/data.xml");
- String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(compositeNode,
- "/cnsn-to-json/augmentation", "/cnsn-to-json/augmentation/xml", "yang", "cont");
-
- assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\""));
- assertTrue(jsonOutput.contains("\"augment-container:cont1\": {"));
- assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\""));
- assertTrue(jsonOutput.contains("\"augment-list:lst1\": ["));
- assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\""));
- assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\""));
- assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": ["));
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.DummyType;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToXmlNotExistingLeafTypeTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CnSnToXmlNotExistingLeafTypeTest.class);
+
+ @Ignore
+ @Test
+ public void incorrectTopLevelElementTest() {
+
+ boolean nullPointerExceptionRaised = false;
+ try {
+ TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
+ (Set<Module>) Collections.EMPTY_SET, prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ LOG.error("WebApplicationException or IOException was raised");
+ } catch (NullPointerException e) {
+ nullPointerExceptionRaised = true;
+ }
+ assertTrue(nullPointerExceptionRaised);
+
+ }
+
+ private CompositeNode prepareCompositeNode() {
+ MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+ TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null);
+ MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(
+ TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null);
+ cont.getChildren().add(lf1);
+ cont.init();
+ return cont;
+ }
+
+ private DataSchemaNode prepareDataSchemaNode() {
+ ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont",
+ "simple:uri", "2012-12-17"), null);
+ LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1",
+ "simple:uri", "2012-12-17"), null);
+ leafBuild.setType(new DummyType());
+ leafBuild.setConfiguration(true);
+
+ contBuild.addChildNode(leafBuild);
+ return contBuild.build();
+ }
+
+}
package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
-import java.io.StringWriter;
-import java.util.Set;
+import java.io.IOException;
-import javax.activation.UnsupportedDataTypeException;
-import javax.xml.transform.*;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
+import javax.ws.rs.WebApplicationException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
import org.junit.BeforeClass;
import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.XmlMapper;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
-import org.opendaylight.yangtools.yang.model.api.*;
-import org.w3c.dom.Document;
/**
*
* XML file
*
*/
-public class CnSnToXmlTest {
-
- private static Set<Module> modules;
- private static DataSchemaNode dataSchemaNode;
-
+public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
@BeforeClass
public static void initialization() {
- modules = TestUtils.resolveModules("/cnsn-to-xml/yang");
- assertEquals(2, modules.size());
- Module module = TestUtils.resolveModule("basic-module", modules);
- assertNotNull(module);
- dataSchemaNode = TestUtils.resolveDataSchemaNode(module, "cont");
- assertNotNull(dataSchemaNode);
-
+ dataLoad("/cnsn-to-xml/yang", 2, "basic-module", "cont");
}
@Test
public void snAsYangIdentityrefToXMLTest() {
- serializeToXml(prepareIdentityrefData(), "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
+ serializeToXml(prepareIdentityrefData(null, true), "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
+ }
+
+ @Test
+ public void snAsYangIdentityrefWithQNamePrefixToXMLTest() {
+ serializeToXml(prepareIdentityrefData("prefix", true),
+ "<lf11 xmlns:prefix=\"referenced:module\">prefix:iden</lf11>");
+ }
+
+ @Test
+ public void snAsYangIdentityrefWithPrefixToXMLTest() {
+ serializeToXml(prepareIdentityrefData("prefix", false), "<lf11>no qname value</lf11>");
+ }
+
+ @Test
+ public void snAsYangLeafrefWithPrefixToXMLTest() {
+ serializeToXml(prepareLeafrefData(), "<lfBoolean>true</lfBoolean>", "<lfLfref>true</lfLfref>");
}
@Test
private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation)
throws TransformerFactoryConfigurationError {
- XmlMapper xmlMapper = new XmlMapper();
- String xmlString = null;
- if (dataSchemaNode instanceof DataNodeContainer) {
- try {
- Document doc = xmlMapper.write(compositeNode, (DataNodeContainer) dataSchemaNode);
- DOMSource domSource = new DOMSource(doc);
- StringWriter writer = new StringWriter();
- StreamResult result = new StreamResult(writer);
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = tf.newTransformer();
- transformer.transform(domSource, result);
- xmlString = writer.toString();
- } catch (UnsupportedDataTypeException | TransformerException e) {
- }
+ String xmlString = "";
+ try {
+ xmlString = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+ StructuredDataToXmlProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
}
- assertNotNull(xmlMapper);
+ assertNotNull(xmlString);
boolean containSearchedStr = false;
String strRepresentation = "";
for (String searchedStr : xmlRepresentation) {
}
- private CompositeNode prepareIdentityrefData() {
+ private CompositeNode prepareIdentityrefData(String prefix, boolean valueAsQName) {
MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null);
MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(
TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null);
cont.getChildren().add(cont1);
+ Object value = null;
+ if (valueAsQName) {
+ value = TestUtils.buildQName("iden", "referenced:module", "2013-12-2", prefix);
+ } else {
+ value = "no qname value";
+ }
MutableSimpleNode<Object> lf11 = NodeFactory.createMutableSimpleNode(
- TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1,
- TestUtils.buildQName("iden", "referenced:module", "2013-12-2"), ModifyAction.CREATE, null);
+ TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, value, ModifyAction.CREATE, null);
cont1.getChildren().add(lf11);
cont1.init();
cont.init();
return cont;
}
+ private CompositeNode prepareLeafrefData() {
+ MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+ ModifyAction.CREATE, null);
+
+ MutableSimpleNode<Object> lfBoolean = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfBoolean"),
+ cont, Boolean.TRUE, ModifyAction.CREATE, null);
+ MutableSimpleNode<Object> lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont,
+ "true", ModifyAction.CREATE, null);
+ cont.getChildren().add(lfBoolean);
+ cont.getChildren().add(lfLfref);
+ cont.init();
+
+ return cont;
+ }
+
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+
+/**
+ *
+ * CnSn = Composite node and Simple node data structure Class contains test of
+ * serializing simple nodes data values according data types from YANG schema to
+ * XML file
+ *
+ */
+public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader {
+ @BeforeClass
+ public static void initialization() {
+ dataLoad("/cnsn-to-xml/choice", 1, "module-with-choice", "cont");
+ }
+
+ @Test
+ public void cnSnToXmlWithYangChoice() {
+ String xmlOutput = "";
+ try {
+ xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(
+ prepareCnStructForYangData("lf1", "String data1"), modules, dataSchemaNode,
+ StructuredDataToXmlProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ }
+
+ assertTrue(xmlOutput.contains("<lf1>String data1</lf1>"));
+
+ try {
+ xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(
+ prepareCnStructForYangData("lf2", "String data2"), modules, dataSchemaNode,
+ StructuredDataToXmlProvider.INSTANCE);
+ } catch (WebApplicationException | IOException e) {
+ }
+ assertTrue(xmlOutput.contains("<lf2>String data2</lf2>"));
+
+ }
+
+ private CompositeNode prepareCnStructForYangData(String lfName, Object data) {
+ MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+ ModifyAction.CREATE, null);
+
+ MutableSimpleNode<Object> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data,
+ ModifyAction.CREATE, null);
+ cont.getChildren().add(lf1);
+ cont.init();
+
+ return cont;
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class CnSnToXmlWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+ }
+
+ @Test
+ public void dataFromSeveralModulesToXmlTest() throws WebApplicationException, IOException, URISyntaxException {
+ SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
+ String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext,
+ StructuredDataToXmlProvider.INSTANCE);
+
+// String output =
+// String.format("<data>" +
+// "\n<cont_m1>" +
+// "\n\t<lf1_m1>" +
+// "\n\t\tlf1 m1 value" +
+// "\n\t</lf1_m1>" +
+// "\n</cont_m1>" +
+// "\n<cont_m2>" +
+// "\n\t<lf1_m2>" +
+// "\n\t\tlf1 m2 value" +
+// "\n\t</lf1_m2>" +
+// "\n</cont_m2>" +
+// "\n</data>");
+
+ StringBuilder regex = new StringBuilder();
+ regex.append("^");
+
+ regex.append(".*<data.*");
+ regex.append(".*xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"");
+ regex.append(".*>");
+
+
+ regex.append(".*<contB_m1.*\\/>");
+ regex.append(".*xmlns=\"module:one\"");
+ regex.append(".*>");
+ regex.append(".*<lf1_m1.*>");
+ regex.append(".*<\\/lf1_m1>");
+ regex.append(".*<\\/cont_m1>");
+
+ regex.append(".*<contB_m2.*/>");
+ regex.append(".*<cont_m2.*");
+ regex.append(".*xmlns=\"module:two\"");
+ regex.append(".*>");
+ regex.append(".*<lf1_m2.*>");
+ regex.append(".*<\\/lf1_m2>");
+ regex.append(".*<\\/cont_m2>");
+
+ regex.append(".*<\\/data.*>");
+
+ regex.append(".*");
+ regex.append("$");
+
+ Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
+ Matcher matcher = ptrn.matcher(output);
+
+ assertTrue(matcher.find());
+
+ }
+
+ private CompositeNode prepareCnSn() throws URISyntaxException {
+ CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data");
+
+ URI uriModule1 = new URI("module:one");
+ CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1");
+ SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value");
+ cont_m1.addValue(lf1_m1);
+ CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1");
+
+ data.addValue(contB_m1);
+ data.addValue(cont_m1);
+
+ URI uriModule2 = new URI("module:two");
+ CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2");
+ SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value");
+ cont_m2.addValue(lf1_m2);
+ CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2");
+ data.addValue(contB_m2);
+ data.addValue(cont_m2);
+ return data;
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+
+public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/json-to-cnsn/identityref", 2, "identityref-module", "cont");
+ }
+
+ @Test
+ public void jsonIdentityrefToCompositeNode() {
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
+ JsonToCompositeNodeProvider.INSTANCE);
+ assertNotNull(compositeNode);
+
+ TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+ assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+ List<Node<?>> childs = compositeNode.getChildren();
+ assertEquals(1, childs.size());
+ Node<?> nd = childs.iterator().next();
+ assertTrue(nd instanceof CompositeNode);
+ assertEquals("cont1", nd.getNodeType().getLocalName());
+
+ childs = ((CompositeNode) nd).getChildren();
+ assertEquals(4, childs.size());
+ SimpleNode<?> lf11 = null;
+ SimpleNode<?> lf12 = null;
+ SimpleNode<?> lf13 = null;
+ SimpleNode<?> lf14 = null;
+ for (Node<?> child : childs) {
+ assertTrue(child instanceof SimpleNode);
+ if (child.getNodeType().getLocalName().equals("lf11")) {
+ lf11 = (SimpleNode<?>) child;
+ } else if (child.getNodeType().getLocalName().equals("lf12")) {
+ lf12 = (SimpleNode<?>) child;
+ } else if (child.getNodeType().getLocalName().equals("lf13")) {
+ lf13 = (SimpleNode<?>) child;
+ } else if (child.getNodeType().getLocalName().equals("lf14")) {
+ lf14 = (SimpleNode<?>) child;
+ }
+ }
+
+ assertTrue(lf11.getValue() instanceof QName);
+ assertEquals("iden", ((QName) lf11.getValue()).getLocalName());
+ assertEquals("identity:module", ((QName) lf11.getValue()).getNamespace().toString());
+
+ assertTrue(lf12.getValue() instanceof QName);
+ assertEquals("iden_local", ((QName) lf12.getValue()).getLocalName());
+ assertEquals("identityref:module", ((QName) lf12.getValue()).getNamespace().toString());
+
+ assertTrue(lf13.getValue() instanceof QName);
+ assertEquals("iden_local", ((QName) lf13.getValue()).getLocalName());
+ assertEquals("identityref:module", ((QName) lf13.getValue()).getNamespace().toString());
+
+ assertTrue(lf14.getValue() instanceof QName);
+ assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName());
+ assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString());
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.*;
+
+public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/json-to-cnsn/leafref");
+ }
+
+ /**
+ * JSON values which represents leafref are always loaded to simple node as
+ * string
+ */
+ @Test
+ public void jsonIdentityrefToCompositeNode() {
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/leafref/json/data.json", false,
+ JsonToCompositeNodeProvider.INSTANCE);
+ assertNotNull(compositeNode);
+ TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+ assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+ SimpleNode<?> lf2 = null;
+ for (Node<?> childNode : compositeNode.getChildren()) {
+ if (childNode instanceof SimpleNode) {
+ if (childNode.getNodeType().getLocalName().equals("lf2")) {
+ lf2 = (SimpleNode<?>) childNode;
+ break;
+ }
+ }
+ }
+
+ assertNotNull(lf2);
+ assertTrue(lf2.getValue() instanceof String);
+ assertEquals("121", (String) lf2.getValue());
+
+ }
+
+}
package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
-import java.io.*;
-import java.net.URISyntaxException;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Test
public void simpleListTest() {
- simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang", "lst", "simple:list:yang1",
+ simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang/1", "lst", "simple:list:yang1",
"simple-list-yang1");
}
*/
@Test
public void multipleItemsInLeafList() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-leaflist-items.json", true);
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true,
+ JsonToCompositeNodeProvider.INSTANCE);
assertNotNull(compositeNode);
assertEquals(3, compositeNode.getChildren().size());
*/
@Test
public void multipleItemsInListTest() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-items-in-list.json", true);
- assertNotNull(compositeNode);
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-items-in-list.json", true,
+ JsonToCompositeNodeProvider.INSTANCE);
+ assertNotNull(compositeNode);
assertEquals("lst", compositeNode.getNodeType().getLocalName());
verityMultipleItemsInList(compositeNode);
@Test
public void nullArrayToSimpleNodeWithNullValueTest() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/array-with-null.json", true);
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/array-with-null.json", true,
+ JsonToCompositeNodeProvider.INSTANCE);
assertNotNull(compositeNode);
assertEquals("cont", compositeNode.getNodeType().getLocalName());
public void incorrectTopLevelElementsTest() {
Throwable cause1 = null;
try {
- compositeContainerFromJson("/json-to-cnsn/wrong-top-level1.json", true);
+ TestUtils
+ .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE);
} catch (WebApplicationException e) {
cause1 = e;
}
Throwable cause2 = null;
try {
- compositeContainerFromJson("/json-to-cnsn/wrong-top-level2.json", true);
+ TestUtils
+ .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE);
} catch (WebApplicationException e) {
cause2 = e;
}
Throwable cause3 = null;
try {
- compositeContainerFromJson("/json-to-cnsn/wrong-top-level3.json", true);
+ TestUtils
+ .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE);
} catch (WebApplicationException e) {
cause3 = e;
}
*/
@Test
public void emptyDataReadTest() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/empty-data.json", true);
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/empty-data.json", true,
+ JsonToCompositeNodeProvider.INSTANCE);
assertNotNull(compositeNode);
String reason = null;
try {
- compositeContainerFromJson("/json-to-cnsn/empty-data1.json", true);
+ TestUtils.readInputToCnSn("/json-to-cnsn/empty-data1.json", true, JsonToCompositeNodeProvider.INSTANCE);
} catch (JsonSyntaxException e) {
reason = e.getMessage();
}
@Test
public void notSupplyNamespaceIfAlreadySupplied() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/simple-list.json");
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/simple-list.json", false,
+ JsonToCompositeNodeProvider.INSTANCE);
assertNotNull(compositeNode);
- DataSchemaNode dataSchemaNode1 = null;
- DataSchemaNode dataSchemaNode2 = null;
- try {
- dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang1");
- dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang2");
- } catch (FileNotFoundException e) {
- LOG.error(e.getMessage());
- assertTrue(false);
- }
- assertNotNull(dataSchemaNode1);
- assertNotNull(dataSchemaNode2);
-
// supplement namespaces according to first data schema -
// "simple:data:types1"
- TestUtils.supplementNamespace(dataSchemaNode1, compositeNode);
+ Set<Module> modules1 = new HashSet<>();
+ Set<Module> modules2 = new HashSet<>();
+ modules1 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/1");
+ modules2 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/2");
+ assertNotNull(modules1);
+ assertNotNull(modules2);
+
+ TestUtils.normalizeCompositeNode(compositeNode, modules1, "simple-list-yang1:lst");
assertTrue(compositeNode instanceof CompositeNodeWrapper);
CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
assertEquals("lst", compNode.getNodeType().getLocalName());
verifyCompositeNode(compNode, "simple:list:yang1");
- // dataSchemaNode2 should't be taken into account, because compNode
- // isn't CompositeNodeWrapper
- TestUtils.supplementNamespace(dataSchemaNode2, compNode);
+ TestUtils.normalizeCompositeNode(compositeNode, modules2, "simple-list-yang2:lst");
verifyCompositeNode(compNode, "simple:list:yang1");
-
}
@Test
public void jsonIdentityrefToCompositeNode() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/identityref/json/data.json");
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
+ JsonToCompositeNodeProvider.INSTANCE);
assertNotNull(compositeNode);
- Set<Module> modules = TestUtils.resolveModules("/json-to-cnsn/identityref");
+ Set<Module> modules = TestUtils.loadModulesFrom("/json-to-cnsn/identityref");
assertEquals(2, modules.size());
- Module module = TestUtils.resolveModule("identityref-module", modules);
- assertNotNull(module);
- DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
- assertNotNull(dataSchemaNode);
- TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "identityref-module:cont");
+ TestUtils.normalizeCompositeNode(compositeNode, modules, "identityref-module:cont");
assertEquals("cont", compositeNode.getNodeType().getLocalName());
private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace,
String moduleName) {
- CompositeNode compositeNode = compositeContainerFromJson(jsonPath);
+ CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
assertNotNull(compositeNode);
- DataSchemaNode dataSchemaNode = null;
- try {
- dataSchemaNode = TestUtils.obtainSchemaFromYang(yangPath, moduleName);
- } catch (FileNotFoundException e) {
- LOG.error(e.getMessage());
- assertTrue(false);
- }
- assertNotNull(dataSchemaNode);
+ Set<Module> modules = null;
+ modules = TestUtils.loadModulesFrom(yangPath);
+ assertNotNull(modules);
- TestUtils.supplementNamespace(dataSchemaNode, compositeNode);
+ TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + topLevelElementName);
assertTrue(compositeNode instanceof CompositeNodeWrapper);
CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
boolean lflst1_2Found = false;
boolean lf1Found = false;
- assertEquals(namespace, compositeNode.getNodeType().getNamespace().toString());
+ // assertEquals(namespace,
+ // compositeNode.getNodeType().getNamespace().toString());
for (Node<?> node : compositeNode.getChildren()) {
if (node.getNodeType().getLocalName().equals("cont1")) {
assertTrue(lf1Found);
}
- private CompositeNode compositeContainerFromJson(String jsonPath) {
- return compositeContainerFromJson(jsonPath, false);
- }
-
- private CompositeNode compositeContainerFromJson(String jsonPath, boolean dummyNamespaces)
- throws WebApplicationException {
-
- JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE;
- InputStream jsonStream = JsonToCnSnTest.class.getResourceAsStream(jsonPath);
+ @Test
+ public void unsupportedDataFormatTest() {
+ String exceptionMessage = "";
try {
- CompositeNode compositeNode = jsonToCompositeNodeProvider
- .readFrom(null, null, null, null, null, jsonStream);
- assertTrue(compositeNode instanceof CompositeNodeWrapper);
- if (dummyNamespaces) {
- try {
- TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
- return ((CompositeNodeWrapper) compositeNode).unwrap();
- } catch (URISyntaxException e) {
- LOG.error(e.getMessage());
- assertTrue(e.getMessage(), false);
- }
- }
- return compositeNode;
- } catch (IOException e) {
- LOG.error(e.getMessage());
- assertTrue(e.getMessage(), false);
+ TestUtils.readInputToCnSn("/json-to-cnsn/unsupported-json-format.json", true,
+ JsonToCompositeNodeProvider.INSTANCE);
+ } catch (WebApplicationException e) {
+ exceptionMessage = e.getCause().getMessage();
}
- return null;
+ assertTrue(exceptionMessage.contains("Root element of Json has to be Object"));
}
}
package org.opendaylight.controller.sal.restconf.impl.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.io.FileNotFoundException;
import java.util.Set;
+import org.junit.After;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
private static final ControllerContext controllerContext = ControllerContext.getInstance();
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
@BeforeClass
public static void init() throws FileNotFoundException {
- Set<Module> allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs").getPath());
+ Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
+ assertNotNull(allModules);
SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
controllerContext.setSchemas(schemaContext);
}
+ @After
+ public void releaseMountService() {
+ controllerContext.setMountService(null);
+ }
+
@Test
public void testToInstanceIdentifierList() throws FileNotFoundException {
- InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo");
+ InstanceIdWithSchemaNode instanceIdentifier = controllerContext
+ .toInstanceIdentifier("simple-nodes:userWithoutClass/foo");
assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass");
instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo/full-name");
instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users/user/foo");
assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user");
+ }
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo");
- assertNull(instanceIdentifier);
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/foo");
- assertNull(instanceIdentifier);
+ @Test
+ public void testToInstanceIdentifierListWithNullKey() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo");
+ }
+ @Test
+ public void testToInstanceIdentifierListWithMissingKey() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:user/foo");
}
@Test
InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users");
assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "users");
assertTrue(instanceIdentifier.getSchemaNode() instanceof ContainerSchemaNode);
- assertEquals(2, ((ContainerSchemaNode)instanceIdentifier.getSchemaNode()).getChildNodes().size());
+ assertEquals(2, ((ContainerSchemaNode) instanceIdentifier.getSchemaNode()).getChildNodes().size());
}
@Test
public void testToInstanceIdentifierChoice() throws FileNotFoundException {
- InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/beer");
+ InstanceIdWithSchemaNode instanceIdentifier = controllerContext
+ .toInstanceIdentifier("simple-nodes:food/nonalcoholic/beer");
assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "beer");
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack");
- assertNull(instanceIdentifier);
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena");
- assertNull(instanceIdentifier);
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
- assertNull(instanceIdentifier);
-
+ }
+
+ @Test
+ public void testToInstanceIdentifierChoiceException() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:food/snack");
+ }
+
+ @Test
+ public void testToInstanceIdentifierCaseException() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena");
+ }
+
+ @Test
+ public void testToInstanceIdentifierChoiceCaseException() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
}
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import java.util.List;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.*;
+
+public class DummyType implements TypeDefinition<DummyType> {
+ QName dummyQName = TestUtils.buildQName("dummy type", "simple:uri", "2012-12-17");
+
+ @Override
+ public QName getQName() {
+ return dummyQName;
+ }
+
+ @Override
+ public SchemaPath getPath() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getReference() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Status getStatus() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public DummyType getBaseType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getUnits() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Object getDefaultValue() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import java.net.*;
-import java.util.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Set;
-import org.junit.*;
+import org.junit.BeforeClass;
+import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.*;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
import org.opendaylight.yangtools.yang.model.api.Module;
@BeforeClass
public static void initialization() {
- modules = TestUtils.resolveModules("/invoke-rpc");
+ modules = TestUtils.loadModulesFrom("/invoke-rpc");
assertEquals(1, modules.size());
Module module = TestUtils.resolveModule("invoke-rpc-module", modules);
assertNotNull(module);
ControllerContext contContext = ControllerContext.getInstance();
contContext.onGlobalContextUpdated(TestUtils.loadSchemaContext(modules));
try {
- contContext.findModuleByNamespace(new URI("invoke:rpc:module"));
+ contContext.findModuleNameByNamespace(new URI("invoke:rpc:module"));
} catch (URISyntaxException e) {
assertTrue("Uri wasn't created sucessfuly", false);
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class MediaTypesTest extends JerseyTest {
+
+ private static RestconfService restconfService;
+ private static String jsonData;
+ private static String xmlData;
+
+ @BeforeClass
+ public static void init() throws IOException {
+ restconfService = mock(RestconfService.class);
+ String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath();
+ jsonData = TestUtils.loadTextFile(jsonPath);
+ InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
+ xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+ }
+
+ @Override
+ protected Application configure() {
+ /* enable/disable Jersey logs to console */
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+ ResourceConfig resourceConfig = new ResourceConfig();
+ resourceConfig = resourceConfig.registerInstances(restconfService, StructuredDataToXmlProvider.INSTANCE,
+ StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+ JsonToCompositeNodeProvider.INSTANCE);
+ return resourceConfig;
+ }
+
+ @Test
+ public void testPostOperationsWithInputDataMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/operations/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.invokeRpc(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+ post(uri, Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+JSON, jsonData);
+ verify(restconfService, times(1)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, Draft02.MediaTypes.DATA+XML, Draft02.MediaTypes.DATA+XML, xmlData);
+ verify(restconfService, times(2)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, jsonData);
+ verify(restconfService, times(3)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, MediaType.APPLICATION_XML, MediaType.APPLICATION_XML, xmlData);
+ verify(restconfService, times(4)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, MediaType.TEXT_XML, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(5)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+
+ // negative tests
+ post(uri, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, xmlData);
+ verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ }
+
+ @Test
+ public void testGetConfigMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.readConfigurationData(uriPath)).thenReturn(null);
+ get(uri, Draft02.MediaTypes.DATA+JSON);
+ verify(restconfService, times(1)).readConfigurationData(uriPath);
+ get(uri, Draft02.MediaTypes.DATA+XML);
+ verify(restconfService, times(2)).readConfigurationData(uriPath);
+ get(uri, MediaType.APPLICATION_JSON);
+ verify(restconfService, times(3)).readConfigurationData(uriPath);
+ get(uri, MediaType.APPLICATION_XML);
+ verify(restconfService, times(4)).readConfigurationData(uriPath);
+ get(uri, MediaType.TEXT_XML);
+ verify(restconfService, times(5)).readConfigurationData(uriPath);
+
+ // negative tests
+ get(uri, MediaType.TEXT_PLAIN);
+ verify(restconfService, times(5)).readConfigurationData(uriPath);
+ }
+
+ @Test
+ public void testGetOperationalMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/operational/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.readOperationalData(uriPath)).thenReturn(null);
+ get(uri, Draft02.MediaTypes.DATA+JSON);
+ verify(restconfService, times(1)).readOperationalData(uriPath);
+ get(uri, Draft02.MediaTypes.DATA+XML);
+ verify(restconfService, times(2)).readOperationalData(uriPath);
+ get(uri, MediaType.APPLICATION_JSON);
+ verify(restconfService, times(3)).readOperationalData(uriPath);
+ get(uri, MediaType.APPLICATION_XML);
+ verify(restconfService, times(4)).readOperationalData(uriPath);
+ get(uri, MediaType.TEXT_XML);
+ verify(restconfService, times(5)).readOperationalData(uriPath);
+
+ // negative tests
+ get(uri, MediaType.TEXT_PLAIN);
+ verify(restconfService, times(5)).readOperationalData(uriPath);
+ }
+
+ @Test
+ public void testPutConfigMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.updateConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+ put(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+ verify(restconfService, times(1)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+ verify(restconfService, times(2)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, null, MediaType.APPLICATION_JSON, jsonData);
+ verify(restconfService, times(3)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, null, MediaType.APPLICATION_XML, xmlData);
+ verify(restconfService, times(4)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, null, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(5)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ }
+
+ @Test
+ public void testPostConfigWithPathMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.createConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+ post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+ verify(restconfService, times(1)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+ verify(restconfService, times(2)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, MediaType.APPLICATION_JSON, jsonData);
+ verify(restconfService, times(3)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, MediaType.APPLICATION_XML, xmlData);
+ verify(restconfService, times(4)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(5)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ }
+
+ @Test
+ public void testPostConfigMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uri = createUri(uriPrefix, "");
+ when(restconfService.createConfigurationData(any(CompositeNode.class))).thenReturn(null);
+ post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+ verify(restconfService, times(1)).createConfigurationData(any(CompositeNode.class));
+ post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+ verify(restconfService, times(2)).createConfigurationData(any(CompositeNode.class));
+ post(uri, null, MediaType.APPLICATION_JSON, jsonData);
+ verify(restconfService, times(3)).createConfigurationData(any(CompositeNode.class));
+ post(uri, null, MediaType.APPLICATION_XML, xmlData);
+ verify(restconfService, times(4)).createConfigurationData(any(CompositeNode.class));
+ post(uri, null, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(5)).createConfigurationData(any(CompositeNode.class));
+ post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).createConfigurationData(any(CompositeNode.class));
+ }
+
+ @Test
+ public void testDeleteConfigMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.deleteConfigurationData(eq(uriPath))).thenReturn(null);
+ target(uri).request("fooMediaType").delete();
+ verify(restconfService, times(1)).deleteConfigurationData(uriPath);
+ }
+
+ private int get(String uri, String acceptMediaType) {
+ return target(uri).request(acceptMediaType).get().getStatus();
+ }
+
+ private int put(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
+ if (acceptMediaType == null) {
+ return target(uri).request().put(Entity.entity(data, contentTypeMediaType)).getStatus();
+ }
+ return target(uri).request(acceptMediaType).put(Entity.entity(data, contentTypeMediaType)).getStatus();
+ }
+
+ private int post(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
+ if (acceptMediaType == null) {
+ if (contentTypeMediaType == null || data == null) {
+ return target(uri).request().post(null).getStatus();
+ }
+ return target(uri).request().post(Entity.entity(data, contentTypeMediaType)).getStatus();
+ }
+ if (contentTypeMediaType == null || data == null) {
+ return target(uri).request(acceptMediaType).post(null).getStatus();
+ }
+ return target(uri).request(acceptMediaType).post(Entity.entity(data, contentTypeMediaType)).getStatus();
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.*;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class NormalizeNodeTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialization() {
+ dataLoad("/normalize-node/yang/");
+ }
+
+ @Test
+ public void namespaceNotNullAndInvalidNamespaceAndNoModuleNameTest() {
+ boolean exceptionReised = false;
+ try {
+ TestUtils.normalizeCompositeNode(prepareCnSn("wrongnamespace"), modules, schemaNodePath);
+ } catch (ResponseException e) {
+ exceptionReised = true;
+ }
+ assertTrue(exceptionReised);
+ }
+
+ @Test
+ public void namespaceNullTest() {
+ String exceptionMessage = null;
+ try {
+ TestUtils.normalizeCompositeNode(prepareCnSn(null), modules, schemaNodePath);
+ } catch (ResponseException e) {
+ exceptionMessage = String.valueOf(e.getResponse().getEntity());
+ }
+ assertNull(exceptionMessage);
+ }
+
+ @Test
+ public void namespaceValidNamespaceTest() {
+ String exceptionMessage = null;
+ try {
+ TestUtils.normalizeCompositeNode(prepareCnSn("normalize:node:module"), modules, schemaNodePath);
+ } catch (ResponseException e) {
+ exceptionMessage = String.valueOf(e.getResponse().getEntity());
+ }
+ assertNull(exceptionMessage);
+ }
+
+ @Test
+ public void namespaceValidModuleNameTest() {
+ String exceptionMessage = null;
+ try {
+ TestUtils.normalizeCompositeNode(prepareCnSn("normalize-node-module"), modules, schemaNodePath);
+ } catch (ResponseException e) {
+ exceptionMessage = String.valueOf(e.getResponse().getEntity());
+ }
+ assertNull(exceptionMessage);
+ }
+
+ private CompositeNode prepareCnSn(String namespace) {
+ URI uri = null;
+ if (namespace != null) {
+ try {
+ uri = new URI(namespace);
+ } catch (URISyntaxException e) {
+ }
+ assertNotNull(uri);
+ }
+
+ SimpleNodeWrapper lf1 = new SimpleNodeWrapper(uri, "lf1", 43);
+ CompositeNodeWrapper cont = new CompositeNodeWrapper(uri, "cont");
+ cont.addValue(lf1);
+
+ return cont;
+ }
+
+}
+++ /dev/null
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLEncoder;
-import java.util.List;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
-import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-import com.google.common.base.Charsets;
-
-public class ReadConfAndOperDataTest extends JerseyTest {
-
- private static ControllerContext controllerContext;
- private static BrokerFacade brokerFacade;
- private static RestconfImpl restconfImpl;
- private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
-
- @BeforeClass
- public static void init() throws FileNotFoundException {
- Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
- .getPath());
- SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
- controllerContext = ControllerContext.getInstance();
- controllerContext.setSchemas(schemaContext);
- brokerFacade = mock(BrokerFacade.class);
- restconfImpl = RestconfImpl.getInstance();
- restconfImpl.setBroker(brokerFacade);
- restconfImpl.setControllerContext(controllerContext);
- }
-
- @Before
- public void logs() {
- List<LogRecord> loggedRecords = getLoggedRecords();
- for (LogRecord l : loggedRecords) {
- System.out.println(l.getMessage());
- }
- }
-
- @Test
- public void testReadConfigurationData() throws UnsupportedEncodingException, FileNotFoundException {
-
- String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
-
- CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
- when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
-
- Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
- assertEquals(200, response.getStatus());
-
- uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example");
- when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null);
-
- response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
- assertEquals(404, response.getStatus());
- }
-
- @Test
- public void testReadOperationalData() throws UnsupportedEncodingException, FileNotFoundException {
- String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
-
- CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
- when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
-
- Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
- assertEquals(200, response.getStatus());
-
- uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example");
- when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null);
-
- response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
- assertEquals(404, response.getStatus());
- }
-
- private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
- return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
- }
-
- @Override
- protected Application configure() {
- enable(TestProperties.LOG_TRAFFIC);
- enable(TestProperties.DUMP_ENTITY);
- enable(TestProperties.RECORD_LOG_LEVEL);
- set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
- XmlToCompositeNodeProvider.INSTANCE);
- return resourceConfig;
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.BitsType;
+
+public class RestCodecExceptionsTest {
+
+ @Test
+ public void serializeExceptionTest() {
+ Codec<Object, Object> codec = RestCodec.from(new BitsType(null));
+ String serializedValue = (String) codec.serialize("incorrect value"); // set
+ // expected
+ assertEquals("incorrect value", serializedValue);
+ }
+
+ @Test
+ public void deserializeExceptionTest() {
+ IdentityrefTypeDefinition mockedIidentityrefType = mock(IdentityrefTypeDefinition.class);
+
+ Codec<Object, Object> codec = RestCodec.from(mockedIidentityrefType);
+ String serializedValue = (String) codec.deserialize("incorrect value"); // IdentityValuesDTO
+ // object
+ // expected
+ assertEquals("incorrect value", serializedValue);
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+import static org.junit.Assert.assertEquals;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.text.ParseException;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.TestProperties;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlMapper;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+
+import com.google.common.base.Charsets;
+
+public class RestConfigDataTest extends JerseyTest {
+
+ private static ControllerContext controllerContext;
+ private static BrokerFacade brokerFacade;
+ private static RestconfImpl restconfImpl;
+ private static MountService mountService;
+ private static SchemaContext schemaContext;
+
+ private static final MediaType MEDIA_TYPE_XML_DRAFT02 = new MediaType("application", "yang.data+xml");
+
+ @BeforeClass
+ public static void init() throws FileNotFoundException {
+ Set<Module> modules = TestUtils.loadModulesFrom("/test-config-data/yang1");
+ schemaContext = TestUtils.loadSchemaContext(modules);
+ initMocking();
+ }
+
+ private static void initMocking() {
+ controllerContext = ControllerContext.getInstance();
+ controllerContext.setSchemas(schemaContext);
+ mountService = mock(MountService.class);
+ controllerContext.setMountService(mountService);
+ brokerFacade = mock(BrokerFacade.class);
+ restconfImpl = RestconfImpl.getInstance();
+ restconfImpl.setBroker(brokerFacade);
+ restconfImpl.setControllerContext(controllerContext);
+ }
+
+// @Test
+ // TODO
+ public void createConfigurationDataTest() throws UnsupportedEncodingException, ParseException {
+ initMocking();
+ String URI_1 = createUri("/config", "");
+ String URI_2 = createUri("/config/", "");
+ String URI_3 = createUri("/config/", "test-interface:interfaces/");
+ String URI_4 = createUri("/config/", "test-interface:interfaces/");
+ String URI_5 = createUri("/config/", "test-interface:interfaces/test-interface2:class");
+
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
+ TransactionStatus.COMMITED).build();
+ Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+
+ when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+ .thenReturn(dummyFuture);
+
+ ArgumentCaptor<InstanceIdentifier> instanceIdCaptor = ArgumentCaptor.forClass(InstanceIdentifier.class);
+ ArgumentCaptor<CompositeNode> compNodeCaptor = ArgumentCaptor.forClass(CompositeNode.class);
+
+ // Test URI_1
+ Entity<String> entity = createEntity("/test-config-data/xml/test-interface.xml");
+ Response response = target(URI_1).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(204, response.getStatus());
+ verify(brokerFacade).commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+ String identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces]";
+ assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+
+ // Test URI_2
+ response = target(URI_2).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(204, response.getStatus());
+ verify(brokerFacade, times(2))
+ .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+ assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+
+ // Test URI_3
+ entity = createEntity("/test-config-data/xml/test-interface2.xml");
+ response = target(URI_3).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(204, response.getStatus());
+ verify(brokerFacade, times(3))
+ .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+
+ identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interface[{(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)name=eth0}]]";
+ assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+
+ // Test URI_4
+ Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
+ SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
+ MountInstance mountInstance = mock(MountInstance.class);
+ when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
+ when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+ entity = createEntity("/test-config-data/xml/test-interface3.xml");
+ response = target(URI_4).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(204, response.getStatus());
+ verify(brokerFacade, times(4))
+ .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+ identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class]";
+ assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+
+ // Test URI_5
+ response = target(URI_5).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(204, response.getStatus());
+ verify(brokerFacade, times(5))
+ .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+ identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class]";
+ assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+ }
+
+// @Test
+ // TODO
+ public void testExistingData() throws UnsupportedEncodingException {
+ initMocking();
+ String URI_1 = createUri("/config", "");
+ String URI_2 = createUri("/config/", "");
+ String URI_3 = createUri("/config/", "test-interface:interfaces/");
+ String URI_4 = createUri("/config/", "test-interface:interfaces/");
+ String URI_5 = createUri("/config/", "test-interface:interfaces/test-interface2:class");
+
+ when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+ .thenReturn(null);
+
+ // Test URI_1
+ Entity<String> entity = createEntity("/test-config-data/xml/test-interface.xml");
+ Response response = target(URI_1).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(202, response.getStatus());
+
+ // Test URI_2
+ response = target(URI_2).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(202, response.getStatus());
+
+ // Test URI_3
+ entity = createEntity("/test-config-data/xml/test-interface2.xml");
+ response = target(URI_3).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(202, response.getStatus());
+
+ // Test URI_4
+ Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
+ SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
+ MountInstance mountInstance = mock(MountInstance.class);
+ when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
+ when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+ entity = createEntity("/test-config-data/xml/test-interface3.xml");
+ response = target(URI_4).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(202, response.getStatus());
+
+ // Test URI_5
+ response = target(URI_5).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+ assertEquals(202, response.getStatus());
+ }
+
+ private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
+ return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
+ }
+
+ private Entity<String> createEntity(final String relativePathToXml) {
+ InputStream inputStream = XmlMapper.class.getResourceAsStream(relativePathToXml);
+ String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(inputStream));
+ Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_XML_DRAFT02);
+
+ return entity;
+ }
+
+ @Override
+ protected Application configure() {
+ enable(TestProperties.LOG_TRAFFIC);
+ enable(TestProperties.DUMP_ENTITY);
+ enable(TestProperties.RECORD_LOG_LEVEL);
+ set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+
+ ResourceConfig resourceConfig = new ResourceConfig();
+ resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+ XmlToCompositeNodeProvider.INSTANCE);
+ return resourceConfig;
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.FileNotFoundException;
+import java.io.UnsupportedEncodingException;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestDeleteOperationTest extends JerseyTest {
+
+ private static ControllerContext controllerContext;
+ private static BrokerFacade brokerFacade;
+ private static RestconfImpl restconfImpl;
+
+ @BeforeClass
+ public static void init() throws FileNotFoundException {
+ Set<Module> allModules = TestUtils.loadModulesFrom("/test-config-data/yang1");
+ assertNotNull(allModules);
+ SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
+ controllerContext = ControllerContext.getInstance();
+ controllerContext.setSchemas(schemaContext);
+ brokerFacade = mock(BrokerFacade.class);
+ restconfImpl = RestconfImpl.getInstance();
+ restconfImpl.setBroker(brokerFacade);
+ restconfImpl.setControllerContext(controllerContext);
+ }
+
+ @Override
+ protected Application configure() {
+ /* enable/disable Jersey logs to console */
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+ ResourceConfig resourceConfig = new ResourceConfig();
+ resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+ XmlToCompositeNodeProvider.INSTANCE);
+ return resourceConfig;
+ }
+
+ @Test
+ public void deleteConfigStatusCodes() throws UnsupportedEncodingException {
+ String uri = createUri("/config/", "test-interface:interfaces");
+ Future<RpcResult<TransactionStatus>> dummyFuture = createFuture(TransactionStatus.COMMITED);
+ when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
+ Response response = target(uri).request(MediaType.APPLICATION_XML).delete();
+ assertEquals(200, response.getStatus());
+
+ dummyFuture = createFuture(TransactionStatus.FAILED);
+ when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
+ response = target(uri).request(MediaType.APPLICATION_XML).delete();
+ assertEquals(500, response.getStatus());
+ }
+
+ private Future<RpcResult<TransactionStatus>> createFuture(TransactionStatus statusName) {
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName).build();
+ return DummyFuture.builder().rpcResult(rpcResult).build();
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.FileNotFoundException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestGetOperationTest extends JerseyTest {
+
+ private static BrokerFacade brokerFacade;
+ private static RestconfImpl restconfImpl;
+ private static SchemaContext schemaContextYangsIetf;
+ private static SchemaContext schemaContextTestModule;
+ private static CompositeNode answerFromGet;
+
+ @BeforeClass
+ public static void init() throws FileNotFoundException {
+ schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
+ schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
+ ControllerContext controllerContext = ControllerContext.getInstance();
+ controllerContext.setSchemas(schemaContextYangsIetf);
+ brokerFacade = mock(BrokerFacade.class);
+ restconfImpl = RestconfImpl.getInstance();
+ restconfImpl.setBroker(brokerFacade);
+ restconfImpl.setControllerContext(controllerContext);
+ answerFromGet = prepareCompositeNodeWithIetfInterfacesInterfacesData();
+ }
+
+ @Override
+ protected Application configure() {
+ /* enable/disable Jersey logs to console */
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+ ResourceConfig resourceConfig = new ResourceConfig();
+ resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+ StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+ JsonToCompositeNodeProvider.INSTANCE);
+ return resourceConfig;
+ }
+
+ /**
+ * Tests of status codes for "/datastore/{identifier}".
+ */
+ @Test
+ public void getDatastoreStatusCodes() throws FileNotFoundException, UnsupportedEncodingException {
+ mockReadOperationalDataMethod();
+ String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+ assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+
+ uri = createUri("/datastore/", "wrong-module:interfaces/interface/eth0");
+ assertEquals(400, get(uri, MediaType.APPLICATION_XML));
+
+ // Test of request for not existing data. Returning status code 404
+ uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+ when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
+ assertEquals(404, get(uri, MediaType.APPLICATION_XML));
+ }
+
+ /**
+ * Tests of status codes for "/operational/{identifier}".
+ */
+ @Test
+ public void getOperationalStatusCodes() throws UnsupportedEncodingException {
+ mockReadOperationalDataMethod();
+ String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
+ assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+
+ uri = createUri("/operational/", "wrong-module:interfaces/interface/eth0");
+ assertEquals(400, get(uri, MediaType.APPLICATION_XML));
+ }
+
+ /**
+ * Tests of status codes for "/config/{identifier}".
+ */
+ @Test
+ public void getConfigStatusCodes() throws UnsupportedEncodingException {
+ mockReadConfigurationDataMethod();
+ String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
+ assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+
+ uri = createUri("/config/", "wrong-module:interfaces/interface/eth0");
+ assertEquals(400, get(uri, MediaType.APPLICATION_XML));
+ }
+
+ /**
+ * MountPoint test. URI represents mount point.
+ */
+ @Test
+ public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException {
+ when(brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
+ any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
+ MountInstance mountInstance = mock(MountInstance.class);
+ when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
+ MountService mockMountService = mock(MountService.class);
+ when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+ ControllerContext.getInstance().setMountService(mockMountService);
+
+ String uri = createUri("/config/",
+ "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1");
+ Response response = target(uri).request(Draft02.MediaTypes.DATA + XML).get();
+ assertEquals(200, response.getStatus());
+
+ uri = createUri("/config/",
+ "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1");
+ response = target(uri).request(Draft02.MediaTypes.DATA + XML).get();
+ assertEquals(200, response.getStatus());
+ }
+
+ private int get(String uri, String mediaType) {
+ return target(uri).request(mediaType).get().getStatus();
+ }
+
+ private CompositeNode prepareCnDataForMountPointTest() throws URISyntaxException {
+ CompositeNodeWrapper cont1 = new CompositeNodeWrapper(new URI("test:module"), "cont1");
+ SimpleNodeWrapper lf11 = new SimpleNodeWrapper(new URI("test:module"), "lf11", "lf11 value");
+ cont1.addValue(lf11);
+ return cont1.unwrap();
+ }
+
+ private void mockReadOperationalDataMethod() {
+ when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
+ }
+
+ private void mockReadConfigurationDataMethod() {
+ when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
+ }
+
+ private static CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
+ CompositeNode intface;
+ try {
+ intface = new CompositeNodeWrapper(new URI("interface"), "interface");
+ List<Node<?>> childs = new ArrayList<>();
+
+ childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
+ childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
+ childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
+ childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
+ intface.setValue(childs);
+ return intface;
+ } catch (URISyntaxException e) {
+ }
+
+ return null;
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+
+import com.google.common.base.Charsets;
+
+public class RestOperationUtils {
+
+ static final String JSON = "+json";
+ static final String XML = "+xml";
+
+ private RestOperationUtils() {
+ }
+
+ static String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
+ return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.Future;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestPostOperationTest extends JerseyTest {
+
+ private static String xmlDataAbsolutePath;
+ private static String xmlDataRpcInput;
+ private static CompositeNodeWrapper cnSnDataOutput;
+ private static String xmlData2;
+
+ private static ControllerContext controllerContext;
+ private static BrokerFacade brokerFacade;
+ private static RestconfImpl restconfImpl;
+ private static SchemaContext schemaContextYangsIetf;
+ private static SchemaContext schemaContextTestModule;
+
+ @BeforeClass
+ public static void init() throws URISyntaxException, IOException {
+ schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
+ schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
+ controllerContext = ControllerContext.getInstance();
+ brokerFacade = mock(BrokerFacade.class);
+ restconfImpl = RestconfImpl.getInstance();
+ restconfImpl.setBroker(brokerFacade);
+ restconfImpl.setControllerContext(controllerContext);
+ loadData();
+ }
+
+ @Override
+ protected Application configure() {
+ /* enable/disable Jersey logs to console */
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+ ResourceConfig resourceConfig = new ResourceConfig();
+ resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+ StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+ JsonToCompositeNodeProvider.INSTANCE);
+ return resourceConfig;
+ }
+
+ @Test
+ public void postOperationsStatusCodes() throws UnsupportedEncodingException {
+ controllerContext.setSchemas(schemaContextTestModule);
+ mockInvokeRpc(cnSnDataOutput, true);
+ String uri = createUri("/operations/", "test-module:rpc-test");
+ assertEquals(200, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+
+ mockInvokeRpc(null, true);
+ assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+
+ mockInvokeRpc(null, false);
+ assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+
+ uri = createUri("/operations/", "test-module:rpc-wrongtest");
+ assertEquals(404, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+ }
+
+ @Test
+ public void postConfigOnlyStatusCodes() throws UnsupportedEncodingException {
+ controllerContext.setSchemas(schemaContextYangsIetf);
+ mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
+ String uri = createUri("/config", "");
+ assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
+ mockCommitConfigurationDataPostMethod(null);
+ assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
+ mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
+ assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+ }
+
+ @Test
+ public void postConfigStatusCodes() throws UnsupportedEncodingException {
+ controllerContext.setSchemas(schemaContextYangsIetf);
+ mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
+ String uri = createUri("/config/", "ietf-interfaces:interfaces");
+ assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
+ mockCommitConfigurationDataPostMethod(null);
+ assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
+ mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
+ assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+ }
+
+ @Test
+ public void postDatastoreStatusCodes() throws UnsupportedEncodingException {
+ controllerContext.setSchemas(schemaContextYangsIetf);
+ mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
+ String uri = createUri("/datastore/", "ietf-interfaces:interfaces");
+ assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
+ mockCommitConfigurationDataPostMethod(null);
+ assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
+ mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
+ assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+ }
+
+ @Test
+ public void postDataViaUrlMountPoint() throws UnsupportedEncodingException {
+ controllerContext.setSchemas(schemaContextYangsIetf);
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+ .build();
+ Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+ when(brokerFacade.commitConfigurationDataPostBehindMountPoint(any(MountInstance.class),
+ any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+
+ MountInstance mountInstance = mock(MountInstance.class);
+ when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
+ MountService mockMountService = mock(MountService.class);
+ when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+ ControllerContext.getInstance().setMountService(mockMountService);
+
+ String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1");
+ assertEquals(204, post(uri, Draft02.MediaTypes.DATA + XML, xmlData2));
+ }
+
+ private void mockInvokeRpc(CompositeNode result, boolean sucessful) {
+ RpcResult<CompositeNode> rpcResult = new DummyRpcResult.Builder<CompositeNode>().result(result)
+ .isSuccessful(sucessful).build();
+ when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(rpcResult);
+ }
+
+ private void mockCommitConfigurationDataPostMethod(TransactionStatus statusName) {
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName)
+ .build();
+ Future<RpcResult<TransactionStatus>> dummyFuture = null;
+ if (statusName != null) {
+ dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+ } else {
+ dummyFuture = DummyFuture.builder().build();
+ }
+
+ when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+ .thenReturn(dummyFuture);
+ }
+
+ private int post(String uri, String mediaType, String data) {
+ return target(uri).request(mediaType).post(Entity.entity(data, mediaType)).getStatus();
+ }
+
+ private static void loadData() throws IOException, URISyntaxException {
+ InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces_absolute_path.xml");
+ xmlDataAbsolutePath = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+ String xmlPathRpcInput = RestconfImplTest.class.getResource("/full-versions/test-data2/data-rpc-input.xml")
+ .getPath();
+ xmlDataRpcInput = TestUtils.loadTextFile(xmlPathRpcInput);
+ cnSnDataOutput = prepareCnSnRpcOutput();
+ String data2Input = RestconfImplTest.class.getResource("/full-versions/test-data2/data2.xml").getPath();
+ xmlData2 = TestUtils.loadTextFile(data2Input);
+ }
+
+ private static CompositeNodeWrapper prepareCnSnRpcOutput() throws URISyntaxException {
+ CompositeNodeWrapper cnSnDataOutput = new CompositeNodeWrapper(new URI("test:module"), "output");
+ CompositeNodeWrapper cont = new CompositeNodeWrapper(new URI("test:module"), "cont-output");
+ cnSnDataOutput.addValue(cont);
+ cnSnDataOutput.unwrap();
+ return cnSnDataOutput;
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.util.concurrent.Future;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestPutOperationTest extends JerseyTest {
+
+ private static String xmlData;
+
+ private static BrokerFacade brokerFacade;
+ private static RestconfImpl restconfImpl;
+ private static SchemaContext schemaContextYangsIetf;
+ private static SchemaContext schemaContextTestModule;
+
+ @BeforeClass
+ public static void init() throws IOException {
+ schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
+ schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
+ ControllerContext controllerContext = ControllerContext.getInstance();
+ controllerContext.setSchemas(schemaContextYangsIetf);
+ brokerFacade = mock(BrokerFacade.class);
+ restconfImpl = RestconfImpl.getInstance();
+ restconfImpl.setBroker(brokerFacade);
+ restconfImpl.setControllerContext(controllerContext);
+ loadData();
+ }
+
+ private static void loadData() throws IOException {
+ InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
+ xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+ }
+
+ @Override
+ protected Application configure() {
+ /* enable/disable Jersey logs to console */
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+ ResourceConfig resourceConfig = new ResourceConfig();
+ resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+ StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+ JsonToCompositeNodeProvider.INSTANCE);
+ return resourceConfig;
+ }
+
+ /**
+ * Tests of status codes for "/config/{identifier}".
+ */
+ @Test
+ public void putConfigStatusCodes() throws UnsupportedEncodingException {
+ String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
+ mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
+ assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData));
+
+ mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED);
+ assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
+ }
+
+
+ /**
+ * Tests of status codes for "/datastore/{identifier}".
+ */
+ @Test
+ public void putDatastoreStatusCodes() throws UnsupportedEncodingException {
+ String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+ mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
+ assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData));
+
+ mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED);
+ assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
+ }
+
+ @Test
+ public void testRpcResultCommitedToStatusCodesWithMountPoint() throws UnsupportedEncodingException,
+ FileNotFoundException, URISyntaxException {
+
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+ .build();
+ Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+ when(brokerFacade.commitConfigurationDataPutBehindMountPoint(any(MountInstance.class),
+ any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+
+
+ InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/full-versions/test-data2/data2.xml");
+ String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+ Entity<String> entity = Entity.entity(xml, Draft02.MediaTypes.DATA + XML);
+
+ MountInstance mountInstance = mock(MountInstance.class);
+ when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
+ MountService mockMountService = mock(MountService.class);
+ when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+ ControllerContext.getInstance().setMountService(mockMountService);
+
+ String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont");
+ Response response = target(uri).request(Draft02.MediaTypes.DATA + XML).put(entity);
+ assertEquals(200, response.getStatus());
+
+ uri = createUri("/config/", "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont");
+ response = target(uri).request(Draft02.MediaTypes.DATA + XML).put(entity);
+ assertEquals(200, response.getStatus());
+ }
+
+ private int put(String uri, String mediaType, String data) throws UnsupportedEncodingException {
+ return target(uri).request(mediaType).put(Entity.entity(data, mediaType)).getStatus();
+ }
+
+ private void mockCommitConfigurationDataPutMethod(TransactionStatus statusName) {
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName)
+ .build();
+ Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+ when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
+ .thenReturn(dummyFuture);
+ }
+
+}
package org.opendaylight.controller.sal.restconf.impl.test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.FileNotFoundException;
-import java.io.InputStream;
import java.util.Set;
import org.junit.BeforeClass;
import org.junit.Test;
-import org.opendaylight.controller.sal.restconf.impl.*;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.Module;
@BeforeClass
public static void init() throws FileNotFoundException {
- Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
- .getPath());
+ Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
+ assertNotNull(allModules);
SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
ControllerContext controllerContext = ControllerContext.getInstance();
controllerContext.setSchemas(schemaContext);
@Test
public void testExample() throws FileNotFoundException {
- InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
+ CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", XmlToCompositeNodeProvider.INSTANCE);
BrokerFacade brokerFacade = mock(BrokerFacade.class);
when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null));
package org.opendaylight.controller.sal.restconf.impl.test;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.Date;
-import java.util.*;
-import java.util.concurrent.Future;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
import javax.ws.rs.WebApplicationException;
-import javax.xml.parsers.*;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.*;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.rest.impl.*;
-import org.opendaylight.controller.sal.restconf.impl.*;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.slf4j.Logger;
public final class TestUtils {
- private static final Logger logger = LoggerFactory.getLogger(TestUtils.class);
+ private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class);
private final static YangModelParser parser = new YangParserImpl();
- public static Set<Module> loadModules(String resourceDirectory) throws FileNotFoundException {
+ private static Set<Module> loadModules(String resourceDirectory) throws FileNotFoundException {
final File testDir = new File(resourceDirectory);
final String[] fileList = testDir.list();
final List<File> testFiles = new ArrayList<File>();
return parser.parseYangModels(testFiles);
}
+ public static Set<Module> loadModulesFrom(String yangPath) {
+ try {
+ return TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath());
+ } catch (FileNotFoundException e) {
+ LOG.error("Yang files at path: " + yangPath + " weren't loaded.");
+ }
+
+ return null;
+ }
+
public static SchemaContext loadSchemaContext(Set<Module> modules) {
return parser.resolveSchemaContext(modules);
}
public static SchemaContext loadSchemaContext(String resourceDirectory) throws FileNotFoundException {
- return parser.resolveSchemaContext(loadModules(resourceDirectory));
+ return parser.resolveSchemaContext(loadModulesFrom(resourceDirectory));
}
public static Module findModule(Set<Module> modules, String moduleName) {
- Module result = null;
for (Module module : modules) {
if (module.getName().equals(moduleName)) {
- result = module;
- break;
+ return module;
}
}
- return result;
+ return null;
}
-
-
public static Document loadDocumentFrom(InputStream inputStream) {
try {
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
return docBuilder.parse(inputStream);
} catch (SAXException | IOException | ParserConfigurationException e) {
- logger.error("Error during loading Document from XML", e);
+ LOG.error("Error during loading Document from XML", e);
return null;
}
}
return new String(charData, "UTF-8");
} catch (IOException | TransformerException e) {
String msg = "Error during transformation of Document into String";
- logger.error(msg, e);
+ LOG.error(msg, e);
return msg;
}
}
- public static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
- String outputPath, String searchedModuleName, String searchedDataSchemaName) {
- Set<Module> modules = resolveModules(yangPath);
- Module module = resolveModule(searchedModuleName, modules);
- DataSchemaNode dataSchemaNode = resolveDataSchemaNode(module, searchedDataSchemaName);
-
- normalizeCompositeNode(compositeNode, modules, dataSchemaNode, searchedModuleName + ":"
- + searchedDataSchemaName);
-
- try {
- return writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
-
- }
-
- public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules,
- DataSchemaNode dataSchemaNode, String schemaNodePath) {
+ /**
+ *
+ * Fill missing data (namespaces) and build correct data type in
+ * {@code compositeNode} according to {@code dataSchemaNode}. The method
+ * {@link RestconfImpl#createConfigurationData createConfigurationData} is
+ * used because it contains calling of method {code normalizeNode}
+ */
+ public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules, String schemaNodePath) {
RestconfImpl restconf = RestconfImpl.getInstance();
ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules));
- TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf);
- restconf.createConfigurationData(schemaNodePath, compositeNode);
+ prepareMocksForRestconf(modules, restconf);
+ restconf.updateConfigurationData(schemaNodePath, compositeNode);
}
+ /**
+ * Searches module with name {@code searchedModuleName} in {@code modules}.
+ * If module name isn't specified and module set has only one element then
+ * this element is returned.
+ *
+ */
public static Module resolveModule(String searchedModuleName, Set<Module> modules) {
- assertNotNull("modules can't be null.", modules);
- Module module = null;
+ assertNotNull("Modules can't be null.", modules);
if (searchedModuleName != null) {
for (Module m : modules) {
if (m.getName().equals(searchedModuleName)) {
- module = m;
- break;
+ return m;
}
}
} else if (modules.size() == 1) {
- module = modules.iterator().next();
+ return modules.iterator().next();
}
- return module;
- }
-
- public static Set<Module> resolveModules(String yangPath) {
- Set<Module> modules = null;
-
- try {
- modules = TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath());
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
-
- return modules;
+ return null;
}
- public static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) {
- assertNotNull("Module is missing", module);
+ public static DataSchemaNode resolveDataSchemaNode(String searchedDataSchemaName, Module module) {
+ assertNotNull("Module can't be null", module);
- DataSchemaNode dataSchemaNode = null;
if (searchedDataSchemaName != null) {
for (DataSchemaNode dsn : module.getChildNodes()) {
if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) {
- dataSchemaNode = dsn;
+ return dsn;
}
}
} else if (module.getChildNodes().size() == 1) {
- dataSchemaNode = module.getChildNodes().iterator().next();
- }
- return dataSchemaNode;
- }
-
- public static String writeCompNodeWithSchemaContextToJson(CompositeNode compositeNode, Set<Module> modules,
- DataSchemaNode dataSchemaNode) throws IOException, WebApplicationException {
- String jsonResult;
-
- assertNotNull(dataSchemaNode);
- assertNotNull("Composite node can't be null", compositeNode);
- ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
-
- ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
-
- StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
- structuredDataToJsonProvider.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null,
- null, byteArrayOS);
-
- jsonResult = byteArrayOS.toString();
-
- return jsonResult;
- }
-
- public static CompositeNode loadCompositeNode(String xmlDataPath) {
- InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
- CompositeNode compositeNode = null;
- try {
- XmlReader xmlReader = new XmlReader();
- compositeNode = xmlReader.read(xmlStream);
-
- } catch (UnsupportedFormatException | XMLStreamException e) {
- e.printStackTrace();
- }
- return compositeNode;
- }
-
- static void outputToFile(ByteArrayOutputStream outputStream, String outputDir) throws IOException {
- FileOutputStream fileOS = null;
- try {
- String path = TestUtils.class.getResource(outputDir).getPath();
- File outFile = new File(path + "/data.json");
- fileOS = new FileOutputStream(outFile);
- try {
- fileOS.write(outputStream.toByteArray());
- } catch (IOException e) {
- e.printStackTrace();
- }
- fileOS.close();
- } catch (FileNotFoundException e1) {
- e1.printStackTrace();
- }
- }
-
- static String readJsonFromFile(String path, boolean removeWhiteChars) {
- FileReader fileReader = getFileReader(path);
-
- StringBuilder strBuilder = new StringBuilder();
- char[] buffer = new char[1000];
-
- while (true) {
- int loadedCharNum;
- try {
- loadedCharNum = fileReader.read(buffer);
- } catch (IOException e) {
- break;
- }
- if (loadedCharNum == -1) {
- break;
- }
- strBuilder.append(buffer, 0, loadedCharNum);
- }
- try {
- fileReader.close();
- } catch (IOException e) {
- System.out.println("The file wasn't closed");
- }
- String rawStr = strBuilder.toString();
- if (removeWhiteChars) {
- rawStr = rawStr.replace("\n", "");
- rawStr = rawStr.replace("\r", "");
- rawStr = rawStr.replace("\t", "");
- rawStr = removeSpaces(rawStr);
- }
-
- return rawStr;
- }
-
- private static FileReader getFileReader(String path) {
- String fullPath = TestUtils.class.getResource(path).getPath();
- assertNotNull("Path to file can't be null.", fullPath);
- File file = new File(fullPath);
- assertNotNull("File can't be null", file);
- FileReader fileReader = null;
- try {
- fileReader = new FileReader(file);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- assertNotNull("File reader can't be null.", fileReader);
- return fileReader;
- }
-
- private static String removeSpaces(String rawStr) {
- StringBuilder strBuilder = new StringBuilder();
- int i = 0;
- int quoteCount = 0;
- while (i < rawStr.length()) {
- if (rawStr.substring(i, i + 1).equals("\"")) {
- quoteCount++;
- }
-
- if (!rawStr.substring(i, i + 1).equals(" ") || (quoteCount % 2 == 1)) {
- strBuilder.append(rawStr.charAt(i));
- }
- i++;
+ return module.getChildNodes().iterator().next();
}
-
- return strBuilder.toString();
+ return null;
}
- public static QName buildQName(String name, String uri, String date) {
+ public static QName buildQName(String name, String uri, String date, String prefix) {
try {
URI u = new URI(uri);
Date dt = null;
if (date != null) {
dt = Date.valueOf(date);
}
- return new QName(u, dt, name);
+ return new QName(u, dt, prefix, name);
} catch (URISyntaxException e) {
return null;
}
}
- public static QName buildQName(String name) {
- return buildQName(name, "", null);
- }
-
- public static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) {
- RestconfImpl restconf = RestconfImpl.getInstance();
-
- InstanceIdWithSchemaNode instIdAndSchema = new InstanceIdWithSchemaNode(mock(InstanceIdentifier.class),
- dataSchemaNode);
-
- ControllerContext controllerContext = mock(ControllerContext.class);
- BrokerFacade broker = mock(BrokerFacade.class);
-
- RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
- TransactionStatus.COMMITED).build();
- Future<RpcResult<TransactionStatus>> future = DummyFuture.builder().rpcResult(rpcResult).build();
- when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema);
- when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(
- future);
-
- restconf.setControllerContext(controllerContext);
- restconf.setBroker(broker);
-
- // method is called only because it contains call of method which
- // supplement namespaces to compositeNode
- restconf.createConfigurationData("something", compositeNode);
- }
-
- public static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException {
- return obtainSchemaFromYang(yangFolder, null);
+ public static QName buildQName(String name, String uri, String date) {
+ return buildQName(name, uri, date, null);
}
- public static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName)
- throws FileNotFoundException {
- Set<Module> modules = null;
- modules = TestUtils.loadModules(TestUtils.class.getResource(yangFolder).getPath());
-
- if (modules == null) {
- return null;
- }
- if (modules.size() < 1) {
- return null;
- }
-
- Module moduleRes = null;
- if (modules.size() > 1) {
- if (moduleName == null) {
- return null;
- } else {
- for (Module module : modules) {
- if (module.getName().equals(moduleName)) {
- moduleRes = module;
- }
- }
- if (moduleRes == null) {
- return null;
- }
- }
- } else {
- moduleRes = modules.iterator().next();
- }
-
- if (moduleRes.getChildNodes() == null) {
- return null;
- }
-
- if (moduleRes.getChildNodes().size() != 1) {
- return null;
- }
- DataSchemaNode dataSchemaNode = moduleRes.getChildNodes().iterator().next();
- return dataSchemaNode;
-
+ public static QName buildQName(String name) {
+ return buildQName(name, "", null);
}
- public static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
+ private static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
wrappedNode.setNamespace(new URI(""));
if (wrappedNode instanceof CompositeNodeWrapper) {
for (NodeWrapper<?> childNodeWrapper : ((CompositeNodeWrapper) wrappedNode).getValues()) {
}
}
- public static void prepareMockForRestconfBeforeNormalization(Set<Module> modules, DataSchemaNode dataSchemaNode,
- RestconfImpl restconf) {
- ControllerContext instance = ControllerContext.getInstance();
- instance.setSchemas(TestUtils.loadSchemaContext(modules));
- restconf.setControllerContext(ControllerContext.getInstance());
-
+ private static void prepareMocksForRestconf(Set<Module> modules, RestconfImpl restconf) {
+ ControllerContext controllerContext = ControllerContext.getInstance();
BrokerFacade mockedBrokerFacade = mock(BrokerFacade.class);
+
+ controllerContext.setSchemas(TestUtils.loadSchemaContext(modules));
+
when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
.thenReturn(
new DummyFuture.Builder().rpcResult(
new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
.build()).build());
+
+ restconf.setControllerContext(controllerContext);
restconf.setBroker(mockedBrokerFacade);
}
-
- static CompositeNode loadCompositeNodeWithXmlTreeBuilder(String xmlDataPath) {
- InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
- CompositeNode compositeNode = null;
+
+ public static CompositeNode readInputToCnSn(String path, boolean dummyNamespaces,
+ MessageBodyReader<CompositeNode> reader) throws WebApplicationException {
+
+ InputStream inputStream = TestUtils.class.getResourceAsStream(path);
try {
- compositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
+ CompositeNode compositeNode = reader.readFrom(null, null, null, null, null, inputStream);
+ assertTrue(compositeNode instanceof CompositeNodeWrapper);
+ if (dummyNamespaces) {
+ try {
+ TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
+ return ((CompositeNodeWrapper) compositeNode).unwrap();
+ } catch (URISyntaxException e) {
+ LOG.error(e.getMessage());
+ assertTrue(e.getMessage(), false);
+ }
+ }
+ return compositeNode;
+ } catch (IOException e) {
+ LOG.error(e.getMessage());
+ assertTrue(e.getMessage(), false);
}
- return compositeNode;
-
-
-
+ return null;
}
-
-
- public static CompositeNode loadCompositeNodeWithXmlTreeBuilder(InputStream xmlInputStream) throws FileNotFoundException {
- if (xmlInputStream == null) {
- throw new IllegalArgumentException();
- }
- Node<?> dataTree;
- try {
- dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
- } catch (XMLStreamException e) {
- logger.error("Error during building data tree from XML", e);
- return null;
- }
- if (dataTree == null) {
- logger.error("data tree is null");
- return null;
- }
- if (dataTree instanceof SimpleNode) {
- logger.error("RPC XML was resolved as SimpleNode");
- return null;
+
+ public static CompositeNode readInputToCnSn(String path, MessageBodyReader<CompositeNode> reader) {
+ return readInputToCnSn(path, false, reader);
+ }
+
+ public static String writeCompNodeWithSchemaContextToOutput(CompositeNode compositeNode, Set<Module> modules,
+ DataSchemaNode dataSchemaNode, MessageBodyWriter<StructuredData> messageBodyWriter) throws IOException,
+ WebApplicationException {
+
+ assertNotNull(dataSchemaNode);
+ assertNotNull("Composite node can't be null", compositeNode);
+ ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
+
+ ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
+
+ messageBodyWriter.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null, null,
+ byteArrayOS);
+
+ return byteArrayOS.toString();
+ }
+
+ public static String loadTextFile(String filePath) throws IOException {
+ FileReader fileReader = new FileReader(filePath);
+ BufferedReader bufReader = new BufferedReader(fileReader);
+
+ String line = null;
+ StringBuilder result = new StringBuilder();
+ while ((line = bufReader.readLine()) != null) {
+ result.append(line);
}
- return (CompositeNode) dataTree;
- }
+ bufReader.close();
+ return result.toString();
+ }
}
+++ /dev/null
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLEncoder;
-import java.util.*;
-import java.util.concurrent.Future;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.rest.api.Draft01;
-import org.opendaylight.controller.sal.rest.api.RestconfService;
-import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
-import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-import com.google.common.base.Charsets;
-
-public class XmlProvidersTest extends JerseyTest {
-
- private static ControllerContext controllerContext;
- private static BrokerFacade brokerFacade;
- private static RestconfImpl restconfImpl;
- private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.data+xml");
- private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
-
- @BeforeClass
- public static void init() throws FileNotFoundException {
- Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
- .getPath());
- SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
- controllerContext = ControllerContext.getInstance();
- controllerContext.setSchemas(schemaContext);
- brokerFacade = mock(BrokerFacade.class);
- restconfImpl = RestconfImpl.getInstance();
- restconfImpl.setBroker(brokerFacade);
- restconfImpl.setControllerContext(controllerContext);
- }
-
- @Before
- public void logs() {
- List<LogRecord> loggedRecords = getLoggedRecords();
- for (LogRecord l : loggedRecords) {
- System.out.println(l.getMessage());
- }
- }
-
- @Test
- public void testStructuredDataToXmlProvider() throws FileNotFoundException, UnsupportedEncodingException {
- String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
-
- CompositeNode loadedCompositeNode = prepareCompositeNodeWithIetfInterfacesInterfacesData();
- when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
-
- Response response = target(uri).request(MEDIA_TYPE).get();
- assertEquals(200, response.getStatus());
- }
-
- private CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
- CompositeNode intface;
- try {
- intface = new CompositeNodeWrapper(new URI("interface"), "interface");
- List<Node<?>> childs = new ArrayList<>();
-
- childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
- childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
- childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
- childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
- intface.setValue(childs);
- return intface;
- } catch (URISyntaxException e) {
- }
-
- return null;
- }
-
- @Test
- public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException {
- String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0");
-
- Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
- Entity.entity("<SimpleNode/>", MEDIA_TYPE));
- assertEquals(400, response.getStatus());
-
- response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
- Entity.entity("<SimpleNode>", MEDIA_TYPE));
- assertEquals(400, response.getStatus());
- }
-
- @Test
- public void testXmlToCompositeNode404NotFound() throws UnsupportedEncodingException, URISyntaxException {
- String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
-
- when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
-
- Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).get();
- assertEquals(404, response.getStatus());
- }
-
- @Test
- public void testXmlToCompositeNode400() throws UnsupportedEncodingException, URISyntaxException {
- String uri = createUri("/datastore/", "simple-nodes:user/name");
-
- when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
-
- Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).get();
- assertEquals(400, response.getStatus());
- }
-
- @Test
- public void testRpcResultCommitedToStatusCodes() throws UnsupportedEncodingException {
- InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
- Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02);
- RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
- TransactionStatus.COMMITED).build();
- Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
- when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
- .thenReturn(dummyFuture);
- when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
- .thenReturn(dummyFuture);
-
- String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
- Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
- assertEquals(200, response.getStatus());
- response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
- assertEquals(204, response.getStatus());
-
- uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
- response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
- assertEquals(200, response.getStatus());
- response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
- assertEquals(204, response.getStatus());
-
- uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
- response = target(uri).request(MEDIA_TYPE).put(entity);
- assertEquals(200, response.getStatus());
- response = target(uri).request(MEDIA_TYPE).post(entity);
- assertEquals(204, response.getStatus());
- }
-
- @Test
- public void testRpcResultOtherToStatusCodes() throws UnsupportedEncodingException {
- InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
- Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02);
- RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
- TransactionStatus.FAILED).build();
- Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
- when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
- .thenReturn(dummyFuture);
- when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
- .thenReturn(dummyFuture);
-
- String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
- Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
- assertEquals(500, response.getStatus());
- response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
- assertEquals(500, response.getStatus());
-
- uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
- response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
- assertEquals(500, response.getStatus());
- response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
- assertEquals(500, response.getStatus());
-
- uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
- response = target(uri).request(MEDIA_TYPE).put(entity);
- assertEquals(500, response.getStatus());
- response = target(uri).request(MEDIA_TYPE).post(entity);
- assertEquals(500, response.getStatus());
- }
-
- private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
- return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
- }
-
- @Override
- protected Application configure() {
- enable(TestProperties.LOG_TRAFFIC);
- enable(TestProperties.DUMP_ENTITY);
- enable(TestProperties.RECORD_LOG_LEVEL);
- set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
- XmlToCompositeNodeProvider.INSTANCE);
- return resourceConfig;
- }
-
-}
import static org.junit.Assert.assertNotNull;
import java.util.Set;
-import org.opendaylight.yangtools.yang.model.api.*;
+
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
public abstract class YangAndXmlAndDataSchemaLoader {
protected static Set<Module> modules;
protected static DataSchemaNode dataSchemaNode;
+ protected static String searchedModuleName;
+ protected static String searchedDataSchemaName;
+ protected static String schemaNodePath;
protected static void dataLoad(String yangPath) {
dataLoad(yangPath, 1, null, null);
}
protected static void dataLoad(String yangPath, int modulesNumber, String moduleName, String dataSchemaName) {
- modules = TestUtils.resolveModules(yangPath);
+ modules = TestUtils.loadModulesFrom(yangPath);
assertEquals(modulesNumber, modules.size());
Module module = TestUtils.resolveModule(moduleName, modules);
+ searchedModuleName = module == null ? "" : module.getName();
assertNotNull(module);
- dataSchemaNode = TestUtils.resolveDataSchemaNode(module, dataSchemaName);
+ dataSchemaNode = TestUtils.resolveDataSchemaNode(dataSchemaName, module);
+ searchedDataSchemaName = dataSchemaNode == null ? "" : dataSchemaNode.getQName().getLocalName();
assertNotNull(dataSchemaNode);
+ schemaNodePath = searchedModuleName + ":" + searchedDataSchemaName;
}
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class XmlLeafrefToCnSnTest {
+ private static final Logger LOG = LoggerFactory.getLogger(XmlLeafrefToCnSnTest.class);
+
+ /**
+ * top level element represents container. second level element is list with
+ * two elements.
+ */
+ @Test
+ public void testXmlDataContainer() {
+ CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-container.xml", false,
+ XmlToCompositeNodeProvider.INSTANCE);
+ assertNotNull(compNode);
+ Set<Module> modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-container-yang");
+
+ assertNotNull(modules);
+ TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont");
+
+ String nameSpace = "data:container:yang";
+ assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString());
+
+ verifyNullAndEmptyStringSingleNode(compNode, nameSpace);
+ verifyCommonPartAOfXml(compNode, "", nameSpace);
+ }
+
+ private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) {
+ assertEquals("cont", compNode.getNodeType().getLocalName());
+
+ SimpleNode<?> lf2 = null;
+ SimpleNode<?> lf3 = null;
+ int found = 0;
+ for (Node<?> child : compNode.getChildren()) {
+ if (found == 0x3)
+ break;
+ if (child instanceof SimpleNode<?>) {
+ SimpleNode<?> childSimple = (SimpleNode<?>) child;
+ if (childSimple.getNodeType().getLocalName().equals("lf3")) {
+ lf3 = childSimple;
+ found = found | (1 << 0);
+ } else if (childSimple.getNodeType().getLocalName().equals("lf2")) {
+ lf2 = childSimple;
+ found = found | (1 << 1);
+ }
+ }
+ assertEquals(nameSpace, child.getNodeType().getNamespace().toString());
+ }
+
+ assertEquals("", lf2.getValue());
+ assertEquals(null, lf3.getValue());
+ }
+
+ @Test
+ public void testXmlDataList() {
+ CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-list.xml", false,
+ XmlToCompositeNodeProvider.INSTANCE);
+ assertNotNull(compNode);
+
+ Set<Module> modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-list-yang");
+ assertNotNull(modules);
+
+ TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont");
+
+ String nameSpaceList = "data:list:yang";
+ String nameSpaceCont = "data:container:yang";
+ assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
+ assertEquals("cont", compNode.getNodeType().getLocalName());
+ assertEquals(3, compNode.getChildren().size());
+ CompositeNode lst1_1 = null;
+ CompositeNode lst1_2 = null;
+ int loopCount = 0;
+ for (Node<?> node : compNode.getChildren()) {
+ if (node.getNodeType().getLocalName().equals("lf1")) {
+ assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
+ assertTrue(node instanceof SimpleNode<?>);
+ assertEquals("lf1", node.getValue());
+ } else {
+ assertTrue(node instanceof CompositeNode);
+ switch (loopCount++) {
+ case 0:
+ lst1_1 = (CompositeNode) node;
+ break;
+ case 1:
+ lst1_2 = (CompositeNode) node;
+ break;
+ }
+ assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString());
+ }
+ }
+ // lst1_1
+ verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont);
+ // :lst1_1
+
+ // lst1_2
+ SimpleNode<?> lflst11 = null;
+ CompositeNode cont11 = null;
+ for (Node<?> node : lst1_2.getChildren()) {
+ String nodeName = node.getNodeType().getLocalName();
+ if (nodeName.equals("lflst11")) {
+ assertTrue(node instanceof SimpleNode<?>);
+ lflst11 = (SimpleNode<?>) node;
+
+ } else if (nodeName.equals("cont11")) {
+ assertTrue(node instanceof CompositeNode);
+ cont11 = (CompositeNode) node;
+ }
+ assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
+ }
+ assertEquals("221", lflst11.getValue());
+
+ assertEquals(1, cont11.getChildren().size());
+ assertTrue(cont11.getChildren().get(0) instanceof SimpleNode<?>);
+ SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getChildren().get(0);
+ assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString());
+ assertEquals("lf111", cont11_lf111.getNodeType().getLocalName());
+ assertEquals((short) 100, cont11_lf111.getValue());
+ // :lst1_2
+
+ }
+
+ @Test
+ public void testXmlEmptyData() {
+ CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/empty-data.xml", true,
+ XmlToCompositeNodeProvider.INSTANCE);
+ assertEquals("cont", compNode.getNodeType().getLocalName());
+ SimpleNode<?> lf1 = null;
+ SimpleNode<?> lflst1_1 = null;
+ SimpleNode<?> lflst1_2 = null;
+ CompositeNode lst1 = null;
+ int lflst1Count = 0;
+ for (Node<?> node : compNode.getChildren()) {
+ if (node.getNodeType().getLocalName().equals("lf1")) {
+ assertTrue(node instanceof SimpleNode<?>);
+ lf1 = (SimpleNode<?>) node;
+ } else if (node.getNodeType().getLocalName().equals("lflst1")) {
+ assertTrue(node instanceof SimpleNode<?>);
+
+ switch (lflst1Count++) {
+ case 0:
+ lflst1_1 = (SimpleNode<?>) node;
+ break;
+ case 1:
+ lflst1_2 = (SimpleNode<?>) node;
+ break;
+ }
+ } else if (node.getNodeType().getLocalName().equals("lst1")) {
+ assertTrue(node instanceof CompositeNode);
+ lst1 = (CompositeNode) node;
+ }
+ }
+
+ assertNotNull(lf1);
+ assertNotNull(lflst1_1);
+ assertNotNull(lflst1_2);
+ assertNotNull(lst1);
+
+ assertEquals("", lf1.getValue());
+ assertEquals("", lflst1_1.getValue());
+ assertEquals("", lflst1_2.getValue());
+ assertEquals(1, lst1.getChildren().size());
+ assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName());
+
+ assertTrue(lst1.getChildren().get(0) instanceof SimpleNode<?>);
+ assertEquals("", lst1.getChildren().get(0).getValue());
+
+ }
+
+ /**
+ * Test case like this <lf11 xmlns:x="namespace">x:identity</lf11>
+ */
+ @Test
+ public void testIdentityrefNmspcInElement() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref",
+ "identityref-module", "cont", 2, "iden", "identity:module");
+ }
+
+ /**
+ *
+ * Test case like <lf11 xmlns="namespace1"
+ * xmlns:x="namespace">identity</lf11>
+ */
+
+ @Test
+ public void testIdentityrefDefaultNmspcInElement() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml",
+ "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module");
+ }
+
+ /**
+ *
+ * Test case like <cont1 xmlns="namespace1"> <lf11
+ * xmlns:x="namespace">identity</lf11> </cont1>
+ */
+ @Test
+ public void testIdentityrefDefaultNmspcInParrentElement() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml",
+ "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+ }
+
+ /**
+ *
+ * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
+ * <lf11>x:identity</lf11> </cont1>
+ */
+ @Test
+ public void testIdentityrefNmspcInParrentElement() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml",
+ "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace");
+
+ }
+
+ /**
+ *
+ * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
+ * </cont1>
+ */
+ @Test
+ public void testIdentityrefNoNmspcValueWithPrefix() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml",
+ "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module");
+ }
+
+ /**
+ *
+ * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
+ * </cont1>
+ */
+ @Test
+ public void testIdentityrefNoNmspcValueWithoutPrefix() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml",
+ "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+ }
+
+ private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
+ SimpleNode<?> lf1suf = null;
+ SimpleNode<?> lflst1suf_1 = null;
+ SimpleNode<?> lflst1suf_2 = null;
+ SimpleNode<?> lflst1suf_3 = null;
+ CompositeNode cont1suf = null;
+ CompositeNode lst1suf = null;
+
+ int lflstCount = 0;
+
+ for (Node<?> node : compNode.getChildren()) {
+ String localName = node.getNodeType().getLocalName();
+ if (localName.equals("lf1" + suf)) {
+ assertTrue(node instanceof SimpleNode<?>);
+ lf1suf = (SimpleNode<?>) node;
+ } else if (localName.equals("lflst1" + suf)) {
+ assertTrue(node instanceof SimpleNode<?>);
+ switch (lflstCount++) {
+ case 0:
+ lflst1suf_1 = (SimpleNode<?>) node;
+ break;
+ case 1:
+ lflst1suf_2 = (SimpleNode<?>) node;
+ break;
+ case 2:
+ lflst1suf_3 = (SimpleNode<?>) node;
+ break;
+ }
+ } else if (localName.equals("lst1" + suf)) {
+ assertTrue(node instanceof CompositeNode);
+ lst1suf = (CompositeNode) node;
+ } else if (localName.equals("cont1" + suf)) {
+ assertTrue(node instanceof CompositeNode);
+ cont1suf = (CompositeNode) node;
+ }
+ assertEquals(nameSpace, node.getNodeType().getNamespace().toString());
+ }
+
+ assertNotNull(lf1suf);
+ assertNotNull(lflst1suf_1);
+ assertNotNull(lflst1suf_2);
+ assertNotNull(lflst1suf_3);
+ assertNotNull(lst1suf);
+ assertNotNull(cont1suf);
+
+ assertEquals("str0", lf1suf.getValue());
+ assertEquals("121", lflst1suf_1.getValue());
+ assertEquals("131", lflst1suf_2.getValue());
+ assertEquals("str1", lflst1suf_3.getValue());
+
+ assertEquals(1, lst1suf.getChildren().size());
+
+ assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode<?>);
+ SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getChildren().get(0);
+ assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString());
+ assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName());
+ assertEquals("str2", lst11_lf11.getValue());
+
+ assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode<?>);
+ SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getChildren().get(0);
+ assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString());
+ assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName());
+ assertEquals((short) 100, cont1_lf11.getValue());
+ }
+
+ private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
+ int moduleCount, String resultLocalName, String resultNamespace) {
+ CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
+ assertNotNull(compositeNode);
+
+ Set<Module> modules = TestUtils.loadModulesFrom(yangPath);
+ assertEquals(moduleCount, modules.size());
+
+ TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + schemaName);
+
+ SimpleNode<?> lf11 = getLf11(compositeNode);
+ assertTrue(lf11.getValue() instanceof QName);
+ QName qName = (QName) lf11.getValue();
+ assertEquals(resultLocalName, qName.getLocalName());
+ assertEquals(resultNamespace, qName.getNamespace().toString());
+ }
+
+ private SimpleNode<?> getLf11(CompositeNode compositeNode) {
+ assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+ List<Node<?>> childs = compositeNode.getChildren();
+ assertEquals(1, childs.size());
+ Node<?> nd = childs.iterator().next();
+ assertTrue(nd instanceof CompositeNode);
+ assertEquals("cont1", nd.getNodeType().getLocalName());
+
+ childs = ((CompositeNode) nd).getChildren();
+ SimpleNode<?> lf11 = null;
+ for (Node<?> child : childs) {
+ assertTrue(child instanceof SimpleNode);
+ if (child.getNodeType().getLocalName().equals("lf11")) {
+ lf11 = (SimpleNode<?>) child;
+ }
+ }
+ assertNotNull(lf11);
+ return lf11;
+ }
+
+}
import static org.junit.Assert.*;
-import java.io.*;
-import java.net.URISyntaxException;
-import java.util.List;
-import java.util.Set;
-
-import javax.ws.rs.WebApplicationException;
-
+import org.junit.BeforeClass;
import org.junit.Test;
import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class XmlToCnSnTest {
- private static final Logger LOG = LoggerFactory.getLogger(XmlToCnSnTest.class);
-
- /**
- * top level element represents container. second level element is list with
- * two elements.
- */
- @Test
- public void testXmlDataContainer() {
- CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-container.xml", false);
- assertNotNull(compNode);
- DataSchemaNode dataSchemaNode = null;
- try {
- dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-container-yang");
- } catch (FileNotFoundException e) {
- LOG.error(e.getMessage());
- assertTrue(false);
- }
-
- assertNotNull(dataSchemaNode);
- TestUtils.supplementNamespace(dataSchemaNode, compNode);
-
- String nameSpace = "data:container:yang";
- assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString());
-
- verifyNullAndEmptyStringSingleNode(compNode, nameSpace);
- verifyCommonPartAOfXml(compNode, "", nameSpace);
- }
-
- private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) {
- assertEquals("cont", compNode.getNodeType().getLocalName());
- SimpleNode<?> lf2 = null;
- SimpleNode<?> lf3 = null;
- int found = 0;
- for (Node<?> child : compNode.getChildren()) {
- if (found == 0x3)
- break;
- if (child instanceof SimpleNode<?>) {
- SimpleNode<?> childSimple = (SimpleNode<?>) child;
- if (childSimple.getNodeType().getLocalName().equals("lf3")) {
- lf3 = childSimple;
- found = found | (1 << 0);
- } else if (childSimple.getNodeType().getLocalName().equals("lf2")) {
- lf2 = childSimple;
- found = found | (1 << 1);
- }
- }
- assertEquals(nameSpace, child.getNodeType().getNamespace().toString());
- }
+public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
- assertEquals("", lf2.getValue());
- assertEquals(null, lf3.getValue());
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/xml-to-cnsn/leafref");
}
@Test
- public void testXmlDataList() {
- CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-list.xml", false);
- assertNotNull(compNode);
-
- DataSchemaNode dataSchemaNode = null;
- try {
- dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-list-yang", "data-container-yang");
- } catch (FileNotFoundException e) {
- LOG.error(e.getMessage());
- }
+ public void testXmlLeafrefToCnSn() {
+ CompositeNode compositeNode = TestUtils.readInputToCnSn("/xml-to-cnsn/leafref/xml/data.xml", false,
+ XmlToCompositeNodeProvider.INSTANCE);
+ assertNotNull(compositeNode);
assertNotNull(dataSchemaNode);
- TestUtils.supplementNamespace(dataSchemaNode, compNode);
-
- String nameSpaceList = "data:list:yang";
- String nameSpaceCont = "data:container:yang";
- assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
- assertEquals("cont", compNode.getNodeType().getLocalName());
- assertEquals(3, compNode.getChildren().size());
- CompositeNode lst1_1 = null;
- CompositeNode lst1_2 = null;
- int loopCount = 0;
- for (Node<?> node : compNode.getChildren()) {
- if (node.getNodeType().getLocalName().equals("lf1")) {
- assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
- assertTrue(node instanceof SimpleNode<?>);
- assertEquals("lf1", node.getValue());
- } else {
- assertTrue(node instanceof CompositeNode);
- switch (loopCount++) {
- case 0:
- lst1_1 = (CompositeNode) node;
- break;
- case 1:
- lst1_2 = (CompositeNode) node;
- break;
- }
- assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString());
- }
- }
- // lst1_1
- verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont);
- // :lst1_1
-
- // lst1_2
- SimpleNode<?> lflst11 = null;
- CompositeNode cont11 = null;
- for (Node<?> node : lst1_2.getChildren()) {
- String nodeName = node.getNodeType().getLocalName();
- if (nodeName.equals("lflst11")) {
- assertTrue(node instanceof SimpleNode<?>);
- lflst11 = (SimpleNode<?>) node;
-
- } else if (nodeName.equals("cont11")) {
- assertTrue(node instanceof CompositeNode);
- cont11 = (CompositeNode) node;
- }
- assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
- }
- assertEquals("221", lflst11.getValue());
-
- assertEquals(1, cont11.getChildren().size());
- assertTrue(cont11.getChildren().get(0) instanceof SimpleNode<?>);
- SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getChildren().get(0);
- assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString());
- assertEquals("lf111", cont11_lf111.getNodeType().getLocalName());
- assertEquals((short) 100, cont11_lf111.getValue());
- // :lst1_2
-
- }
-
- @Test
- public void testXmlEmptyData() {
- CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/empty-data.xml", true);
- assertEquals("cont", compNode.getNodeType().getLocalName());
- SimpleNode<?> lf1 = null;
- SimpleNode<?> lflst1_1 = null;
- SimpleNode<?> lflst1_2 = null;
- CompositeNode lst1 = null;
- int lflst1Count = 0;
- for (Node<?> node : compNode.getChildren()) {
- if (node.getNodeType().getLocalName().equals("lf1")) {
- assertTrue(node instanceof SimpleNode<?>);
- lf1 = (SimpleNode<?>) node;
- } else if (node.getNodeType().getLocalName().equals("lflst1")) {
- assertTrue(node instanceof SimpleNode<?>);
-
- switch (lflst1Count++) {
- case 0:
- lflst1_1 = (SimpleNode<?>) node;
- break;
- case 1:
- lflst1_2 = (SimpleNode<?>) node;
- break;
- }
- } else if (node.getNodeType().getLocalName().equals("lst1")) {
- assertTrue(node instanceof CompositeNode);
- lst1 = (CompositeNode) node;
- }
- }
-
- assertNotNull(lf1);
- assertNotNull(lflst1_1);
- assertNotNull(lflst1_2);
- assertNotNull(lst1);
-
- assertEquals("", lf1.getValue());
- assertEquals("", lflst1_1.getValue());
- assertEquals("", lflst1_2.getValue());
- assertEquals(1, lst1.getChildren().size());
- assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName());
-
- assertTrue(lst1.getChildren().get(0) instanceof SimpleNode<?>);
- assertEquals("", lst1.getChildren().get(0).getValue());
-
- }
-
- /**
- * Test case like this <lf11 xmlns:x="namespace">x:identity</lf11>
- */
- @Test
- public void testIdentityrefNmspcInElement() {
- testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref",
- "identityref-module", "cont", 2, "iden", "identity:module");
- }
+ TestUtils.normalizeCompositeNode(compositeNode, modules, schemaNodePath);
- /**
- *
- * Test case like <lf11 xmlns="namespace1"
- * xmlns:x="namespace">identity</lf11>
- */
-
- @Test
- public void testIdentityrefDefaultNmspcInElement() {
- testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml",
- "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module");
- }
-
- /**
- *
- * Test case like <cont1 xmlns="namespace1"> <lf11
- * xmlns:x="namespace">identity</lf11> </cont1>
- */
- @Test
- public void testIdentityrefDefaultNmspcInParrentElement() {
- testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml",
- "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
- }
-
- /**
- *
- * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
- * <lf11>x:identity</lf11> </cont1>
- */
- @Test
- public void testIdentityrefNmspcInParrentElement() {
- testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml",
- "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace");
-
- }
-
- /**
- *
- * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
- * </cont1>
- */
- @Test
- public void testIdentityrefNoNmspcValueWithPrefix() {
- testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml",
- "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module");
- }
-
- /**
- *
- * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
- * </cont1>
- */
- @Test
- public void testIdentityrefNoNmspcValueWithoutPrefix() {
- testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml",
- "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
- }
-
- private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
- SimpleNode<?> lf1suf = null;
- SimpleNode<?> lflst1suf_1 = null;
- SimpleNode<?> lflst1suf_2 = null;
- SimpleNode<?> lflst1suf_3 = null;
- CompositeNode cont1suf = null;
- CompositeNode lst1suf = null;
-
- int lflstCount = 0;
+ assertEquals("cont", compositeNode.getNodeType().getLocalName());
- for (Node<?> node : compNode.getChildren()) {
- String localName = node.getNodeType().getLocalName();
- if (localName.equals("lf1" + suf)) {
- assertTrue(node instanceof SimpleNode<?>);
- lf1suf = (SimpleNode<?>) node;
- } else if (localName.equals("lflst1" + suf)) {
- assertTrue(node instanceof SimpleNode<?>);
- switch (lflstCount++) {
- case 0:
- lflst1suf_1 = (SimpleNode<?>) node;
- break;
- case 1:
- lflst1suf_2 = (SimpleNode<?>) node;
- break;
- case 2:
- lflst1suf_3 = (SimpleNode<?>) node;
+ SimpleNode<?> lf2 = null;
+ for (Node<?> childNode : compositeNode.getChildren()) {
+ if (childNode instanceof SimpleNode) {
+ if (childNode.getNodeType().getLocalName().equals("lf2")) {
+ lf2 = (SimpleNode<?>) childNode;
break;
}
- } else if (localName.equals("lst1" + suf)) {
- assertTrue(node instanceof CompositeNode);
- lst1suf = (CompositeNode) node;
- } else if (localName.equals("cont1" + suf)) {
- assertTrue(node instanceof CompositeNode);
- cont1suf = (CompositeNode) node;
}
- assertEquals(nameSpace, node.getNodeType().getNamespace().toString());
}
- assertNotNull(lf1suf);
- assertNotNull(lflst1suf_1);
- assertNotNull(lflst1suf_2);
- assertNotNull(lflst1suf_3);
- assertNotNull(lst1suf);
- assertNotNull(cont1suf);
-
- assertEquals("str0", lf1suf.getValue());
- assertEquals("121", lflst1suf_1.getValue());
- assertEquals("131", lflst1suf_2.getValue());
- assertEquals("str1", lflst1suf_3.getValue());
-
- assertEquals(1, lst1suf.getChildren().size());
-
- assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode<?>);
- SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getChildren().get(0);
- assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString());
- assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName());
- assertEquals("str2", lst11_lf11.getValue());
-
- assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode<?>);
- SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getChildren().get(0);
- assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString());
- assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName());
- assertEquals((short) 100, cont1_lf11.getValue());
- }
-
- private CompositeNode compositeNodeFromXml(String xmlPath, boolean dummyNamespaces) {
- XmlToCompositeNodeProvider xmlToCompositeNodeProvider = XmlToCompositeNodeProvider.INSTANCE;
- try {
- InputStream xmlStream = XmlToCnSnTest.class.getResourceAsStream(xmlPath);
- CompositeNode compositeNode = xmlToCompositeNodeProvider.readFrom(null, null, null, null, null, xmlStream);
- if (dummyNamespaces) {
- try {
- TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
- return ((CompositeNodeWrapper) compositeNode).unwrap();
- } catch (URISyntaxException e) {
- LOG.error(e.getMessage());
- assertTrue(e.getMessage(), false);
- }
- }
- return compositeNode;
-
- } catch (WebApplicationException | IOException e) {
- LOG.error(e.getMessage());
- assertTrue(false);
- }
- return null;
- }
-
- private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
- int moduleCount, String resultLocalName, String resultNamespace) {
- CompositeNode compositeNode = compositeNodeFromXml(xmlPath, false);
- assertNotNull(compositeNode);
-
- Set<Module> modules = TestUtils.resolveModules(yangPath);
- assertEquals(moduleCount, modules.size());
- Module module = TestUtils.resolveModule(moduleName, modules);
- assertNotNull(module);
- DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
- assertNotNull(dataSchemaNode);
-
- TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, moduleName + ":" + schemaName);
-
- SimpleNode<?> lf11 = getLf11(compositeNode);
- assertTrue(lf11.getValue() instanceof QName);
- QName qName = (QName) lf11.getValue();
- assertEquals(resultLocalName, qName.getLocalName());
- assertEquals(resultNamespace, qName.getNamespace().toString());
-
- }
-
- private SimpleNode<?> getLf11(CompositeNode compositeNode) {
- assertEquals("cont", compositeNode.getNodeType().getLocalName());
-
- List<Node<?>> childs = compositeNode.getChildren();
- assertEquals(1, childs.size());
- Node<?> nd = childs.iterator().next();
- assertTrue(nd instanceof CompositeNode);
- assertEquals("cont1", nd.getNodeType().getLocalName());
-
- childs = ((CompositeNode) nd).getChildren();
- SimpleNode<?> lf11 = null;
- for (Node<?> child : childs) {
- assertTrue(child instanceof SimpleNode);
- if (child.getNodeType().getLocalName().equals("lf11")) {
- lf11 = (SimpleNode<?>) child;
- }
- }
- assertNotNull(lf11);
- return lf11;
+ assertNotNull(lf2);
+ assertTrue(lf2.getValue() instanceof String);
+ assertEquals("121", (String) lf2.getValue());
}
}
--- /dev/null
+module invalid-top-level-element {
+ namespace "invalid:top:level:element";
+
+ prefix "intoleel";
+ revision 2013-12-17 {
+ }
+
+
+ leaf lf {
+ type string;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+module simple-data-types {
+ namespace "simple:data:types";
+
+ prefix "smpdtp";
+ revision 2013-11-12 {
+ }
+
+ identity iden {
+ }
+
+ typedef tpdfempty {
+ type empty;
+ }
+
+ typedef tpdfbit {
+ type bits {
+ bit b1;
+ bit b2;
+ bit b3;
+ }
+ }
+
+ typedef tpdfun4 {
+ type boolean;
+ }
+
+ typedef tpdfun3 {
+ type union {
+ type tpdfbit;
+ type tpdfempty;
+ }
+ }
+
+ typedef tpdfun2 {
+ type union {
+ type tpdfun3;
+ type tpdfun4;
+ }
+ }
+
+ typedef tpdfun1 {
+ type union {
+ type uint8;
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+ }
+
+ container cont {
+ leaf lfnint8Min {
+ type int8;
+ }
+ leaf lfnint8Max {
+ type int8;
+ }
+ leaf lfnint16Min {
+ type int16;
+ }
+ leaf lfnint16Max {
+ type int16;
+ }
+ leaf lfnint32Min {
+ type int32;
+ }
+ leaf lfnint32Max {
+ type int32;
+ }
+ leaf lfnint64Min {
+ type int64;
+ }
+ leaf lfnint64Max {
+ type int64;
+ }
+
+ leaf lfnuint8Max {
+ type uint8;
+ }
+ leaf lfnuint16Max {
+ type uint16;
+ }
+ leaf lfnuint32Max {
+ type uint32;
+ }
+ leaf lfuint64Max {
+ type uint64;
+ }
+ leaf lfstr {
+ type string;
+ }
+ leaf lfstr1 {
+ type string;
+ }
+ leaf lfbool1 {
+ type boolean;
+ }
+ leaf lfbool2 {
+ type boolean;
+ }
+ leaf lfbool3 {
+ type boolean;
+ }
+ leaf lfdecimal1 {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+ leaf lfdecimal2 {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+ leaf lfdecimal3 {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+
+ leaf lfdecimal4 {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+
+
+ leaf lfdecimal6 {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+
+ leaf lfenum {
+ type enumeration {
+ enum enum1;
+ enum enum2;
+ enum enum3;
+ enum enum4;
+ }
+ }
+
+ leaf lfbits {
+ type bits {
+ bit bit1;
+ bit bit2;
+ bit bit3;
+ bit bit4;
+ }
+ }
+
+ leaf lfbinary {
+ type binary;
+ }
+
+ leaf lfref1 { //reference to string type
+ type leafref {
+ path "../lfstr";
+ }
+ }
+
+ leaf lfref2 { //reference to number type
+ type leafref {
+ path "../lfnint8Max";
+ }
+ }
+
+ leaf lfempty {
+ type empty;
+ }
+
+ leaf lfunion1 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+ leaf lfunion2 {
+ type union {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ type string;
+ }
+ }
+
+ leaf lfunion3 {
+ type union {
+ type empty;
+ type string;
+ }
+ }
+
+ leaf lfunion4 {
+ type union {
+ type boolean;
+ type string;
+ }
+ }
+
+ leaf lfunion5 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+
+ leaf lfunion6 {
+ type union {
+ type uint16;
+ type empty;
+ }
+ }
+
+ leaf lfunion7 {
+ type tpdfun3;
+ }
+
+ leaf lfunion8 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+
+ leaf lfunion9 {
+ type union {
+ type uint16;
+ type boolean;
+ }
+ }
+
+ leaf lfunion10 {
+ type union {
+ type bits {
+ bit bt1;
+ bit bt2;
+ }
+ type boolean;
+ }
+ }
+
+ leaf lfunion11 {
+ type union {
+ type tpdfun1;
+ type tpdfun2;
+ }
+ }
+
+ leaf lfunion12 {
+ type tpdfun2;
+ }
+
+ leaf lfunion13 {
+ type tpdfbit;
+ }
+
+ leaf lfunion14 {
+ type union {
+ type enumeration {
+ enum zero;
+ enum one;
+ }
+ type uint16;
+ }
+ }
+
+ leaf identityref1 {
+ type identityref {
+ base iden;
+ }
+ }
+
+
+ }
+}
\ No newline at end of file
--- /dev/null
+module module-with-choice {
+ namespace "module:with:choice";
+
+ prefix "mowicho";
+
+ revision 2013-12-18 {
+ }
+
+
+ container cont {
+ choice choA {
+ case caA1 {
+ leaf lf1 {
+ type string;
+ }
+ }
+ case caA2 {
+ leaf lf2 {
+ type string;
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
}
}
+ leaf lfLfref {
+ type leafref {
+ path "/cont/lfBoolean";
+ }
+ }
+
}
}
\ No newline at end of file
--- /dev/null
+{
+ "test-module:input":{
+ "cont":{
+ "cont1":{
+ "lf11":"lf1 data",
+ "lf12":"lf2 data"
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<input xmlns="test:module">
+ <cont>
+ <cont1>
+ <lf11>lf1 data</lf11>
+ <lf12>lf2 data</lf12>
+ </cont1>
+ </cont>
+</input>
\ No newline at end of file
--- /dev/null
+<cont xmlns="test:module">
+ <cont1>
+ <lf11>lf1 data</lf11>
+ <lf12>lf2 data</lf12>
+ </cont1>
+</cont>
--- /dev/null
+module test-module {
+ namespace "test:module";
+ prefix tstmod;
+
+ revision 2014-01-09 {
+ }
+
+ container cont {
+ container cont1 {
+ leaf lf11 {
+ type string;
+ }
+ leaf lf12 {
+ type string;
+ }
+ }
+ }
+
+
+ rpc rpc-test {
+ input {
+ container cont {
+ container cont1 {
+ leaf lf11 {
+ type string;
+ }
+ leaf lf12 {
+ type string;
+ }
+ }
+ }
+ }
+ output {
+ container cont-output {
+ }
+ }
+
+ }
+
+
+
+
+}
\ No newline at end of file
leaf beer {
type string;
}
+ container nonalcoholic {
+ leaf beer {
+ type string;
+ }
+ }
}
case late-night {
leaf chocolate {
--- /dev/null
+{
+ "cont":{
+ "lf1":121,
+ "lf2":121
+ }
+}
\ No newline at end of file
--- /dev/null
+module leafref-module {
+ namespace "leafref:module";
+
+ prefix "lfrfmo";
+ revision 2013-11-18 {
+ }
+
+ container cont {
+ leaf lf1 {
+ type int32;
+ }
+ leaf lf2 {
+ type leafref {
+ path "/cont/lf1";
+ }
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+fffff
\ No newline at end of file
--- /dev/null
+module normalize-node-module {
+ namespace "normalize:node:module";
+
+ prefix "nonomo";
+ revision 2014-01-09 {
+ }
+
+ container cont {
+ leaf lf1 {
+ type int32;
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+{
+ "interface":[
+ {
+ "name":"eth0",
+ "type":"ethernetCsmacd",
+ "enabled":false,
+ "description": "some interface"
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "ietf-interfaces:interfaces":{
+ "interface":[
+ {
+ "name":"eth0",
+ "type":"ethernetCsmacd",
+ "enabled":false,
+ "description": "some interface"
+ }
+ ]
+ }
+}
\ No newline at end of file
--- /dev/null
+<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces" >
+ <interface>
+ <name>eth0</name>
+ <type>ethernetCsmacd</type>
+ <enabled>false</enabled>
+ <description>some interface</description>
+ </interface>
+</interfaces>
\ No newline at end of file
--- /dev/null
+<interfaces xmlns="urn:ietf:params:xml:ns:yang:test-interface">
+ <interface>
+ <name>eth0</name>
+ <type>ethernetCsmacd</type>
+ <enabled>false</enabled>
+ </interface>
+</interfaces>
+
--- /dev/null
+<interface>
+ <name>eth0</name>
+ <type>ethernetCsmacd</type>
+ <enabled>false</enabled>
+</interface>
--- /dev/null
+<class xmlns="urn:ietf:params:xml:ns:yang:test-interface2">
+ <student>
+ <name>Thomas</name>
+ <age>23</age>
+ </student>
+</class>
--- /dev/null
+module test-interface {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:test-interface";
+ prefix "sn";
+
+ description
+ "test file";
+
+ revision "2014-07-01" {
+ description
+ "Initial revision";
+ reference "will be defined";
+ }
+
+ container interfaces {
+ list interface {
+ key "name";
+
+ leaf name {
+ type string;
+ }
+ leaf type {
+ type string;
+ }
+ leaf enabled {
+ type string;
+ }
+ }
+ }
+}
--- /dev/null
+module test-interface2 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:test-interface2";
+ prefix "snn";
+
+ description
+ "test file";
+
+ revision "2014-08-01" {
+ description
+ "Initial revision";
+ reference "will be defined";
+ }
+
+ container class {
+ list student {
+ key "name";
+
+ leaf name {
+ type string;
+ }
+ leaf age {
+ type string;
+ }
+ }
+ }
+}
--- /dev/null
+module module1 {
+ namespace "module:one";
+
+ prefix "m1";
+ revision 2014-01-17 {
+ }
+
+ container cont_m1 {
+ leaf lf1_m1 {
+ type string;
+ }
+ }
+ container contB_m1 {
+ }
+
+}
\ No newline at end of file
--- /dev/null
+module module2 {
+ namespace "module:two";
+
+ prefix "m2";
+ revision 2014-01-17 {
+ }
+
+ container cont_m2 {
+ leaf lf1_m2 {
+ type string;
+ }
+ }
+ container contB_m2 {
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+module leafref-module {
+ namespace "leafref:module";
+
+ prefix "lfrfmo";
+ revision 2013-11-18 {
+ }
+
+ container cont {
+ leaf lf1 {
+ type int32;
+ }
+ leaf lf2 {
+ type leafref {
+ path "/cont/lf1";
+ }
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+<cont>
+ <lf1>121</lf1>
+ <lf2>121</lf2>
+</cont>
\ No newline at end of file
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-/*
- * TODO: Handle multipart messages with following flag true
- * OFPMPF_REPLY_MORE = 1 << 0
- * Better accumulate all the messages and update local cache
- * and configurational data store
- */
+
package org.opendaylight.controller.md.statistics.manager;
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
for (Node targetNode : targetNodes){
- InstanceIdentifier<Node> targetInstanceId = InstanceIdentifier.builder(Nodes.class).child(Node.class,targetNode.getKey()).toInstance();
- NodeRef targetNodeRef = new NodeRef(targetInstanceId);
-
- System.out.println("ANIL: Target Node object ::"+targetNode.toString());
-
- System.out.println("ANIL: FlowCapableNode augmentations ::"+targetNode.getAugmentation(FlowCapableNode.class));
+ if(targetNode.getAugmentation(FlowCapableNode.class) != null){
+
+ spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
+
+ InstanceIdentifier<Node> targetInstanceId = InstanceIdentifier.builder(Nodes.class).child(Node.class,targetNode.getKey()).toInstance();
+
+ NodeRef targetNodeRef = new NodeRef(targetInstanceId);
- try {
+ try{
+ sendAggregateFlowsStatsFromAllTablesRequest(targetNode.getKey());
- sendAggregateFlowsStatsFromAllTablesRequest(targetNode.getKey());
+ sendAllFlowsStatsFromAllTablesRequest(targetNodeRef);
- sendAllFlowsStatsFromAllTablesRequest(targetNodeRef);
-
- sendAllPortStatisticsRequest(targetNodeRef);
+ sendAllNodeConnectorsStatisticsRequest(targetNodeRef);
- sendAllFlowTablesStatisticsRequest(targetNodeRef);
+ sendAllFlowTablesStatisticsRequest(targetNodeRef);
- sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
-
- }catch(Exception e){
- spLogger.error("Exception occured while sending statistics requests : {}",e);
- }
-
- if(targetNode.getAugmentation(FlowCapableNode.class) != null){
-
- spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
-
- try{
- sendAllGroupStatisticsRequest(targetNodeRef);
- Thread.sleep(1000);
- sendAllMeterStatisticsRequest(targetNodeRef);
- Thread.sleep(1000);
- sendGroupDescriptionRequest(targetNodeRef);
- Thread.sleep(1000);
- sendMeterConfigStatisticsRequest(targetNodeRef);
- Thread.sleep(1000);
+ sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
+
+ sendAllGroupStatisticsRequest(targetNodeRef);
+
+ sendAllMeterStatisticsRequest(targetNodeRef);
+
+ sendGroupDescriptionRequest(targetNodeRef);
+
+ sendMeterConfigStatisticsRequest(targetNodeRef);
}catch(Exception e){
spLogger.error("Exception occured while sending statistics requests : {}", e);
}
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.AGGR_FLOW);
}
+ }else{
+ spLogger.debug("No details found in data store for flow tables associated with Node {}",targetNodeKey);
}
-
- //Note: Just for testing, because i am not able to fetch table list from datastore
- // Bug-225 is raised for investigation.
-
-// spLogger.info("Send aggregate stats request for flow table {} to node {}",1,targetNodeKey);
-// GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
-// new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
-//
-// input.setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).toInstance()));
-// input.setTableId(new TableId((short)1));
-// Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> response =
-// flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build());`
-//
-// multipartMessageManager.setTxIdAndTableIdMapEntry(response.get().getResult().getTransactionId(), (short)1);
-
}
- private void sendAllPortStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
+ private void sendAllNodeConnectorsStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
- final GetAllPortsStatisticsInputBuilder input = new GetAllPortsStatisticsInputBuilder();
+ final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
input.setNode(targetNode);
- Future<RpcResult<GetAllPortsStatisticsOutput>> response =
- portStatsService.getAllPortsStatistics(input.build());
+ Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> response =
+ portStatsService.getAllNodeConnectorsStatistics(input.build());
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.ALL_PORT);
private List<Short> getTablesFromNode(NodeKey nodeKey){
InstanceIdentifier<FlowCapableNode> nodesIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class,nodeKey).augmentation(FlowCapableNode.class).toInstance();
- FlowCapableNode node = (FlowCapableNode)dps.readConfigurationData(nodesIdentifier);
+ FlowCapableNode node = (FlowCapableNode)dps.readOperationalData(nodesIdentifier);
List<Short> tablesId = new ArrayList<Short>();
if(node != null && node.getTable()!=null){
spLogger.info("Number of tables {} supported by node {}",node.getTable().size(),nodeKey);
*/
package org.opendaylight.controller.md.statistics.manager;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.ConcurrentMap;
-
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowTableStatisticsUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.NodeConnectorStatisticsUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericQueueStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.PortStatisticsUpdate;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+
/**
* Class implement statistics manager related listener interface and augment all the
* received statistics data to data stores.
.child(Flow.class,existingFlow.getKey()).toInstance();
flowBuilder.setKey(existingFlow.getKey());
flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
- sucLogger.debug("Found matching flow in the datastore, augmenting statistics");
+ sucLogger.info("Found matching flow in the datastore, augmenting statistics");
foundOriginalFlow = true;
it.putOperationalData(flowRef, flowBuilder.build());
it.commit();
}
if(!foundOriginalFlow){
- sucLogger.info("Associated original flow is not found in data store. Augmenting flow in operational data st");
- //TODO: Temporary fix: format [ 0+tableid+0+unaccounted flow counter]
- long flowKey = Long.getLong(new String("0"+Short.toString(tableId)+"0"+Integer.toString(this.unaccountedFlowsCounter)));
- FlowKey newFlowKey = new FlowKey(new FlowId(flowKey));
+ sucLogger.debug("Associated original flow is not found in data store. Augmenting flow in operational data store");
+ //TODO: Temporary fix: format [ 1+tableid+1+unaccounted flow counter]
+ long flowKey = Long.parseLong(new String("1"+Short.toString(tableId)+"1"+Integer.toString(this.unaccountedFlowsCounter)));
+ FlowKey newFlowKey = new FlowKey(new FlowId(Long.toString(flowKey)));
InstanceIdentifier<Flow> flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
.augmentation(FlowCapableNode.class)
.child(Table.class, new TableKey(tableId))
}
@Override
- public void onPortStatisticsUpdate(PortStatisticsUpdate notification) {
+ public void onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
//Check if response is for the request statistics-manager sent.
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
}
- @Override
- public void onFlowStatisticsUpdated(FlowStatisticsUpdated notification) {
- // TODO Auto-generated method stub
- //TODO: Depricated, will clean it up once sal-compatibility is fixed.
- //Sal-Compatibility code usage this notification event.
-
- }
-
- @Override
- public void onFlowTableStatisticsUpdated(FlowTableStatisticsUpdated notification) {
- // TODO Auto-generated method stub
- //TODO: Need to implement it yet
-
- }
-
- @Override
- public void onNodeConnectorStatisticsUpdated(NodeConnectorStatisticsUpdated notification) {
- // TODO Auto-generated method stub
- //TODO: Need to implement it yet
-
- }
-
private NodeRef getNodeRef(NodeKey nodeKey){
InstanceIdentifierBuilder<?> builder = InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeKey);
return new NodeRef(builder.toInstance());
if (storedFlow.getMatch() != null) {
return false;
}
- } else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
- return false;
- }
- if (statsFlow.getCookie()== null) {
- if (storedFlow.getCookie()!= null) {
- return false;
- }
- } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
+ } //else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
+ else if(!matchEquals(statsFlow.getMatch(), storedFlow.getMatch())) {
return false;
}
if (statsFlow.getHardTimeout() == null) {
}
return true;
}
+
+ /**
+ * Explicit equals method to compare the 'match' for flows stored in the data-stores and flow fetched from the switch.
+ * Usecase: e.g If user don't set any ethernet source and destination address for match,data store will store null for
+ * these address.
+ * e.g [_ethernetMatch=EthernetMatch [_ethernetDestination=null, _ethernetSource=null, _ethernetType=
+ * EthernetType [_type=EtherType [_value=2048], _mask=null, augmentation=[]]
+ *
+ * But when you fetch the flows from switch, openflow driver library converts all zero bytes of mac address in the
+ * message stream to 00:00:00:00:00:00. Following string shows how library interpret the zero mac address bytes and
+ * eventually when translator convert it to MD-SAL match, this is how it looks
+ * [_ethernetDestination=EthernetDestination [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]],
+ * _ethernetSource=EthernetSource [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]],
+ * _ethernetType=EthernetType [_type=EtherType [_value=2048], _mask=null, augmentation=[]]
+ *
+ * Similarly for inPort, if user/application don't set any value for it, FRM will store null value for it in data store.
+ * When we fetch the same flow (with its statistics) from switch, plugin converts its value to openflow:X:0.
+ * e.g _inPort=Uri [_value=openflow:1:0]
+ *
+ * So this custom equals method add additional check to take care of these scenario, in case any match element is null in data-store-flow, but not
+ * in the flow fetched from switch.
+ *
+ * @param statsFlow
+ * @param storedFlow
+ * @return
+ */
+ public boolean matchEquals(Match statsFlow, Match storedFlow) {
+ if (statsFlow == storedFlow) {
+ return true;
+ }
+ if (storedFlow.getClass() != statsFlow.getClass()) {
+ return false;
+ }
+ if (storedFlow.getEthernetMatch() == null) {
+ if (statsFlow.getEthernetMatch() != null) {
+ if(!statsFlow.getEthernetMatch().getEthernetDestination().getAddress().getValue().equals("00:00:00:00:00:00") ||
+ !statsFlow.getEthernetMatch().getEthernetSource().getAddress().getValue().equals("00:00:00:00:00:00")){
+ return false;
+ }
+ }
+ } else if(!EthernetMatchEquals(statsFlow.getEthernetMatch(),storedFlow.getEthernetMatch())) {
+ return false;
+ }
+ if (storedFlow.getIcmpv4Match()== null) {
+ if (statsFlow.getIcmpv4Match() != null) {
+ return false;
+ }
+ } else if(!storedFlow.getIcmpv4Match().equals(statsFlow.getIcmpv4Match())) {
+ return false;
+ }
+ if (storedFlow.getIcmpv6Match() == null) {
+ if (statsFlow.getIcmpv6Match() != null) {
+ return false;
+ }
+ } else if(!storedFlow.getIcmpv6Match().equals(statsFlow.getIcmpv6Match())) {
+ return false;
+ }
+ if (storedFlow.getInPhyPort() == null) {
+ if (statsFlow.getInPhyPort() != null) {
+ return false;
+ }
+ } else if(!storedFlow.getInPhyPort().equals(statsFlow.getInPhyPort())) {
+ return false;
+ }
+ if (storedFlow.getInPort()== null) {
+ if (statsFlow.getInPort() != null) {
+ String[] portArr = statsFlow.getInPort().getValue().split(":");
+ if(portArr.length >= 3){
+ if(Integer.parseInt(portArr[2]) != 0){
+ return false;
+ }
+ }
+ }
+ } else if(!storedFlow.getInPort().equals(statsFlow.getInPort())) {
+ return false;
+ }
+ if (storedFlow.getIpMatch()== null) {
+ if (statsFlow.getIpMatch() != null) {
+ return false;
+ }
+ } else if(!storedFlow.getIpMatch().equals(statsFlow.getIpMatch())) {
+ return false;
+ }
+ if (storedFlow.getLayer3Match()== null) {
+ if (statsFlow.getLayer3Match() != null) {
+ Ipv4Match ipv4Match = (Ipv4Match)statsFlow.getLayer3Match();
+ if(!ipv4Match.getIpv4Source().getValue().equals("0.0.0.0/0") ||
+ !ipv4Match.getIpv4Destination().getValue().equals("0.0.0.0/0")){
+ return false;
+ }
+ }
+ } else if(!storedFlow.getLayer3Match().equals(statsFlow.getLayer3Match())) {
+ return false;
+ }
+ if (storedFlow.getLayer4Match()== null) {
+ if (statsFlow.getLayer4Match() != null) {
+ TcpMatch tcpMatch = (TcpMatch)statsFlow.getLayer4Match();
+ if(!tcpMatch.getTcpDestinationPort().getValue().equals(0) ||
+ !tcpMatch.getTcpSourcePort().getValue().equals(0)){
+ return false;
+ }
+ }
+ } else if(!storedFlow.getLayer4Match().equals(statsFlow.getLayer4Match())) {
+ return false;
+ }
+ if (storedFlow.getMetadata() == null) {
+ if (statsFlow.getMetadata() != null) {
+ return false;
+ }
+ } else if(!storedFlow.getMetadata().equals(statsFlow.getMetadata())) {
+ return false;
+ }
+ if (storedFlow.getProtocolMatchFields() == null) {
+ if (statsFlow.getProtocolMatchFields() != null) {
+ return false;
+ }
+ } else if(!storedFlow.getProtocolMatchFields().equals(statsFlow.getProtocolMatchFields())) {
+ return false;
+ }
+ if (storedFlow.getTunnel()== null) {
+ if (statsFlow.getTunnel() != null) {
+ return false;
+ }
+ } else if(!storedFlow.getTunnel().equals(statsFlow.getTunnel())) {
+ return false;
+ }
+ if (storedFlow.getVlanMatch()== null) {
+ if (statsFlow.getVlanMatch() != null) {
+ VlanMatch vlanMatch = statsFlow.getVlanMatch();
+ if(!vlanMatch.getVlanId().getVlanId().getValue().equals(0) ||
+ !vlanMatch.getVlanPcp().getValue().equals((short)0)){
+ return false;
+ }
+ }
+ } else if(!storedFlow.getVlanMatch().equals(statsFlow.getVlanMatch())) {
+ return false;
+ }
+ return true;
+ }
+ public boolean EthernetMatchEquals(EthernetMatch statsEtherMatch, EthernetMatch storedEtherMatch) {
+ if (statsEtherMatch == storedEtherMatch) {
+ return true;
+ }
+ if (storedEtherMatch.getEthernetDestination()== null) {
+ if (statsEtherMatch.getEthernetDestination() != null) {
+ if(!statsEtherMatch.getEthernetDestination().getAddress().getValue().equals("00:00:00:00:00:00")){
+ return false;
+ }
+ }
+ } else if(!storedEtherMatch.getEthernetDestination().equals(statsEtherMatch.getEthernetDestination())) {
+ return false;
+ }
+ if (storedEtherMatch.getEthernetSource() == null) {
+ if (statsEtherMatch.getEthernetSource() != null) {
+ if(!statsEtherMatch.getEthernetSource().getAddress().getValue().equals("00:00:00:00:00:00")){
+ return false;
+ }
+ }
+ } else if(!storedEtherMatch.getEthernetSource().equals(statsEtherMatch.getEthernetSource())) {
+ return false;
+ }
+ if (storedEtherMatch.getEthernetType() == null) {
+ if (statsEtherMatch.getEthernetType() != null) {
+ if(!statsEtherMatch.getEthernetType().getType().getValue().equals(0)){
+ return false;
+ }
+ }
+ } else if(!storedEtherMatch.getEthernetType().equals(statsEtherMatch.getEthernetType())) {
+ return false;
+ }
+ return true;
+ }
}
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-json</artifactId>
- <version>${jersey.version}</version>
- </dependency>
+
<dependency>
<groupId>eclipselink</groupId>
<artifactId>javax.resource</artifactId>
// Northbound bundles
mavenBundle("org.opendaylight.controller", "commons.northbound").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-jaxrs").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-xc").versionAsInProject(),
+
+ mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.module", "jackson-module-jaxb-annotations").versionAsInProject(),
+
mavenBundle("org.codehaus.jettison", "jettison").versionAsInProject(),
mavenBundle("commons-io", "commons-io").versionAsInProject(),
mavenBundle("com.sun.jersey", "jersey-client").versionAsInProject(),
mavenBundle("com.sun.jersey", "jersey-server").versionAsInProject().startLevel(2),
mavenBundle("com.sun.jersey", "jersey-core").versionAsInProject().startLevel(2),
- mavenBundle("com.sun.jersey", "jersey-json").versionAsInProject().startLevel(2),
-
junitBundles());
}
--- /dev/null
+<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.0-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <groupId>org.opendaylight.controller.md</groupId>
+ <artifactId>topology-lldp-discovery</artifactId>
+ <packaging>bundle</packaging>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ </scm>
+ <properties>
+ <guava.version>14.0.1</guava.version>
+ <xtend.version>2.4.3</xtend.version>
+ <bundle.plugin.version>2.4.0</bundle.plugin.version>
+ <maven.clean.plugin.version>2.5</maven.clean.plugin.version>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-service</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-base</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-management</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-inventory</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.lib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>equinoxSDK381</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>3.8.1.v20120830-144521</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>org.opendaylight.md.controller.topology.lldp.LLDPActivator</Bundle-Activator>
+ <Export-Package>org.opendaylight.md.controller.topology.lldp.utils</Export-Package>
+ <Embed-Dependency>commons-lang</Embed-Dependency>>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ </instructions>
+ <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>xtend-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>${basedir}/src/main/xtend-gen</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.md.controller.topology.lldp
+
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.osgi.framework.BundleContext
+
+class LLDPActivator extends AbstractBindingAwareProvider {
+
+ static var LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider();
+
+ override onSessionInitiated(ProviderContext session) {
+ provider.dataService = session.getSALService(DataProviderService)
+ provider.notificationService = session.getSALService(NotificationProviderService)
+ provider.start();
+ }
+
+ override protected stopImpl(BundleContext context) {
+ provider.close();
+ }
+
+}
--- /dev/null
+package org.opendaylight.md.controller.topology.lldp;
+
+import org.opendaylight.md.controller.topology.lldp.utils.LLDPDiscoveryUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscoveredBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class LLDPDiscoveryListener implements PacketProcessingListener {
+ static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryListener.class);
+
+ private LLDPDiscoveryProvider manager;
+
+ LLDPDiscoveryListener(LLDPDiscoveryProvider manager) {
+ this.manager = manager;
+ }
+
+ public void onPacketReceived(PacketReceived lldp) {
+ NodeConnectorRef src = LLDPDiscoveryUtils.lldpToNodeConnectorRef(lldp.getPayload());
+ if(src != null) {
+ LinkDiscoveredBuilder ldb = new LinkDiscoveredBuilder();
+ ldb.setDestination(lldp.getIngress());
+ ldb.setSource(new NodeConnectorRef(src));
+ LinkDiscovered ld = ldb.build();
+
+ manager.getNotificationService().publish(ld);
+ LLDPLinkAger.getInstance().put(ld);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.md.controller.topology.lldp
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.binding.NotificationListener
+import org.slf4j.LoggerFactory
+
+class LLDPDiscoveryProvider implements AutoCloseable {
+
+
+ static val LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider);
+
+ @Property
+ DataProviderService dataService;
+
+ @Property
+ NotificationProviderService notificationService;
+
+ val LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(this);
+
+ Registration<NotificationListener> listenerRegistration
+
+ def void start() {
+ listenerRegistration = notificationService.registerNotificationListener(commiter);
+ LLDPLinkAger.instance.manager = this;
+ LOG.info("LLDPDiscoveryListener Started.");
+
+ }
+
+ override close() {
+ LOG.info("LLDPDiscoveryListener stopped.");
+ listenerRegistration?.close();
+ LLDPLinkAger.instance.close();
+ }
+
+}
+
+
--- /dev/null
+package org.opendaylight.md.controller.topology.lldp;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Timer;
+import java.util.Map.Entry;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.md.controller.topology.lldp.utils.LLDPDiscoveryUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemovedBuilder;
+
+
+public class LLDPLinkAger {
+ private static final LLDPLinkAger instance = new LLDPLinkAger();
+ private Map<LinkDiscovered,Date> linkToDate = new ConcurrentHashMap<LinkDiscovered,Date>();
+ private LLDPDiscoveryProvider manager;
+ private Timer timer = new Timer();
+
+ public LLDPDiscoveryProvider getManager() {
+ return manager;
+ }
+ public void setManager(LLDPDiscoveryProvider manager) {
+ this.manager = manager;
+ }
+ private LLDPLinkAger() {
+ timer.schedule(new LLDPAgingTask(), 0,LLDPDiscoveryUtils.LLDP_INTERVAL);
+ }
+ public static LLDPLinkAger getInstance() {
+ return instance;
+ }
+
+ public void put(LinkDiscovered link) {
+ Date expires = new Date();
+ expires.setTime(expires.getTime() + LLDPDiscoveryUtils.LLDP_EXPIRATION_TIME);
+ linkToDate.put(link, expires);
+ }
+
+ public void close() {
+ timer.cancel();
+ }
+
+ private class LLDPAgingTask extends TimerTask {
+
+ @Override
+ public void run() {
+ for (Entry<LinkDiscovered,Date> entry : linkToDate.entrySet()) {
+ LinkDiscovered link = entry.getKey();
+ Date expires = entry.getValue();
+ Date now = new Date();
+ if(now.after(expires)) {
+ if(getInstance().getManager() != null) {
+ LinkRemovedBuilder lrb = new LinkRemovedBuilder(link);
+ getInstance().getManager().getNotificationService().publish(lrb.build());
+ linkToDate.remove(link);
+ }
+ }
+ }
+
+ }
+
+ }
+}
+
--- /dev/null
+package org.opendaylight.md.controller.topology.lldp.utils;
+
+import java.nio.charset.Charset;
+
+import org.opendaylight.controller.sal.packet.Ethernet;
+import org.opendaylight.controller.sal.packet.LLDP;
+import org.opendaylight.controller.sal.packet.LLDPTLV;
+import org.opendaylight.controller.sal.utils.NetUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LLDPDiscoveryUtils {
+ static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryUtils.class);
+
+ public static final Long LLDP_INTERVAL = (long) (1000*5); // Send LLDP every five seconds
+ public static final Long LLDP_EXPIRATION_TIME = LLDP_INTERVAL*3; // Let up to three intervals pass before we decide we are expired.
+
+ public static String macToString(byte[] mac) {
+ StringBuilder b = new StringBuilder();
+ for (int i = 0; i < mac.length; i++) {
+ b.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
+ }
+
+ return b.toString();
+ }
+
+ public static NodeConnectorRef lldpToNodeConnectorRef(byte[] payload) {
+ Ethernet ethPkt = new Ethernet();
+ try {
+ ethPkt.deserialize(payload, 0,payload.length * NetUtils.NumBitsInAByte);
+ } catch (Exception e) {
+ LOG.warn("Failed to decode LLDP packet {}", e);
+ }
+
+ if (ethPkt.getPayload() instanceof LLDP) {
+ LLDP lldp = (LLDP) ethPkt.getPayload();
+
+ try {
+ NodeId srcNodeId = null;
+ NodeConnectorId srcNodeConnectorId = null;
+ for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
+ if (lldptlv.getType() == LLDPTLV.TLVType.Custom.getValue()) {
+ srcNodeConnectorId = new NodeConnectorId(LLDPTLV.getCustomString(lldptlv.getValue(), lldptlv.getLength()));
+ }
+ if (lldptlv.getType() == LLDPTLV.TLVType.SystemName.getValue()) {
+ String srcNodeIdString = new String(lldptlv.getValue(),Charset.defaultCharset());
+ srcNodeId = new NodeId(srcNodeIdString);
+ }
+ }
+ if(srcNodeId != null && srcNodeConnectorId != null) {
+ InstanceIdentifier<NodeConnector> srcInstanceId = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class,new NodeKey(srcNodeId))
+ .child(NodeConnector.class, new NodeConnectorKey(srcNodeConnectorId))
+ .toInstance();
+ return new NodeConnectorRef(srcInstanceId);
+ }
+ } catch (Exception e) {
+ LOG.warn("Caught exception ", e);
+ }
+ }
+ return null;
+ }
+}
</dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-topology-view</artifactId>
+ <artifactId>model-topology</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
- <Bundle-Activator>org.opendaylight.controller.md.inventory.manager.InventoryActivator</Bundle-Activator>
- <Private-Package>org.opendaylight.controller.md.inventory.manager</Private-Package>
+ <Bundle-Activator>org.opendaylight.md.controller.topology.manager.FlowCapableTopologyProvider</Bundle-Activator>
+ <Private-Package>org.opendaylight.md.controller.topology.manager</Private-Package>
</instructions>
</configuration>
</plugin>
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.SourceBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.DestinationBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.LinkId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnectorBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
class FlowCapableNodeMapping {
(ref?.value?.path?.get(2) as IdentifiableItem<NodeConnector,NodeConnectorKey>).key
}
- static def TerminationPoint toTerminationPoint(NodeConnectorUpdated updated) {
- val it = new TerminationPointBuilder
- key = new TerminationPointKey(new TpId(updated.id));
- return it.build()
- }
-
static def NodeId toToplogyNodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId) {
return new NodeId(nodeId);
}
static def toTerminationPointId(NodeConnectorId id) {
return new TpId(id);
}
+
+ static def toTopologyNode(NodeId nodeId,NodeRef invNodeRef) {
+ val nb = new NodeBuilder();
+ nb.setNodeId(nodeId)
+ val inb = new InventoryNodeBuilder
+ inb.setInventoryNodeRef(invNodeRef)
+ nb.addAugmentation(InventoryNode,inb.build)
+ return nb.build();
+ }
+
+ static def toTerminationPoint(TpId id, NodeConnectorRef invNodeConnectorRef) {
+ val tpb = new TerminationPointBuilder
+ tpb.setTpId(id);
+ val incb = new InventoryNodeConnectorBuilder
+ incb.setInventoryNodeConnectorRef(invNodeConnectorRef)
+ tpb.addAugmentation(InventoryNodeConnector,incb.build())
+ return tpb.build();
+ }
+
+ static def toTopologyLink(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link) {
+ val sb = new SourceBuilder();
+ sb.setSourceNode(link.source.nodeKey.id.toToplogyNodeId)
+ sb.setSourceTp(link.source.nodeConnectorKey.id.toTerminationPointId)
+ val db = new DestinationBuilder();
+ db.setDestNode(link.destination.nodeKey.id.toToplogyNodeId)
+ db.setDestTp(link.destination.nodeConnectorKey.id.toTerminationPointId)
+ val lb = new LinkBuilder();
+ lb.setSource(sb.build())
+ lb.setDestination(db.build());
+ lb.setLinkId(new LinkId(lb.source.sourceTp.value))
+ return lb.build();
+ }
}
package org.opendaylight.md.controller.topology.manager
+import com.google.common.collect.FluentIterable
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyBuilder
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
-
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+
import static extension org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.*
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
-import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
-import com.google.common.collect.FluentIterable
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
class FlowCapableTopologyExporter implements //
FlowTopologyDiscoveryListener, //
OpendaylightInventoryListener //
{
- var TopologyKey topology;
+ var TopologyKey topology = new TopologyKey(new TopologyId("flow:1"));
@Property
var DataProviderService dataService;
+
+ def start() {
+ val tb = new TopologyBuilder();
+ tb.setKey(topology);
+ val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,topology).toInstance;
+ val top = tb.build();
+ val it = dataService.beginTransaction
+ putOperationalData(path,top);
+ commit()
+ }
override onNodeRemoved(NodeRemoved notification) {
- val invNodeKey = notification.nodeRef.nodeKey
- val tpNodeId = invNodeKey.id.toToplogyNodeId()
- val tpNodeInstance = notification.nodeRef.toNodeIdentifier()
+ val nodeId = notification.nodeRef.nodeKey.id.toToplogyNodeId()
+ val nodeInstance = notification.nodeRef.toNodeIdentifier()
val it = dataService.beginTransaction
- removeRuntimeData(tpNodeInstance);
- removeAffectedLinks(tpNodeId)
+ removeOperationalData(nodeInstance);
+ removeAffectedLinks(it,nodeId)
commit()
}
override onNodeUpdated(NodeUpdated notification) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ val fcnu = notification.getAugmentation(FlowCapableNodeUpdated)
+ if(fcnu != null) {
+ val node = notification.id.toToplogyNodeId.toTopologyNode(notification.nodeRef)
+ val path = notification.id.toToplogyNodeId.nodePath;
+ val it = dataService.beginTransaction
+ putOperationalData(path, node);
+ commit()
+ }
}
override onNodeConnectorRemoved(NodeConnectorRemoved notification) {
- val tpRef = notification.nodeConnectorRef.toTerminationPointIdentifier();
+ val tpInstance = notification.nodeConnectorRef.toTerminationPointIdentifier;
+ val tpId = notification.nodeConnectorRef.nodeConnectorKey.id.toTerminationPointId;
val it = dataService.beginTransaction
- removeRuntimeData(tpRef);
+ removeOperationalData(tpInstance);
+ removeAffectedLinks(it,tpId)
commit()
}
override onNodeConnectorUpdated(NodeConnectorUpdated notification) {
- val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId();
- val TerminationPoint point = notification.toTerminationPoint();
- val path = tpPath(nodeId, point.key.tpId);
-
- val it = dataService.beginTransaction
- putRuntimeData(path, point);
- commit()
+ val fcncu = notification.getAugmentation(FlowCapableNodeConnectorUpdated)
+ if(fcncu != null) {
+ val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId;
+ val TerminationPoint point = notification.id.toTerminationPointId.toTerminationPoint(notification.nodeConnectorRef);
+ val path = tpPath(nodeId, point.key.tpId);
+
+ val it = dataService.beginTransaction
+ putOperationalData(path, point);
+ if((fcncu.state != null && fcncu.state.linkDown) || (fcncu.configuration != null && fcncu.configuration.PORTDOWN)) {
+ removeAffectedLinks(it,point.tpId)
+ }
+ commit()
+ }
}
override onLinkDiscovered(LinkDiscovered notification) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ val link = notification.toTopologyLink;
+ val path = link.linkPath;
+ val it = dataService.beginTransaction
+ putOperationalData(path, link);
+ commit()
}
override onLinkOverutilized(LinkOverutilized notification) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ // NOOP
}
override onLinkRemoved(LinkRemoved notification) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
-
+ val path = notification.toTopologyLink.linkPath
+ val it = dataService.beginTransaction
+ removeOperationalData(path);
+ commit()
}
override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ // NOOP
}
def InstanceIdentifier<Node> toNodeIdentifier(NodeRef ref) {
val invNodeKey = ref.nodeKey
val nodeKey = new NodeKey(invNodeKey.id.toToplogyNodeId);
- return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
+ return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
toInstance;
}
private def void removeAffectedLinks(DataModificationTransaction transaction, NodeId id) {
val reader = TypeSafeDataReader.forReader(transaction)
- val topologyPath = InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).toInstance;
+ val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance;
val topologyData = reader.readOperationalData(topologyPath);
if (topologyData === null) {
return;
val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[
source.sourceNode == id || destination.destNode == id].transform [
//
- InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
+ InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
//
]
for(affectedLink : affectedLinkInstances) {
- transaction.removeRuntimeData(affectedLink);
+ transaction.removeOperationalData(affectedLink);
}
}
+ private def void removeAffectedLinks(DataModificationTransaction transaction, TpId id) {
+ val reader = TypeSafeDataReader.forReader(transaction)
+ val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance;
+ val topologyData = reader.readOperationalData(topologyPath);
+ if (topologyData === null) {
+ return;
+ }
+ val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[
+ source.sourceTp == id || destination.destTp == id].transform [
+ //
+ InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
+ //
+ ]
+ for(affectedLink : affectedLinkInstances) {
+ transaction.removeOperationalData(affectedLink);
+ }
+ }
+
+ private def InstanceIdentifier<Node> nodePath(NodeId nodeId) {
+ val nodeKey = new NodeKey(nodeId);
+ return InstanceIdentifier.builder(NetworkTopology)
+ .child(Topology, topology)
+ .child(Node, nodeKey)
+ .toInstance;
+ }
+
private def InstanceIdentifier<TerminationPoint> tpPath(NodeId nodeId, TpId tpId) {
val nodeKey = new NodeKey(nodeId);
val tpKey = new TerminationPointKey(tpId)
- return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
+ return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
child(TerminationPoint, tpKey).toInstance;
}
+
+ private def InstanceIdentifier<Link> linkPath(Link link) {
+ val linkInstanceId = InstanceIdentifier.builder(NetworkTopology)
+ .child(Topology, topology)
+ .child(Link, link.key)
+ .toInstance;
+ return linkInstanceId;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.md.controller.topology.manager
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.binding.NotificationListener
+import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+
+class FlowCapableTopologyProvider extends AbstractBindingAwareProvider implements AutoCloseable {
+
+
+
+ static val LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider);
+
+ @Property
+ DataProviderService dataService;
+
+ @Property
+ NotificationProviderService notificationService;
+
+ val FlowCapableTopologyExporter exporter = new FlowCapableTopologyExporter();
+
+ Registration<NotificationListener> listenerRegistration
+
+ override close() {
+ LOG.info("FlowCapableTopologyProvider stopped.");
+ listenerRegistration?.close();
+ }
+
+ override onSessionInitiated(ProviderContext session) {
+ dataService = session.getSALService(DataProviderService)
+ notificationService = session.getSALService(NotificationProviderService)
+ exporter.setDataService(dataService);
+ exporter.start();
+ listenerRegistration = notificationService.registerNotificationListener(exporter);
+ }
+
+}
+
+
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes;
-
-public class AttributesConstants {
-
- /**
- * Property placed into object names for dependencies to preserve reference name
- */
- public static final String REF_NAME_ON_PROPERTY_KEY = "X-refName";
-}
resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value);
Optional<?> resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue);
resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null;
-
}
public static AttributeConfigElement create(Object nullableDefault, Object value) {
import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeType;
public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingStrategy<?, ? extends OpenType<?>>> {
- private final Services dependencyTracker;
+ private final ServiceRegistryWrapper dependencyTracker;
- public ObjectMapper(Services depTracker) {
+ public ObjectMapper(ServiceRegistryWrapper depTracker) {
this.dependencyTracker = depTracker;
}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import javax.management.ObjectName;
public class ObjectNameAttributeMappingStrategy extends
AbstractAttributeMappingStrategy<ObjectNameAttributeMappingStrategy.MappedDependency, SimpleType<?>> {
- private final Services tracker;
+ private final ServiceRegistryWrapper tracker;
private final String serviceName;
private final String namespace;
- public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, Services dependencyTracker, String serviceName, String namespace) {
+ public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) {
super(openType);
this.tracker = dependencyTracker;
this.serviceName = serviceName;
ObjectName on = (ObjectName) value;
- String expectedRefName = on.getKeyProperty(AttributesConstants.REF_NAME_ON_PROPERTY_KEY);
-
- String refName = expectedRefName == null ? tracker.getRefName(namespace, serviceName, on, Optional.<String> absent())
- : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName));
+ String refName = ObjectNameUtil.getReferenceName(on);
return Optional.of(new MappedDependency(namespace, serviceName, refName));
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
import com.google.common.base.Optional;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<ObjectName, SimpleType<?>> {
- private final Services serviceTracker;
+ private final ServiceRegistryWrapper serviceTracker;
private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeResolvingStrategy.class);
- ObjectNameAttributeResolvingStrategy(Services serviceTracker) {
+ ObjectNameAttributeResolvingStrategy(ServiceRegistryWrapper serviceTracker) {
super(SimpleType.OBJECTNAME);
this.serviceTracker = serviceTracker;
}
String namespace = mappedDep.getNamespace();
logger.trace("Getting service instance by service name {} : {} and ref name {}", namespace, serviceName, refName);
- ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
- ObjectName on = ObjectNameUtil.createReadOnlyModuleON(byRefName.getModuleName(), byRefName.getInstanceName());
- on = ObjectNameUtil.createON(on.toString() + "," + AttributesConstants.REF_NAME_ON_PROPERTY_KEY + "=" + refName);
+ ObjectName on = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
logger.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType());
return Optional.of(on);
import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeType;
public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvingStrategy<?, ? extends OpenType<?>>> {
- private final Services serviceTracker;
+ private final ServiceRegistryWrapper serviceTracker;
- public ObjectResolver(Services serviceTracker) {
+ public ObjectResolver(ServiceRegistryWrapper serviceTracker) {
this.serviceTracker = serviceTracker;
}
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
// }
public Element toXml(Set<ObjectName> instancesToMap, Optional<String> maybeNamespace, Document document,
- Element dataElement, Services serviceTracker) {
+ Element dataElement, ServiceRegistryWrapper serviceTracker) {
Map<String, Map<String, Collection<ObjectName>>> moduleToInstances = getMappedInstances(instancesToMap,
moduleConfigs);
ModuleConfig mapping = moduleConfigs.get(moduleNamespace).get(moduleMappingEntry.getKey());
if (moduleMappingEntry.getValue().isEmpty()) {
- addEmptyModulesCommented(document, modulesElement, moduleNamespace, moduleMappingEntry);
- } else {
- for (ObjectName objectName : moduleMappingEntry.getValue()) {
- modulesElement
- .appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace));
- }
+ continue;
+ }
+
+ for (ObjectName objectName : moduleMappingEntry.getValue()) {
+ modulesElement.appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace));
}
}
}
- root.appendChild(serviceTracker.toXml(serviceTracker.getMappedServices(), document));
+ root.appendChild(Services.toXml(serviceTracker, document));
return root;
}
- // TODO remove commented modules from output
- private void addEmptyModulesCommented(Document document, Element root, String moduleNamespace,
- Entry<String, Collection<ObjectName>> moduleMappingEntry) {
- Element emptyModule = document.createElement(XmlNetconfConstants.MODULE_KEY);
-
- Element typeElement = XmlUtil.createTextElement(document, XmlNetconfConstants.TYPE_KEY,
- moduleMappingEntry.getKey());
- emptyModule.appendChild(typeElement);
-
- root.appendChild(document.createComment(XmlUtil.toString(emptyModule, false)));
- }
-
// TODO refactor, replace string representing namespace with namespace class
// TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
// class
- public ConfigElementResolved fromXml(XmlElement xml,
- EditStrategyType defaultEditStrategyType, ServiceReferenceReadableRegistry taClient) {
- Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
- List<XmlElement> recognisedChildren = Lists.newArrayList();
+ public Map<String, Multimap<String, ModuleElementResolved>> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+ Optional<XmlElement> modulesElement = getModulesElement(xml);
+ List<XmlElement> moduleElements = getModulesElementList(modulesElement);
- Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient);
- List<XmlElement> moduleElements = fromXmlModules(xml, recognisedChildren);
-
- xml.checkUnrecognisedElements(recognisedChildren);
+ Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
for (XmlElement moduleElement : moduleElements) {
- resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType);
- }
+ ResolvingStrategy<ModuleElementResolved> resolvingStrategy = new ResolvingStrategy<ModuleElementResolved>() {
+ @Override
+ public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) {
+ return moduleMapping.fromXml(moduleElement, serviceTracker,
+ instanceName, moduleNamespace, defaultStrategy);
+ }
+ };
- return new ConfigElementResolved(retVal, serviceTracker);
+ resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
+ }
+ return retVal;
}
- public static class ConfigElementResolved {
+ /**
+ * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted.
+ */
+ public Map<String, Multimap<String, ModuleElementDefinition>> fromXmlModulesMap(XmlElement xml,
+ EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+ Optional<XmlElement> modulesElement = getModulesElement(xml);
+ List<XmlElement> moduleElements = getModulesElementList(modulesElement);
- private final Map<String, Multimap<String, ModuleElementResolved>> resolvedModules;
- private final Services services;
+ Map<String, Multimap<String, ModuleElementDefinition>> retVal = Maps.newHashMap();
- public ConfigElementResolved(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker) {
- this.resolvedModules = retVal;
- this.services = serviceTracker;
- }
+ for (XmlElement moduleElement : moduleElements) {
+ ResolvingStrategy<ModuleElementDefinition> resolvingStrategy = new ResolvingStrategy<ModuleElementDefinition>() {
+ @Override
+ public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement,
+ ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace,
+ EditStrategyType defaultStrategy) {
+ // TODO: add check for conflicts between global and local
+ // edit strategy
+ String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY,
+ XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy);
+ }
+ };
- public Map<String, Multimap<String, ModuleElementResolved>> getResolvedModules() {
- return resolvedModules;
+ resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
}
+ return retVal;
+ }
- public Services getServices() {
- return services;
- }
+ private static Optional<XmlElement> getModulesElement(XmlElement xml) {
+ return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
+ XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
}
- private List<XmlElement> fromXmlModules(XmlElement xml, List<XmlElement> recognisedChildren) {
- Optional<XmlElement> modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
- XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+ private List<XmlElement> getModulesElementList(Optional<XmlElement> modulesElement) {
List<XmlElement> moduleElements;
+
if (modulesElement.isPresent()) {
moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY);
- recognisedChildren.add(modulesElement.get());
modulesElement.get().checkUnrecognisedElements(moduleElements);
} else {
moduleElements = Lists.newArrayList();
return moduleElements;
}
- private void resolveModule(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker,
- XmlElement moduleElement, EditStrategyType defaultStrategy) {
+ private <T> void resolveModule(Map<String, Multimap<String, T>> retVal, ServiceRegistryWrapper serviceTracker,
+ XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy<T> resolvingStrategy) {
XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
String moduleNamespace = prefixToNamespace.getValue();
ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName);
- Multimap<String, ModuleElementResolved> innerMap = retVal.get(moduleNamespace);
+ Multimap<String, T> innerMap = retVal.get(moduleNamespace);
if (innerMap == null) {
innerMap = HashMultimap.create();
retVal.put(moduleNamespace, innerMap);
}
- ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker,
+ T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker,
instanceName, moduleNamespace, defaultStrategy);
- innerMap.put(factoryName, moduleElementResolved);
+ innerMap.put(factoryName, resolvedElement);
}
- private Services fromXmlServices(XmlElement xml, List<XmlElement> recognisedChildren,
- ServiceReferenceReadableRegistry taClient) {
- Optional<XmlElement> servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
- XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+ public Services fromXmlServices(XmlElement xml) {
+ Optional<XmlElement> servicesElement = getServicesElement(xml);
- Map<String, Map<String, Map<String, String>>> mappedServices;
+ Services services;
if (servicesElement.isPresent()) {
- mappedServices = Services.fromXml(servicesElement.get());
- recognisedChildren.add(servicesElement.get());
+ services = Services.fromXml(servicesElement.get());
} else {
- mappedServices = new HashMap<>();
+ services = new Services();
}
- Services services = Services.resolveServices(mappedServices, taClient);
return services;
}
+ private static Optional<XmlElement> getServicesElement(XmlElement xml) {
+ return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
+ XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+ }
+
+ public static void checkUnrecognisedChildren(XmlElement parent) {
+ Optional<XmlElement> servicesOpt = getServicesElement(parent);
+ Optional<XmlElement> modulesOpt = getModulesElement(parent);
+
+ List<XmlElement> recognised = Lists.newArrayList();
+ if(servicesOpt.isPresent())
+ recognised.add(servicesOpt.get());
+ if(modulesOpt.isPresent())
+ recognised.add(modulesOpt.get());
+
+ parent.checkUnrecognisedElements(recognised);
+ }
+
private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) {
checkState(
factoryNameWithPrefix.startsWith(prefixOrEmptyString),
return moduleMapping;
}
+ private interface ResolvingStrategy<T> {
+ public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker,
+ String instanceName, String moduleNamespace, EditStrategyType defaultStrategy);
+ }
}
this.configRegistryClient = configRegistryClient;
}
- private Map<String, Object> getMappedConfiguration(ObjectName on, Services depTracker) {
+ private Map<String, Object> getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) {
// TODO make field, mappingStrategies can be instantiated only once
Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> mappingStrategies = new ObjectMapper(depTracker)
return toXml;
}
- public Element toXml(ObjectName on, Services depTracker, String namespace, Document document, Element rootElement) {
+ public Element toXml(ObjectName on, ServiceRegistryWrapper depTracker, String namespace, Document document, Element rootElement) {
Element cfgElement = rootElement;
return cfgElement;
}
- private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, Services depTracker) {
+ private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) {
// TODO make field, resolvingStrategies can be instantiated only once
Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> resolvingStrategies = new ObjectResolver(
}
}
- public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace,
+ public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace,
EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
private final Multimap<String, String> providedServices;
public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
- EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy);
+ EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy);
this.editStrategy = valueOf;
this.configuration = configuration;
this.providedServices = providedServices;
}
- EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
- EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy);
+ static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
+ EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy);
if (defaultStrategy.isEnforcing()) {
Preconditions
.checkArgument(
- valueOf == defaultStrategy,
+ parsedStrategy == defaultStrategy,
"With "
+ defaultStrategy
+ " as "
+ EditConfigXmlParser.DEFAULT_OPERATION_KEY
+ " operations on module elements are not permitted since the default option is restrictive");
}
- return valueOf;
+ return parsedStrategy;
}
return providedServices;
}
- public Element toXml(ObjectName instanceON, Services depTracker, Document document, String namespace) {
+ public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) {
Element root = document.createElement(XmlNetconfConstants.MODULE_KEY);
// Xml.addNamespaceAttr(document, root, namespace);
}
- public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName,
+ public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
String moduleNamespace, EditStrategyType defaultStrategy) {
InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices);
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
+
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy;
+
+public class ModuleElementDefinition {
+
+ public static final NoneEditConfigStrategy NONE_EDIT_CONFIG_STRATEGY = new NoneEditConfigStrategy();
+ public static final MissingInstanceHandlingStrategy MISSING_INSTANCE_HANDLING_STRATEGY = new MissingInstanceHandlingStrategy();
+
+ private final String instanceName;
+ private final EditStrategyType editStrategy;
+
+ public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) {
+ this.instanceName = instanceName;
+ if (currentStrategy == null || currentStrategy.isEmpty())
+ this.editStrategy = defaultStrategy;
+ else
+ this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy);
+ }
+
+ public String getInstanceName() {
+ return instanceName;
+ }
+
+ public EditStrategyType getEditStrategyType() {
+ return editStrategy;
+ }
+
+ public EditConfigStrategy getEditStrategy() {
+ switch (editStrategy) {
+ case delete :
+ case remove :
+ case none : return NONE_EDIT_CONFIG_STRATEGY;
+ default : return MISSING_INSTANCE_HANDLING_STRATEGY;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ServiceRegistryWrapper {
+
+ private ServiceReferenceReadableRegistry configServiceRefRegistry;
+
+ private long suffix = 1;
+
+ public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) {
+ this.configServiceRefRegistry = configServiceRefRegistry;
+ }
+
+
+ public boolean hasRefName(String namespace, String serviceName, ObjectName on) {
+ String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
+ Map<String, ObjectName> forQName = configServiceRefRegistry.getServiceMapping().get(qname);
+ if(forQName==null) return false;
+ return forQName.values().contains(on);
+ }
+
+ public ObjectName getByServiceAndRefName(String namespace, String serviceName, String refName) {
+ Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+ Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
+
+ Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+ Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
+ + serviceNameToRefNameToInstance.keySet());
+
+ String instanceId = refNameToInstance.get(refName);
+ Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
+ + refName + ", " + serviceNameToRefNameToInstance.keySet());
+
+ Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId);
+ Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
+ + " under service name " + serviceName + " , " + refNameToInstance.keySet());
+
+ String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
+ try {
+ return configServiceRefRegistry.getServiceReference(qNameOfService, refName);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalArgumentException("No serviceInstance mapped to " + refName
+ + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e);
+
+ }
+ }
+
+ public Map<String, Map<String, Map<String, String>>> getMappedServices() {
+ Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
+
+ Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
+ for (String serviceQName : serviceMapping.keySet())
+ for (String refName : serviceMapping.get(serviceQName).keySet()) {
+
+ ObjectName on = serviceMapping.get(serviceQName).get(refName);
+ Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on);
+
+ // FIXME use QName's new String constructor, after it is fixed
+// QName qname;
+// try {
+// qname = new QName(serviceQName);
+// } catch (ParseException e) {
+// throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e);
+// }
+ Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
+ Matcher matcher = p.matcher(serviceQName);
+ Preconditions.checkArgument(matcher.matches());
+ String namespace = matcher.group(1);
+ String localName = matcher.group(2);
+
+// String namespace = qname.getNamespace().toString();
+ Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
+ if(serviceToRefs==null) {
+ serviceToRefs = Maps.newHashMap();
+ retVal.put(namespace, serviceToRefs);
+ }
+
+// String localName = qname.getLocalName();
+ Map<String, String> refsToSis = serviceToRefs.get(localName);
+ if(refsToSis==null) {
+ refsToSis = Maps.newHashMap();
+ serviceToRefs.put(localName, refsToSis);
+ }
+
+ Preconditions.checkState(refsToSis.containsKey(refName) == false,
+ "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
+ localName, on);
+ refsToSis.put(refName, si.toString());
+ }
+
+ return retVal;
+ }
+
+ @VisibleForTesting
+ public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
+ String refName;
+ refName = "ref_" + instanceName;
+
+ Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+ Map<String, String> refNameToInstance;
+ if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
+ refNameToInstance = Collections.emptyMap();
+ } else
+ refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+
+ final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
+ if (refNamesAsSet.contains(refName)) {
+ refName = findAvailableRefName(refName, refNamesAsSet);
+ }
+
+ return refName;
+ }
+
+
+ private Set<String> toSet(Collection<String> values) {
+ Set<String> refNamesAsSet = Sets.newHashSet();
+
+ for (String refName : values) {
+ boolean resultAdd = refNamesAsSet.add(refName);
+ Preconditions.checkState(resultAdd,
+ "Error occurred building services element, reference name {} was present twice", refName);
+ }
+
+ return refNamesAsSet;
+ }
+
+ private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
+ String intitialRefName = refName;
+
+ while (true) {
+ refName = intitialRefName + "_" + suffix++;
+ if (refNamesAsSet.contains(refName) == false)
+ return refName;
+ }
+ }
+}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.w3c.dom.Element;
import javax.management.ObjectName;
-import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static final String TYPE_KEY = "type";
public static final String SERVICE_KEY = "service";
- private long suffix = 1;
-
private final Map<String /*Namespace*/, Map<String/* ServiceName */, Map<String/* refName */, ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = Maps
.newHashMap();
- private ServiceReferenceReadableRegistry configServiceRefRegistry;
-
- public Services(ServiceReferenceReadableRegistry configServiceRefRegistry) {
- this.configServiceRefRegistry = configServiceRefRegistry;
- }
-
- @VisibleForTesting
- public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
- String refName;
- refName = "ref_" + instanceName;
-
- Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
- Map<String, String> refNameToInstance;
- if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
- refNameToInstance = Collections.emptyMap();
- } else
- refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
-
- final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
- if (refNamesAsSet.contains(refName)) {
- refName = findAvailableRefName(refName, refNamesAsSet);
- }
-
- return refName;
- }
-
- private Set<String> toSet(Collection<String> values) {
- Set<String> refNamesAsSet = Sets.newHashSet();
-
- for (String refName : values) {
- boolean resultAdd = refNamesAsSet.add(refName);
- Preconditions.checkState(resultAdd,
- "Error occurred building services element, reference name {} was present twice", refName);
- }
-
- return refNamesAsSet;
- }
-
- public ServiceInstance getByServiceAndRefName(String namespace, String serviceName, String refName) {
- Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
- Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
-
- Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
- Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
- + serviceNameToRefNameToInstance.keySet());
-
- String instanceId = refNameToInstance.get(refName);
- Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
- + refName + ", " + serviceNameToRefNameToInstance.keySet());
-
- ServiceInstance serviceInstance = ServiceInstance.fromString(instanceId);
- Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
- + " under service name " + serviceName + " , " + refNameToInstance.keySet());
- return serviceInstance;
- }
-
- // TODO hide getMappedServices, call it explicitly in toXml
-
- public Map<String, Map<String, Map<String, String>>> getMappedServices() {
- Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
-
- for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) {
-
- Map<String, Map<String, ServiceInstance>> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance
- .get(namespace);
- Map<String, Map<String, String>> innerRetVal = Maps.newHashMap();
-
- for (String serviceName : serviceNameToRefNameToInstance.keySet()) {
-
- Map<String, String> innerInnerRetVal = Maps.newHashMap();
- for (Entry<String, ServiceInstance> refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) {
- innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString());
- }
- innerRetVal.put(serviceName, innerInnerRetVal);
- }
- retVal.put(namespace, innerRetVal);
- }
-
- Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
- for (String serviceQName : serviceMapping.keySet())
- for (String refName : serviceMapping.get(serviceQName).keySet()) {
-
- ObjectName on = serviceMapping.get(serviceQName).get(refName);
- ServiceInstance si = ServiceInstance.fromObjectName(on);
-
- // FIXME use QName's new String constructor, after its implemented
- Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
- Matcher matcher = p.matcher(serviceQName);
- Preconditions.checkArgument(matcher.matches());
- String namespace = matcher.group(1);
- String localName = matcher.group(2);
-
- Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
- if(serviceToRefs==null) {
- serviceToRefs = Maps.newHashMap();
- retVal.put(namespace, serviceToRefs);
- }
-
- Map<String, String> refsToSis = serviceToRefs.get(localName);
- if(refsToSis==null) {
- refsToSis = Maps.newHashMap();
- serviceToRefs.put(localName, refsToSis);
- }
-
- Preconditions.checkState(refsToSis.containsKey(refName) == false,
- "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
- localName, on);
- refsToSis.put(refName, si.toString());
- }
-
- return retVal;
- }
/**
*
return namespaceToServiceNameToRefNameToInstance;
}
- // TODO hide resolveServices, call it explicitly in fromXml
-
- public static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices, ServiceReferenceReadableRegistry taClient) {
- Services tracker = new Services(taClient);
+ private static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices) {
+ Services tracker = new Services();
for (Entry<String, Map<String, Map<String, String>>> namespaceEntry : mappedServices.entrySet()) {
String namespace = namespaceEntry.getKey();
// TODO support edit strategies on services
- public static Map<String, Map<String, Map<String, String>>> fromXml(XmlElement xml) {
+ public static Services fromXml(XmlElement xml) {
Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
List<XmlElement> services = xml.getChildElements(SERVICE_KEY);
}
}
- return retVal;
- }
-
- private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
- String intitialRefName = refName;
-
- while (true) {
- refName = intitialRefName + "_" + suffix++;
- if (refNamesAsSet.contains(refName) == false)
- return refName;
- }
+ return resolveServices(retVal);
}
- public Element toXml(Map<String, Map<String, Map<String, String>>> mappedServices, Document document) {
+ public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) {
Element root = document.createElement(XmlNetconfConstants.SERVICES_KEY);
XmlUtil.addNamespaceAttr(root, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+ Map<String, Map<String, Map<String, String>>> mappedServices = serviceRegistryWrapper.getMappedServices();
for (String namespace : mappedServices.keySet()) {
for (Entry<String, Map<String, String>> serviceEntry : mappedServices.get(namespace).entrySet()) {
return root;
}
- public String getRefName(String namespace, String serviceName, ObjectName on, Optional<String> expectedRefName) {
- Optional<String> refNameOptional = getRefNameOptional(namespace, serviceName, on, expectedRefName);
- Preconditions.checkState(refNameOptional.isPresent(), "No reference names mapped to %s, %s, %s", namespace,
- serviceName, on);
- return refNameOptional.get();
- }
-
- public Optional<String> getRefNameOptional(String namespace, String serviceName, ObjectName on,
- Optional<String> expectedRefName) {
- Map<String, Map<String, String>> services = getMappedServices().get(namespace);
-
- if(services == null) return Optional.absent();
- Map<String, String> refs = services.get(serviceName);
-
- if(refs == null) return Optional.absent();
- Multimap<ServiceInstance, String> reverted = revertMap(refs);
-
- ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on);
- Collection<String> references = reverted.get(serviceInstance);
-
- if (expectedRefName.isPresent() && references.contains(expectedRefName.get())) {
- logger.debug("Returning expected ref name {} for {}", expectedRefName.get(), on);
- return expectedRefName;
- } else if (references.size() > 0) {
- String next = references.iterator().next();
- logger.debug("Returning random ref name {} for {}", next, on);
- return Optional.of(next);
- } else
- return Optional.absent();
- }
-
- private Multimap<ServiceInstance, String> revertMap(Map<String, String> refs) {
- Multimap<ServiceInstance, String> multimap = HashMultimap.create();
-
- for (Entry<String, String> e : refs.entrySet()) {
- multimap.put(ServiceInstance.fromString(e.getValue()), e.getKey());
- }
-
- return multimap;
- }
-
- public boolean hasRefName(String key, String value, ObjectName on) {
- return getRefNameOptional(key, value, on, Optional.<String>absent()).isPresent();
- }
-
public static final class ServiceInstance {
public ServiceInstance(String moduleName, String instanceName) {
this.moduleName = moduleName;
public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, String instanceIndex,
Element parentElement, String namespace) {
- // TODO namespace
Element xml = instanceMapping.toXml(rootOn, null, namespace, document, parentElement);
if (instanceIndex != null) {
import com.google.common.collect.Sets;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
}
public Element toXml(String namespace, Collection<ObjectName> runtimeBeanOns,
- Document document, ModuleConfig moduleConfig, ObjectName configBeanON, Services serviceTracker) {
+ Document document, ModuleConfig moduleConfig, ObjectName configBeanON, ServiceRegistryWrapper serviceTracker) {
Element moduleElement = moduleConfig.toXml(configBeanON, serviceTracker, document, namespace);
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
return retVal;
}
- public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) {
- Services serviceTracker = new Services(serviceRegistry);
-
+ public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceRegistryWrapper serviceRegistry) {
Element root = document.createElement(XmlNetconfConstants.DATA_KEY);
Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY);
Element runtimeXml;
ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName);
if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) {
- runtimeXml = moduleConfig.toXml(instanceON, serviceTracker, document, localNamespace);
+ runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace);
} else {
ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document,
- moduleConfig, instanceON, serviceTracker);
+ moduleConfig, instanceON, serviceRegistry);
}
modulesElement.appendChild(runtimeXml);
}
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, Services services) {
+ ConfigTransactionClient ta, ServiceRegistryWrapper services) {
try {
ObjectName on = ta.lookupConfigBean(module, instance);
}
+ // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR
+ // edit configs should not handle missing
+
abstract void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services);
+ String module, String instance, ServiceRegistryWrapper services);
abstract void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- ObjectName objectName, Services services);
+ ObjectName objectName, ServiceRegistryWrapper services);
}
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services) {
+ String module, String instance, ServiceRegistryWrapper services) {
throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found");
}
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
try {
ta.destroyModule(on);
logger.debug("ServiceInstance {} deleted successfully", on);
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
logger.debug("Test phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG);
}
- private void test(ConfigRegistryClient configRegistryClient,
- EditConfigExecution execution, EditStrategyType editStrategyType) {
+ private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution,
+ EditStrategyType editStrategyType) {
ObjectName taON = transactionProvider.getTestTransaction();
try {
transactionProvider.wipeTestTransaction(taON);
}
- setOnTransaction(configRegistryClient, execution.getResolvedXmlElements(), execution.getServices(), taON);
- // TODO add service reference persistance testing here
+ ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+
+ handleMisssingInstancesOnTransaction(ta, execution);
+ setServicesOnTransaction(ta, execution);
+ setOnTransaction(ta, execution);
transactionProvider.validateTestTransaction(taON);
} finally {
transactionProvider.abortTestTransaction(taON);
transactionProvider.wipeTransaction();
}
- setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(),
- editConfigExecution.getServices(), taON);
- setServicesOnTransaction(configRegistryClient, editConfigExecution.getServices(), taON);
+ ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+
+ handleMisssingInstancesOnTransaction(ta, editConfigExecution);
+ setServicesOnTransaction(ta, editConfigExecution);
+ setOnTransaction(ta, editConfigExecution);
}
- private void setServicesOnTransaction(ConfigRegistryClient configRegistryClient, Services services,
- ObjectName taON) {
- ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+ private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+ Services services = execution.getServices();
Map<String, Map<String, Map<String, Services.ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = services
.getNamespaceToServiceNameToRefNameToInstance();
for (String refName : refNameToInstance.keySet()) {
ObjectName on = refNameToInstance.get(refName).getObjectName(ta.getTransactionName());
- // TODO check for duplicates
try {
- ta.saveServiceReference(qnameOfService, refName, on);
+ ObjectName saved = ta.saveServiceReference(qnameOfService, refName, on);
+ logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService,
+ on, refName, saved);
} catch (InstanceNotFoundException e) {
throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e);
}
return ta.getServiceInterfaceName(namespace, serviceName);
}
- private void setOnTransaction(ConfigRegistryClient configRegistryClient,
- Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements, Services services, ObjectName taON) {
- ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+ private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+ for (Multimap<String, ModuleElementResolved> modulesToResolved : execution.getResolvedXmlElements(ta).values()) {
- for (Multimap<String, ModuleElementResolved> modulesToResolved : resolvedXmlElements.values()) {
for (Entry<String, ModuleElementResolved> moduleToResolved : modulesToResolved.entries()) {
String moduleName = moduleToResolved.getKey();
InstanceConfigElementResolved ice = moduleElementResolved.getInstanceConfigElementResolved();
EditConfigStrategy strategy = ice.getEditStrategy();
- strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, services);
+ strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, execution.getServiceRegistryWrapper(ta));
+ }
+ }
+ }
+
+ private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta,
+ EditConfigExecution execution) {
+
+ for (Multimap<String,ModuleElementDefinition> modulesToResolved : execution.getModulesDefinition(ta).values()) {
+ for (Entry<String, ModuleElementDefinition> moduleToResolved : modulesToResolved.entries()) {
+ String moduleName = moduleToResolved.getKey();
+
+ ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue();
+
+ EditConfigStrategy strategy = moduleElementDefinition.getEditStrategy();
+ strategy.executeConfiguration(moduleName, moduleElementDefinition.getInstanceName(), null, ta, execution.getServiceRegistryWrapper(ta));
}
}
}
public static Config getConfigMapping(ConfigRegistryClient configRegistryClient,
Map<String/* Namespace from yang file */,
Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
- Map<String, Map<String, ModuleConfig>> factories = transform(configRegistryClient, mBeanEntries);
+ Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries);
return new Config(factories);
}
- // TODO refactor
- private static Map<String/* Namespace from yang file */,
- Map<String /* Name of module entry from yang file */, ModuleConfig>> transform
- (final ConfigRegistryClient configRegistryClient, Map<String/* Namespace from yang file */,
+ public static Map<String/* Namespace from yang file */,
+ Map<String /* Name of module entry from yang file */, ModuleConfig>> transformMbeToModuleConfigs
+ (final ConfigRegistryClient configRegistryClient, Map<String/* Namespace from yang file */,
Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
- return Maps.transformEntries(mBeanEntries,
- new Maps.EntryTransformer<String, Map<String, ModuleMXBeanEntry>, Map<String, ModuleConfig>>() {
-
- @Override
- public Map<String, ModuleConfig> transformEntry(String arg0, Map<String, ModuleMXBeanEntry> arg1) {
- return Maps.transformEntries(arg1,
- new Maps.EntryTransformer<String, ModuleMXBeanEntry, ModuleConfig>() {
-
- @Override
- public ModuleConfig transformEntry(String key, ModuleMXBeanEntry moduleMXBeanEntry) {
- return new ModuleConfig(key, new InstanceConfig(configRegistryClient, moduleMXBeanEntry
- .getAttributes()), moduleMXBeanEntry.getProvidedServices().values());
- }
- });
- }
- });
+
+ Map<String, Map<String, ModuleConfig>> namespaceToModuleNameToModuleConfig = Maps.newHashMap();
+
+ for (String namespace : mBeanEntries.keySet()) {
+ for (Entry<String, ModuleMXBeanEntry> moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) {
+ String moduleName = moduleNameToMbe.getKey();
+ ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue();
+
+ ModuleConfig moduleConfig = new ModuleConfig(moduleName, new InstanceConfig(configRegistryClient,
+ moduleMXBeanEntry.getAttributes()), moduleMXBeanEntry
+ .getProvidedServices().values());
+
+ Map<String, ModuleConfig> moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespace);
+ if(moduleNameToModuleConfig == null) {
+ moduleNameToModuleConfig = Maps.newHashMap();
+ namespaceToModuleNameToModuleConfig.put(namespace, moduleNameToModuleConfig);
+ }
+
+ moduleNameToModuleConfig.put(moduleName, moduleConfig);
+ }
+ }
+
+ return namespaceToModuleNameToModuleConfig;
}
@Override
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import java.util.Map;
public interface EditConfigStrategy {
void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, Services services);
+ ConfigTransactionClient ta, ServiceRegistryWrapper services);
}
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.management.ObjectName;
import java.util.Arrays;
import java.util.Map;
XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
- ObjectName taON = transactionProvider.getOrCreateTransaction();
- ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
-
- return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption,
- ta, editStrategyType);
+ return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType);
}
@VisibleForTesting
@VisibleForTesting
static class EditConfigExecution {
- private final Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements;
private final TestOption testOption;
private final EditStrategyType defaultEditStrategyType;
private final Services services;
-
- EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, ServiceReferenceReadableRegistry ta, EditStrategyType defaultStrategy) {
- Config.ConfigElementResolved configElementResolved = configResolver.fromXml(configElement, defaultStrategy, ta);
- this.resolvedXmlElements = configElementResolved.getResolvedModules();
- this.services = configElementResolved.getServices();
+ private final Config configResolver;
+ private final XmlElement configElement;
+
+ EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) {
+ Config.checkUnrecognisedChildren(configElement);
+ this.configResolver = configResolver;
+ this.configElement = configElement;
+ this.services = configResolver.fromXmlServices(configElement);
this.testOption = testOption;
this.defaultEditStrategyType = defaultStrategy;
}
return testOption == TestOption.set || testOption == TestOption.testThenSet;
}
- Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements() {
- return resolvedXmlElements;
+ Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) {
+ return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
+ }
+
+ ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) {
+ // TODO cache service registry
+ return new ServiceRegistryWrapper(serviceRegistry);
+ }
+
+ Map<String, Multimap<String,ModuleElementDefinition>> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) {
+ return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
}
EditStrategyType getDefaultStrategy() {
import java.util.EnumSet;
import java.util.Set;
-//FIXME: make thread safe
public enum EditStrategyType {
// can be default
merge, replace, none,
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
import java.util.Map;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services) {
- ObjectName on = null;
- try {
- on = ta.createModule(module, instance);
- logger.info("New instance for {} {} created under name {}", module, instance, on);
- addRefNames(services, providedServices, module, instance, ta, on);
- executeStrategy(configuration, ta, on, services);
- } catch (InstanceAlreadyExistsException e1) {
- throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
- } catch (InstanceNotFoundException e) {
- throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
- }
+ String module, String instance, ServiceRegistryWrapper services) {
+ throw new IllegalStateException(
+ "Unable to handle missing instance, no missing instances should appear at this point, missing: "
+ + module + ":" + instance);
}
- private void addRefNames(Services services, Multimap<String, String> providedServices, String module,
- String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+ private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
for (Entry<String, String> namespaceToService : providedServices.entries()) {
if(services.hasRefName(namespaceToService.getKey(),
continue;
String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
- module, instance);
+ ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
ta.saveServiceReference(
ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on);
}
}
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+ try {
+ addRefNames(services, providedServices, ta, on);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+ }
+
for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
try {
AttributeConfigElement ace = configAttributeEntry.getValue();
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
+
+import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.util.Map;
+
+public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy {
+
+ private static final Logger logger = LoggerFactory.getLogger(MissingInstanceHandlingStrategy.class);
+
+ @Override
+ void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+ String module, String instance, ServiceRegistryWrapper services) {
+ ObjectName on = null;
+ try {
+ on = ta.createModule(module, instance);
+ logger.info("New instance for {} {} created under name {}", module, instance, on);
+ } catch (InstanceAlreadyExistsException e1) {
+ throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
+ }
+ }
+
+ @Override
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+ ObjectName objectName, ServiceRegistryWrapper services) {
+ return;
+ }
+}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-import java.util.Map;
-
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Map;
+
public class NoneEditConfigStrategy implements EditConfigStrategy {
private static final Logger logger = LoggerFactory.getLogger(NoneEditConfigStrategy.class);
@Override
public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, Services services) {
+ ConfigTransactionClient ta, ServiceRegistryWrapper services) {
logger.debug("Skipping configuration element for {}:{}", module, instance);
}
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services) {
+ String module, String instance, ServiceRegistryWrapper services) {
logger.warn("Unable to delete {}:{}, ServiceInstance not found", module, instance);
}
}
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
import java.util.Map;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services) {
- ObjectName on = null;
- try {
- on = ta.createModule(module, instance);
- logger.debug("New instance for {} {} created under name {}", module, instance, on);
- addRefNames(services, providedServices, module, instance, ta, on);
- executeStrategy(configuration, ta, on, services);
- } catch (InstanceAlreadyExistsException e) {
- logger.warn("Error creating instance {}:{}, replace failed", module, instance, e);
- throw new IllegalStateException("Unable to create new instance for " + module + " : " + instance, e);
- } catch (InstanceNotFoundException e) {
- throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
- }
+ String module, String instance, ServiceRegistryWrapper services) {
+ throw new IllegalStateException(
+ "Unable to handle missing instance, no missing instances should appear at this point, missing: "
+ + module + ":" + instance);
}
- private void addRefNames(Services services, Multimap<String, String> providedServices, String module,
- String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+ private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
for (Entry<String, String> namespaceToService : providedServices.entries()) {
if(services.hasRefName(namespaceToService.getKey(),
continue;
String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
- module, instance);
+ ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
ta.saveServiceReference(
ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on);
}
}
+
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+ try {
+ addRefNames(services, providedServices, ta, on);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+ }
+
for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
try {
AttributeConfigElement ace = configAttributeEntry.getValue();
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.InstanceRuntime;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.ModuleRuntime;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.Runtime;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(configRegistryClient,
yangStoreSnapshot.getModuleMXBeanEntryMap());
- final Map<String, Map<String, ModuleConfig>> moduleConfigs = GetConfig.transform(configRegistryClient,
- yangStoreSnapshot.getModuleMXBeanEntryMap());
+ final Map<String, Map<String, ModuleConfig>> moduleConfigs = EditConfig.transformMbeToModuleConfigs(
+ configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
ObjectName txOn = transactionProvider.getOrCreateTransaction();
ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn);
- final Element element = runtime.toXml(runtimeBeans, configBeans, document, ta);
+ final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta));
logger.info("{} operation successful", XmlNetconfConstants.GET);
package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
import com.google.common.base.Optional;
-import com.google.common.collect.Maps;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
final Set<ObjectName> instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider)
.queryInstances(configRegistryClient);
- final Config configMapping = new Config(transform(configRegistryClient,
+ final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(configRegistryClient,
yangStoreSnapshot.getModuleMXBeanEntryMap()));
ObjectName on = transactionProvider.getOrCreateTransaction();
ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(on);
- Services serviceTracker = new Services(ta);
+ ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta);
dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
logger.info("{} operation successful", GET_CONFIG);
return dataElement;
}
- // TODO refactor ... duplicate code
- public static Map<String, Map<String, ModuleConfig>> transform(final ConfigRegistryClient configRegistryClient,
- Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries) {
- return Maps.transformEntries(mBeanEntries,
- new Maps.EntryTransformer<String, Map<String, ModuleMXBeanEntry>, Map<String, ModuleConfig>>() {
-
- @Override
- public Map<String, ModuleConfig> transformEntry(String arg0, Map<String, ModuleMXBeanEntry> arg1) {
- return Maps.transformEntries(arg1,
- new Maps.EntryTransformer<String, ModuleMXBeanEntry, ModuleConfig>() {
-
- @Override
- public ModuleConfig transformEntry(String key, ModuleMXBeanEntry value) {
- return new ModuleConfig(key, new InstanceConfig(configRegistryClient, value
- .getAttributes()), value.getProvidedServices().values());
- }
- });
- }
- });
- }
-
@Override
protected String getOperationName() {
return GET_CONFIG;
if (contextInstanceElement.isPresent() == false)
return HandlingPriority.CANNOT_HANDLE;
- // FIXME update xpath to instance to conform to config-api yang
final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get()
.getTextContent(), netconfOperationName, netconfOperationNamespace);
try {
Thread.sleep(ATTEMPT_TIMEOUT_MS);
} catch (InterruptedException e1) {
+ Thread.currentThread().interrupt();
throw new RuntimeException(e1);
}
continue;
package org.opendaylight.controller.netconf.confignetconfconnector.util;
import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
import java.text.ParseException;
import java.text.SimpleDateFormat;
+ " should be " + clazz + " of " + value);
}
- // TODO: add message and proper error types
- public static YangStoreSnapshot getYangStore(final YangStoreService yangStoreService)
- throws NetconfDocumentedException {
- try {
- return yangStoreService.getYangStoreSnapshot();
- } catch (final YangStoreException e) {
- throw new NetconfDocumentedException("TODO", e, ErrorType.application, ErrorTag.bad_attribute,
- ErrorSeverity.error);
- }
- }
-
}
"ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
"ref_from_code_to_instance-from-code_1");
+
edit("netconfMessages/editConfig_addServiceName.xml");
config = getConfigCandidate();
assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user",
"ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
"ref_from_code_to_instance-from-code_1", "ref_dep_user_another");
+ edit("netconfMessages/editConfig_addServiceNameOnTest.xml");
+ config = getConfigCandidate();
+ assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user",
+ "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
+ "ref_from_code_to_instance-from-code_1", "ref_dep_user_another");
+
commit();
config = getConfigRunning();
assertCorrectRefNamesForDependencies(config);
edit("netconfMessages/editConfig.xml");
Element configCandidate = getConfigCandidate();
+ System.err.println(XmlUtil.toString(configCandidate));
checkBinaryLeafEdited(configCandidate);
commit();
response = getConfigCandidate();
final String responseFromCandidate = XmlUtil.toString(response).replaceAll("\\s+", "");
- // System.out.println(responseFromCandidate);
response = getConfigRunning();
final String responseFromRunning = XmlUtil.toString(response).replaceAll("\\s+", "");
- // System.out.println(responseFromRunning);
assertEquals(responseFromCandidate, responseFromRunning);
final String expectedResult = XmlFileLoader.fileToString("netconfMessages/editConfig_expectedResult.xml")
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution;
import java.util.Map;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.anyMapOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING);
EditConfigStrategy editStrat = mock(EditConfigStrategy.class);
- doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMap(),
- any(ConfigTransactionClient.class), any(Services.class));
+ doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class),
+ any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
EditConfigExecution editConfigExecution = mockExecution(editStrat);
verify(provider).getOrCreateTransaction();
// For every instance execute strat
- verify(editStrat, times(2/* Test */+ 2/* Set */)).executeConfiguration(anyString(), anyString(), anyMap(),
- any(ConfigTransactionClient.class), any(Services.class));
+ verify(editStrat, times(2/* Test */+ 2/* Set */ + 2/*Handle missing instance Test*/ + 2 /*Handle missing instance Set*/)).executeConfiguration(anyString(),
+ anyString(), anyMapOf(String.class, AttributeConfigElement.class),
+ any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
}
private EditConfigExecution mockExecution(EditConfigStrategy editStrat) {
EditConfigExecution mock = mock(EditConfigExecution.class);
- doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements();
+ doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class));
+ doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class));
doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy();
doReturn(true).when(mock).shouldSet();
doReturn(true).when(mock).shouldTest();
- doReturn(mockServices()).when(mock).getServices();
+ doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class));
+ doReturn(new Services()).when(mock).getServices();
return mock;
}
+ private Object getMappingDefinition(EditConfigStrategy editStrat) {
+ Map<String, Multimap<String, ModuleElementDefinition>> result = Maps.newHashMap();
+
+ Multimap<String, ModuleElementDefinition> innerMultimap = HashMultimap.create();
+ Map<String, AttributeConfigElement> attributes = getSimpleAttributes();
+
+ ModuleElementDefinition mockedDefinition = mock(ModuleElementDefinition.class);
+ doReturn(editStrat).when(mockedDefinition).getEditStrategy();
+ doReturn("i1").when(mockedDefinition).getInstanceName();
+ innerMultimap.put("m1", mockedDefinition);
+
+ ModuleElementDefinition mockedDefinition2 = mock(ModuleElementDefinition.class);
+ doReturn(editStrat).when(mockedDefinition2).getEditStrategy();
+ doReturn("i2").when(mockedDefinition2).getInstanceName();
+ innerMultimap.put("m1", mockedDefinition2);
+
+ result.put("n1", innerMultimap);
+
+ return result;
+ }
+
private static ServiceReferenceReadableRegistry mockServiceRegistry() {
ServiceReferenceReadableRegistry mock = mock(ServiceReferenceReadableRegistry.class);
doReturn(
return mock;
}
- static Services mockServices() {
- return new Services(mockServiceRegistry());
+ static ServiceRegistryWrapper mockServices() {
+ return new ServiceRegistryWrapper(mockServiceRegistry());
}
private Map<String, Multimap<String, ModuleElementResolved>> getMapping(EditConfigStrategy editStrat) {
package org.opendaylight.controller.netconf.persist.impl;
+import org.opendaylight.controller.config.persist.api.Persister;
import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
import org.opendaylight.controller.netconf.api.jmx.DefaultCommitOperationMXBean;
import org.opendaylight.controller.netconf.api.jmx.NetconfJMXNotification;
private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterNotificationHandler.class);
private final MBeanServerConnection mBeanServerConnection;
private final NetconfClient netconfClient;
- private final PersisterAggregator persisterAggregator;
+ private final Persister persisterAggregator;
private final Pattern ignoredMissingCapabilityRegex;
public ConfigPersisterNotificationHandler(MBeanServerConnection mBeanServerConnection, NetconfClient netconfClient,
- PersisterAggregator persisterAggregator, Pattern ignoredMissingCapabilityRegex) {
+ Persister persisterAggregator, Pattern ignoredMissingCapabilityRegex) {
this.mBeanServerConnection = mBeanServerConnection;
this.netconfClient = netconfClient;
this.persisterAggregator = persisterAggregator;
if (notification instanceof CommitJMXNotification) {
try {
handleAfterCommitNotification((CommitJMXNotification) notification);
- } catch (Exception e) {
- // TODO: notificationBroadcast support logs only DEBUG
+ } catch (Throwable e) {
+ // log exceptions from notification Handler here since
+ // notificationBroadcastSupport logs only DEBUG level
logger.warn("Exception occured during notification handling: ", e);
throw e;
}
return true;
}
-
- // TODO: check if closing in correct order
public static void closeClientAndDispatcher(NetconfClient client) {
NetconfClientDispatcher dispatcher = client.getNetconfClientDispatcher();
Exception fromClient = null;
ignoredMissingCapabilityRegex);
jmxNotificationHandler.init();
} catch (InterruptedException e) {
- logger.info("Interrupted while waiting for netconf connection");
+ Thread.currentThread().interrupt();
+ logger.error("Interrupted while waiting for netconf connection");
+ // uncaught exception handler will deal with this failure
+ throw new RuntimeException("Interrupted while waiting for netconf connection", e);
}
}
};
-/**
- * @author Tomas Olvecky
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
- * 11 2013
- *
- * Copyright (c) 2013 by Cisco Systems, Inc.
- * 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.persist.impl.osgi;
return new NetconfClient(clientLabelForLogging,address,strat,netconfClientDispatcher);
}
+ public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher,NetconfClientSessionListener listener) throws InterruptedException {
+ return new NetconfClient(clientLabelForLogging,address,strat,netconfClientDispatcher,listener);
+ }
+
public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs,
NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
this(clientLabelForLogging, address,
DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher);
}
+ public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat,
+ NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{
+ this.label = clientLabelForLogging;
+ dispatch = netconfClientDispatcher;
+ sessionListener = listener;
+ Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strat);
+ this.address = address;
+ clientSession = get(clientFuture);
+ this.sessionId = clientSession.getSessionId();
+ }
+
public NetconfMessage sendMessage(NetconfMessage message) {
return sendMessage(message, 5, 1000);
}
public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) {
long startTime = System.currentTimeMillis();
Preconditions.checkState(clientSession.isUp(), "Session was not up yet");
+ //logger.debug("Sending message: {}",XmlUtil.toString(message.getDocument()));
clientSession.sendMessage(message);
try {
return sessionListener.getLastMessage(attempts, attemptMsDelay);
} catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
throw new RuntimeException(this + " Cannot read message from " + address, e);
} catch (IllegalStateException e) {
throw new IllegalStateException(this + " Cannot read message from " + address, e);
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
import org.opendaylight.controller.netconf.mapping.api.Capability;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.Map;
private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot;
private final Set<String> capabilityURIs;
+ private static final Logger logger = LoggerFactory.getLogger(DefaultCommitNotificationProducer.class);
+
public CapabilityProviderImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot;
Map<String, Capability> urisToCapabilitiesInternalMap = getCapabilitiesInternal(netconfOperationServiceSnapshot);
final Set<Capability> caps = netconfOperationService.getCapabilities();
for (Capability cap : caps) {
- // TODO check for duplicates ?
+
+ if(capabilityMap.containsKey(cap.getCapabilityUri())) {
+ logger.debug("Duplicate capability {} from service {}", cap.getCapabilityUri(), netconfOperationService);
+ }
+
capabilityMap.put(cap.getCapabilityUri(), cap);
}
}
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.concurrent.Promise;
-import java.net.InetSocketAddress;
import org.opendaylight.controller.netconf.api.NetconfSession;
import org.opendaylight.controller.netconf.impl.util.DeserializerExceptionHandler;
import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
import org.opendaylight.protocol.framework.AbstractDispatcher;
+import java.net.InetSocketAddress;
+
public class NetconfServerDispatcher extends AbstractDispatcher<NetconfSession, NetconfServerSessionListener> {
private final ServerChannelInitializer initializer;
this.initializer = serverChannelInitializer;
}
- // TODO test create server with same address twice
public ChannelFuture createServer(InetSocketAddress address) {
return super.createServer(address, new PipelineInitializer<NetconfSession>() {
package org.opendaylight.controller.netconf.impl;
+import com.google.common.base.Preconditions;
import io.netty.channel.Channel;
import io.netty.util.Timer;
import io.netty.util.concurrent.Promise;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
+import java.io.InputStream;
public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory {
+ public static final String SERVER_HELLO_XML_LOCATION = "/server_hello.xml";
+
private final Timer timer;
private static final Document helloMessageTemplate = loadHelloMessageTemplate();
}
private static Document loadHelloMessageTemplate() {
- return NetconfUtil.createMessage(
- NetconfServerSessionNegotiatorFactory.class.getResourceAsStream("/server_hello.xml")).getDocument();
+ InputStream resourceAsStream = NetconfServerSessionNegotiatorFactory.class
+ .getResourceAsStream(SERVER_HELLO_XML_LOCATION);
+ Preconditions.checkNotNull(resourceAsStream, "Unable to load server hello message blueprint from %s",
+ SERVER_HELLO_XML_LOCATION);
+ return NetconfUtil.createMessage(resourceAsStream).getDocument();
}
@Override
@Override
public Schemas getSchemas() {
// FIXME, session ID
+ // capabilities should be split from operations (it will allow to move getSchema operation to monitoring module)
return transformSchemas(factoriesListener.getSnapshot(0));
}
for (NetconfOperationService netconfOperationService : snapshot.getServices()) {
// TODO check for duplicates ? move capability merging to snapshot
+ // Split capabilities from operations first and delete this duplicate code
caps.addAll(netconfOperationService.getCapabilities());
}
monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.NETCONF));
for (String location : locations) {
- // TODO how to create enumerration from string location ?
- // monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.valueOf(location)));
+ monitoringLocations.add(new Schema.Location(new Uri(location)));
}
return monitoringLocations;
private NetconfOperationExecution getNetconfOperationWithHighestPriority(
Document message, NetconfSession session) {
- // TODO test
TreeMap<HandlingPriority, Set<NetconfOperation>> sortedPriority = getSortedNetconfOperationsWithCanHandle(
message, session);
+/*
+ * 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.impl.util;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
+import com.google.common.base.Preconditions;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.slf4j.Logger;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
-// TODO purge nulls
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
public class NetconfUtil {
private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class);
public static NetconfMessage createMessage(final File f) {
+ Preconditions.checkNotNull(f, "File parameter was null");
try {
return createMessage(new FileInputStream(f));
} catch (final FileNotFoundException e) {
}
public static NetconfMessage createMessage(final InputStream is) {
+ Preconditions.checkNotNull(is, "InputStream parameter was null");
Document doc = null;
try {
doc = XmlUtil.readXmlToDocument(is);
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.netconf.impl;\r
\r
import static junit.framework.Assert.assertNotNull;\r
public class NetconfDispatcherImplTest {
private EventLoopGroup nettyGroup;
+ private NetconfServerDispatcher dispatch;
+ private DefaultCommitNotificationProducer commitNot;
@Before
public void setUp() throws Exception {
nettyGroup = new NioEventLoopGroup();
- }
-
- @After
- public void tearDown() throws Exception {
- nettyGroup.shutdownGracefully();
- }
- @Test
- public void test() throws Exception {
-
- DefaultCommitNotificationProducer commitNot = new DefaultCommitNotificationProducer(
+ commitNot = new DefaultCommitNotificationProducer(
ManagementFactory.getPlatformMBeanServer());
NetconfOperationServiceFactoryListener factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
factoriesListener, commitNot, idProvider, null);
NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory, listenerFactory);
-
- NetconfServerDispatcher dispatch = new NetconfServerDispatcher(
+ dispatch = new NetconfServerDispatcher(
serverChannelInitializer, nettyGroup, nettyGroup);
+ }
+ @After
+ public void tearDown() throws Exception {
+ commitNot.close();
+ nettyGroup.shutdownGracefully();
+ }
+
+ @Test
+ public void test() throws Exception {
InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8333);
ChannelFuture s = dispatch.createServer(addr);
-
- commitNot.close();
+ s.get();
}
}
--- /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;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.yang.store.api.YangStoreException;
+import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
+import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
+import org.opendaylight.controller.netconf.client.NetconfClient;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
+import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
+import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
+import org.opendaylight.controller.netconf.impl.SessionIdProvider;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
+import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
+import org.opendaylight.controller.netconf.mapping.api.Capability;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
+import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator;
+import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService;
+import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
+import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+public class NetconfConfigPersisterITTest extends AbstractConfigTest {
+
+ private static final Logger logger = LoggerFactory.getLogger(NetconfConfigPersisterITTest.class);
+
+ private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
+
+ private EventLoopGroup nettyThreadgroup;
+
+ private NetconfClientDispatcher clientDispatcher;
+
+ @Before
+ public void setUp() throws Exception {
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+ new ModuleFactory[0])));
+
+ NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getFactoriesListener());
+
+ NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
+ factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
+ factoriesListener
+ .onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
+ new NetconfMonitoringOperationService(monitoringService)));
+
+ nettyThreadgroup = new NioEventLoopGroup();
+
+ NetconfServerDispatcher dispatch = createDispatcher(factoriesListener);
+ ChannelFuture s = dispatch.createServer(tcpAddress);
+ s.await();
+
+ clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup);
+ }
+
+ private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
+ final Collection<InputStream> yangDependencies = NetconfITTest.getBasicYangs();
+ return new HardcodedYangStoreService(yangDependencies);
+ }
+
+ private NetconfServerDispatcher createDispatcher(
+ NetconfOperationServiceFactoryListenerImpl factoriesListener) {
+ SessionIdProvider idProvider = new SessionIdProvider();
+ NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+ new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
+
+ NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
+ factoriesListener, new DefaultCommitNotificationProducer(platformMBeanServer), idProvider, mockSessionMonitoringService());
+
+ NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
+ serverNegotiatorFactory, listenerFactory);
+ return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
+ }
+
+ private SessionMonitoringService mockSessionMonitoringService() {
+ SessionMonitoringService mockedSessionMonitor = mock(SessionMonitoringService.class);
+ doNothing().when(mockedSessionMonitor).onSessionUp(any(NetconfManagementSession.class));
+ doNothing().when(mockedSessionMonitor).onSessionDown(any(NetconfManagementSession.class));
+ return mockedSessionMonitor;
+ }
+
+ @Test
+ public void testNetconfCommitNotifications() throws Exception {
+
+ VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
+ VerifyingPersister mockedAggregator = mockAggregator();
+
+ try (NetconfClient persisterClient = new NetconfClient("persister", tcpAddress, 4000, clientDispatcher)) {
+ ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
+ platformMBeanServer, persisterClient, mockedAggregator,
+ Pattern.compile(""));
+ configPersisterNotificationHandler.init();
+
+ try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) {
+ NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage());
+ assertResponse(response, "<modules");
+ assertResponse(response, "<services");
+ response = netconfClient.sendMessage(loadCommitMessage());
+ assertResponse(response, "ok");
+
+ response = netconfClient.sendMessage(loadEditConfigMessage());
+ assertResponse(response, "ok");
+ response = netconfClient.sendMessage(loadCommitMessage());
+ assertResponse(response, "ok");
+ }
+ }
+
+ notificationVerifier.assertNotificationCount(2);
+ notificationVerifier.assertNotificationContent(0, 0, 0, 9);
+ notificationVerifier.assertNotificationContent(1, 4, 4, 9);
+
+ mockedAggregator.assertSnapshotCount(2);
+ // Capabilities are stripped for persister
+ mockedAggregator.assertSnapshotContent(0, 0, 0, 1);
+ mockedAggregator.assertSnapshotContent(1, 4, 4, 3);
+ }
+
+ private VerifyingPersister mockAggregator() throws IOException {
+ return new VerifyingPersister();
+ }
+
+ private VerifyingNotificationListener createCommitNotificationListener() throws InstanceNotFoundException {
+ VerifyingNotificationListener listener = new VerifyingNotificationListener();
+ platformMBeanServer.addNotificationListener(DefaultCommitNotificationProducer.objectName, listener, null, null);
+ return listener;
+ }
+
+ private void assertResponse(NetconfMessage response, String content) {
+ Assert.assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString(content));
+ }
+
+ private NetconfMessage loadGetConfigMessage() throws Exception {
+ return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
+ }
+
+ private NetconfMessage loadEditConfigMessage() throws Exception {
+ return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig.xml");
+ }
+
+ private NetconfMessage loadCommitMessage() throws Exception {
+ return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
+ }
+
+
+ public NetconfOperationServiceFactoryListener getFactoriesListener() {
+ NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class);
+ NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class);
+ NetconfOperationService service = mock(NetconfOperationService.class);
+ Set<Capability> caps = Sets.newHashSet();
+ doReturn(caps).when(service).getCapabilities();
+ Set<NetconfOperationService> services = Sets.newHashSet(service);
+ doReturn(services).when(snap).getServices();
+ doReturn(snap).when(factoriesListener).getSnapshot(anyLong());
+
+ return factoriesListener;
+ }
+
+ private static class VerifyingNotificationListener implements NotificationListener {
+ public List<Notification> notifications = Lists.newArrayList();
+
+ @Override
+ public void handleNotification(Notification notification, Object handback) {
+ this.notifications.add(notification);
+ }
+
+ void assertNotificationCount(Object size) {
+ assertEquals(size, notifications.size());
+ }
+
+ void assertNotificationContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
+ Notification notification = notifications.get(notificationIndex);
+ assertEquals(CommitJMXNotification.class, notification.getClass());
+ int capsSize = ((CommitJMXNotification) notification).getCapabilities().size();
+ assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
+ Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot();
+ int modulesSize = configSnapshot.getElementsByTagName("module").getLength();
+ assertEquals("Expected modules count", expectedModulesSize, modulesSize);
+ int servicesSize = configSnapshot.getElementsByTagName("instance").getLength();
+ assertEquals("Expected services count", expectedServicesSize, servicesSize);
+ }
+ }
+
+ private static class VerifyingPersister implements Persister {
+
+ public List<ConfigSnapshotHolder> snapshots = Lists.newArrayList();
+ private Persister mockedPersister;
+
+ public VerifyingPersister() throws IOException {
+ Persister mockedAggregator = mock(Persister.class);
+
+ doAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0];
+ snapshots.add(configSnapshot);
+ return null;
+ }
+ }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class));
+
+ this.mockedPersister = mockedAggregator;
+ }
+
+ void assertSnapshotCount(Object size) {
+ assertEquals(size, snapshots.size());
+ }
+
+ void assertSnapshotContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
+ ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex);
+ int capsSize = snapshot.getCapabilities().size();
+ assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
+ String configSnapshot = snapshot.getConfigSnapshot();
+ int modulesSize = StringUtils.countMatches(configSnapshot, "<module>");
+ assertEquals("Expected modules count", expectedModulesSize, modulesSize);
+ int servicesSize = StringUtils.countMatches(configSnapshot, "<instance>");
+ assertEquals("Expected services count", expectedServicesSize, servicesSize);
+ }
+
+ @Override
+ public void persistConfig(ConfigSnapshotHolder configSnapshotHolder) throws IOException {
+ mockedPersister.persistConfig(configSnapshotHolder);
+ }
+
+ @Override
+ public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
+ return mockedPersister.loadLastConfigs();
+ }
+
+ @Override
+ public void close() {
+ mockedPersister.close();
+ }
+ }
+}
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.HashedWheelTimer;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
+
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
import static java.util.Collections.emptyList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
}
}
-
- //TODO: test persister actually
- @Ignore
- @Test(timeout = 10000)
- public void testPersister() throws Exception {
-// Persister persister = mock(Persister.class);
-// doReturn("mockPersister").when(persister).toString();
-// doReturn(Collections.emptyList()).when(persister).loadLastConfigs();
-// ConfigPersisterNotificationHandler h =
-// new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer(),
-// Pattern.compile(ConfigPersisterActivator.DEFAULT_IGNORED_REGEX));
-// h.init();
- }
-
@Ignore
@Test
public void waitingTest() throws Exception {
private void startSSHServer() throws Exception{
logger.info("Creating SSH server");
StubUserManager um = new StubUserManager(USERNAME,PASSWORD);
- AuthProvider ap = new AuthProvider(um);
+ InputStream is = getClass().getResourceAsStream("/RSA.pk");
+ AuthProvider ap = new AuthProvider(um, is);
Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress,ap));
sshServerThread.setDaemon(true);
sshServerThread.start();
*/
package org.opendaylight.controller.netconf.it;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.HashedWheelTimer;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
import junit.framework.Assert;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
public class NetconfMonitoringITTest extends AbstractConfigTest {
responseBuilder.append(line);
responseBuilder.append(System.lineSeparator());
- System.out.println(responseBuilder.toString());
if(line.contains("</rpc-reply>"))
break;
return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml");
}
- public NetconfOperationServiceFactoryListener getFactoriesListener() {
+ public static NetconfOperationServiceFactoryListener getFactoriesListener() {
NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class);
NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class);
NetconfOperationService service = mock(NetconfOperationService.class);
--- /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-----
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.netconf.mapping.api;\r
\r
import org.opendaylight.controller.netconf.api.NetconfSession;\r
return Optional.of(priority).or(Optional.<Integer> absent());
}
- // TODO test
-
@Override
public int compareTo(HandlingPriority o) {
if (this == o)
+/*
+ * 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
+ */
@XmlSchema(
elementFormDefault = XmlNsForm.QUALIFIED,
// xmlns = {
*/
package org.opendaylight.controller.netconf.monitoring.xml;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.util.Date;
-
+import com.google.common.collect.Lists;
import org.junit.Test;
import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.ZeroBasedCounter32;
import org.w3c.dom.Element;
-import com.google.common.collect.Lists;
+import java.util.Date;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
public class JaxBSerializerTest {
};
NetconfState model = new NetconfState(service);
Element xml = new JaxBSerializer().toXml(model);
- System.out.println(XmlUtil.toString(xml));
}
private Session getMockSession() {
<configuration>
<instructions>
<Bundle-Activator>org.opendaylight.controller.netconf.osgi.NetconfSSHActivator</Bundle-Activator>
- <Export-Package>
- org.opendaylight.controller.netconf.ssh,
- </Export-Package>
<Import-Package>
com.google.common.base,
ch.ethz.ssh2,
ch.ethz.ssh2.signature,
- java.net,
- javax.annotation,
org.apache.commons.io,
- org.opendaylight.controller.netconf.util,
org.opendaylight.controller.netconf.util.osgi,
org.opendaylight.controller.usermanager,
org.opendaylight.controller.sal.authorization,
org.opendaylight.controller.sal.utils,
- org.opendaylight.protocol.framework,
org.osgi.framework,
org.osgi.util.tracker,
org.slf4j,
package org.opendaylight.controller.netconf.osgi;
import com.google.common.base.Optional;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.net.InetSocketAddress;
import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
@Override
public IUserManager addingService(ServiceReference<IUserManager> reference) {
- logger.info("Service IUserManager added, let there be SSH bridge.");
+ logger.info("Service {} added, let there be SSH bridge.", reference);
iUserManager = context.getService(reference);
try {
onUserManagerFound(iUserManager);
}
@Override
public void modifiedService(ServiceReference<IUserManager> reference, IUserManager service) {
- logger.info("Replacing modified service IUserManager in netconf SSH.");
+ logger.info("Replacing modified service {} in netconf SSH.", reference);
server.addUserManagerService(service);
}
@Override
public void removedService(ServiceReference<IUserManager> reference, IUserManager service) {
- logger.info("Removing service IUserManager from netconf SSH. " +
- "SSH won't authenticate users until IUserManeger service will be started.");
+ logger.info("Removing service {} from netconf SSH. " +
+ "SSH won't authenticate users until IUserManeger service will be started.", reference);
removeUserManagerService();
}
};
EXCEPTION_MESSAGE, true);
if (sshSocketAddressOptional.isPresent()){
- AuthProvider authProvider = new AuthProvider(iUserManager);
+ String path = NetconfConfigUtil.getPrivateKeyPath(context);
+ path = path.replace("\\", "/");
+ if (path.equals("")){
+ throw new Exception("Missing netconf.ssh.pk.path key in configuration file.");
+ }
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(path);
+ } catch (FileNotFoundException e){
+ throw new Exception("Missing file described by netconf.ssh.pk.path key in configuration file.");
+ } catch (SecurityException e){
+ throw new Exception("Read access denied to file described by netconf.ssh.pk.path key in configuration file.");
+ }
+ AuthProvider authProvider = null;
+ try {
+ authProvider = new AuthProvider(iUserManager,fis);
+ } catch (Exception e){
+ if (fis!=null){
+ fis.close();
+ }
+ throw (e);
+ }
this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
Thread serverThread = new Thread(server,"netconf SSH server thread");
serverThread.setDaemon(true);
*/
package org.opendaylight.controller.netconf.ssh.authentication;
-import ch.ethz.ssh2.signature.RSAPrivateKey;
-import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.opendaylight.controller.sal.authorization.UserLevel;
import org.opendaylight.controller.usermanager.IUserManager;
import org.opendaylight.controller.usermanager.UserConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AuthProvider implements AuthProviderInterface {
- private static RSAPrivateKey hostkey = null;
private static IUserManager um;
- private static final String DEAFULT_USER = "netconf";
- private static final String DEAFULT_PASSWORD = "netconf";
+ private static final String DEFAULT_USER = "netconf";
+ private static final String DEFAULT_PASSWORD = "netconf";
+ private static InputStream privateKeyFileInputStream;
+ private static final Logger logger = LoggerFactory.getLogger(AuthProvider.class);
- public AuthProvider(IUserManager ium) throws Exception {
+ public AuthProvider(IUserManager ium,InputStream privateKeyFileInputStream) throws Exception {
this.um = ium;
-
if (this.um == null){
throw new Exception("No usermanager service available.");
}
+ this.privateKeyFileInputStream = privateKeyFileInputStream;
+
List<String> roles = new ArrayList<String>(1);
roles.add(UserLevel.SYSTEMADMIN.toString());
- this.um.addLocalUser(new UserConfig(DEAFULT_USER, DEAFULT_PASSWORD, roles));
+ this.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles));
}
@Override
public boolean authenticated(String username, String password) throws Exception {
}
@Override
- public char[] getPEMAsCharArray() {
-
- InputStream is = getClass().getResourceAsStream("/RSA.pk");
- try {
- return IOUtils.toCharArray(is);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
+ public char[] getPEMAsCharArray() throws Exception {
+ char [] PEM = IOUtils.toCharArray(privateKeyFileInputStream);
+ privateKeyFileInputStream.close();
+ return PEM;
}
@Override
public interface AuthProviderInterface {
public boolean authenticated(String username, String password) throws Exception;
- public char[] getPEMAsCharArray();
+ public char[] getPEMAsCharArray() throws Exception;
public void removeUserManagerService();
public void addUserManagerService(IUserManager userManagerService);
}
+/*
+ * 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.ssh.threads;
conn = new ServerConnection(socket);
try {
conn.setPEMHostKey(authProvider.getPEMAsCharArray(),"netconf");
- } catch (IOException e) {
- e.printStackTrace();
+ } catch (Exception e) {
+ logger.debug("Server authentication setup failed.");
}
conn.setAuthenticationCallback(this);
conn.setServerConnectionCallback(this);
netconf_ssh_input.join();
}
} catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
logger.error("netconf_ssh_input join error ",e);
}
netconf_ssh_output.join();
}
} catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
logger.error("netconf_ssh_output join error ",e);
}
package org.opendaylight.controller.netconf;
import ch.ethz.ssh2.Connection;
+import java.io.InputStream;
import java.net.InetSocketAddress;
import junit.framework.Assert;
import org.junit.Test;
public void startSSHServer() throws Exception{
logger.info("Creating SSH server");
StubUserManager um = new StubUserManager(USER,PASSWORD);
- AuthProvider ap = new AuthProvider(um);
+ InputStream is = getClass().getResourceAsStream("/RSA.pk");
+ AuthProvider ap = new AuthProvider(um, is);
NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress,ap);
sshServerThread = new Thread(server);
sshServerThread.setDaemon(true);
--- /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-----
public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences, S extends NetconfSession>
extends AbstractSessionNegotiator<NetconfMessage, S> {
- // TODO what time ?
+ // TODO Adjust wait time for negotiation, now is 1 minute ?
private static final long INITIAL_HOLDTIMER = 1;
private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.netconf.util.handler.ssh.client;
import java.io.IOException;
try {
lock.wait();
} catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
private static final String PORT_SUFFIX_PROP = ".port";
private static final String ADDRESS_SUFFIX_PROP = ".address";
private static final String CLIENT_PROP = ".client";
+ private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
public static InetSocketAddress extractTCPNetconfAddress(BundleContext context, String exceptionMessageIfNotFound, boolean forClient) {
return extractSomeNetconfAddress(context, InfixProp.ssh, exceptionMessage, false);
}
+ public static String getPrivateKeyPath(BundleContext context){
+ return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP);
+ }
+ private static String getPropertyValue(BundleContext context, String propertyName){
+ String propertyValue = context.getProperty(propertyName);
+ if (propertyValue == null){
+ throw new IllegalStateException("Cannot find initial property with name '"+propertyName+"'");
+ }
+ return propertyValue;
+ }
/**
* @param context
* from which properties are being read.
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.netconf.util.xml;\r
\r
import com.siemens.ct.exi.CodingMode;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.netconf.util.xml;\r
\r
import io.netty.buffer.ByteBuf;\r
--- /dev/null
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <edit-config>
+ <target>
+ <candidate/>
+ </target>
+ <test-option>
+ test-only
+ </test-option>
+ <default-operation>merge</default-operation>
+ <config>
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+ <module>
+ <name>instance-from-code_dep</name>
+ <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+ test-impl:impl-dep
+ </type>
+ </module>
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+ <instance>
+ <name>ref_dep_user_another_test1</name>
+ <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+ </provider>
+ </instance>
+ <instance>
+ <name>ref_dep_user_another_test2</name>
+ <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+ </provider>
+ </instance>
+ </service>
+ </services>
+ </config>
+ </edit-config>
+</rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
<data>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <!--<module>
- <type>impl</type>
- </module>
- -->
- <!--<module>
- <type>impl-dep</type>
- </module>
- -->
- <!--<module>
- <type>impl-netconf</type>
- </module>
- -->
- </modules>
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
</data>
</rpc-reply>
</type>
</module>
-
<module>
<type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
test-impl:impl-netconf
</type>
- <name>test1</name>
+ <name>instance-from-code</name>
<simple-long-2>44</simple-long-2>
<binaryLeaf>8ad1</binaryLeaf>
<dto_d>
<type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
test-impl:impl-netconf
</type>
- <name>test2</name>
+ <name>test3</name>
</module>
</modules>
<properties>
<osgi.version>5.0.0</osgi.version>
- <maven.bundle.version>2.3.7</maven.bundle.version>
+ <maven.bundle.version>2.4.0</maven.bundle.version>
<slf4j.version>1.7.2</slf4j.version>
<netconf.netty.version>4.0.10.Final</netconf.netty.version>
<ct.exi.version>0.9.2</ct.exi.version>
<instructions>
<Import-Package>
org.opendaylight.controller.clustering.services,
+ org.opendaylight.controller.configuration,
org.opendaylight.controller.sal.core,
org.opendaylight.controller.sal.utils,
org.apache.felix.dm,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>configuration</artifactId>
<version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
import java.util.Hashtable;
import java.util.Dictionary;
+
import org.apache.felix.dm.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
* ComponentActivatorAbstractBase.
*
*/
+ @Override
public void init() {
}
* cleanup done by ComponentActivatorAbstractBase
*
*/
+ @Override
public void destroy() {
}
* instantiated in order to get an fully working implementation
* Object
*/
+ @Override
public Object[] getImplementations() {
Object[] res = { NeutronFloatingIPInterface.class,
NeutronRouterInterface.class,
* also optional per-container different behavior if needed, usually
* should not be the case though.
*/
+ @Override
public void configureInstance(Component c, Object imp, String containerName) {
if (imp.equals(NeutronFloatingIPInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronFloatingIPCRUD.class.getName() }, null);
+ new String[] { INeutronFloatingIPCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
if (imp.equals(NeutronRouterInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronRouterCRUD.class.getName() }, null);
+ new String[] { INeutronRouterCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
if (imp.equals(NeutronPortInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronPortCRUD.class.getName() }, null);
+ new String[] { INeutronPortCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
if (imp.equals(NeutronSubnetInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronSubnetCRUD.class.getName() }, null);
+ new String[] { INeutronSubnetCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
if (imp.equals(NeutronNetworkInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronNetworkCRUD.class.getName() }, null);
+ new String[] { INeutronNetworkCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
+public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.floatingip";
+ private static String fileName;
private String containerName = null;
private IClusterContainerServices clusterContainerService = null;
private void startUp() {
allocateCache();
retrieveCache();
+ if (floatingIPDB.isEmpty()) {
+ loadConfiguration();
+ }
}
/**
// In the Global instance case the containerName is empty
this.containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
// IfNBFloatingIPCRUD interface methods
+ @Override
public boolean floatingIPExists(String uuid) {
return floatingIPDB.containsKey(uuid);
}
+ @Override
public NeutronFloatingIP getFloatingIP(String uuid) {
if (!floatingIPExists(uuid))
return null;
return floatingIPDB.get(uuid);
}
+ @Override
public List<NeutronFloatingIP> getAllFloatingIPs() {
Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();
for (Entry<String, NeutronFloatingIP> entry : floatingIPDB.entrySet()) {
return ans;
}
+ @Override
public boolean addFloatingIP(NeutronFloatingIP input) {
INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
return true;
}
+ @Override
public boolean removeFloatingIP(String uuid) {
INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
return true;
}
+ @Override
public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {
INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
target.setFixedIPAddress(delta.getFixedIPAddress());
return true;
}
+
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronFloatingIP> confList = (ConcurrentMap<String, NeutronFloatingIP>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ floatingIPDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronFloatingIP>(floatingIPDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
}
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronNetworkInterface implements INeutronNetworkCRUD {
+public class NeutronNetworkInterface implements INeutronNetworkCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.network";
+ private static String fileName;
private String containerName = null;
private ConcurrentMap<String, NeutronNetwork> networkDB;
private void startUp() {
allocateCache();
retrieveCache();
+ if (networkDB.isEmpty()) {
+ loadConfiguration();
+ }
}
/**
// In the Global instance case the containerName is empty
this.containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
// IfNBNetworkCRUD methods
+ @Override
public boolean networkExists(String uuid) {
return networkDB.containsKey(uuid);
}
+ @Override
public NeutronNetwork getNetwork(String uuid) {
if (!networkExists(uuid))
return null;
return networkDB.get(uuid);
}
+ @Override
public List<NeutronNetwork> getAllNetworks() {
Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();
for (Entry<String, NeutronNetwork> entry : networkDB.entrySet()) {
return ans;
}
+ @Override
public boolean addNetwork(NeutronNetwork input) {
if (networkExists(input.getID()))
return false;
return true;
}
+ @Override
public boolean removeNetwork(String uuid) {
if (!networkExists(uuid))
return false;
return true;
}
+ @Override
public boolean updateNetwork(String uuid, NeutronNetwork delta) {
if (!networkExists(uuid))
return false;
return overwrite(target, delta);
}
+ @Override
public boolean networkInUse(String netUUID) {
if (!networkExists(netUUID))
return true;
return true;
return false;
}
+
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronNetwork> confList = (ConcurrentMap<String, NeutronNetwork>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ networkDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronNetwork>(networkDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
+
}
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronPortInterface implements INeutronPortCRUD {
+public class NeutronPortInterface implements INeutronPortCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.port";
+ private static String fileName;
private String containerName = null;
private IClusterContainerServices clusterContainerService = null;
private void startUp() {
allocateCache();
retrieveCache();
+ if (portDB.isEmpty()) {
+ loadConfiguration();
+ }
+
}
/**
// In the Global instance case the containerName is empty
containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
return null;
}
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronPort> confList = (ConcurrentMap<String, NeutronPort>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ portDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronPort>(portDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
+
}
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronRouterInterface implements INeutronRouterCRUD {
+public class NeutronRouterInterface implements INeutronRouterCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.router";
+ private static String fileName;
private String containerName = null;
private IClusterContainerServices clusterContainerService = null;
private void startUp() {
allocateCache();
retrieveCache();
+ if (routerDB.isEmpty()) {
+ loadConfiguration();
+ }
+
}
/**
// In the Global instance case the containerName is empty
this.containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
// IfNBRouterCRUD Interface methods
+ @Override
public boolean routerExists(String uuid) {
return routerDB.containsKey(uuid);
}
+ @Override
public NeutronRouter getRouter(String uuid) {
if (!routerExists(uuid))
return null;
return routerDB.get(uuid);
}
+ @Override
public List<NeutronRouter> getAllRouters() {
Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();
for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {
return ans;
}
+ @Override
public boolean addRouter(NeutronRouter input) {
if (routerExists(input.getID()))
return false;
return true;
}
+ @Override
public boolean removeRouter(String uuid) {
if (!routerExists(uuid))
return false;
return true;
}
+ @Override
public boolean updateRouter(String uuid, NeutronRouter delta) {
if (!routerExists(uuid))
return false;
return overwrite(target, delta);
}
+ @Override
public boolean routerInUse(String routerUUID) {
if (!routerExists(routerUUID))
return true;
NeutronRouter target = routerDB.get(routerUUID);
return (target.getInterfaces().size() > 0);
}
+
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronRouter> confList = (ConcurrentMap<String, NeutronRouter>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ routerDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronRouter>(routerDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
+
}
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronSubnetInterface implements INeutronSubnetCRUD {
+public class NeutronSubnetInterface implements INeutronSubnetCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.subnet";
+ private static String fileName;
+
private String containerName = null;
private IClusterContainerServices clusterContainerService = null;
private void startUp() {
allocateCache();
retrieveCache();
+ if (subnetDB.isEmpty()) {
+ loadConfiguration();
+ }
+
}
/**
// In the Global instance case the containerName is empty
this.containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
// IfNBSubnetCRUD methods
+ @Override
public boolean subnetExists(String uuid) {
return subnetDB.containsKey(uuid);
}
+ @Override
public NeutronSubnet getSubnet(String uuid) {
if (!subnetExists(uuid))
return null;
return subnetDB.get(uuid);
}
+ @Override
public List<NeutronSubnet> getAllSubnets() {
Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();
for (Entry<String, NeutronSubnet> entry : subnetDB.entrySet()) {
return ans;
}
+ @Override
public boolean addSubnet(NeutronSubnet input) {
String id = input.getID();
if (subnetExists(id))
return true;
}
+ @Override
public boolean removeSubnet(String uuid) {
if (!subnetExists(uuid))
return false;
return true;
}
+ @Override
public boolean updateSubnet(String uuid, NeutronSubnet delta) {
if (!subnetExists(uuid))
return false;
return overwrite(target, delta);
}
+ @Override
public boolean subnetInUse(String subnetUUID) {
if (!subnetExists(subnetUUID))
return true;
NeutronSubnet target = subnetDB.get(subnetUUID);
return (target.getPortsInSubnet().size() > 0);
}
+
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronSubnet> confList = (ConcurrentMap<String, NeutronSubnet>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ subnetDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronSubnet>(subnetDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
+
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronFloatingIP {
+public class NeutronFloatingIP implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@XmlRootElement(name = "network")
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronNetwork {
+public class NeutronNetwork implements Serializable {
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
+ private static final long serialVersionUID = 1L;
+
@XmlElement (name="id")
String networkUUID; // network UUID
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronPort {
+public class NeutronPort implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronRouter {
+public class NeutronRouter implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
@XmlElement (name="id")
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronRouter_Interface {
+public class NeutronRouter_Interface implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronRouter_NetworkReference {
+public class NeutronRouter_NetworkReference implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronSubnet {
+public class NeutronSubnet implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronSubnet_HostRoute {
+public class NeutronSubnet_HostRoute implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronSubnet_IPAllocationPool {
+public class NeutronSubnet_IPAllocationPool implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
@XmlElement(name="end")
String poolEnd;
- public NeutronSubnet_IPAllocationPool() { }
+ public NeutronSubnet_IPAllocationPool() {
+ }
public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) {
poolStart = lowAddress;
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class Neutron_IPs {
+public class Neutron_IPs implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>bundlescanner</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${bundlescanner.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</project>
org.osgi.service.packageadmin,
org.osgi.util.tracker,
javax.servlet.http,
- org.codehaus.jackson,
- org.codehaus.jackson.jaxrs,
- org.codehaus.jackson.map,
+ com.fasterxml.jackson.core,
+ com.fasterxml.jackson.databind,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
org.slf4j
</Import-Package>
</instructions>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${usermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>bundlescanner</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${bundlescanner.version}</version>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-jaxrs</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-base</artifactId>
+ </dependency>
+
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-json</artifactId>
- <version>${jersey.version}</version>
- </dependency>
+
</dependencies>
</project>
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
-import org.codehaus.jackson.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+
/**
* A custom exception mapper for handling Jackson JsonProcessingException types
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-
import javax.ws.rs.core.Application;
import javax.ws.rs.ext.ContextResolver;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlRootElement;
-import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
-import org.codehaus.jackson.map.DeserializationConfig;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import org.opendaylight.controller.northbound.bundlescanner.IBundleScanService;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
private static final JacksonJaxbJsonProvider getJsonProvider() {
JacksonJaxbJsonProvider jsonProvider = new JacksonJaxbJsonProvider();
- jsonProvider.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,
+ jsonProvider.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
return jsonProvider;
}
try {
throw new InternalServerErrorException("Internal Server Exception");
} catch (InternalServerErrorException e) {
- Assert.assertTrue(e instanceof InternalServerErrorException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Internal Server Exception"));
}
try {
throw new MethodNotAllowedException("Method Not Allowed Exception");
} catch (MethodNotAllowedException e) {
- Assert.assertTrue(e instanceof MethodNotAllowedException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Method Not Allowed Exception"));
}
try {
throw new NotAcceptableException("Not Acceptable Exception");
} catch (NotAcceptableException e) {
- Assert.assertTrue(e instanceof NotAcceptableException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Not Acceptable Exception"));
}
try {
throw new ResourceConflictException("Resource Conflict Exception");
} catch (ResourceConflictException e) {
- Assert.assertTrue(e instanceof ResourceConflictException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Resource Conflict Exception"));
}
try {
throw new ResourceForbiddenException("Resource Forbidden Exception");
} catch (ResourceForbiddenException e) {
- Assert.assertTrue(e instanceof ResourceForbiddenException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Resource Forbidden Exception"));
}
try {
throw new ResourceGoneException("Resource Gone Exception");
} catch (ResourceGoneException e) {
- Assert.assertTrue(e instanceof ResourceGoneException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Resource Gone Exception"));
}
try {
throw new ResourceNotFoundException("Resource Not Found Exception");
} catch (ResourceNotFoundException e) {
- Assert.assertTrue(e instanceof ResourceNotFoundException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Resource Not Found Exception"));
}
throw new ServiceUnavailableException(
"Service Unavailable Exception");
} catch (ServiceUnavailableException e) {
- Assert.assertTrue(e instanceof ServiceUnavailableException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Service Unavailable Exception"));
}
try {
throw new UnauthorizedException("Unauthorized Exception");
} catch (UnauthorizedException e) {
- Assert.assertTrue(e instanceof UnauthorizedException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Unauthorized Exception"));
}
throw new UnsupportedMediaTypeException(
"Unsupported Media Type Exception");
} catch (UnsupportedMediaTypeException e) {
- Assert.assertTrue(e instanceof UnsupportedMediaTypeException);
Assert.assertTrue(e.getResponse().getEntity()
.equals("Unsupported Media Type Exception"));
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind.annotation,
javax.xml.bind,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Export-Package>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>${sal.connection.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>${connectionmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
</dependencies>
</project>
javax.xml.bind,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Web-ContextPath>/controller/nb/v2/containermanager</Web-ContextPath>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
</dependencies>
</project>
import java.util.Set;
import javax.ws.rs.core.Application;
-import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
/**
* Instance of javax.ws.rs.core.Application used to return the classes
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
<Import-Package>
org.opendaylight.controller.sal.core,
org.opendaylight.controller.sal.utils,
+ org.opendaylight.controller.configuration,
org.opendaylight.controller.containermanager,
org.opendaylight.controller.switchmanager,
org.opendaylight.controller.usermanager,
javax.xml.bind,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
- org.codehaus.jackson.annotate,
+ com.fasterxml.jackson.annotation,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Web-ContextPath>/controller/nb/v2/controllermanager</Web-ContextPath>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>com.sun.jersey.jersey-servlet</artifactId>
- <version>1.18-SNAPSHOT</version>
+ <version>${jersey-servlet.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.6.1-SNAPSHOT</version>
+ <version>${switchmanager.api.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
- <version>7.0.43-SNAPSHOT</version>
+ <version>${corsfilter.version}</version>
</dependency>
</dependencies>
</project>
import org.codehaus.enunciate.jaxrs.ResponseCode;
import org.codehaus.enunciate.jaxrs.StatusCodes;
import org.codehaus.enunciate.jaxrs.TypeHint;
+import org.opendaylight.controller.configuration.IConfigurationService;
import org.opendaylight.controller.containermanager.IContainerManager;
import org.opendaylight.controller.northbound.commons.RestMessages;
import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
return NorthboundUtils.getResponse(status);
}
+ /**
+ * Save controller configuration
+ *
+ * Request URL:
+ * http://localhost:8080/controller/nb/v2/controllermanager/configuration
+ *
+ * Request body is empty
+ */
+ @Path("/configuration")
+ @PUT
+ @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
+ @ResponseCode(code = 503, condition = "Configuration service is unavailable.")
+ })
+ public Response saveConfiguration() {
+
+ if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation");
+ }
+
+ IConfigurationService configService = (IConfigurationService)
+ ServiceHelper.getGlobalInstance(IConfigurationService.class, this);
+
+ if (configService == null) {
+ throw new ServiceUnavailableException("Configuration Service " +
+ RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ Status status = configService.saveConfigurations();
+ if (status.isSuccess()) {
+ NorthboundUtils.auditlog("Controller Configuration", username,
+ "save", "configuration");
+ return Response.noContent().build();
+ }
+ return NorthboundUtils.getResponse(status);
+ }
+
private boolean isValidContainer(String containerName) {
if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
return true;
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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
import org.opendaylight.controller.sal.core.Property;
/**
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind.annotation,
javax.xml.bind,
org.slf4j,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Export-Package>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${forwardingrulesmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Web-ContextPath>/controller/nb/v2/hosttracker</Web-ContextPath>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- <version>${jackson.version}</version>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- <version>${jackson.version}</version>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-jaxrs</artifactId>
- <version>${jackson.version}</version>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-xc</artifactId>
- <version>${jackson.version}</version>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-jaxb-annotations</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-json</artifactId>
- <version>${jersey.version}</version>
- </dependency>
+
<dependency>
<groupId>eclipselink</groupId>
<artifactId>javax.resource</artifactId>
import java.util.List;
import java.util.Map;
import java.util.Set;
-
import javax.inject.Inject;
import org.apache.commons.codec.binary.Base64;
import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
import org.opendaylight.controller.switchmanager.IInventoryListener;
import org.opendaylight.controller.usermanager.IUserManager;
-import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.util.PathUtils;
import org.osgi.framework.Bundle;
private IUserManager userManager = null;
private IInventoryListener invtoryListener = null;
private IListenTopoUpdates topoUpdates = null;
-
+ private static final String baseUrlPrefix = "http://127.0.0.1:8080/controller/nb/v2/";
private final Boolean debugMsg = false;
private String stateToString(int state) {
System.out.println("HTTP response code: " + response.getStatus());
System.out.println("HTTP response message: " + response.getEntity());
}
-
return response.getEntity();
} catch (Exception e) {
if (debugMsg) {
@Test
public void testSubnetsNorthbound() throws JSONException, ConstructionException {
System.out.println("Starting Subnets JAXB client.");
- String baseURL = "http://127.0.0.1:8080/controller/nb/v2/subnetservice/";
+ String baseURL = baseUrlPrefix + "subnetservice/";
String name1 = "testSubnet1";
String subnet1 = "1.1.1.1/24";
@Test
public void testStaticRoutingNorthbound() throws JSONException {
System.out.println("Starting StaticRouting JAXB client.");
- String baseURL = "http://127.0.0.1:8080/controller/nb/v2/staticroute/";
+ String baseURL = baseUrlPrefix + "staticroute/";
String name1 = "testRoute1";
String prefix1 = "192.168.1.1/24";
@Test
public void testSwitchManager() throws JSONException {
System.out.println("Starting SwitchManager JAXB client.");
- String baseURL = "http://127.0.0.1:8080/controller/nb/v2/switchmanager/default/";
+ String baseURL = baseUrlPrefix + "switchmanager/default/";
// define Node/NodeConnector attributes for test
int nodeId_1 = 51966;
"SET_NW_SRC", "SET_NW_DST", "SET_NW_TOS", "SET_TP_SRC", "SET_TP_DST" };
System.out.println("Starting Statistics JAXB client.");
- String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/";
+ String baseURL = baseUrlPrefix + "statistics/default/";
String result = getJsonResult(baseURL + "flow");
JSONTokener jt = new JSONTokener(result);
@Test
public void testFlowProgrammer() throws JSONException {
System.out.println("Starting FlowProgrammer JAXB client.");
- String baseURL = "http://127.0.0.1:8080/controller/nb/v2/flowprogrammer/default/";
+ String baseURL = baseUrlPrefix + "flowprogrammer/default/";
// Attempt to get a flow that doesn't exit. Should return 404
// status.
String result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test1", "GET");
// code
fc = "{\"name\":\"test1\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"LOOPBACK\"]}";
result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test1", "PUT", fc);
- Assert.assertTrue(result.equals("Success"));
+ Assert.assertTrue(result.contains("Success"));
fc = "{\"name\":\"test2\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test2", "PUT", fc);
Integer nodeConnectorId_2 = 34;
String vlan_2 = "123";
- String baseURL = "http://127.0.0.1:8080/controller/nb/v2/hosttracker/default";
+ String baseURL = baseUrlPrefix + "hosttracker/default";
// test PUT method: addHost()
JSONObject fc_json = new JSONObject();
} else {
JSONObject ja = json.getJSONObject("hostConfig");
String na = ja.getString("networkAddress");
- return (na.equalsIgnoreCase(hostIp)) ? true : false;
+ return na.equalsIgnoreCase(hostIp);
}
}
@Test
public void testTopology() throws JSONException, ConstructionException {
System.out.println("Starting Topology JAXB client.");
- String baseURL = "http://127.0.0.1:8080/controller/nb/v2/topology/default";
+ String baseURL = baseUrlPrefix + "topology/default";
// === test GET method for getTopology()
short state_1 = State.EDGE_UP, state_2 = State.EDGE_DOWN;
mavenBundle("org.opendaylight.controller", "flowprogrammer.northbound").versionAsInProject(),
mavenBundle("org.opendaylight.controller", "subnets.northbound").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-jaxrs").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-xc").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-base").versionAsInProject(),
+ mavenBundle("com.fasterxml.jackson.module", "jackson-module-jaxb-annotations").versionAsInProject(),
+
mavenBundle("org.codehaus.jettison", "jettison").versionAsInProject(),
mavenBundle("commons-io", "commons-io").versionAsInProject(),
mavenBundle("com.sun.jersey", "jersey-client").versionAsInProject(),
mavenBundle("com.sun.jersey", "jersey-server").versionAsInProject().startLevel(2),
mavenBundle("com.sun.jersey", "jersey-core").versionAsInProject().startLevel(2),
- mavenBundle("com.sun.jersey", "jersey-json").versionAsInProject().startLevel(2), junitBundles());
+ junitBundles());
}
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind.annotation,
javax.xml.bind,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Export-Package>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>${sal.connection.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.networkconfiguration</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>${sal.networkconfiguration.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>${connectionmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
List<NeutronPort> bulk = input.getBulk();
Iterator<NeutronPort> i = bulk.iterator();
HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
while (i.hasNext()) {
NeutronPort test = i.next();
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind.annotation,
javax.xml.bind,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Export-Package>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Export-Package>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${statisticsmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${clustering.services.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${configuration.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${switchmanager.api.version}</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind.annotation,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Export-Package>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
- org.codehaus.jackson.annotate,
+ com.fasterxml.jackson.annotation,
+ com.fasterxml.jackson.databind,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Web-ContextPath>/controller/nb/v2/switchmanager</Web-ContextPath>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlElementRef;
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 org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
+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 java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlElementRef;
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 org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
+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;
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
</dependencies>
</plugin>
org.opendaylight.controller.usermanager,
org.opendaylight.controller.topologymanager,
com.sun.jersey.spi.container.servlet,
- org.codehaus.jackson.annotate,
+ com.fasterxml.jackson.annotation,
javax.ws.rs,
javax.ws.rs.core,
javax.xml.bind,
javax.xml.bind.annotation,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Web-ContextPath>/controller/nb/v2/topology</Web-ContextPath>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${topologymanager.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
+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;
javax.xml.bind.annotation,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Export-Package>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${usermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
for (OFStatistics stats : targetList) {
V6StatsReply v6Stats = (V6StatsReply) stats;
V6Match v6Match = v6Stats.getMatch();
- if (v6Stats.getPriority() == priority && v6Match.equals(targetMatch)) {
+ if (v6Stats.getPriority() == priority && targetMatch.equals(v6Match)) {
List<OFStatistics> list = new ArrayList<OFStatistics>();
list.add(stats);
return list;
} else {
for (OFStatistics stats : statsList) {
OFFlowStatisticsReply flowStats = (OFFlowStatisticsReply) stats;
- if (flowStats.getPriority() == priority && flowStats.getMatch().equals(ofMatch)) {
+ if (flowStats.getPriority() == priority && ofMatch.equals(flowStats.getMatch())) {
List<OFStatistics> list = new ArrayList<OFStatistics>();
list.add(stats);
return list;
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
}
}
+ @Override
+ public Set<Node> getConfiguredNotConnectedNodes() {
+ // TODO
+ return null;
+ }
+
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
Logger logger = LoggerFactory
.getLogger(ComponentActivatorAbstractBase.class);
private DependencyManager dm;
- private ConcurrentMap<ImmutablePair<String, Object>, Component> dbInstances = (ConcurrentMap<ImmutablePair<String, Object>, Component>) new ConcurrentHashMap<ImmutablePair<String, Object>, Component>();
- private ConcurrentMap<Object, Component> dbGlobalInstances = (ConcurrentMap<Object, Component>) new ConcurrentHashMap<Object, Component>();
+ private ConcurrentMap<ImmutablePair<String, Object>, Component> dbInstances = new ConcurrentHashMap<ImmutablePair<String, Object>, Component>();
+ private ConcurrentMap<Object, Component> dbGlobalInstances = new ConcurrentHashMap<Object, Component>();
/**
* Method that should be overriden by the derived class for customization
containerName, imps[i]);
Component c = this.dbInstances.get(key);
if (c != null) {
+ if (c.getService() != null) {
+ c.invokeCallbackMethod(new Object[] { c.getService() }, "containerStop",
+ new Class[][] {{ Component.class}, {} },
+ new Object[][] { {c}, {} });
+ }
// Now remove the component from dependency manager,
// which will implicitely stop it first
this.dm.remove(c);
package org.opendaylight.controller.sal.flowprogrammer;
-import java.io.Serializable;
-import java.net.Inet6Address;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
import org.opendaylight.controller.sal.action.Action;
import org.opendaylight.controller.sal.action.ActionType;
import org.opendaylight.controller.sal.action.SetDlType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.net.Inet6Address;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
/**
* Represent a flow: match + actions + flow specific properties
*/
}
return true;
}
+
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
public void testRoundRobinPolicy() {\r
ConfigManager cm = null;\r
cm = new ConfigManager();\r
- Assert.assertFalse(cm== null);\r
\r
Pool pool = cm.createPool("TestPool","roundrobin");\r
VIP vip = cm.createVIP("TestVIP","10.0.0.9","TCP",(short)5550,"TestPool");\r
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
javax.xml.bind,
org.slf4j,
org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
+ com.fasterxml.jackson.jaxrs.base,
+ com.fasterxml.jackson.jaxrs.json,
!org.codehaus.enunciate.jaxrs
</Import-Package>
<Web-ContextPath>/one/nb/v2/lb</Web-ContextPath>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
log.debug("Host Facing Port in a container came up, install the rules for all hosts from this port !");
Set<HostNodeConnector> allHosts = this.hostTracker.getAllHosts();
for (HostNodeConnector host : allHosts) {
- if (node.equals(host.getnodeconnectorNode())
- && swPort.equals(host.getnodeConnector())) {
+ if (node.equals(host.getnodeconnectorNode())) {
/*
* This host resides behind the same switch and port for which a port up
* message is received. Ideally this should not happen, but if it does,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
}
InetAddress thisPrefix = getPrefixForAddress(this.networkAddress);
InetAddress otherPrefix = getPrefixForAddress(ip);
- if ((thisPrefix == null) || (otherPrefix == null)) {
- return false;
- }
- if (thisPrefix.equals(otherPrefix)) {
- return true;
- }
- else {
- return false;
+ boolean isSubnetOf = true;
+ if (((thisPrefix == null) || (otherPrefix == null)) || (!thisPrefix.equals(otherPrefix)) ) {
+ isSubnetOf = false;
}
+ return isSubnetOf;
}
public short getVlan() {
}
public boolean isMutualExclusive(Subnet otherSubnet) {
- if (this.networkAddress.getClass() != otherSubnet.networkAddress
- .getClass()) {
- return true;
- }
- if (this.isSubnetOf(otherSubnet.getNetworkAddress())) {
- return false;
- }
- if (otherSubnet.isSubnetOf(this.getNetworkAddress())) {
- return false;
- }
- return true;
+ return !(isSubnetOf(otherSubnet.getNetworkAddress()) || otherSubnet.isSubnetOf(getNetworkAddress()));
}
/**
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
@XmlAccessorType(XmlAccessType.NONE)
public class SubnetConfig implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
- private static final String prettyFields[] = { GUIField.NAME.toString(),
- GUIField.GATEWAYIP.toString(), GUIField.NODEPORTS.toString() };
+ private static final String prettyFields[] = { GUIField.NAME.toString(), GUIField.GATEWAYIP.toString(),
+ GUIField.NODEPORTS.toString() };
/**
* Name of the subnet
@XmlElement
private String name;
/**
- * A.B.C.D/MM Where A.B.C.D is the Default
- * Gateway IP (L3) or ARP Querier IP (L2)
+ * A.B.C.D/MM Where A.B.C.D is the Default Gateway IP (L3) or ARP Querier IP
+ * (L2)
*/
@XmlElement
private String subnet;
/**
- * Set of node connectors in the format:
- * Port Type|Port Id@Node Type|Node Id
+ * Set of node connectors in the format: Port Type|Port Id@Node Type|Node Id
*/
@XmlElement
private List<String> nodeConnectors;
public SubnetConfig(SubnetConfig subnetConfig) {
name = subnetConfig.name;
subnet = subnetConfig.subnet;
- nodeConnectors = (subnetConfig.nodeConnectors == null) ? null : new ArrayList<String>(subnetConfig.nodeConnectors);
+ nodeConnectors = (subnetConfig.nodeConnectors == null) ? null : new ArrayList<String>(
+ subnetConfig.nodeConnectors);
}
public String getName() {
public Short getIPMaskLen() {
Short maskLen = 0;
String[] s = subnet.split("/");
- maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
+
+ try {
+ maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
+ } catch (NumberFormatException e) {
+ maskLen = 32;
+ }
return maskLen;
}
private Status validateSubnetAddress() {
if (!NetUtils.isIPAddressValid(subnet)) {
- return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s", subnet));
+ return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s",
+ subnet));
+ }
+ if ((this.getIPMaskLen() == 0) || (this.getIPMaskLen() == 32)) {
+ return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid mask: /%s",
+ this.getIPMaskLen()));
}
- if((this.getIPMaskLen() == 0) || (this.getIPMaskLen() == 32)) {
- return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid mask: /%s", this.getIPMaskLen()));
+
+ //checks that address doesn't start with 0 or 255
+ String address = subnet.split("/")[0];
+ if (address.startsWith("0.") || address.startsWith("255.")) {
+ return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s", address));
}
+
byte[] bytePrefix = NetUtils.getSubnetPrefix(this.getIPAddress(), this.getIPMaskLen()).getAddress();
long prefix = BitBufferHelper.getLong(bytePrefix);
if (prefix == 0) {
return new Status(StatusCode.BADREQUEST, "Invalid network source address: subnet zero");
}
+
+ //check that host is not set to all 0's or 1's
+ long hostAddress = BitBufferHelper.getLong(this.getIPAddress().getAddress()) - prefix;
+ if (hostAddress == 0 || hostAddress == Math.pow(2, 32-this.getIPMaskLen()) - 1) {
+ return new Status(StatusCode.BADREQUEST, String.format("Invalid subnet gateway address: /%s", subnet));
+ }
+
return new Status(StatusCode.SUCCESS);
}
}
public boolean isGlobal() {
- // If no ports are specified to be part of the domain, then it's a global domain IP
+ // If no ports are specified to be part of the domain, then it's a
+ // global domain IP
return (nodeConnectors == null || nodeConnectors.isEmpty());
}
@Override
public String toString() {
- return ("SubnetConfig [Name=" + name + ", Subnet=" + subnet
- + ", NodeConnectors=" + nodeConnectors + "]");
+ return ("SubnetConfig [Name=" + name + ", Subnet=" + subnet + ", NodeConnectors=" + nodeConnectors + "]");
}
/**
package org.opendaylight.controller.switchmanager;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import java.net.Inet6Address;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Set;
public void testSubnet() throws Exception {
InetAddress ipaddr = InetAddress.getByName("100.0.0.1");
Subnet subnet = new Subnet(ipaddr, (short) 24, (short) 5);
- Assert.assertTrue(subnet.equals(subnet));
- Assert.assertFalse(subnet.equals(null));
- Assert.assertFalse(subnet.equals(ipaddr));
+ assertTrue(subnet.equals(subnet));
+ assertFalse(subnet.equals(null));
+ assertFalse(subnet.equals(ipaddr));
Subnet subnet2 = new Subnet(ipaddr, (short) 24, (short) 5);
Inet6Address ipv6 = (Inet6Address) Inet6Address
.getByName("1111::2222:3333:4444:5555:6666");
Subnet subnet3 = new Subnet(ipv6, (short) 24, (short) 5);
- Assert.assertTrue(subnet.equals(subnet2));
- Assert.assertFalse(subnet.isMutualExclusive(subnet2));
- Assert.assertTrue(subnet.isMutualExclusive(subnet3));
+ assertTrue(subnet.equals(subnet2));
+ assertFalse(subnet.isMutualExclusive(subnet2));
+ assertTrue(subnet.isMutualExclusive(subnet3));
InetAddress subnetAddr = InetAddress.getByName("200.0.0.100");
- Assert.assertTrue(subnet.isFlatLayer2() == true);
+ assertTrue(subnet.isFlatLayer2() == true);
Set<NodeConnector> ncSet = new HashSet<NodeConnector>();
Node node = NodeCreator.createOFNode(((long) 10));
ncSet.add(nc1);
ncSet.add(nc2);
- Assert.assertTrue(subnet.hasNodeConnector(nc0));
- Assert.assertFalse(subnet.hasNodeConnector(null));
+ assertTrue(subnet.hasNodeConnector(nc0));
+ assertFalse(subnet.hasNodeConnector(null));
subnet.addNodeConnectors(ncSet);
- Assert.assertTrue(subnet.hasNodeConnector(nc0));
+ assertTrue(subnet.hasNodeConnector(nc0));
Set<NodeConnector> resultncSet = subnet.getNodeConnectors();
Assert.assertEquals(resultncSet, ncSet);
Set<NodeConnector> ncSet2 = new HashSet<NodeConnector>();
ncSet2.add(nc0);
subnet.deleteNodeConnectors(ncSet2);
- Assert.assertFalse(subnet.getNodeConnectors().contains(nc0));
- Assert.assertFalse(subnet.hasNodeConnector(nc0));
- Assert.assertTrue(subnet.getNodeConnectors().contains(nc1));
- Assert.assertTrue(subnet.getNodeConnectors().contains(nc2));
+ assertFalse(subnet.getNodeConnectors().contains(nc0));
+ assertFalse(subnet.hasNodeConnector(nc0));
+ assertTrue(subnet.getNodeConnectors().contains(nc1));
+ assertTrue(subnet.getNodeConnectors().contains(nc2));
subnet.deleteNodeConnectors(ncSet2);
subnet.setNetworkAddress(subnetAddr);
- Assert.assertTrue(subnet.isMutualExclusive(subnet2));
- Assert.assertTrue(subnet.getNetworkAddress().equals(subnetAddr));
+ assertTrue(subnet.isMutualExclusive(subnet2));
+ assertTrue(subnet.getNetworkAddress().equals(subnetAddr));
subnet.setSubnetMaskLength((short) 16);
- Assert.assertTrue(subnet.getSubnetMaskLength() == 16);
+ assertTrue(subnet.getSubnetMaskLength() == 16);
subnet.setVlan((short) 100);
- Assert.assertTrue(subnet.getVlan() == 100);
+ assertTrue(subnet.getVlan() == 100);
+
+ assertTrue(subnet.isFlatLayer2() == false);
+ }
+
+ @Test
+ public void checkIsSubnetOfComparisonMatch() {
+ String host = "10.0.0.1";
+ InetAddress ipAddrForSubnetComparison = null;
+ try {
+ ipAddrForSubnetComparison = InetAddress.getByName(host);
+ } catch (UnknownHostException e) {
+ fail("Failed to create InetAddress object for" + host);
+ }
+ SubnetConfig subnetConf = new SubnetConfig("subnet", "10.0.0.254/24",null);
+ Subnet subnet = new Subnet(subnetConf);
+ assertTrue(subnet.isSubnetOf(ipAddrForSubnetComparison));
+ }
- Assert.assertTrue(subnet.isFlatLayer2() == false);
+ @Test
+ public void checkIsSubnetOfComparisonNoMatch() {
+ String host = "100.0.0.1";
+ InetAddress ipAddrForSubnetComparison = null;
+ try {
+ ipAddrForSubnetComparison = InetAddress.getByName(host);
+ } catch (UnknownHostException e) {
+ fail("Failed to create InetAddress object for" + host);
+ }
+ SubnetConfig subnetConf = new SubnetConfig("subnet", "10.0.0.254/24",null);
+ Subnet subnet = new Subnet(subnetConf);
+ assertFalse(subnet.isSubnetOf(ipAddrForSubnetComparison));
+ }
+
+ @Test
+ public void checkIsSubnetOfComparisonIpEmpty() {
+ SubnetConfig subnetConf = new SubnetConfig("subnet", "10.0.0.254/24",null);
+ Subnet subnet = new Subnet(subnetConf);
+ assertFalse(subnet.isSubnetOf(null));
}
+
+
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
import org.opendaylight.controller.sal.core.UpdateType;
import org.opendaylight.controller.sal.packet.address.EthernetAddress;
import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
import org.opendaylight.controller.sal.utils.NodeCreator;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.switchmanager.ISwitchManager;
import org.opendaylight.controller.switchmanager.SpanConfig;
import org.opendaylight.controller.switchmanager.Subnet;
private final class TestSwitchManager implements ISwitchManager {
private final Set<Node> nodeSet = new HashSet<Node>();
private final Set<NodeConnector> nodeConnectorSet =
- new HashSet<NodeConnector>();
+ new HashSet<NodeConnector>();
private void addNodeConnectors(NodeConnector ... connectors) {
for (NodeConnector nc: connectors) {
private void addNodeConnectors(TopologyUserLinkConfig ... links) {
for (TopologyUserLinkConfig link: links) {
NodeConnector src =
- NodeConnector.fromString(link.getSrcNodeConnector());
+ NodeConnector.fromString(link.getSrcNodeConnector());
NodeConnector dst =
- NodeConnector.fromString(link.getDstNodeConnector());
+ NodeConnector.fromString(link.getDstNodeConnector());
addNodeConnectors(src, dst);
}
}
public String getNodeDescription(Node node) {
return null;
}
+
+ @Override
+ public Status removeControllerProperty(String propertyName){
+ return null;
+ }
+
+ @Override
+ public Set<Switch> getConfiguredNotConnectedSwitches() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Map<String, Property> getControllerProperties() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Property getControllerProperty(String propertyName) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Status setControllerProperty(Property property) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
/*
Assert.assertTrue(topoManagerImpl.getUserLinks().isEmpty());
TopologyUserLinkConfig badlink1 =
- new TopologyUserLinkConfig("bad1", "OF|1@OF|4", "OF|1@OF|5");
+ new TopologyUserLinkConfig("bad1", "OF|1@OF|4", "OF|1@OF|5");
TopologyUserLinkConfig badlink2 =
- new TopologyUserLinkConfig("bad2", "OF|10@OF|7", "OF|7@OF|13");
+ new TopologyUserLinkConfig("bad2", "OF|10@OF|7", "OF|7@OF|13");
Assert.assertEquals(StatusCode.NOTFOUND,
- topoManagerImpl.addUserLink(badlink1).getCode());
+ topoManagerImpl.addUserLink(badlink1).getCode());
Assert.assertEquals(StatusCode.NOTFOUND,
- topoManagerImpl.addUserLink(badlink2).getCode());
+ topoManagerImpl.addUserLink(badlink2).getCode());
}
@Test
reverseLink[i] = new TopologyUserLinkConfig(name, dstNodeConnector, srcNodeConnector);
Assert.assertEquals(StatusCode.NOTFOUND,
- topoManagerImpl.addUserLink(link[i]).getCode());
+ topoManagerImpl.addUserLink(link[i]).getCode());
swMgr.addNodeConnectors(link[i]);
Assert.assertTrue(topoManagerImpl.addUserLink(link[i]).isSuccess());
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
org.apache.taglibs.standard.tag.rt.fmt,
org.apache.taglibs.standard.tei,
org.apache.taglibs.standard.tlv,
- org.codehaus.jackson,
- org.codehaus.jackson.annotate,
- org.codehaus.jackson.map,
- org.codehaus.jackson.map.annotate,
+ com.fasterxml.jackson.databind,
+ com.fasterxml.jackson.annotation,
org.osgi.framework,
org.slf4j,
org.springframework.beans,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting</artifactId>
<version>${forwarding.staticrouting}</version>
</dependency>
+
<dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
</project>
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.codehaus.jackson.map.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.opendaylight.controller.connectionmanager.IConnectionManager;
import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
one.f.menu = {
left : {
top : [
- one.f.dashlet.nodesLearnt,
- one.f.dashlet.connection
+ one.f.dashlet.nodesLearnt
],
bottom : [
- one.f.dashlet.staticRouteConfig
+ one.f.dashlet.staticRouteConfig,
+ one.f.dashlet.connection
]
},
right : {
$fieldset.append($label).append($select);
// input port
- var $label = one.lib.form.label("Input Port");
+ var $label = one.lib.form.label("Port");
var $select = one.lib.form.select.create();
one.lib.form.select.prepend($select, {'':'None'});
$select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.port);
org.apache.taglibs.standard.tag.rt.fmt,
org.apache.taglibs.standard.tei,
org.apache.taglibs.standard.tlv,
- org.codehaus.jackson,
- org.codehaus.jackson.annotate,
- org.codehaus.jackson.map,
- org.codehaus.jackson.map.annotate,
+ com.fasterxml.jackson.core,
+ com.fasterxml.jackson.annotation,
+ com.fasterxml.jackson.databind,
org.osgi.framework,
org.slf4j,
org.springframework.beans,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
$tr = $(tr);
$span = $("td span", $tr);
var flowstatus = $span.data("flowstatus");
- if($span.data("installInHw") != null) {
- var installInHw = $span.data("installInHw").toString();
+ if($span.data("installinhw") != null) {
+ var installInHw = $span.data("installinhw").toString();
if(installInHw == "true" && flowstatus == "Success") {
$tr.addClass("success");
} else {
org.apache.taglibs.standard.tag.rt.fmt,
org.apache.taglibs.standard.tei,
org.apache.taglibs.standard.tlv,
- org.codehaus.jackson,
- org.codehaus.jackson.annotate,
- org.codehaus.jackson.map,
- org.codehaus.jackson.map.annotate,
+ com.fasterxml.jackson.core,
+ com.fasterxml.jackson.databind,
+ com.fasterxml.jackson.annotation,
org.osgi.framework,
org.slf4j,
org.springframework.beans,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
package org.opendaylight.controller.web;
+import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.opendaylight.controller.usermanager.IUserManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
return "main";
}
+ /**
+ * Read the version.properties file for the property
+ *
+ * @param request
+ * @return String value configured in the version.properties file
+ */
+ @RequestMapping(value="/versionProperty/{property}", method = RequestMethod.GET)
+ @ResponseBody
+ public String getVersion(HttpServletRequest request, @PathVariable("property") String property) {
+ Properties prop = new Properties();
+ try {
+ prop.load(new FileInputStream("version.properties"));
+ return prop.getProperty(property+".version");
+ } catch (Exception e) {
+ return null;
+ }
+ }
@RequestMapping(value = "web.json")
@ResponseBody
public Map<String, Map<String, Object>> bundles(HttpServletRequest request) {
<url-pattern>/images/*</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/favicon.ico</url-pattern>
+ <url-pattern>/versionProperty/*</url-pattern>
</web-resource-collection>
</security-constraint>
org.apache.taglibs.standard.tag.rt.fmt,
org.apache.taglibs.standard.tei,
org.apache.taglibs.standard.tlv,
- org.codehaus.jackson,
- org.codehaus.jackson.annotate,
- org.codehaus.jackson.map,
- org.codehaus.jackson.map.annotate,
+ com.fasterxml.jackson.core,
+ com.fasterxml.jackson.databind,
+ com.fasterxml.jackson.annotation,
org.osgi.framework,
org.slf4j,
org.springframework.beans,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
org.apache.taglibs.standard.tag.rt.fmt,
org.apache.taglibs.standard.tei,
org.apache.taglibs.standard.tlv,
- org.codehaus.jackson,
- org.codehaus.jackson.annotate,
- org.codehaus.jackson.map,
- org.codehaus.jackson.map.annotate,
+ com.fasterxml.jackson.core,
+ com.fasterxml.jackson.databind,
+ com.fasterxml.jackson.annotation,
org.osgi.framework,
org.slf4j,
org.springframework.beans,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
<version>0.4.1-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
</dependencies>
</project>