From: Ed Warnicke Date: Sat, 18 Jan 2014 16:58:20 +0000 (+0000) Subject: Merge "Fix for Bug 3" X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~69 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=91d7c1ee52322acad08e9f81228ac36b3aa684f5;hp=65906d0c56d26e1f69d39875b7efe3b1b84930dc Merge "Fix for Bug 3" --- diff --git a/.gitignore b/.gitignore index 18817e7c35..b079cba0a1 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ opendaylight/northbound/integrationtest/logs/* .idea xtend-gen classes +out/ diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000000..5c4f71de40 --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=git.opendaylight.org +port=29418 +project=controller.git diff --git a/opendaylight/appauth/pom.xml b/opendaylight/appauth/pom.xml index cba2bb89ba..f3a6a3bf4d 100644 --- a/opendaylight/appauth/pom.xml +++ b/opendaylight/appauth/pom.xml @@ -50,7 +50,7 @@ org.opendaylight.controller sal - 0.6.0-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/arphandler/pom.xml b/opendaylight/arphandler/pom.xml index e3576e6ed8..8d3df87c58 100644 --- a/opendaylight/arphandler/pom.xml +++ b/opendaylight/arphandler/pom.xml @@ -78,7 +78,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java b/opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java index 8c91c71533..8ae038c30f 100644 --- a/opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java +++ b/opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java @@ -461,6 +461,11 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA 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 diff --git a/opendaylight/clustering/services_implementation/pom.xml b/opendaylight/clustering/services_implementation/pom.xml index 90df7511e4..536fb7dd2e 100644 --- a/opendaylight/clustering/services_implementation/pom.xml +++ b/opendaylight/clustering/services_implementation/pom.xml @@ -142,7 +142,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.jboss.jbossts.jta diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java index fcf71a90ac..65e7720dd3 100644 --- a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java +++ b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java @@ -68,7 +68,7 @@ public class ClusterManager implements IClusterServices { private HashSet 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; diff --git a/opendaylight/clustering/stub/pom.xml b/opendaylight/clustering/stub/pom.xml index 8fe1a99a0d..26980e4ff5 100644 --- a/opendaylight/clustering/stub/pom.xml +++ b/opendaylight/clustering/stub/pom.xml @@ -53,7 +53,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java b/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java index fe73e240f9..f27e6f069f 100644 --- a/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java +++ b/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java @@ -43,7 +43,7 @@ public abstract class ClusterManagerCommon implements IClusterServicesCommon { private ConcurrentMap> caches = new ConcurrentHashMap>(); protected ClusterManagerCommon() throws UnknownHostException { - loopbackAddress = InetAddress.getByName("127.0.0.1"); + loopbackAddress = InetAddress.getLoopbackAddress(); } /** diff --git a/opendaylight/clustering/test/pom.xml b/opendaylight/clustering/test/pom.xml index 4c00ba0db1..e6f889c478 100644 --- a/opendaylight/clustering/test/pom.xml +++ b/opendaylight/clustering/test/pom.xml @@ -52,12 +52,12 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT equinoxSDK381 diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 5183165752..24b1ed9cbc 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -46,7 +46,7 @@ org.openflow.openflowj,net.sf.jung2 1.0.9 1.7.2 - 1.9.8 + 2.3.0 3.1.3.RELEASE 3.1.3.RELEASE 1.2.1 @@ -61,6 +61,7 @@ 5.0.0 2010.09.24.2-SNAPSHOT 2010.09.24.2-SNAPSHOT + 2013.10.21.0-SNAPSHOT 2013.08.27.1 2013.09.07.1 3.17.1-GA @@ -95,12 +96,21 @@ 0.0.1-SNAPSHOT 4.0.10.Final 2.4 - - jacoco - java + 0.4.1-SNAPSHOT + 0.4.1-SNAPSHOT 0.5.0-SNAPSHOT 0.5.0-SNAPSHOT 0.5.0-SNAPSHOT + 0.4.1-SNAPSHOT + 0.4.1-SNAPSHOT + + 1.18-SNAPSHOT + 7.0.43-SNAPSHOT + + 0.4.1-SNAPSHOT + + jacoco + java 2.5.1 1.7 1.7 @@ -149,26 +159,43 @@ logback-classic ${logback.version} - - org.codehaus.jackson - jackson-mapper-asl - ${jackson.version} - - - org.codehaus.jackson - jackson-core-asl + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base ${jackson.version} - - - org.codehaus.jackson - jackson-jaxrs + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider ${jackson.version} - - - org.codehaus.jackson - jackson-xc + + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations ${jackson.version} - + + org.codehaus.jettison jettison @@ -577,11 +604,7 @@ jersey-client ${jersey.version} - - com.sun.jersey - jersey-json - ${jersey.version} - + org.ow2.asm asm-all @@ -621,12 +644,12 @@ org.opendaylight.controller.thirdparty com.sun.jersey.jersey-servlet - 1.17 + ${jersey-servlet.version} org.opendaylight.controller.thirdparty org.apache.catalina.filters.CorsFilter - 7.0.42 + ${corsfilter.version} org.opendaylight.controller.thirdparty @@ -644,6 +667,11 @@ ietf-yang-types ${ietf-yang-types.version} + + org.opendaylight.yangtools.model + ietf-topology + ${ietf-topology.version} + org.opendaylight.yangtools.model opendaylight-l2-types @@ -726,7 +754,7 @@ org.opendaylight.controller switchmanager - 0.5.1-SNAPSHOT + ${switchmanager.api.version} diff --git a/opendaylight/config/config-api/pom.xml b/opendaylight/config/config-api/pom.xml index 38fb8ed66b..10c9fad07e 100644 --- a/opendaylight/config/config-api/pom.xml +++ b/opendaylight/config/config-api/pom.xml @@ -58,10 +58,6 @@ org.opendaylight.yangtools yang-maven-plugin - - org.codehaus.mojo - build-helper-maven-plugin - diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ValidationException.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ValidationException.java index 90b8bb6d85..da54a8341a 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ValidationException.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ValidationException.java @@ -21,7 +21,7 @@ import java.util.Map.Entry; public class ValidationException extends RuntimeException { private static final long serialVersionUID = -6072893219820274247L; - private final Map> failedValidations; + private final Map> failedValidations; public ValidationException( Map> failedValidations) { @@ -70,7 +70,7 @@ public class ValidationException extends RuntimeException { return new ValidationException(failedValidations); } - public Map> getFailedValidations() { + public Map> getFailedValidations() { return failedValidations; } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java index 81b0921660..64ce14e8f1 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java @@ -8,7 +8,6 @@ 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; @@ -26,19 +25,25 @@ import org.opendaylight.controller.config.util.ConfigRegistryJMXClient; 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; @@ -66,8 +71,16 @@ public abstract class AbstractConfigTest extends protected BundleContext mockedContext = mock(BundleContext.class); protected ServiceRegistration mockedServiceRegistration; - protected Map 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 @@ -166,9 +179,8 @@ public abstract class AbstractConfigTest extends 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) { @@ -204,26 +216,68 @@ public abstract class AbstractConfigTest extends } 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 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; + } + } diff --git a/opendaylight/config/config-persister-api/pom.xml b/opendaylight/config/config-persister-api/pom.xml index 80016a804b..f622992bb5 100644 --- a/opendaylight/config/config-persister-api/pom.xml +++ b/opendaylight/config/config-persister-api/pom.xml @@ -24,6 +24,10 @@ + + org.apache.maven.plugins + maven-jar-plugin + org.apache.felix maven-bundle-plugin diff --git a/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java b/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java new file mode 100644 index 0000000000..2df07b114c --- /dev/null +++ b/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java @@ -0,0 +1,29 @@ +/* + * 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 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; + } +} diff --git a/opendaylight/config/config-persister-directory-adapter/pom.xml b/opendaylight/config/config-persister-directory-adapter/pom.xml index b2da71eea2..c67a08c7af 100644 --- a/opendaylight/config/config-persister-directory-adapter/pom.xml +++ b/opendaylight/config/config-persister-directory-adapter/pom.xml @@ -42,6 +42,12 @@ mockito-configuration test + + ${project.groupId} + config-persister-api + test-jar + test + diff --git a/opendaylight/config/config-persister-directory-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryPersister.java b/opendaylight/config/config-persister-directory-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryPersister.java index a123eb981e..eb8ef8cddf 100644 --- a/opendaylight/config/config-persister-directory-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryPersister.java +++ b/opendaylight/config/config-persister-directory-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryPersister.java @@ -33,21 +33,23 @@ public class DirectoryPersister implements Persister { 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) { @@ -78,13 +80,18 @@ public class DirectoryPersister implements Persister { 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() { diff --git a/opendaylight/config/config-persister-directory-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryStorageAdapterTest.java b/opendaylight/config/config-persister-directory-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryStorageAdapterTest.java index f17e414c49..72bd208ff3 100644 --- a/opendaylight/config/config-persister-directory-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryStorageAdapterTest.java +++ b/opendaylight/config/config-persister-directory-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryStorageAdapterTest.java @@ -8,28 +8,32 @@ 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.emptyList(), tested.loadLastConfigs()); try { @@ -60,7 +64,11 @@ public class DirectoryStorageAdapterTest { @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 results = tested.loadLastConfigs(); assertEquals(1, results.size()); ConfigSnapshotHolder result = results.get(0); @@ -71,7 +79,11 @@ public class DirectoryStorageAdapterTest { @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 results = tested.loadLastConfigs(); assertEquals(2, results.size()); assertSnapshot(results.get(0), "twoFilesExpected1"); diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml b/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml new file mode 100644 index 0000000000..0ec7726e3a --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + + config-subsystem + org.opendaylight.controller + 0.2.3-SNAPSHOT + .. + + config-persister-directory-autodetect-adapter + ${project.artifactId} + bundle + + + + + ${project.groupId} + config-persister-api + + + org.apache.commons + commons-lang3 + + + com.google.guava + guava + + + org.opendaylight.controller + config-persister-directory-adapter + ${config.version} + + + org.opendaylight.controller + config-persister-directory-xml-adapter + ${config.version} + + + + org.slf4j + slf4j-api + + + commons-io + commons-io + + + + + org.opendaylight.bgpcep + mockito-configuration + test + + + + + + + + + org.codehaus.groovy.maven + gmaven-plugin + + + generate-sources + + execute + + + + System.setProperty("osgiversion", "${project.version}".replace('-', '.')) + + + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.groupId}.config-persister-impl;bundle-version=${osgiversion} + + org.opendaylight.controller.config.persister.storage.adapter + + + 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 + + + org.opendaylight.controller.config.persist.storage.file.xml.model, + org.opendaylight.controller.config.persist.storage.directory, + org.opendaylight.controller.config.persist.storage.directory.xml, + + + + + + + + diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java new file mode 100644 index 0000000000..f262952281 --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java @@ -0,0 +1,95 @@ +/* + * 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 loadLastConfigs() throws IOException { + File[] filesArray = storage.listFiles(); + if (filesArray == null || filesArray.length == 0) { + return Collections.emptyList(); + } + List sortedFiles = new ArrayList<>(Arrays.asList(filesArray)); + Collections.sort(sortedFiles); + + // combine all found files + logger.debug("Reading files in following order: {}", sortedFiles); + + List 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(); + } +} diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java new file mode 100644 index 0000000000..f856ddd6cb --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java @@ -0,0 +1,39 @@ +/* + * 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); + } + +} diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java new file mode 100644 index 0000000000..779a887924 --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java @@ -0,0 +1,83 @@ +/* + * 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 = " { + 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; + } + } +} diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java new file mode 100644 index 0000000000..7e423914c2 --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java @@ -0,0 +1,37 @@ +/* + * 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 configs = persister.loadLastConfigs(); + + Assert.assertEquals(2, configs.size()); + String snapFromTxt = configs.get(0).getConfigSnapshot(); + org.junit.Assert.assertThat(snapFromTxt, JUnitMatchers.containsString("txt")); + org.junit.Assert.assertThat(snapFromTxt, JUnitMatchers.containsString("txt")); + + String snapFromXml = configs.get(1).getConfigSnapshot(); + org.junit.Assert.assertThat(snapFromXml, JUnitMatchers.containsString("xml")); + + Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities()); + } +} diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java new file mode 100644 index 0000000000..bbc272d388 --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java @@ -0,0 +1,52 @@ +/* + * 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); + } + +} diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config new file mode 100644 index 0000000000..f72cd1c080 --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config @@ -0,0 +1,8 @@ +//MODULES START + txt +//SERVICES START + txt +//CAPABILITIES START +cap1&rev +cap2 +capa a \ No newline at end of file diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config new file mode 100644 index 0000000000..988f86675d --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config @@ -0,0 +1,10 @@ + + + cap1&rev + cap2 + capa a + + + xml + + \ No newline at end of file diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config new file mode 100644 index 0000000000..edf37caf0e --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config @@ -0,0 +1,2 @@ +//MODULES START +configuration \ No newline at end of file diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config new file mode 100644 index 0000000000..fe94299adb --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config new file mode 100644 index 0000000000..c4218c8d64 --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config @@ -0,0 +1,2 @@ +unknown +file type \ No newline at end of file diff --git a/opendaylight/config/config-persister-directory-xml-adapter/pom.xml b/opendaylight/config/config-persister-directory-xml-adapter/pom.xml index b2ea632834..96d3a71c30 100644 --- a/opendaylight/config/config-persister-directory-xml-adapter/pom.xml +++ b/opendaylight/config/config-persister-directory-xml-adapter/pom.xml @@ -57,6 +57,12 @@ mockito-configuration test + + ${project.groupId} + config-persister-api + test-jar + test + diff --git a/opendaylight/config/config-persister-directory-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/xml/XmlDirectoryPersister.java b/opendaylight/config/config-persister-directory-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/xml/XmlDirectoryPersister.java index f6f6de9fd5..0ca47edf0e 100644 --- a/opendaylight/config/config-persister-directory-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/xml/XmlDirectoryPersister.java +++ b/opendaylight/config/config-persister-directory-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/xml/XmlDirectoryPersister.java @@ -63,17 +63,21 @@ public class XmlDirectoryPersister implements Persister { 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() { diff --git a/opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java b/opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java index 73061f81de..825eb946c8 100644 --- a/opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java +++ b/opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java @@ -8,20 +8,21 @@ 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 { @@ -58,7 +59,8 @@ public class DirectoryStorageAdapterTest { @Test public void testOneFile() throws Exception { File folder = getFolder("oneFile"); - tested = new XmlDirectoryPersister((folder)); + tested = new XmlDirectoryPersister(folder); + logger.info("Testing : "+tested.toString()); List results = tested.loadLastConfigs(); assertEquals(1, results.size()); ConfigSnapshotHolder result = results.get(0); @@ -77,6 +79,7 @@ public class DirectoryStorageAdapterTest { public void testTwoFiles() throws Exception { File folder = getFolder("twoFiles"); tested = new XmlDirectoryPersister((folder)); + logger.info("Testing : "+tested.toString()); List results = tested.loadLastConfigs(); assertEquals(2, results.size()); diff --git a/opendaylight/config/config-persister-file-adapter/pom.xml b/opendaylight/config/config-persister-file-adapter/pom.xml index b16cb2b6f3..3cd3e907b3 100644 --- a/opendaylight/config/config-persister-file-adapter/pom.xml +++ b/opendaylight/config/config-persister-file-adapter/pom.xml @@ -38,6 +38,12 @@ mockito-configuration test + + ${project.groupId} + config-persister-api + test-jar + test + diff --git a/opendaylight/config/config-persister-file-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapter.java b/opendaylight/config/config-persister-file-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapter.java index 3ec8713b47..1b9948bf39 100644 --- a/opendaylight/config/config-persister-file-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapter.java +++ b/opendaylight/config/config-persister-file-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapter.java @@ -13,15 +13,6 @@ import com.google.common.base.Charsets; 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; @@ -31,9 +22,17 @@ import java.util.List; 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); diff --git a/opendaylight/config/config-persister-file-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapterTest.java b/opendaylight/config/config-persister-file-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapterTest.java index 0236598f2b..0366dbcaed 100644 --- a/opendaylight/config/config-persister-file-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapterTest.java +++ b/opendaylight/config/config-persister-file-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapterTest.java @@ -11,18 +11,18 @@ package org.opendaylight.controller.config.persist.storage.file; 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; @@ -42,6 +42,49 @@ public class FileStorageAdapterTest { 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 getCapabilities() { + return createCaps(); + } + }; + configPersister.persistConfig(holder); + + configPersister.persistConfig(holder); + + Collection readLines = Collections2.filter(com.google.common.io.Files.readLines(file, Charsets.UTF_8), + new Predicate() { + + @Override + public boolean apply(String input) { + if (input.equals("")) + return false; + return true; + } + }); + assertEquals(14, readLines.size()); + + List lastConf = storage.loadLastConfigs(); + assertEquals(1, lastConf.size()); + ConfigSnapshotHolder configSnapshotHolder = lastConf.get(0); + assertEquals("2", + configSnapshotHolder.getConfigSnapshot().replaceAll("\\s", "")); + assertEquals(createCaps(), configSnapshotHolder.getCapabilities()); + } @Test public void testFileAdapter() throws Exception { FileStorageAdapter storage = new FileStorageAdapter(); diff --git a/opendaylight/config/config-persister-file-xml-adapter/pom.xml b/opendaylight/config/config-persister-file-xml-adapter/pom.xml index abbec382b7..d08a93e114 100644 --- a/opendaylight/config/config-persister-file-xml-adapter/pom.xml +++ b/opendaylight/config/config-persister-file-xml-adapter/pom.xml @@ -47,6 +47,12 @@ mockito-configuration test + + ${project.groupId} + config-persister-api + test-jar + test + diff --git a/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/ConfigSnapshot.java b/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/ConfigSnapshot.java index 41976000ba..cfc70858c3 100644 --- a/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/ConfigSnapshot.java +++ b/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/ConfigSnapshot.java @@ -15,9 +15,11 @@ import javax.xml.bind.annotation.XmlElementWrapper; 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 capabilities; diff --git a/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java b/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java index d6bbeb31da..0e4cce544f 100644 --- a/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java +++ b/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java @@ -9,18 +9,17 @@ 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; @@ -43,8 +42,11 @@ public class FileStorageAdapterTest { @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() { @@ -89,8 +91,12 @@ public class FileStorageAdapterTest { @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() { @@ -106,7 +112,7 @@ public class FileStorageAdapterTest { 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 lastConf = storage.loadLastConfigs(); assertEquals(1, lastConf.size()); diff --git a/opendaylight/config/config-plugin-parent/pom.xml b/opendaylight/config/config-plugin-parent/pom.xml index 7696ae5573..0117098ee1 100644 --- a/opendaylight/config/config-plugin-parent/pom.xml +++ b/opendaylight/config/config-plugin-parent/pom.xml @@ -72,6 +72,7 @@ ${jmxGeneratorPath} + ${salGeneratorPath} diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionClient.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionClient.java index 75b180921a..4f02db5a38 100644 --- a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionClient.java +++ b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionClient.java @@ -32,8 +32,13 @@ public interface ConfigTransactionClient extends 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); } diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java index e683d915ba..3583dafd0d 100644 --- a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java +++ b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java @@ -84,12 +84,23 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient { } @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(); diff --git a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetter.java b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetter.java index 3241fb01af..4c83668ab6 100644 --- a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetter.java +++ b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetter.java @@ -1,11 +1,9 @@ -/** - * 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; diff --git a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetterImpl.java b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetterImpl.java index 02fba141b3..9837a04e7f 100644 --- a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetterImpl.java +++ b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetterImpl.java @@ -1,11 +1,9 @@ -/** - * 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; diff --git a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModule.java b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModule.java index d75bf6367a..adc69fe31e 100644 --- a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModule.java +++ b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleFactory.java b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleFactory.java index 5e8612f7b9..5a91796ed6 100644 --- a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleFactory.java +++ b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackStatusListener.java b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackStatusListener.java index 9e63e57489..e8d161afbb 100644 --- a/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackStatusListener.java +++ b/opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackStatusListener.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java index 02cbd247a7..3c52d8c17a 100644 --- a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java +++ b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java index 79a5121fa8..c03ade8b5f 100644 --- a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java +++ b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java b/opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java index 6af508829b..71c4b192e5 100644 --- a/opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java +++ b/opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java @@ -1,3 +1,11 @@ +/* + * 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; diff --git a/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java b/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java index 9ceef3116a..3d5a3bf4ad 100644 --- a/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java +++ b/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleFactory.java b/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleFactory.java index 1dca38182d..c97bd566b0 100644 --- a/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleFactory.java +++ b/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModule.java b/opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModule.java index cc78124680..e65a4d335e 100644 --- a/opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModule.java +++ b/opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleFactory.java b/opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleFactory.java index e291ab5465..c869413a5e 100644 --- a/opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleFactory.java +++ b/opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/netty-timer-config/src/test/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleTest.java b/opendaylight/config/netty-timer-config/src/test/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleTest.java index 8bc4d95d60..1b5668b610 100644 --- a/opendaylight/config/netty-timer-config/src/test/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleTest.java +++ b/opendaylight/config/netty-timer-config/src/test/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleTest.java @@ -1,3 +1,10 @@ +/* + * 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; diff --git a/opendaylight/config/pom.xml b/opendaylight/config/pom.xml index eba5e07c0f..acd4916a4b 100644 --- a/opendaylight/config/pom.xml +++ b/opendaylight/config/pom.xml @@ -41,7 +41,10 @@ netty-timer-config config-persister-directory-adapter config-persister-directory-xml-adapter + config-persister-directory-autodetect-adapter yang-test-plugin + shutdown-api + shutdown-impl @@ -61,13 +64,14 @@ 1.7 1.7 4.10 - 2.3.7 + 2.4.0 5.0.0 0.6.2.201302030002 1.7.2 0.5.9-SNAPSHOT 0.6.0-SNAPSHOT 0.1.1-SNAPSHOT + ${project.build.directory}/generated-sources/sal @@ -155,6 +159,12 @@ config-persister-api ${config.version} + + ${project.groupId} + config-persister-api + ${config.version} + test-jar + org.opendaylight.bgpcep mockito-configuration @@ -212,6 +222,12 @@ ${config.version} + + org.opendaylight.controller + shutdown-api + ${config.version} + + org.opendaylight.yangtools @@ -269,10 +285,8 @@ org.apache.maven.plugins maven-surefire-plugin - - org.codehaus.mojo - build-helper-maven-plugin - + + @@ -295,7 +309,7 @@ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - target/generated-sources/sal + ${salGeneratorPath} @@ -316,6 +330,26 @@ + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + add-source + generate-sources + + add-source + + + + ${salGeneratorPath} + + + + + org.apache.maven.plugins maven-jar-plugin diff --git a/opendaylight/config/shutdown-api/pom.xml b/opendaylight/config/shutdown-api/pom.xml new file mode 100644 index 0000000000..0603b2d82d --- /dev/null +++ b/opendaylight/config/shutdown-api/pom.xml @@ -0,0 +1,47 @@ + + + + config-plugin-parent + org.opendaylight.controller + 0.2.3-SNAPSHOT + ../config-plugin-parent + + 4.0.0 + bundle + shutdown-api + + + + com.google.guava + guava + + + org.opendaylight.controller + config-api + + + + + + + org.apache.felix + maven-bundle-plugin + + + + org.opendaylight.controller.config.shutdown, + org.opendaylight.controller.config.yang.shutdown + + + + + + org.opendaylight.yangtools + yang-maven-plugin + + + + + diff --git a/opendaylight/config/shutdown-api/src/main/java/org/opendaylight/controller/config/shutdown/ShutdownService.java b/opendaylight/config/shutdown-api/src/main/java/org/opendaylight/controller/config/shutdown/ShutdownService.java new file mode 100644 index 0000000000..104241757f --- /dev/null +++ b/opendaylight/config/shutdown-api/src/main/java/org/opendaylight/controller/config/shutdown/ShutdownService.java @@ -0,0 +1,21 @@ +/* + * 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 reason); +} diff --git a/opendaylight/config/shutdown-api/src/main/yang/shutdown.yang b/opendaylight/config/shutdown-api/src/main/yang/shutdown.yang new file mode 100644 index 0000000000..eb09178841 --- /dev/null +++ b/opendaylight/config/shutdown-api/src/main/yang/shutdown.yang @@ -0,0 +1,29 @@ +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"; + } + +} diff --git a/opendaylight/config/shutdown-impl/pom.xml b/opendaylight/config/shutdown-impl/pom.xml new file mode 100644 index 0000000000..4fcb0c89f0 --- /dev/null +++ b/opendaylight/config/shutdown-impl/pom.xml @@ -0,0 +1,64 @@ + + + + config-plugin-parent + org.opendaylight.controller + 0.2.3-SNAPSHOT + ../config-plugin-parent + + 4.0.0 + bundle + shutdown-impl + + + + com.google.guava + guava + + + org.opendaylight.controller + config-api + + + org.opendaylight.controller + shutdown-api + + + org.opendaylight.controller + config-manager + test + test-jar + + + org.opendaylight.controller + config-manager + test + + + org.opendaylight.controller + config-util + test + + + org.opendaylight.bgpcep + mockito-configuration + test + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.opendaylight.yangtools + yang-maven-plugin + + + + + diff --git a/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModule.java b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModule.java new file mode 100644 index 0000000000..f6937f9ef1 --- /dev/null +++ b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModule.java @@ -0,0 +1,91 @@ +/** + * 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()); + } +} diff --git a/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModuleFactory.java b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModuleFactory.java new file mode 100644 index 0000000000..637395bc48 --- /dev/null +++ b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModuleFactory.java @@ -0,0 +1,49 @@ +/** + * 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); + } +} diff --git a/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java new file mode 100644 index 0000000000..e5b95c812b --- /dev/null +++ b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java @@ -0,0 +1,104 @@ +/* + * 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 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 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 optionalReason; + if (nullableReason == null) { + optionalReason = Optional.absent(); + } else { + optionalReason = Optional.of(nullableReason); + } + impl.shutdown(inputSecret, optionalReason); + } +} diff --git a/opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang b/opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang new file mode 100644 index 0000000000..78b44abfb2 --- /dev/null +++ b/opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang @@ -0,0 +1,71 @@ +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; + } + } + } +} diff --git a/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java b/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java new file mode 100644 index 0000000000..86cd6fa812 --- /dev/null +++ b/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java @@ -0,0 +1,149 @@ +/* + * 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.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> 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.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(); + } +} diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModule.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModule.java index f108303165..0bdcbbcca4 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModule.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModuleFactory.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModuleFactory.java index 14fcf41758..17d50562d3 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModuleFactory.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModule.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModule.java index 92eaee5ef2..6c36599078 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModule.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModuleFactory.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModuleFactory.java index e909998a72..955d4f16e4 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModuleFactory.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModule.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModule.java index a761727e5c..53320ae147 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModule.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModuleFactory.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModuleFactory.java index 5e70afb93e..ff81bc82ae 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModuleFactory.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModule.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModule.java index de6e6a5ec8..d06e6164b1 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModule.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModuleFactory.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModuleFactory.java index 1d3a37c50d..39e5f9a508 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModuleFactory.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java index 259d90817e..94639d43c0 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModuleFactory.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModuleFactory.java index 878adcfb2c..64b2a07fff 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModuleFactory.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModule.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModule.java index 83c4cccfeb..c6330e2e59 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModule.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModule.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModuleFactory.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModuleFactory.java index ea345baaeb..69f5b1f9ac 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModuleFactory.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModuleFactory.java @@ -1,3 +1,11 @@ +/* + * 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 diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java index b2fc75d700..b9731cd46d 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java @@ -1,3 +1,10 @@ +/* + * 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.async; import static org.junit.Assert.assertThat; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java index 4cd279f881..bc5e98bcb3 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java @@ -1,3 +1,10 @@ +/* + * 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; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/TestingEventBusModule.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/TestingEventBusModule.java index ee6bbc51bc..01a89a987b 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/TestingEventBusModule.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/TestingEventBusModule.java @@ -1,3 +1,10 @@ +/* + * 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.mockito.Mockito.doNothing; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java index 81455a9b21..8bfd049b4b 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java @@ -1,3 +1,10 @@ +/* + * 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.fixed; import org.junit.Before; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/TestingFixedThreadPoolModule.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/TestingFixedThreadPoolModule.java index 00be5d8118..1fc0821405 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/TestingFixedThreadPoolModule.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/TestingFixedThreadPoolModule.java @@ -1,3 +1,10 @@ +/* + * 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.fixed; import static org.mockito.Mockito.doNothing; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java index 5f1a3ee957..43cb7e1bcb 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java @@ -1,3 +1,10 @@ +/* + * 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.flexible; import org.junit.Before; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java index 9e9565a4f9..7280b04103 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java @@ -1,3 +1,10 @@ +/* + * 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.naming; import static org.junit.Assert.assertEquals; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/TestingNamingThreadPoolFactoryModule.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/TestingNamingThreadPoolFactoryModule.java index 5c717ccd4c..f22da34d76 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/TestingNamingThreadPoolFactoryModule.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/TestingNamingThreadPoolFactoryModule.java @@ -1,3 +1,10 @@ +/* + * 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.naming; import static org.mockito.Matchers.any; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java index 1567896701..6183cb56c1 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java @@ -1,3 +1,10 @@ +/* + * 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.scheduled; import org.junit.Before; diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/TestingScheduledThreadPoolModule.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/TestingScheduledThreadPoolModule.java index d1464baa6e..0fe5b0d183 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/TestingScheduledThreadPoolModule.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/TestingScheduledThreadPoolModule.java @@ -1,3 +1,10 @@ +/* + * 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.scheduled; import com.google.common.util.concurrent.ListenableFutureTask; diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java index 10f19e8399..7075865573 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java @@ -12,6 +12,16 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import 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; @@ -22,6 +32,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry 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; @@ -29,17 +40,6 @@ import org.slf4j.Logger; 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 @@ -70,7 +70,7 @@ public class JMXGenerator implements CodeGenerator { @Override public Collection generateSources(SchemaContext context, - File outputBaseDir, Set yangModulesInCurrentMavenModule) { + File outputBaseDir, Set yangModulesInCurrentMavenModule) { Preconditions.checkArgument(context != null, "Null context received"); Preconditions.checkArgument(outputBaseDir != null, @@ -86,24 +86,25 @@ public class JMXGenerator implements CodeGenerator { outputBaseDir.mkdirs(); GeneratedFilesTracker generatedFiles = new GeneratedFilesTracker(); + // create SIE structure qNamesToSIEs Map qNamesToSIEs = new HashMap<>(); - // create SIE structure qNamesToSIEs + + Map knownSEITracker = new HashMap<>(); for (Module module : context.getModules()) { String packageName = packageTranslator.getPackageName(module); Map namesToSIEntries = ServiceInterfaceEntry - .create(module, packageName); + .create(module, packageName, knownSEITracker); for (Entry 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)) { diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java index 869488e777..5bcc5402af 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java @@ -7,11 +7,9 @@ */ 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; @@ -21,7 +19,6 @@ import java.util.Map.Entry; 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; @@ -52,10 +49,10 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; 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. diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java index f19a46d0f4..4831545b39 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java @@ -163,41 +163,42 @@ public class RuntimeBeanEntry { 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 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 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); } } - } } } diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntry.java index aa2d6a5d7f..ef40d9515b 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntry.java @@ -7,10 +7,7 @@ */ 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; @@ -18,15 +15,15 @@ import java.util.Iterator; 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}. @@ -123,7 +120,7 @@ public class ServiceInterfaceEntry extends AbstractEntry { * values */ public static Map create(Module currentModule, - String packageName) { + String packageName,Map definedSEItracker) { logger.debug("Generating ServiceInterfaces from {} to package {}", currentModule.getNamespace(), packageName); @@ -152,7 +149,7 @@ public class ServiceInterfaceEntry extends AbstractEntry { // 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) { @@ -160,12 +157,15 @@ public class ServiceInterfaceEntry extends AbstractEntry { 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(); } } diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java index 38de6e1528..b3e7b90c96 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java @@ -1,3 +1,10 @@ +/* + * 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; diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java index e86c876169..9ea34ca2b8 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java @@ -8,6 +8,7 @@ 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; @@ -22,6 +23,7 @@ import org.opendaylight.yangtools.sal.binding.model.api.Type; 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; @@ -94,16 +96,18 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest { @Before public void setUp() { + Map identitiesToSIs = new HashMap<>(); modulesToSIEs = ServiceInterfaceEntry.create(threadsModule, - "packages.sis"); + "packages.sis",identitiesToSIs); } @Test public void test_jmxImplModule() { + Map identitiesToSIs = new HashMap<>(); Map modulesToSIEs = ServiceInterfaceEntry - .create(threadsModule, PACKAGE_NAME); + .create(threadsModule, PACKAGE_NAME,identitiesToSIs); modulesToSIEs.putAll(ServiceInterfaceEntry.create(jmxModule, - PACKAGE_NAME)); + PACKAGE_NAME,identitiesToSIs)); Map namesToMBEs = ModuleMXBeanEntry .create(jmxImplModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl(context)) , PACKAGE_NAME); diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java index 97258fb697..b570302563 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java @@ -7,12 +7,14 @@ */ 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; @@ -41,6 +43,7 @@ public class RuntimeBeanEntryTest extends AbstractYangTest { 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 identitiesToSIs = new HashMap<>(); @Test public void createRuntimeBean() { @@ -61,7 +64,7 @@ public class RuntimeBeanEntryTest extends AbstractYangTest { public void runtimeBeanRPCTest() { // create service interfaces Map modulesToSIEs = ServiceInterfaceEntry - .create(threadsModule, "packages.sis"); + .create(threadsModule, "packages.sis",identitiesToSIs); assertNotNull(modulesToSIEs); // create MXBeans map diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntryTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntryTest.java index 0da61b46c3..eed8695103 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntryTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntryTest.java @@ -7,27 +7,26 @@ */ 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"; @@ -38,6 +37,7 @@ public class ServiceInterfaceEntryTest extends AbstractYangTest { private static final URI THREADS_NAMESPACE; private static final Date THREADS_REVISION_DATE; + static { try { THREADS_NAMESPACE = new URI(ConfigConstants.CONFIG_NAMESPACE @@ -77,8 +77,9 @@ public class ServiceInterfaceEntryTest extends AbstractYangTest { @Test public void testCreateFromIdentities() { // each identity has to have a base that leads to service-type + Map definedIdentities = new HashMap<>(); Map 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())); diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java index 9356dd3752..0d704a8f6a 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java @@ -186,7 +186,15 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt 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); } } diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java index 2be6c81ee7..d54996dbb7 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java @@ -17,6 +17,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry 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; @@ -47,11 +48,12 @@ public class MbeParser { Map qNamesToSIEs = new HashMap<>(); + Map knownSEITracker = new HashMap<>(); // create SIE structure qNamesToSIEs for (Module module : resolveSchemaContext.getModules()) { String packageName = packageTranslator.getPackageName(module); Map namesToSIEntries = ServiceInterfaceEntry - .create(module, packageName); + .create(module, packageName,knownSEITracker); for (Entry sieEntry : namesToSIEntries .entrySet()) { diff --git a/opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java b/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java similarity index 64% rename from opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java rename to opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java index 50e1d4bb6a..41ceab0e55 100644 --- a/opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java +++ b/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java @@ -4,8 +4,6 @@ import com.google.common.collect.Lists; 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; @@ -15,8 +13,14 @@ import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; 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"; @@ -32,17 +36,16 @@ public class NetconfTestImplModuleTest extends AbstractConfigTest { } @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(); @@ -56,6 +59,38 @@ public class NetconfTestImplModuleTest extends AbstractConfigTest { 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.emptyList()); } private void assertTestingDeps(List testingDeps, int i) { diff --git a/opendaylight/configuration/api/pom.xml b/opendaylight/configuration/api/pom.xml index d4ae152375..282185bd70 100644 --- a/opendaylight/configuration/api/pom.xml +++ b/opendaylight/configuration/api/pom.xml @@ -44,7 +44,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT diff --git a/opendaylight/configuration/implementation/pom.xml b/opendaylight/configuration/implementation/pom.xml index 498b3d4e93..db596bf346 100644 --- a/opendaylight/configuration/implementation/pom.xml +++ b/opendaylight/configuration/implementation/pom.xml @@ -52,7 +52,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -62,7 +62,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/configuration/integrationtest/pom.xml b/opendaylight/configuration/integrationtest/pom.xml index e18fe8c1ed..65d46c3e0a 100644 --- a/opendaylight/configuration/integrationtest/pom.xml +++ b/opendaylight/configuration/integrationtest/pom.xml @@ -35,7 +35,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/connectionmanager/api/pom.xml b/opendaylight/connectionmanager/api/pom.xml index 4471863c0d..ab0a32882e 100644 --- a/opendaylight/connectionmanager/api/pom.xml +++ b/opendaylight/connectionmanager/api/pom.xml @@ -45,7 +45,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/connectionmanager/implementation/pom.xml b/opendaylight/connectionmanager/implementation/pom.xml index 58b21eccb8..a3cbe51607 100644 --- a/opendaylight/connectionmanager/implementation/pom.xml +++ b/opendaylight/connectionmanager/implementation/pom.xml @@ -54,7 +54,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -64,7 +64,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java b/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java index 5ba156ea7c..718a3ff166 100644 --- a/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java +++ b/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java @@ -277,6 +277,11 @@ public abstract class AbstractScheme { 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)) { diff --git a/opendaylight/containermanager/api/pom.xml b/opendaylight/containermanager/api/pom.xml index f7e385c878..1ca905054b 100644 --- a/opendaylight/containermanager/api/pom.xml +++ b/opendaylight/containermanager/api/pom.xml @@ -54,7 +54,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT diff --git a/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java b/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java index 9740a92598..9d65ad343c 100644 --- a/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java +++ b/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java @@ -15,7 +15,9 @@ import java.net.Inet6Address; 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; @@ -308,9 +310,10 @@ public class ContainerFlowConfig implements Serializable { } /** - * 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) { @@ -320,7 +323,8 @@ public class ContainerFlowConfig implements Serializable { if (dlVlan == null || flowSpec.dlVlan == null) { return false; } - return dlVlan.equals(flowSpec.dlVlan); + + return this.getVlanList().equals(flowSpec.getVlanList()); } /** @@ -404,18 +408,34 @@ public class ContainerFlowConfig implements Serializable { } /** - * 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 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 vlanList = new HashSet(); 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; } /** @@ -617,13 +637,25 @@ public class ContainerFlowConfig implements Serializable { 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); } @@ -706,20 +738,46 @@ public class ContainerFlowConfig implements Serializable { /** * 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 getMatches() { List matches = new ArrayList(); - 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 forwardMatches = new ArrayList(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("/"); @@ -756,15 +814,7 @@ public class ContainerFlowConfig implements Serializable { 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; } /* diff --git a/opendaylight/containermanager/implementation/pom.xml b/opendaylight/containermanager/implementation/pom.xml index 18ed78c37b..bd12bfc87d 100644 --- a/opendaylight/containermanager/implementation/pom.xml +++ b/opendaylight/containermanager/implementation/pom.xml @@ -62,7 +62,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -87,7 +87,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/containermanager/it.implementation/pom.xml b/opendaylight/containermanager/it.implementation/pom.xml index 3b86a797ca..ee1ef12c11 100644 --- a/opendaylight/containermanager/it.implementation/pom.xml +++ b/opendaylight/containermanager/it.implementation/pom.xml @@ -57,7 +57,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -67,7 +67,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked1.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked1.txt deleted file mode 100644 index aad72393cb..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked1.txt +++ /dev/null @@ -1,35 +0,0 @@ - -#24 - - - 14 - fred - - < -#2 -/r -#3 -pc> -## diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked2.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked2.txt deleted file mode 100644 index a36a85ea1f..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked2.txt +++ /dev/null @@ -1,48 +0,0 @@ - -#22 - - - - - -#18 - - - -#19 - - -#8 - - -#77 - - - - - -## diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked3.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked3.txt deleted file mode 100644 index d9dc43d620..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked3.txt +++ /dev/null @@ -1,43 +0,0 @@ - -#43 - - -#26 - - - -#35 - - - -#39 - - < -#40 -top xmlns="http://example.com/schema/1.2 -#26 -/config"> - - -#36 - - f -#56 -red - - - -#28 - - - - -## diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked4.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked4.txt deleted file mode 100644 index 0b8a102dff..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked4.txt +++ /dev/null @@ -1,40 +0,0 @@ - -#17 - - - - - - -#43 - - - -#16 - - -#22 - - - -## diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked5.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked5.txt deleted file mode 100644 index f8f3c4d7c2..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked5.txt +++ /dev/null @@ -1,42 +0,0 @@ - -#43 - - - - - < -#4 -/tar -#18 -get> - - -#41 - - - -#29 - Ethernet0/0 - 1500 - -#61 - - - - - -## diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_config_bean_response.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_config_bean_response.txt deleted file mode 100644 index 2ae32efb65..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_config_bean_response.txt +++ /dev/null @@ -1,18 +0,0 @@ -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 diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_lookupConfigBeans.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_lookupConfigBeans.txt deleted file mode 100644 index 2ae705a54f..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_lookupConfigBeans.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ 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" - } - ] -} diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_commit.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_commit.xml deleted file mode 100644 index 6eca609b6c..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_commit.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_candidate.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_candidate.xml deleted file mode 100644 index 6a9ed639d8..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_candidate.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_running.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_running.xml deleted file mode 100644 index 2d66c45906..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_running.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_modify_candidate.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_modify_candidate.xml deleted file mode 100644 index ce67845de1..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_modify_candidate.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - none - test-then-set - stop-on-error - - - - 7 - - - - - \ No newline at end of file diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_candidate.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_candidate.xml deleted file mode 100644 index dd6fe1ba1e..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_candidate.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_running.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_running.xml deleted file mode 100644 index f94af4698d..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_running.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/server_error_missing_attribute.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/server_error_missing_attribute.xml deleted file mode 100644 index c70184e2b4..0000000000 --- a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/server_error_missing_attribute.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - rpc - missing-attribute - error - - message-id - rpc - - - diff --git a/opendaylight/distribution/opendaylight/opendaylight.target b/opendaylight/distribution/opendaylight/opendaylight.target index e3d1e5275d..7ae309cce4 100644 --- a/opendaylight/distribution/opendaylight/opendaylight.target +++ b/opendaylight/distribution/opendaylight/opendaylight.target @@ -51,7 +51,6 @@ - diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index b0f7ad89a4..5acdec834d 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -134,6 +134,30 @@ forwardingrules-manager ${mdsal.version} + + org.opendaylight.controller.md + topology-lldp-discovery + ${mdsal.version} + + + org.opendaylight.controller.md + topology-manager + ${mdsal.version} + + + org.opendaylight.controller.model + model-topology + 1.0-SNAPSHOT + + + org.opendaylight.yangtools.model + ietf-topology + + + org.opendaylight.controller + sal-binding-util + 1.0-SNAPSHOT + org.opendaylight.controller.md statistics-manager @@ -238,6 +262,22 @@ config-persister-directory-xml-adapter ${config.version} + + org.opendaylight.controller + config-persister-directory-autodetect-adapter + ${config.version} + + + + org.opendaylight.controller + shutdown-api + ${config.version} + + + org.opendaylight.controller + shutdown-impl + ${config.version} + @@ -903,22 +943,37 @@ ch.qos.logback logback-classic + - org.codehaus.jackson - jackson-mapper-asl + com.fasterxml.jackson.core + jackson-databind + - org.codehaus.jackson - jackson-core-asl + com.fasterxml.jackson.core + jackson-annotations + - org.codehaus.jackson - jackson-jaxrs + com.fasterxml.jackson.core + jackson-core + - org.codehaus.jackson - jackson-xc + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + org.codehaus.jettison jettison @@ -1244,11 +1299,7 @@ com.sun.jersey jersey-client - - com.sun.jersey - jersey-json - ${jersey.version} - + org.ow2.asm asm-all diff --git a/opendaylight/distribution/opendaylight/src/assemble/bin.xml b/opendaylight/distribution/opendaylight/src/assemble/bin.xml index 8fea175614..6f8878bee9 100644 --- a/opendaylight/distribution/opendaylight/src/assemble/bin.xml +++ b/opendaylight/distribution/opendaylight/src/assemble/bin.xml @@ -24,7 +24,6 @@ ch.qos.logback:logback-core ch.qos.logback:logback-classic com.sun.jersey:jersey-core - com.sun.jersey:jersey-json com.sun.jersey:jersey-server org.opendaylight.controller:logging.bridge org.opendaylight.controller:sanitytest @@ -52,7 +51,6 @@ ch.qos.logback:logback-core ch.qos.logback:logback-classic com.sun.jersey:jersey-core - com.sun.jersey:jersey-json com.sun.jersey:jersey-server org.opendaylight.controller:logging.bridge diff --git a/opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk b/opendaylight/distribution/opendaylight/src/main/resources/configuration/RSA.pk similarity index 100% rename from opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk rename to opendaylight/distribution/opendaylight/src/main/resources/configuration/RSA.pk diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini index ba5d862c57..be6fae7598 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini @@ -10,7 +10,6 @@ osgi.bundles=\ 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 @@ -22,10 +21,16 @@ netconf.tcp.client.port=8383 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 @@ -41,7 +46,6 @@ netconf.config.persister.2.storageAdapterClass=org.opendaylight.controller.confi 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 diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf deleted file mode 100644 index c2f9bc311d..0000000000 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf +++ /dev/null @@ -1,48 +0,0 @@ -//MODULES START - - netty:netty-threadgroup-fixed - global-boss-group - - - netty:netty-threadgroup-fixed - global-worker-group - - - netty:netty-hashed-wheel-timer - global-timer - - - netty:netty-global-event-executor - global-event-executor - -//SERVICES START - - netty:netty-threadgroup - - global-boss-group - /modules/module[type='netty-threadgroup-fixed'][name='global-boss-group'] - - - global-worker-group - /modules/module[type='netty-threadgroup-fixed'][name='global-worker-group'] - - - - netty:netty-event-executor - - global-event-executor - /modules/module[type='netty-global-event-executor'][name='global-event-executor'] - - - - netty:netty-timer - - global-timer - /modules/module[type='netty-hashed-wheel-timer'][name='global-timer'] - - -//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 diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf new file mode 100644 index 0000000000..9ba590820a --- /dev/null +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf @@ -0,0 +1,60 @@ + + + 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 + + + + + + + netty:netty-threadgroup-fixed + global-boss-group + + + netty:netty-threadgroup-fixed + global-worker-group + + + netty:netty-hashed-wheel-timer + global-timer + + + netty:netty-global-event-executor + global-event-executor + + + + + + netty:netty-threadgroup + + global-boss-group + /modules/module[type='netty-threadgroup-fixed'][name='global-boss-group'] + + + global-worker-group + /modules/module[type='netty-threadgroup-fixed'][name='global-worker-group'] + + + + netty:netty-event-executor + + global-event-executor + /modules/module[type='netty-global-event-executor'][name='global-event-executor'] + + + + netty:netty-timer + + global-timer + /modules/module[type='netty-hashed-wheel-timer'][name='global-timer'] + + + + + + + diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf deleted file mode 100644 index edee185c17..0000000000 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf +++ /dev/null @@ -1,137 +0,0 @@ -//MODULES START - - prefix:schema-service-singleton - yang-schema-service - - - prefix:hash-map-data-store - hash-map-data-store - - - prefix:dom-clustered-store-impl - cluster-data-store - - - prefix:dom-broker-impl - dom-broker - - dom:dom-data-store - - hash-map-data-store - - - - - prefix:binding-broker-impl - binding-broker-impl - - binding:binding-notification-service - binding-notification-broker - - - binding:binding-data-broker - binding-data-broker - - - - prefix:runtime-generated-mapping - runtime-mapping-singleton - - - prefix:binding-notification-broker - binding-notification-broker - - - prefix:binding-data-broker - binding-data-broker - - dom:dom-broker-osgi-registry - dom-broker - - - binding:binding-dom-mapping-service - runtime-mapping-singleton - - -//SERVICES START - - dom:schema-service - - yang-schema-service - /modules/module[type='schema-service-singleton'][name='yang-schema-service'] - - - - binding:binding-notification-service - - binding-notification-broker - /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] - - - - dom:dom-data-store - - hash-map-data-store - /modules/module[type='hash-map-data-store'][name='hash-map-data-store'] - - - cluster-data-store - /modules/module[type='dom-clustered-store-impl'][name='cluster-data-store'] - - - - binding:binding-broker-osgi-registry - - binding-osgi-broker - /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] - - - - binding:binding-rpc-registry - - binding-rpc-broker - /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] - - - - binding-impl:binding-dom-mapping-service - - runtime-mapping-singleton - /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] - - - - dom:dom-broker-osgi-registry - - dom-broker - /modules/module[type='dom-broker-impl'][name='dom-broker'] - - - - binding:binding-data-broker - - binding-data-broker - /modules/module[type='binding-data-broker'][name='binding-data-broker'] - - -//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 diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf new file mode 100644 index 0000000000..20f59892c3 --- /dev/null +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf @@ -0,0 +1,153 @@ + + + + + + + + prefix:schema-service-singleton + yang-schema-service + + + prefix:hash-map-data-store + hash-map-data-store + + + prefix:dom-clustered-store-impl + cluster-data-store + + + prefix:dom-broker-impl + dom-broker + + dom:dom-data-store + + hash-map-data-store + + + + + prefix:binding-broker-impl + binding-broker-impl + + binding:binding-notification-service + binding-notification-broker + + + binding:binding-data-broker + binding-data-broker + + + + prefix:runtime-generated-mapping + runtime-mapping-singleton + + + prefix:binding-notification-broker + binding-notification-broker + + + prefix:binding-data-broker + binding-data-broker + + dom:dom-broker-osgi-registry + dom-broker + + + binding:binding-dom-mapping-service + runtime-mapping-singleton + + + + + + + dom:schema-service + + yang-schema-service + /modules/module[type='schema-service-singleton'][name='yang-schema-service'] + + + + binding:binding-notification-service + + binding-notification-broker + /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] + + + + dom:dom-data-store + + hash-map-data-store + /modules/module[type='hash-map-data-store'][name='hash-map-data-store'] + + + cluster-data-store + /modules/module[type='dom-clustered-store-impl'][name='cluster-data-store'] + + + + binding:binding-broker-osgi-registry + + binding-osgi-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + binding:binding-rpc-registry + + binding-rpc-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + binding-impl:binding-dom-mapping-service + + runtime-mapping-singleton + /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] + + + + dom:dom-broker-osgi-registry + + dom-broker + /modules/module[type='dom-broker-impl'][name='dom-broker'] + + + + binding:binding-data-broker + + binding-data-broker + /modules/module[type='binding-data-broker'][name='binding-data-broker'] + + + + + + + + + + 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 + + + diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml index 84d1c913c4..61d274d80c 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml @@ -41,7 +41,8 @@ - + + diff --git a/opendaylight/distribution/opendaylight/src/main/resources/run.sh b/opendaylight/distribution/opendaylight/src/main/resources/run.sh index f59d54ce2c..1f3e8e20f3 100755 --- a/opendaylight/distribution/opendaylight/src/main/resources/run.sh +++ b/opendaylight/distribution/opendaylight/src/main/resources/run.sh @@ -164,6 +164,8 @@ FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.virgo.kernel.equinox. 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}"` diff --git a/opendaylight/forwarding/staticrouting/pom.xml b/opendaylight/forwarding/staticrouting/pom.xml index f160cddaad..a0b7367acd 100644 --- a/opendaylight/forwarding/staticrouting/pom.xml +++ b/opendaylight/forwarding/staticrouting/pom.xml @@ -67,7 +67,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -86,7 +86,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT diff --git a/opendaylight/forwardingrulesmanager/api/pom.xml b/opendaylight/forwardingrulesmanager/api/pom.xml index 499b98c28a..afd3d0ba7c 100644 --- a/opendaylight/forwardingrulesmanager/api/pom.xml +++ b/opendaylight/forwardingrulesmanager/api/pom.xml @@ -78,7 +78,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java b/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java index 3ec9f8443a..de6b8182b0 100644 --- a/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java +++ b/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java @@ -8,19 +8,6 @@ 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; @@ -62,6 +49,18 @@ import org.opendaylight.controller.switchmanager.Switch; 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. @@ -1044,6 +1043,7 @@ public class FlowConfig implements Serializable { } Flow flow = new Flow(match, getActionList()); + if (this.cookie != null) { flow.setId(Long.parseLong(cookie)); } @@ -1056,6 +1056,8 @@ public class FlowConfig implements Serializable { if (this.priority != null) { flow.setPriority(Integer.decode(this.priority).shortValue()); } + + return flow; } diff --git a/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowEntry.java b/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowEntry.java index 83106a391c..d9a0891c2a 100644 --- a/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowEntry.java +++ b/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowEntry.java @@ -122,7 +122,7 @@ public class FlowEntry implements Cloneable, Serializable { } if (flow == null) { - return (other.flow == null) ? true : false; + return other.flow == null; } else if (other.flow == null) { return false; } diff --git a/opendaylight/forwardingrulesmanager/implementation/pom.xml b/opendaylight/forwardingrulesmanager/implementation/pom.xml index 6b3f5347ad..ef69b49ca9 100644 --- a/opendaylight/forwardingrulesmanager/implementation/pom.xml +++ b/opendaylight/forwardingrulesmanager/implementation/pom.xml @@ -84,7 +84,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java index 3d6a0292ef..41075b9554 100644 --- a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java +++ b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java @@ -2639,6 +2639,13 @@ public class ForwardingRulesManager implements } } + /** + * 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 ()" @@ -2646,7 +2653,6 @@ public class ForwardingRulesManager implements */ void stop() { stopping = true; - uninstallAllFlowEntries(false); // Shutdown executor this.executor.shutdownNow(); // Now walk all the workMonitor and wake up the one sleeping because @@ -2988,7 +2994,11 @@ public class ForwardingRulesManager implements // 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); } } } diff --git a/opendaylight/hosttracker/api/pom.xml b/opendaylight/hosttracker/api/pom.xml index ea66c34fa3..bf2e360334 100644 --- a/opendaylight/hosttracker/api/pom.xml +++ b/opendaylight/hosttracker/api/pom.xml @@ -66,12 +66,12 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/hosttracker/implementation/pom.xml b/opendaylight/hosttracker/implementation/pom.xml index 258327cca7..78c4ae4160 100644 --- a/opendaylight/hosttracker/implementation/pom.xml +++ b/opendaylight/hosttracker/implementation/pom.xml @@ -129,12 +129,12 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java b/opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java index d7c60e67a9..e222fcd7e4 100644 --- a/opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java +++ b/opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java @@ -25,7 +25,6 @@ public class HostTrackerTest extends TestCase { HostTracker hostTracker = null; hostTracker = new HostTracker(); - Assert.assertFalse(hostTracker == null); InetAddress hostIP = InetAddress.getByName("192.168.0.8"); IHostId id = IPHostId.fromIP(hostIP); @@ -44,7 +43,6 @@ public class HostTrackerTest extends TestCase { public void testHostTracker() throws UnknownHostException { HostTracker hostTracker = null; hostTracker = new HostTracker(); - Assert.assertFalse(hostTracker == null); InetAddress hostIP_1 = InetAddress.getByName("192.168.0.8"); IHostId id1 = IPHostId.fromIP(hostIP_1); diff --git a/opendaylight/hosttracker_new/api/pom.xml b/opendaylight/hosttracker_new/api/pom.xml index d8b5a48435..ba3da5f764 100644 --- a/opendaylight/hosttracker_new/api/pom.xml +++ b/opendaylight/hosttracker_new/api/pom.xml @@ -65,12 +65,12 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/hosttracker_new/implementation/pom.xml b/opendaylight/hosttracker_new/implementation/pom.xml index 0405d45b6e..c5caa7f317 100644 --- a/opendaylight/hosttracker_new/implementation/pom.xml +++ b/opendaylight/hosttracker_new/implementation/pom.xml @@ -110,12 +110,12 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/Activator.java b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/Activator.java index 95f57ae31c..b231faf153 100644 --- a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/Activator.java +++ b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/Activator.java @@ -1,4 +1,3 @@ - /* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * @@ -6,11 +5,13 @@ * 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; @@ -21,7 +22,11 @@ import org.slf4j.ILoggerFactory; 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 @@ -62,16 +67,25 @@ public class Activator implements BundleActivator { * 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"); @@ -90,14 +104,17 @@ public class Activator implements BundleActivator { 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; } diff --git a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionHandler.java b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionHandler.java deleted file mode 100644 index 6fe9c4441f..0000000000 --- a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionHandler.java +++ /dev/null @@ -1,13 +0,0 @@ -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); - } -} diff --git a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionPolicy.java b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionPolicy.java new file mode 100644 index 0000000000..0545578b7f --- /dev/null +++ b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionPolicy.java @@ -0,0 +1,31 @@ +/* + * 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); +} diff --git a/opendaylight/md-sal/clustered-data-store/implementation/pom.xml b/opendaylight/md-sal/clustered-data-store/implementation/pom.xml index 9cbf35576f..62775c1eec 100644 --- a/opendaylight/md-sal/clustered-data-store/implementation/pom.xml +++ b/opendaylight/md-sal/clustered-data-store/implementation/pom.xml @@ -104,12 +104,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT junit diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml b/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml index 176ab6cbe0..129e6ff5fc 100644 --- a/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml +++ b/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml @@ -71,12 +71,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.yangtools @@ -95,22 +95,22 @@ org.opendaylight.controller sal.implementation - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT org.opendaylight.controller containermanager - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT org.opendaylight.controller containermanager.it.implementation - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT org.opendaylight.controller clustering.stub - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml b/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml index 3c8bf97961..fd31e35859 100644 --- a/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml @@ -77,7 +77,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml index d9fb18f84d..1b510d0e0b 100644 --- a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml +++ b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml @@ -51,7 +51,7 @@ org.opendaylight.controller switchmanager - 0.6.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller @@ -98,7 +98,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend index 430b5957ef..5d0e7e6fe7 100644 --- a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend +++ b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend @@ -225,7 +225,7 @@ class CompatibleSwitchManager extends ConfigurableSwitchManager implements ISwit val ret = new HashSet(); 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)); } } @@ -286,4 +286,7 @@ class CompatibleSwitchManager extends ConfigurableSwitchManager implements ISwit throw new UnsupportedOperationException("TODO: auto-generated method stub") } + override getConfiguredNotConnectedSwitches() { + return null; } +} diff --git a/opendaylight/md-sal/compatibility/pom.xml b/opendaylight/md-sal/compatibility/pom.xml index 151fdbfaaa..37d866dca5 100644 --- a/opendaylight/md-sal/compatibility/pom.xml +++ b/opendaylight/md-sal/compatibility/pom.xml @@ -25,7 +25,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller.model diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/pom.xml b/opendaylight/md-sal/compatibility/sal-compatibility/pom.xml index 15a9a689b3..74193ea128 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/pom.xml +++ b/opendaylight/md-sal/compatibility/sal-compatibility/pom.xml @@ -20,6 +20,21 @@ model-flow-statistics 1.0-SNAPSHOT + + org.opendaylight.controller.model + model-topology + 1.0-SNAPSHOT + + + org.opendaylight.controller + sal-binding-util + 1.0-SNAPSHOT + + + org.opendaylight.controller + clustering.services + 0.5.0-SNAPSHOT + bundle diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend index a03128995f..4587cc59ed 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend @@ -1,37 +1,50 @@ 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; @@ -45,11 +58,25 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi 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) { @@ -58,38 +85,32 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi } 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) { @@ -116,31 +137,59 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi .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 properties() { @@ -150,3 +199,54 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi 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) + } +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend index 2eae511e02..35c641c45a 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend @@ -1,12 +1,21 @@ 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 @@ -18,7 +27,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Node 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.* @@ -26,67 +47,55 @@ import static extension org.opendaylight.controller.sal.compatibility.ToSalConve 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 flowToFlowId = new ConcurrentHashMap(); + + 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) { @@ -101,13 +110,17 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi 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); @@ -147,4 +160,90 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi NodeExperimenterErrorNotification notification) { // NOOP : Not supported by AD SAL } + + private def Future> 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> 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> 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> 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> 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 getCache(){ + if(clusterGlobalServices == null){ + return new ConcurrentHashMap(); + } + + 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; + + } + } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java index ad6009c827..eba4aa901b 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java @@ -1,5 +1,9 @@ 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; @@ -8,11 +12,7 @@ import java.net.Inet4Address; 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; @@ -22,14 +22,12 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. 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; @@ -53,9 +51,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026 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 { @@ -63,19 +60,7 @@ 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) { @@ -100,6 +85,7 @@ public class FromSalConversionsUtils { targetBuilder.setVlanMatch(vlanMatch(sourceMatch)); targetBuilder.setLayer3Match(layer3Match(sourceMatch)); targetBuilder.setLayer4Match(layer4Match(sourceMatch)); + targetBuilder.setInPort(inPortMatch(sourceMatch)); return targetBuilder.build(); } @@ -107,6 +93,14 @@ public class FromSalConversionsUtils { } + 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; @@ -138,8 +132,10 @@ public class FromSalConversionsUtils { 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) { @@ -157,8 +153,10 @@ public class FromSalConversionsUtils { 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) { @@ -175,8 +173,10 @@ public class FromSalConversionsUtils { 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, @@ -196,7 +196,7 @@ public class FromSalConversionsUtils { 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()); } @@ -206,8 +206,10 @@ public class FromSalConversionsUtils { 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) { @@ -225,21 +227,24 @@ public class FromSalConversionsUtils { 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) { @@ -249,7 +254,12 @@ public class FromSalConversionsUtils { .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) { @@ -270,12 +280,12 @@ public class FromSalConversionsUtils { 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) { @@ -290,7 +300,7 @@ public class FromSalConversionsUtils { (Inet4Address) inetDestAddress); } } else if ((inetSourceAddress instanceof Inet6Address) - && (inetDestAddress instanceof Inet6Address)) { + || (inetDestAddress instanceof Inet6Address)) { return setLayer3MatchAsIpv6((Inet6Address) inetSourceAddress, (Inet6Address) inetDestAddress); } @@ -344,15 +354,18 @@ public class FromSalConversionsUtils { 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(); } @@ -360,16 +373,90 @@ public class FromSalConversionsUtils { 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; + } + } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend index 609ace4695..21af047c3d 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend @@ -1,155 +1,336 @@ 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 statisticsPublisher = new CopyOnWriteArrayList(); + + @Property + List inventoryPublisher = new CopyOnWriteArrayList(); + + 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(); - 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(); + 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(); - 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(); + + 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) { @@ -158,54 +339,97 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead override onNodeRemoved(NodeRemoved notification) { val properties = Collections.emptySet(); - val org.opendaylight.yangtools.yang.binding.InstanceIdentifier identifier = notification.nodeRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - 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(); - - - val org.opendaylight.yangtools.yang.binding.InstanceIdentifier identifier = update.nodeConnectorRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier; var updateType = UpdateType.CHANGED; - if ( this._dataService.readOperationalData(identifier) == null ){ + if ( this._dataService.readOperationalData(update.nodeConnectorRef.value as InstanceIdentifier) == 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.emptySet(); - val org.opendaylight.yangtools.yang.binding.InstanceIdentifier identifier = notification.nodeRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + val InstanceIdentifier identifier = notification.nodeRef.value as InstanceIdentifier; 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>() + + 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 + 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>() + 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 + 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) { @@ -218,57 +442,159 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) { val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier); 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(); + + 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(); + + 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(); + + 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 properties){ + for( publisher : inventoryPublisher){ + publisher.updateNode(node, updateType, properties); + } + } + + private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set properties){ + for( publisher : inventoryPublisher){ + publisher.updateNodeConnector(nodeConnector, updateType, properties); + } + } } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend index 6cf728cde9..5a91e919dd 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend @@ -5,7 +5,6 @@ import java.math.BigInteger 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 @@ -40,7 +39,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddF 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 @@ -67,7 +65,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti 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 @@ -106,6 +103,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti 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 { @@ -130,34 +130,52 @@ 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(); + 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 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.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(); } @@ -355,7 +373,7 @@ public class MDFlowMapping { } 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) { @@ -367,4 +385,25 @@ public class MDFlowMapping { } 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(); + for (sourceAction : sourceActions) { + targetActions.add(sourceAction.toAction()); + } + instructions = targetActions.toApplyInstruction(); + match = sourceFlow.match.toMatch(); + return it.build(); + } + } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeConnectorFactory.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeConnectorFactory.java new file mode 100644 index 0000000000..5b4b16a39a --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeConnectorFactory.java @@ -0,0 +1,23 @@ +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; + + } +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeFactory.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeFactory.java index 0c1ee781ac..e36ebd7245 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeFactory.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeFactory.java @@ -3,8 +3,6 @@ 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.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; @@ -15,7 +13,7 @@ public class MDSalNodeFactory implements INodeFactory{ 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); } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend index 4c9a9e6658..4378e7dffe 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend @@ -7,13 +7,48 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableIt 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 { @@ -27,29 +62,80 @@ 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); } @@ -57,7 +143,19 @@ public class NodeMapping { public static def toNodeConnectorRef(NodeConnector nodeConnector) { val node = nodeConnector.node.toNodeRef(); val nodePath = node.getValue() as InstanceIdentifier - 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); } @@ -66,4 +164,194 @@ public class NodeMapping { return toADNode(node.getValue()); } + public static def toADNodeConnectorProperties(NodeConnectorUpdated nc) { + val fcncu = nc.getAugmentation(FlowCapableNodeConnectorUpdated) + if (fcncu != null) { + return fcncu.toADNodeConnectorProperties + } + return new HashSet(); + } + + 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(); + } + + public static def toADNodeConnectorProperties(FlowNodeConnector fcncu) { + val props = new HashSet(); + 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(); + + } + + public static def toADNodeProperties(FlowNode fcnu, NodeId id) { + val props = new HashSet(); + 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> 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) + } + } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java index a8349be1b4..46fd62f3f2 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java @@ -1,6 +1,25 @@ 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; @@ -24,6 +43,7 @@ import org.opendaylight.controller.sal.action.SetVlanCfi; 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; @@ -33,7 +53,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. 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; @@ -67,6 +86,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti 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; @@ -88,26 +108,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026 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 { @@ -484,11 +485,11 @@ 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) { @@ -506,22 +507,22 @@ public class ToSalConversionsUtils { 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); } } @@ -564,7 +565,7 @@ public class ToSalConversionsUtils { } } - 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++) { @@ -572,4 +573,15 @@ public class ToSalConversionsUtils { } 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; + } } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/DataPacketServiceAdapter.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/DataPacketServiceAdapter.java index aa67600124..edd3a27255 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/DataPacketServiceAdapter.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/DataPacketServiceAdapter.java @@ -3,7 +3,6 @@ package org.opendaylight.controller.sal.compatibility.adsal; 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; @@ -22,8 +21,12 @@ public class DataPacketServiceAdapter implements IPluginInDataPacketService { 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); @@ -33,4 +36,14 @@ public class DataPacketServiceAdapter implements IPluginInDataPacketService { return builderTPIB.build(); } + public PacketProcessingService getDelegate() { + return delegate; + } + + public void setDelegate(PacketProcessingService delegate) { + this.delegate = delegate; + } + + + } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java index 09585d6273..149544b6c4 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java @@ -8,6 +8,8 @@ import java.util.concurrent.Future; 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; @@ -19,87 +21,78 @@ import org.opendaylight.controller.sal.reader.IReadServiceListener; 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> getAllFlowStatistics(GetAllFlowStatisticsInput input) { - GetAllFlowStatisticsOutput rpcResultType = null; - boolean rpcResultBool = false; - - try { - Node adNode = NodeMapping.toADNode(input.getNode()); - List flowsOnNode = readDelegate.readAllFlows(adNode); - List flowsStatistics = toOdFlowsStatistics(flowsOnNode); - GetAllFlowStatisticsOutputBuilder builder = new GetAllFlowStatisticsOutputBuilder(); - rpcResultType = builder.setFlowStatistics(flowsStatistics).build(); - rpcResultBool = true; - } catch (ConstructionException e) { - LOG.error(e.getMessage()); - } + public Future> 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> 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> getAllNodeConnectorStatistics( - GetAllNodeConnectorStatisticsInput input) { - GetAllNodeConnectorStatisticsOutput rpcResultType = null; + public Future> getAllFlowStatisticsFromFlowTable( + GetAllFlowStatisticsFromFlowTableInput input) { + GetAllFlowStatisticsFromFlowTableOutput rpcResultType = null; boolean rpcResultBool = false; try { Node adNode = NodeMapping.toADNode(input.getNode()); - List nodesConnectorStatistics = readDelegate.readNodeConnectors(adNode); - List odNodesConnectorStatistics; - odNodesConnectorStatistics = toOdNodesConnectorStatistics(nodesConnectorStatistics); - GetAllNodeConnectorStatisticsOutputBuilder builder = new GetAllNodeConnectorStatisticsOutputBuilder(); - rpcResultType = builder.setNodeConnectorStatistics(odNodesConnectorStatistics).build(); + List flowsOnNode = readDelegate.readAllFlows(adNode); + List 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()); @@ -108,17 +101,24 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null)); } + /** + * Essentially this API will return the same result as getAllFlowStatisticsFromFlowTable + */ @Override - public Future> getFlowStatistics(GetFlowStatisticsInput input) { - GetFlowStatisticsOutput rpcResultType = null; + public Future> 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 flowsOnNode = readDelegate.readAllFlows(adNode); + List 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()); @@ -128,38 +128,18 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, } @Override - public Future> getFlowTableStatistics(GetFlowTableStatisticsInput input) { - GetFlowTableStatisticsOutput rpcResultType = null; + public Future> getFlowStatisticsFromFlowTable( + GetFlowStatisticsFromFlowTableInput input) { + GetFlowStatisticsFromFlowTableOutput rpcResultType = null; boolean rpcResultBool = false; try { Node node = NodeMapping.toADNode(input.getNode()); - List 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> 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 flowOnNodeToFlowStatistics = new ArrayList(); + flowOnNodeToFlowStatistics.add(toOdFlowStatistics(readFlow)); + rpcResultType = new GetFlowStatisticsFromFlowTableOutputBuilder().setFlowAndStatisticsMapList(flowOnNodeToFlowStatistics).build(); rpcResultBool = true; } catch (ConstructionException e) { LOG.error(e.getMessage()); @@ -169,59 +149,74 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, } @Override - public void descriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) { - - // TODO which *StatisticsUpdated interface should be used? - + public void nodeFlowStatisticsUpdated(Node node, List flowStatsList) { + List 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 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 flowStatsList) { - for (FlowOnNode flowOnNode : flowStatsList) { - FlowStatistics flowStatistics = toOdFlowStatistics(flowOnNode); - FlowStatisticsUpdatedBuilder statisticsBuilder = new FlowStatisticsUpdatedBuilder(flowStatistics); - notifier.publish(statisticsBuilder.build()); - } + NodeConnectorStatisticsUpdateBuilder nodeConnectorStatisticsUpdateBuilder = new NodeConnectorStatisticsUpdateBuilder(); + List 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 tableStatsList) { - // TODO : Not implemented by AD-SAL. + + FlowTableStatisticsUpdateBuilder flowTableStatisticsUpdateBuilder = new FlowTableStatisticsUpdateBuilder(); + + List 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 toOdFlowsStatistics(List flowsOnNode) { - List flowsStatistics = new ArrayList<>(); + private List toOdFlowsStatistics(List flowsOnNode) { + List 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(); } @@ -231,38 +226,43 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, 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 toOdNodesConnectorStatistics( - List nodesConnectorStatistics) { - List odNodesConnectorStatistics = new ArrayList<>(); - for (NodeConnectorStatistics nodeConnectorStatistics : nodesConnectorStatistics) { - odNodesConnectorStatistics.add(toOdNodeConnectorStatistics(nodeConnectorStatistics)); + private List toOdFlowTableStatistics(List tableStatsList) { + + List flowTableStatsMap = new ArrayList(); + 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 toOdNodeConnectorStatistics( + List ncStatsList) { + List nodeConnectorStatisticsList = new ArrayList(); + 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) { @@ -292,49 +292,4 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, 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> getAggregateFlowStatisticsFromFlowTableForAllFlows( - GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Future> getAggregateFlowStatisticsFromFlowTableForGivenMatch( - GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Future> getAllFlowStatisticsFromFlowTable( - GetAllFlowStatisticsFromFlowTableInput input) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Future> getAllFlowsStatisticsFromAllFlowTables( - GetAllFlowsStatisticsFromAllFlowTablesInput input) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Future> getFlowStatisticsFromFlowTable( - GetFlowStatisticsFromFlowTableInput input) { - // TODO Auto-generated method stub - return null; - } - } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend new file mode 100644 index 0000000000..bd2590f18b --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend @@ -0,0 +1,30 @@ +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 diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend new file mode 100644 index 0000000000..7d05ce60fa --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend @@ -0,0 +1,62 @@ +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, DataObject> { + static val LOG = LoggerFactory.getLogger(TopologyCommitHandler); + @Property + IPluginOutTopologyService topologyPublisher; + + @Property + DataProviderService dataService; + + new(DataProviderService dataService) { + _topologyPublisher = topologyPublisher + _dataService = dataService + } + + override requestCommit(DataModification, DataObject> modification) { + val msg = new CopyOnWriteArrayList() + 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)] + .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 diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend new file mode 100644 index 0000000000..62983ccce4 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend @@ -0,0 +1,71 @@ +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 result = new CopyOnWriteArrayList() + 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) + 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 diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend new file mode 100644 index 0000000000..1fde2820e2 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend @@ -0,0 +1,48 @@ +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,DataObject>> commitHandlerRegistration; + + def void start() { + commitHandler = new TopologyCommitHandler(dataService) + commitHandler.setTopologyPublisher(topologyPublisher) + val InstanceIdentifier 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 diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend new file mode 100644 index 0000000000..33927ff316 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend @@ -0,0 +1,66 @@ +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, DataObject> { + static val LOG = LoggerFactory.getLogger(TopologyTransaction); + @Property + val DataModification, DataObject> modification; + + @Property + IPluginOutTopologyService topologyPublisher; + + @Property + DataProviderService dataService; + @Property + List edgeUpdates; + + new(DataModification, DataObject> modification,IPluginOutTopologyService topologyPublisher, + DataProviderService dataService,List 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 { + + override getErrors() { + return Collections.emptySet + } + + override getResult() { + return null; + } + + override isSuccessful() { + return true; + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend index 5203d3c1a8..dc2a7ee6f9 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend @@ -15,14 +15,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N 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, DataObject> modification,SalFlowService salFlowService) { - super(modification) + super(modification) _salFlowService = salFlowService; } @@ -32,8 +35,10 @@ class FlowTransaction extends AbstractTransaction { 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()); } } @@ -45,8 +50,10 @@ class FlowTransaction extends AbstractTransaction { 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()); @@ -61,6 +68,8 @@ class FlowTransaction extends AbstractTransaction { 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()); } diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend index 54382ea056..f79c9b61a6 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend @@ -2,34 +2,27 @@ package org.opendaylight.controller.frm.group 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, DataObject> modification,SalGroupService groupService) { - super(modification) + super(modification) _groupService = groupService; } @@ -39,6 +32,8 @@ class GroupTransaction extends AbstractTransaction { 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()); } } @@ -50,8 +45,10 @@ class GroupTransaction extends AbstractTransaction { 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()); @@ -65,6 +62,8 @@ class GroupTransaction extends AbstractTransaction { 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()); } } diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend index 3ed1f40735..594a16c34e 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend @@ -13,14 +13,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.met 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, DataObject> modification,SalMeterService salMeterService) { - super(modification) + super(modification) _salMeterService = salMeterService; } @@ -30,6 +32,8 @@ class MeterTransaction extends AbstractTransaction { 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()); } } @@ -41,8 +45,10 @@ class MeterTransaction extends AbstractTransaction { 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()); @@ -56,6 +62,8 @@ class MeterTransaction extends AbstractTransaction { 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()); } } diff --git a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend index 2b023a72e1..1a66b3ba16 100644 --- a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend +++ b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend @@ -76,7 +76,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener { // Check path val it = manager.startChange() - removeRuntimeData(ref.value as InstanceIdentifier); + removeOperationalData(ref.value as InstanceIdentifier); commit() } @@ -93,7 +93,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener { data.addAugmentation(FlowCapableNodeConnector, augment) } - putRuntimeData(ref.value as InstanceIdentifier, data.build()); + putOperationalData(ref.value as InstanceIdentifier, data.build()); commit() } @@ -101,7 +101,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener { val ref = node.nodeRef; val it = manager.startChange() - removeRuntimeData(ref.value as InstanceIdentifier); + removeOperationalData(ref.value as InstanceIdentifier); commit() } @@ -117,7 +117,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener { data.addAugmentation(FlowCapableNode, augment) } - putRuntimeData(ref.value as InstanceIdentifier, data.build()) + putOperationalData(ref.value as InstanceIdentifier, data.build()) commit() } } diff --git a/opendaylight/md-sal/model/model-flow-base/pom.xml b/opendaylight/md-sal/model/model-flow-base/pom.xml index 13ffa3f910..5e69548d9a 100644 --- a/opendaylight/md-sal/model/model-flow-base/pom.xml +++ b/opendaylight/md-sal/model/model-flow-base/pom.xml @@ -19,7 +19,12 @@ org.opendaylight.yangtools.model opendaylight-l2-types - 2013.08.27.0 + 2013.08.27.1 + + + ${project.groupId} + model-inventory + ${project.version} bundle diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/group-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/group-types.yang index 8c874e2fe8..4442fbb335 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/group-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/group-types.yang @@ -84,6 +84,10 @@ module opendaylight-group-types { description "Check chaining for loops and delete"; } + typedef group-ref { + type instance-identifier; + } + grouping group { leaf group-type { @@ -102,10 +106,6 @@ module opendaylight-group-types { type string; } - leaf install { - type boolean; - } - leaf barrier { type boolean; } diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang index 1ed1b6827b..31736d2737 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang @@ -5,6 +5,7 @@ module opendaylight-match-types { 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"; @@ -270,11 +271,11 @@ module opendaylight-match-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" { diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/meter-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/meter-types.yang index b380af2212..d84b2f0851 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/meter-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/meter-types.yang @@ -112,6 +112,10 @@ module opendaylight-meter-types { } } + typedef meter-ref { + type instance-identifier; + } + grouping meter { leaf flags { @@ -120,11 +124,12 @@ module opendaylight-meter-types { leaf meter-id { type meter-id; - } + } - leaf install { + leaf barrier { type boolean; } + leaf meter-name { type string; } diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-action-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-action-types.yang index 43754a1dfd..3cc490f017 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-action-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-action-types.yang @@ -49,9 +49,7 @@ module opendaylight-action-types { } leaf max-length { - type uint16 { - range "0..65294"; - } + type uint16; } } } @@ -59,9 +57,7 @@ module opendaylight-action-types { case controller-action-case { container controller-action { leaf max-length { - type uint16 { - range "0..65294"; - } + type uint16; } } } diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang index 2bcd405223..a0beb2a84c 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang @@ -12,6 +12,10 @@ module opendaylight-flow-types { description "Initial revision of flow service"; } + typedef flow-ref { + type instance-identifier; + } + typedef output-port-values { type enumeration { enum MAX { diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang index bc05894da8..2554fffadb 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang @@ -27,11 +27,15 @@ module opendaylight-port-types { } } - 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; } } @@ -103,9 +107,9 @@ module opendaylight-port-types { 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 { diff --git a/opendaylight/md-sal/model/model-flow-management/pom.xml b/opendaylight/md-sal/model/model-flow-management/pom.xml index 1a0c37055b..db2c62d9af 100644 --- a/opendaylight/md-sal/model/model-flow-management/pom.xml +++ b/opendaylight/md-sal/model/model-flow-management/pom.xml @@ -29,7 +29,7 @@ org.opendaylight.yangtools.model opendaylight-l2-types - 2013.08.27.0 + 2013.08.27.1 bundle diff --git a/opendaylight/md-sal/model/model-flow-service/pom.xml b/opendaylight/md-sal/model/model-flow-service/pom.xml index 6b8df6a4c8..c2e48b3df5 100644 --- a/opendaylight/md-sal/model/model-flow-service/pom.xml +++ b/opendaylight/md-sal/model/model-flow-service/pom.xml @@ -29,7 +29,7 @@ org.opendaylight.yangtools.model opendaylight-l2-types - 2013.08.27.0 + 2013.08.27.1 bundle diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang index 483c0c9e12..1c675f015d 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang @@ -3,6 +3,7 @@ module flow-capable-transaction { 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" { @@ -12,6 +13,12 @@ module flow-capable-transaction { 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 { diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-node-inventory.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-node-inventory.yang index e55c50fb29..0f5cc71e8b 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-node-inventory.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-node-inventory.yang @@ -92,7 +92,7 @@ module flow-node-inventory { } typedef flow-id { - type uint32; // Note: This doesn't really belong here, and not sure if unint32 is right + type inet:uri; } grouping tables { diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang index 089469f045..5c68a137c3 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang @@ -51,8 +51,11 @@ module sal-flow { 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; @@ -61,8 +64,11 @@ module sal-flow { 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; @@ -71,8 +77,11 @@ module sal-flow { 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; @@ -80,16 +89,28 @@ module sal-flow { } 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; } @@ -101,6 +122,7 @@ module sal-flow { notification node-error-notification { uses error:error-message; uses tr:transaction-aware; + uses tr:transaction-metadata; } notification node-experimenter-error-notification { diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/group-service.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/group-service.yang index bbe4740e71..7eeb0ac0f3 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/group-service.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/group-service.yang @@ -31,8 +31,11 @@ module sal-group { 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; @@ -41,8 +44,11 @@ module sal-group { 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; @@ -51,8 +57,11 @@ module sal-group { 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; @@ -60,16 +69,28 @@ module sal-group { } 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; } diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/meter-service.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/meter-service.yang index 65b22b29dd..ecdef41951 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/meter-service.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/meter-service.yang @@ -31,8 +31,11 @@ module sal-meter { 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; @@ -41,8 +44,12 @@ module sal-meter { 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; @@ -51,8 +58,12 @@ module sal-meter { 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; @@ -60,16 +71,28 @@ module sal-meter { } 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; } diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang index bfdf5049c3..00ecdbacf0 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang @@ -6,6 +6,8 @@ module packet-processing { 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 ""; @@ -34,11 +36,44 @@ module packet-processing { } } + 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; } @@ -56,4 +91,4 @@ module packet-processing { uses raw-packet; } } -} \ No newline at end of file +} diff --git a/opendaylight/md-sal/model/model-flow-statistics/pom.xml b/opendaylight/md-sal/model/model-flow-statistics/pom.xml index 476c817c90..e95fe24f28 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/pom.xml +++ b/opendaylight/md-sal/model/model-flow-statistics/pom.xml @@ -29,7 +29,7 @@ org.opendaylight.yangtools.model opendaylight-l2-types - 2013.08.27-SNAPSHOT + 2013.08.27.1-SNAPSHOT bundle diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/flow-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/flow-statistics.yang index 3bd37bcf33..2b1d993026 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/flow-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/flow-statistics.yang @@ -11,6 +11,7 @@ module opendaylight-flow-statistics { 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" { @@ -33,7 +34,7 @@ module opendaylight-flow-statistics { typedef flow-id { description "flow id"; - type yang:counter32; + type inet:uri; } grouping flow-and-statistics-map-list { @@ -115,7 +116,7 @@ module opendaylight-flow-statistics { } } - // 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 { @@ -150,76 +151,4 @@ module opendaylight-flow-statistics { 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; - } } diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang index 5640858d51..834e0a7835 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang @@ -6,6 +6,7 @@ module opendaylight-group-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 @@ -22,7 +23,7 @@ module opendaylight-group-statistics { } } - augment "/inv:nodes/inv:node/group-types:group" { + augment "/inv:nodes/inv:node/fni:group" { ext:augment-identifier "node-group-statistics"; uses group-statistics; } diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/port-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/port-statistics.yang index 0cb6a60cfe..787a4e6aa0 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/port-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/port-statistics.yang @@ -30,19 +30,19 @@ module opendaylight-port-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 { @@ -55,9 +55,9 @@ module opendaylight-port-statistics { } } - //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 { @@ -67,7 +67,7 @@ module opendaylight-port-statistics { } } - notification port-statistics-update { + notification node-connector-statistics-update { leaf moreReplies { type boolean; } diff --git a/opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang b/opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang new file mode 100644 index 0000000000..b5cde6ee5b --- /dev/null +++ b/opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang @@ -0,0 +1,27 @@ +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 diff --git a/opendaylight/md-sal/model/model-topology/pom.xml b/opendaylight/md-sal/model/model-topology/pom.xml index c91b9dd53a..e2ce7a9735 100644 --- a/opendaylight/md-sal/model/model-topology/pom.xml +++ b/opendaylight/md-sal/model/model-topology/pom.xml @@ -17,15 +17,15 @@ bundle - - org.opendaylight.controller.model - model-inventory - 1.0-SNAPSHOT - - - org.opendaylight.yangtools.model - ietf-topology - 2013.07.12.2-SNAPSHOT - + + org.opendaylight.controller.model + model-inventory + 1.0-SNAPSHOT + + + org.opendaylight.yangtools.model + ietf-topology + 2013.10.21.0-SNAPSHOT + diff --git a/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang b/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang index 33c03ba059..87de0f5ae1 100644 --- a/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang +++ b/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang @@ -8,7 +8,7 @@ module opendaylight-topology-inventory { 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"; @@ -21,14 +21,16 @@ module opendaylight-topology-inventory { 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 +} diff --git a/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang b/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang index 038a1b7c67..6bbfd4b479 100644 --- a/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang +++ b/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang @@ -7,7 +7,7 @@ module opendaylight-topology { 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"; diff --git a/opendaylight/md-sal/model/model-topology/src/main/yang/topology-view.yang b/opendaylight/md-sal/model/model-topology/src/main/yang/topology-view.yang index 2fecb327ca..1a10bf6fdd 100644 --- a/opendaylight/md-sal/model/model-topology/src/main/yang/topology-view.yang +++ b/opendaylight/md-sal/model/model-topology/src/main/yang/topology-view.yang @@ -6,7 +6,7 @@ module opendaylight-topology-view { 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"; @@ -45,4 +45,4 @@ module opendaylight-topology-view { ext:augment-identifier "aggregated-node"; uses aggregate-node; } -} \ No newline at end of file +} diff --git a/opendaylight/md-sal/model/pom.xml b/opendaylight/md-sal/model/pom.xml index c5f1dddc34..571e9d8df2 100644 --- a/opendaylight/md-sal/model/pom.xml +++ b/opendaylight/md-sal/model/pom.xml @@ -19,7 +19,7 @@ UTF-8 - 2.3.7 + 2.4.0 @@ -40,7 +40,7 @@ ${project.groupId}.${project.artifactId} - *,org.opendaylight.yangtools.yang.binding.annotations + org.opendaylight.yangtools.yang.binding.annotations, * @@ -68,6 +68,10 @@ org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl target/site/models + + org.opendaylight.yangtools.yang.wadl.generator.maven.WadlGenerator + target/site/models + true diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index 0d6523bc0b..efc84237b5 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -50,7 +50,9 @@ inventory-manager statistics-manager + topology-manager forwardingrules-manager + topology-lldp-discovery compatibility diff --git a/opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml b/opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml index a788baf4c0..dedd318a0c 100644 --- a/opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml +++ b/opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml @@ -86,7 +86,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml index 35b2a4b250..1fd4b762c1 100644 --- a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml +++ b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml @@ -25,7 +25,7 @@ com.sun.jersey.spi.container.servlet, - org.codehaus.jackson.annotate, + com.fasterxml.jackson.annotation, javax.ws.rs, javax.ws.rs.core, javax.xml.bind, diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java index e20640d420..72c6b1d75d 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java @@ -7,7 +7,7 @@ import org.opendaylight.yangtools.yang.binding.RpcService; * 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. diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java index 972e64faf6..cc764888cc 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java @@ -1,18 +1,22 @@ 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> { /** * Registers an global RpcService implementation. * @@ -25,12 +29,16 @@ public interface RpcProviderRegistry extends RpcConsumerRegistry { /** * - * 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 */ diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java index d91a216baa..194c431ec0 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java @@ -1,18 +1,36 @@ 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 registerProvisionListener(MountProvisionListener listener); + + public interface MountProvisionListener extends EventListener { + + void onMountPointCreated(InstanceIdentifier path); + + void onMountPointRemoved(InstanceIdentifier path); + + } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcContextIdentifier.java similarity index 97% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcContextIdentifier.java index 33569eb077..8437c18f09 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcContextIdentifier.java @@ -1,4 +1,4 @@ -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; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java similarity index 98% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java index 621d048dfd..31fed62d87 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java @@ -5,7 +5,7 @@ * 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; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingContext.java similarity index 82% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingContext.java index e3a7235652..db93766c3c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingContext.java @@ -1,4 +1,4 @@ -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; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingTable.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingTable.java similarity index 96% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingTable.java rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingTable.java index 4d9d51b133..cc800b6bbb 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingTable.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingTable.java @@ -5,7 +5,7 @@ * 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; diff --git a/opendaylight/md-sal/sal-binding-broker/pom.xml b/opendaylight/md-sal/sal-binding-broker/pom.xml index 1b0f78384f..29357c0432 100644 --- a/opendaylight/md-sal/sal-binding-broker/pom.xml +++ b/opendaylight/md-sal/sal-binding-broker/pom.xml @@ -163,6 +163,11 @@ sal-binding-api 1.0-SNAPSHOT + + org.opendaylight.controller + sal-binding-util + 1.0-SNAPSHOT + org.slf4j slf4j-api diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java index c46b0dd6b4..cd45f2c8b2 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java @@ -1,48 +1,85 @@ /** -* Generated file + * Generated file -* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Wed Nov 20 17:33:01 CET 2013 -* -* Do not modify this file unless it is present under src/main directory -*/ + * Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl + * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + * Generated at: Wed Nov 20 17:33:01 CET 2013 + * + * Do not modify this file unless it is present under src/main directory + */ package org.opendaylight.controller.config.yang.md.sal.binding.impl; -import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl; +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; +import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker; +import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl; +import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl; +import org.opendaylight.controller.sal.binding.impl.forward.DomForwardingUtils; import org.osgi.framework.BundleContext; -import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.MoreExecutors; /** * */ -public final class BindingBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule { +public final class BindingBrokerImplModule extends + org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule { private BundleContext bundleContext; - public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, + org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) { + public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, + org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, + BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @Override - public void validate(){ + public void validate() { super.validate(); } @Override public java.lang.AutoCloseable createInstance() { - BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getIdentifier().getInstanceName(),getBundleContext()); - broker.setDataBroker(getDataBrokerDependency()); - broker.setNotifyBroker(getNotificationServiceDependency()); + + RootBindingAwareBroker broker; + if (DomForwardingUtils.isDomForwardedBroker(getDataBrokerDependency())) { + broker = createForwardedBroker(); + } else { + broker = createStandaloneBroker(); + } broker.start(); return broker; } + private RootBindingAwareBroker createStandaloneBroker() { + RootBindingAwareBroker broker = new RootBindingAwareBroker(getIdentifier().getInstanceName()); + + broker.setDataBroker(getDataBrokerDependency()); + broker.setNotificationBroker(getNotificationServiceDependency()); + broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier())); + return broker; + } + + private RootBindingAwareBroker createForwardedBroker() { + DomForwardedBindingBrokerImpl broker = new DomForwardedBindingBrokerImpl(getIdentifier().getInstanceName()); + + broker.setDataBroker(getDataBrokerDependency()); + broker.setNotificationBroker(getNotificationServiceDependency()); + broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier())); + + broker.getMountManager().setDataCommitExecutor(SingletonHolder.getDefaultCommitExecutor()); + broker.getMountManager().setNotificationExecutor(SingletonHolder.getDefaultNotificationExecutor()); + + + DomForwardingUtils.reuseForwardingFrom(broker, broker.getDataBroker()); + broker.startForwarding(); + return broker; + } + public BundleContext getBundleContext() { return bundleContext; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java index 01dc6b8c0c..185b37bab5 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java @@ -13,12 +13,16 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import org.opendaylight.controller.config.yang.md.sal.binding.statistics.DataBrokerRuntimeMXBeanImpl; import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter; +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl; +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.binding.impl.connect.dom.BindingIndependentMappingService; +import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl; import org.opendaylight.controller.sal.core.api.Broker; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; import org.opendaylight.controller.sal.core.api.data.DataProviderService; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -52,25 +56,38 @@ public final class DataBrokerImplModule extends @Override public java.lang.AutoCloseable createInstance() { - DataBrokerRuntimeMXBeanImpl dataBindingBroker = new DataBrokerRuntimeMXBeanImpl(); + RootDataBrokerImpl dataBindingBroker; - // FIXME: obtain via dependency management - ExecutorService executor = Executors.newCachedThreadPool(); - ExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor); - dataBindingBroker.setExecutor(listeningExecutor); - - Broker domBroker = getDomBrokerDependency(); - BindingIndependentMappingService mappingService = getMappingServiceDependency(); - if (domBroker != null && mappingService != null) { - BindingIndependentConnector runtimeMapping = new BindingIndependentConnector(); - runtimeMapping.setMappingService(mappingService); - runtimeMapping.setBaDataService(dataBindingBroker); - domBroker.registerProvider(runtimeMapping, getBundleContext()); + ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor(); + + if (getDomBrokerDependency() != null && getMappingServiceDependency() != null) { + + dataBindingBroker = createDomConnectedBroker(listeningExecutor); + } else { + dataBindingBroker = createStandAloneBroker(listeningExecutor); } - getRootRuntimeBeanRegistratorWrapper().register(dataBindingBroker); + dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper()); + return dataBindingBroker; } + private RootDataBrokerImpl createStandAloneBroker(ExecutorService listeningExecutor) { + RootDataBrokerImpl broker = new RootDataBrokerImpl(); + broker.setExecutor(listeningExecutor); + return broker; + } + + private RootDataBrokerImpl createDomConnectedBroker(ExecutorService listeningExecutor) { + DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl(); + forwardedBroker.setExecutor(listeningExecutor); + BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(getMappingServiceDependency()); + getDomBrokerDependency().registerProvider(forwardedBroker, getBundleContext()); + ProviderSession domContext = forwardedBroker.getDomProviderContext(); + forwardedBroker.setConnector(connector); + forwardedBroker.setDomProviderContext(domContext); + forwardedBroker.startForwarding(); + return forwardedBroker; + } public BundleContext getBundleContext() { return bundleContext; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java index e4f74deb4b..644860595e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java @@ -13,6 +13,7 @@ import java.util.concurrent.ExecutorService; 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; @@ -43,8 +44,7 @@ public final class NotificationBrokerImplModule extends @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; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java deleted file mode 100644 index 5da084e9bd..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.opendaylight.controller.config.yang.md.sal.binding.statistics; - -import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data; -import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean; -import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions; -import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl; - -public class DataBrokerRuntimeMXBeanImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean { - - private final Transactions transactions = new Transactions(); - private final Data data = new Data(); - - public Transactions getTransactions() { - transactions.setCreated(getCreatedTransactionsCount().get()); - transactions.setSubmitted(getSubmittedTransactionsCount().get()); - transactions.setSuccessful(getFinishedTransactionsCount().get()); - transactions.setFailed(getFailedTransactionsCount().get()); - return transactions; - } - - @Override - public Data getData() { - transactions.setCreated(getCreatedTransactionsCount().get()); - transactions.setSubmitted(getSubmittedTransactionsCount().get()); - transactions.setSuccessful(getFinishedTransactionsCount().get()); - transactions.setFailed(getFailedTransactionsCount().get()); - data.setTransactions(transactions); - return data; - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java index 7789a06fe8..8aff12b44a 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java @@ -7,8 +7,8 @@ */ 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; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java index 8b2db8b13c..d976a0cec9 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java @@ -3,7 +3,8 @@ package org.opendaylight.controller.sal.binding.codegen.impl; 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; @@ -13,7 +14,6 @@ import java.util.Map; 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; @@ -147,7 +147,6 @@ public class RpcRouterCodegenInstance implements // @Override public void unregisterPath(Class context, InstanceIdentifier path) { routingTables.get(context).removeRoute(path, getInstance()); - } @Override diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java index 808358fb35..76318ae843 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java @@ -1,6 +1,6 @@ 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; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java index 266293fb6d..446a9caf8e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java @@ -1,14 +1,49 @@ 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); + + } + } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/AugmentationCodec.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/AugmentationCodec.java index cdddec76d4..970e077c03 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/AugmentationCodec.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/AugmentationCodec.java @@ -1,6 +1,7 @@ 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; @@ -12,4 +13,6 @@ public interface AugmentationCodec> extends DomCodec deserialize(Node input); + + public QName getAugmentationQName(); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/CodecRegistry.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/CodecRegistry.java index b9a4fe87ac..4565b545ba 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/CodecRegistry.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/CodecRegistry.java @@ -10,6 +10,7 @@ import java.util.List; 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 { @@ -36,4 +37,6 @@ public interface CodecRegistry { void bindingClassEncountered(Class cls); void putPathToClass(List names, Class cls); + + public abstract QName getQNameForAugmentation(Class cls); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/InstanceIdentifierCodecImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/InstanceIdentifierCodecImpl.xtend index 150d0f199f..f84503bea4 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/InstanceIdentifierCodecImpl.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/InstanceIdentifierCodecImpl.xtend @@ -26,13 +26,13 @@ import org.opendaylight.yangtools.yang.binding.Augmentable 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,QName> classToQName = new WeakHashMap; val Map, Map, Class>> classToPreviousAugment = new WeakHashMap; public new(CodecRegistry registry) { @@ -106,7 +106,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec { previousAugmentation = null; } else { - previousQName = resolveQname(baArg.type); + previousQName = codecRegistry.getQNameForAugmentation(baArg.type as Class); previousAugmentation = baArg.type; } } @@ -122,7 +122,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec { 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); } @@ -134,7 +134,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec { val Map 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) { @@ -145,15 +145,4 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec { } 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 diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java index cabb1bc4e2..89d9b49081 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java @@ -44,6 +44,7 @@ import org.opendaylight.yangtools.yang.binding.BindingCodec; 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; @@ -153,6 +154,12 @@ public class LazyGeneratedCodecRegistry implements // } return codec; } + + @Override + public QName getQNameForAugmentation(Class cls) { + checkArgument(Augmentation.class.isAssignableFrom(cls)); + return getCodecForAugmentation((Class)cls).getAugmentationQName(); + } private static Class> getAugmentableArgumentFrom( final Class> augmentation) { @@ -909,9 +916,11 @@ public class LazyGeneratedCodecRegistry implements // Delegator { private BindingCodec delegate; + private QName augmentationQName; public AugmentationCodecWrapper(BindingCodec, Object> rawCodec) { this.delegate = rawCodec; + this.augmentationQName = BindingReflections.findQName(rawCodec.getClass()); } @Override @@ -936,6 +945,11 @@ public class LazyGeneratedCodecRegistry implements // Object rawCodecValue = getDelegate().deserialize((Map) input); return new ValueWithQName(input.getNodeType(), (T) rawCodecValue); } + + @Override + public QName getAugmentationQName() { + return augmentationQName; + } } private class IdentityCompositeCodec implements IdentitityCodec { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend deleted file mode 100644 index b4bf3f5a83..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 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 >> registerRouteChangeListener(L listener) { - super.registerRouteChangeListener(listener) - } - - override close() throws Exception { - - } -} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java index 5db522f56c..0069de9802 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java @@ -3,7 +3,7 @@ package org.opendaylight.controller.sal.binding.impl; import java.util.Set; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicLong; - + import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker; import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; @@ -11,12 +11,13 @@ import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderR import org.opendaylight.controller.sal.common.DataStoreIdentifier; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.DataRoot; +import org.opendaylight.yangtools.yang.binding.Identifiable; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; -public class DataBrokerImpl extends AbstractDataBroker, DataObject, DataChangeListener> implements - DataProviderService, AutoCloseable { +public class DataBrokerImpl extends AbstractDataBroker, DataObject, DataChangeListener> // + implements DataProviderService, AutoCloseable { private final AtomicLong nextTransaction = new AtomicLong(); private final AtomicLong createdTransactionsCount = new AtomicLong(); @@ -114,7 +115,6 @@ public class DataBrokerImpl extends AbstractDataBroker, BindingMountPointImpl> mountPoints; + private final ListenerRegistry 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 listener : listeners) { + try { + listener.getInstance().onMountPointCreated(path); + } catch (Exception e) { + LOG.error("Unhandled exception during invoking listener.", e); + } + } + } + + @Override + public ListenerRegistration registerProvisionListener(MountProvisionListener listener) { + return listeners.register(listener); + } + + public class BindingMountPointImpl extends + AbstractBindingSalProviderInstance + 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; + } + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend index b10c06f0c5..b4fd6b6771 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend @@ -20,8 +20,9 @@ import org.opendaylight.yangtools.concepts.AbstractObjectRegistration import org.opendaylight.yangtools.concepts.ListenerRegistration import org.opendaylight.yangtools.concepts.Registration import org.opendaylight.yangtools.yang.binding.Notification -import org.slf4j.LoggerFactory import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder - +import org.slf4j.LoggerFactory +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder + class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { val Multimap, NotificationListener> listeners; @@ -174,14 +175,24 @@ class NotifyTask implements Callable { private static val log = LoggerFactory.getLogger(NotifyTask); + @SuppressWarnings("rawtypes") val NotificationListener listener; val Notification notification; override call() { + //Only logging the complete notification in debug mode try { - log.info("Delivering notification {} to {}",notification,listener); + if(log.isDebugEnabled){ + log.debug("Delivering notification {} to {}",notification,listener); + } else { + log.info("Delivering notification {} to {}",notification.class.name,listener); + } listener.onNotification(notification); - log.info("Notification delivered {} to {}",notification,listener); + if(log.isDebugEnabled){ + log.debug("Notification delivered {} to {}",notification,listener); + } else { + log.info("Notification delivered {} to {}",notification.class.name,listener); + } } catch (Exception e) { log.error("Unhandled exception thrown by listener: {}", listener, e); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend deleted file mode 100644 index 644c50b86a..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 getSALService(Class service) { - - // SAL Services are global - var ref = bundleContext.getServiceReference(service); - return bundleContext.getService(ref) as T; - } - - override def T getRpcService(Class 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; - 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»)''' - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend deleted file mode 100644 index d1ec35157f..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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, RpcRegistration> registeredServices - - new(BundleContext ctx, BindingAwareBrokerImpl broker) { - super(ctx, broker); - _registeredServices = new HashMap(); - } - - override addRpcImplementation(Class type, T implementation) { - val salReg = broker.addRpcImplementation(type, implementation) - registeredServices.put(type, salReg) - return salReg; - } - - override addRoutedRpcImplementation(Class 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 - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java new file mode 100644 index 0000000000..35c2bee646 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java @@ -0,0 +1,174 @@ +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, // + 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 supportedConsumerServices; + + private ImmutableClassToInstanceMap 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. builder() + .put(NotificationService.class, getRoot()) // + .put(DataBrokerService.class, getRoot()) // + .put(RpcConsumerRegistry.class, getRoot()) // + .put(MountService.class, mountManager).build(); + + supportedProviderServices = ImmutableClassToInstanceMap. 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 RoutedRpcRegistration addRoutedRpcImplementation(Class type, T implementation) + throws IllegalStateException { + return getRoot().addRoutedRpcImplementation(type, implementation); + } + + @Override + public RpcRegistration addRpcImplementation(Class type, T implementation) + throws IllegalStateException { + return getRoot().addRpcImplementation(type, implementation); + } + + @Override + public T getRpcService(Class module) { + return getRoot().getRpcService(module); + } + @Override + public >> ListenerRegistration registerRouteChangeListener( + L arg0) { + return getRoot().registerRouteChangeListener(arg0); + } + + + public class RootSalInstance extends + AbstractBindingSalProviderInstance { + + public RootSalInstance(RpcProviderRegistry rpcRegistry, NotificationProviderService notificationBroker, + DataProviderService dataBroker) { + super(rpcRegistry, notificationBroker, dataBroker); + } + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java new file mode 100644 index 0000000000..1b6c56d15d --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java @@ -0,0 +1,43 @@ +package org.opendaylight.controller.sal.binding.impl; + +import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistration; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistrator; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector; + +public class RootDataBrokerImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean { + + private final Transactions transactions = new Transactions(); + private final Data data = new Data(); + private BindingIndependentConnector bindingIndependentConnector; + private DataBrokerImplRuntimeRegistration runtimeBeanRegistration; + + public BindingIndependentConnector getBindingIndependentConnector() { + return bindingIndependentConnector; + } + + public Transactions getTransactions() { + transactions.setCreated(getCreatedTransactionsCount().get()); + transactions.setSubmitted(getSubmittedTransactionsCount().get()); + transactions.setSuccessful(getFinishedTransactionsCount().get()); + transactions.setFailed(getFailedTransactionsCount().get()); + return transactions; + } + + @Override + public Data getData() { + data.setTransactions(getTransactions()); + return data; + } + + public void setBindingIndependentConnector(BindingIndependentConnector runtimeMapping) { + this.bindingIndependentConnector = runtimeMapping; + } + + public void registerRuntimeBean(DataBrokerImplRuntimeRegistrator rootRegistrator) { + runtimeBeanRegistration = rootRegistrator.register(this); + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java index 6a17007d22..8773476cae 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java @@ -15,11 +15,11 @@ import org.opendaylight.controller.md.sal.common.impl.routing.RoutingUtils; 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; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java new file mode 100644 index 0000000000..f200b4d08d --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java @@ -0,0 +1,103 @@ +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; + // } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java index daa3914cf7..75b0138e7c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java @@ -1,12 +1,9 @@ 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; @@ -18,21 +15,23 @@ import java.util.concurrent.ConcurrentMap; 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; @@ -49,7 +48,6 @@ import org.opendaylight.yangtools.yang.binding.BindingMapping; 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; @@ -65,7 +63,6 @@ import com.google.common.collect.FluentIterable; 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, // @@ -96,7 +93,7 @@ public class BindingIndependentConnector implements // private Registration> biCommitHandlerRegistration; private RpcProvisionRegistry biRpcRegistry; - private RpcProviderRegistryImpl baRpcRegistry; + private RpcProviderRegistry baRpcRegistry; private ListenerRegistration domToBindingRpcManager; // private ListenerRegistration @@ -111,36 +108,44 @@ public class BindingIndependentConnector implements // }; + private Registration, DataObject>> baDataReaderRegistration; + + private boolean rpcForwarding = false; + + private boolean dataForwarding = false; + + private boolean notificationForwarding = false; + @Override public DataObject readOperationalData(InstanceIdentifier path) { try { org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); - CompositeNode result = biDataService.readOperationalData(biPath); - Class targetType = path.getTargetType(); - - if (Augmentation.class.isAssignableFrom(targetType)) { - path = mappingService.fromDataDom(biPath); - Class> augmentType = (Class>) 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 path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException { + Class targetType = path.getTargetType(); + if (Augmentation.class.isAssignableFrom(targetType)) { + path = mappingService.fromDataDom(biPath); + Class> augmentType = (Class>) 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 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); } @@ -222,7 +227,7 @@ public class BindingIndependentConnector implements // 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; } @@ -230,7 +235,7 @@ public class BindingIndependentConnector implements // return baDataService; } - public void setBaDataService(DataProviderService baDataService) { + protected void setBindingDataService(DataProviderService baDataService) { this.baDataService = baDataService; } @@ -238,23 +243,33 @@ public class BindingIndependentConnector implements // 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; } @@ -265,8 +280,9 @@ public class BindingIndependentConnector implements // @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 void onRpcRouterCreated(Class serviceType, RpcRouter router) { @@ -381,7 +397,7 @@ public class BindingIndependentConnector implements // */ if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) { - return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction); + return CommitHandlerTransactions.allwaysSuccessfulTransaction(bindingTransaction); } DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction); BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction); @@ -420,7 +436,7 @@ public class BindingIndependentConnector implements // * 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); @@ -597,6 +613,7 @@ public class BindingIndependentConnector implements // @SuppressWarnings("rawtypes") private WeakReference outputClass; + @SuppressWarnings({ "rawtypes", "unchecked" }) public DefaultInvocationStrategy(Method targetMethod, Class outputClass, Class inputClass) { super(targetMethod); @@ -624,10 +641,27 @@ public class BindingIndependentConnector implements // } public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { + @SuppressWarnings("unchecked") Future> result = (Future>) targetMethod.invoke(rpcService); RpcResult 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; } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java new file mode 100644 index 0000000000..630b5fa8df --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java @@ -0,0 +1,128 @@ +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, BindingIndependentConnector> connectors; + private ConcurrentMap, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded; + private ListenerRegistration domListenerRegistration; + private ListenerRegistration 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); + } + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java deleted file mode 100644 index d22da3038c..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.opendaylight.controller.sal.binding.impl.connect.dom; - -public class BindingIndependentRpcConnector { - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java new file mode 100644 index 0000000000..c715c67dd2 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java @@ -0,0 +1,166 @@ +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, BindingIndependentConnector> connectors = new ConcurrentHashMap<>(); + private ConcurrentMap, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded = new ConcurrentHashMap<>(); + private ListenerRegistration domListenerRegistration; + private ListenerRegistration 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); + } + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java new file mode 100644 index 0000000000..c7dbcd4f5c --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java @@ -0,0 +1,17 @@ +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(); +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java new file mode 100644 index 0000000000..f90a4acf2a --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java @@ -0,0 +1,49 @@ +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 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()); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java new file mode 100644 index 0000000000..581b217bfa --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java @@ -0,0 +1,25 @@ +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()); + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend deleted file mode 100644 index 9fb2140e83..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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" -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend deleted file mode 100644 index d04ca7f4ce..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 properties, String value) { - properties.put(SAL_SERVICE_TYPE, value) - return properties - } - - static def getSalServiceType(Hashtable properties) { - return properties.get(SAL_SERVICE_TYPE) - } - - static def newProperties() { - new Hashtable() - } - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java deleted file mode 100644 index d788ccf3a3..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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 diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java deleted file mode 100644 index 49e056b100..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.opendaylight.controller.sal.binding.spi; - -public class RoutingContext { - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang b/opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang index b040aa025e..b0d1629a73 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang +++ b/opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang @@ -85,10 +85,10 @@ module opendaylight-sal-binding-broker-impl { 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'"; @@ -100,6 +100,7 @@ module opendaylight-sal-binding-broker-impl { } } } + container mapping-service { uses config:service-ref { refine type { diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java index 6f0db4cd8d..20181a62c8 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java @@ -16,11 +16,11 @@ import org.junit.Test; 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; diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java index d4d27a14ec..c03d851f5c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java @@ -4,26 +4,44 @@ import java.io.InputStream; 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; @@ -33,26 +51,26 @@ import org.slf4j.Logger; 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; @@ -61,15 +79,15 @@ public class BindingTestContext implements AutoCloseable { 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; @@ -82,74 +100,133 @@ public class BindingTestContext implements AutoCloseable { 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 domBrokerServices = ImmutableClassToInstanceMap + . 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> rpc(QName rpc, CompositeNode input) { + throw new UnsupportedOperationException(); + } + + @Override + public T getService(Class service) { + return domBrokerServices.getInstance(service); + } + + @Override + public boolean isClosed() { + return false; + } + + @Override + public Set getSupportedRpcs() { + return null; + } + + @Override + public void close() { + } + + @Override + public ListenerRegistration 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 predicate = new Predicate() { @Override @@ -161,7 +238,7 @@ public class BindingTestContext implements AutoCloseable { Set result = reflection.getResources(predicate); return (String[]) result.toArray(new String[result.size()]); } - + private static SchemaContext getContext(String[] yangFiles) { ClassLoader loader = BindingTestContext.class.getClassLoader(); List streams = new ArrayList<>(); @@ -173,7 +250,7 @@ public class BindingTestContext implements AutoCloseable { Set modules = parser.parseYangModelsFromStreams(streams); return parser.resolveSchemaContext(modules); } - + public void start() { startBindingDataBroker(); startBindingNotificationBroker(); @@ -181,13 +258,19 @@ public class BindingTestContext implements AutoCloseable { 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(); @@ -198,7 +281,7 @@ public class BindingTestContext implements AutoCloseable { public void startBindingNotificationBroker() { checkState(executor != null); baNotifyImpl = new NotificationBrokerImpl(executor); - + } public void loadYangSchemaFromClasspath() { @@ -223,10 +306,10 @@ public class BindingTestContext implements AutoCloseable { } 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()); @@ -241,22 +324,30 @@ public class BindingTestContext implements AutoCloseable { } 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; } } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/FlagsSerializationTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/FlagsSerializationTest.java index 1304f0d52a..e31ae6b8c7 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/FlagsSerializationTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/FlagsSerializationTest.java @@ -1,35 +1,10 @@ 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; @@ -48,16 +23,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru 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; @@ -65,21 +37,21 @@ import org.opendaylight.yangtools.yang.common.QName; 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"; diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java index 96d0361b1d..d9b16af469 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java @@ -12,6 +12,8 @@ import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; 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; @@ -130,8 +132,60 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data 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 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 ncPath = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA) + .child(NodeConnector.class, ncKey).toInstance(); + InstanceIdentifier 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 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); diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java index ea36f81b0b..0258c3e439 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java @@ -1,29 +1,18 @@ 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; @@ -44,14 +33,10 @@ 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.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; @@ -59,7 +44,14 @@ import org.opendaylight.yangtools.yang.common.QName; 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 { @@ -69,7 +61,7 @@ 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)); @@ -144,7 +136,7 @@ public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest { public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction, DataObject> requestCommit( DataModification, DataObject> modification) { modificationCapture = modification; - return CommitHandlersTransactions.allwaysSuccessfulTransaction(modification); + return CommitHandlerTransactions.allwaysSuccessfulTransaction(modification); } }; diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java new file mode 100644 index 0000000000..a99d80ff30 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java @@ -0,0 +1,154 @@ +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 NODE_KEY_BI = Collections. singletonMap(NODE_ID_QNAME, + NODE_ID); + + private static final InstanceIdentifier 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 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 simpleReader = new DataReader() { + + @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()); + } +} diff --git a/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java b/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java index 112b57cd33..c943226cca 100644 --- a/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java +++ b/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java @@ -87,6 +87,7 @@ public class TestHelper { 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(), // // diff --git a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java index 6fec18033f..2f86ee4cc2 100644 --- a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java +++ b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java @@ -5,13 +5,16 @@ import static org.junit.Assert.assertNotNull; 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; @@ -24,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalF 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 { @@ -95,16 +99,36 @@ 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 getImplementations() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Collection 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 diff --git a/opendaylight/md-sal/sal-binding-util/pom.xml b/opendaylight/md-sal/sal-binding-util/pom.xml index 26041ea85e..67c10f4a04 100644 --- a/opendaylight/md-sal/sal-binding-util/pom.xml +++ b/opendaylight/md-sal/sal-binding-util/pom.xml @@ -24,10 +24,5 @@ sal-binding-api 1.0-SNAPSHOT - - org.apache.felix - org.apache.felix.dependencymanager - 3.1.0 - diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java new file mode 100644 index 0000000000..ff6f6185ea --- /dev/null +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java @@ -0,0 +1,178 @@ +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 // + 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 getRpcService(Class module) { + return getRpcRegistryChecked().getRpcService(module); + } + + @Deprecated + public void addNotificationListener(Class notificationType, + NotificationListener 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 void removeNotificationListener(Class notificationType, + NotificationListener listener) { + getNotificationBrokerChecked().removeNotificationListener(notificationType, listener); + } + + public Registration> registerNotificationListener( + Class notificationType, NotificationListener listener) { + return getNotificationBrokerChecked().registerNotificationListener(notificationType, listener); + } + + public Registration registerNotificationListener( + org.opendaylight.yangtools.yang.binding.NotificationListener listener) { + return getNotificationBrokerChecked().registerNotificationListener(listener); + } + + @Deprecated + public T getData(DataStoreIdentifier store, Class rootType) { + return getDataBrokerChecked().getData(store, rootType); + } + + @Deprecated + public T getData(DataStoreIdentifier store, T filter) { + return getDataBrokerChecked().getData(store, filter); + } + + @Deprecated + public T getCandidateData(DataStoreIdentifier store, Class rootType) { + return getDataBrokerChecked().getCandidateData(store, rootType); + } + + @Deprecated + public T getCandidateData(DataStoreIdentifier store, T filter) { + return getDataBrokerChecked().getCandidateData(store, filter); + } + + @Deprecated + public RpcResult editCandidateData(DataStoreIdentifier store, DataRoot changeSet) { + return getDataBrokerChecked().editCandidateData(store, changeSet); + } + + @Deprecated + public Future> commit(DataStoreIdentifier store) { + return getDataBrokerChecked().commit(store); + } + + @Deprecated + public DataObject getData(InstanceIdentifier 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 path, DataChangeListener changeListener) { + getDataBrokerChecked().registerChangeListener(path, changeListener); + } + + @Deprecated + public void unregisterChangeListener(InstanceIdentifier path, + DataChangeListener changeListener) { + getDataBrokerChecked().unregisterChangeListener(path, changeListener); + } + + @Deprecated + public DataObject readConfigurationData(InstanceIdentifier path) { + return getDataBrokerChecked().readConfigurationData(path); + } + + public DataObject readOperationalData(InstanceIdentifier path) { + return getDataBrokerChecked().readOperationalData(path); + } + + @Deprecated + public ListenerRegistration registerDataChangeListener( + InstanceIdentifier path, DataChangeListener listener) { + return getDataBrokerChecked().registerDataChangeListener(path, listener); + } +} diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java new file mode 100644 index 0000000000..278e90ee6b --- /dev/null +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java @@ -0,0 +1,95 @@ +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 // + extends AbstractBindingSalConsumerInstance // + implements // + DataProviderService, // + RpcProviderRegistry, // + NotificationProviderService { + + public AbstractBindingSalProviderInstance(R rpcRegistry, N notificationBroker, + D dataBroker) { + super(rpcRegistry, notificationBroker, dataBroker); + } + + @Override + public Registration, DataObject>> registerDataReader( + InstanceIdentifier path, + DataReader, DataObject> reader) { + return getDataBrokerChecked().registerDataReader(path, reader); + } + + @Override + public Registration, DataObject>> registerCommitHandler( + InstanceIdentifier path, + DataCommitHandler, DataObject> commitHandler) { + return getDataBrokerChecked().registerCommitHandler(path, commitHandler); + } + + @Override + public ListenerRegistration, DataObject>>> registerCommitHandlerListener( + RegistrationListener, DataObject>> commitHandlerListener) { + return getDataBrokerChecked().registerCommitHandlerListener(commitHandlerListener); + } + + @Override + public RpcRegistration addRpcImplementation(Class type, T implementation) + throws IllegalStateException { + return getRpcRegistryChecked().addRpcImplementation(type, implementation); + } + + @Override + public RoutedRpcRegistration addRoutedRpcImplementation(Class 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 >> ListenerRegistration registerRouteChangeListener( + L listener) { + return getRpcRegistryChecked().registerRouteChangeListener(listener); + } +} diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java new file mode 100644 index 0000000000..6f2186be88 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java @@ -0,0 +1,143 @@ +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 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 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 serviceProvider) { + ConsumerContext context = createConsumerContext(consumer, serviceProvider); + consumer.onSessionInitialized(context); + return context; + } + + public static ProviderContext createProviderContextAndInitialize(BindingAwareProvider provider, + ClassToInstanceMap serviceProvider) { + ProviderContext context = createProviderContext(provider, serviceProvider); + provider.onSessionInitiated(context); + return context; + } + + public static T createContextProxyOrReturnService(Class service, T instance) { + // FIXME: Create Proxy + return instance; + } + + private static class SingleConsumerContextImpl implements ConsumerContext, AutoCloseable { + + private ClassToInstanceMap alreadyRetrievedServices; + private ClassToInstanceMap serviceProvider; + + public SingleConsumerContextImpl(ClassToInstanceMap serviceProvider) { + this.alreadyRetrievedServices = MutableClassToInstanceMap.create(); + this.serviceProvider = serviceProvider; + } + + @Override + public final T getRpcService(Class module) { + return getSALService(RpcConsumerRegistry.class).getRpcService(module); + } + + @Override + public final T getSALService(Class 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 tryToRetrieveSalService(Class 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 serviceProvider) { + super(serviceProvider); + } + + @Override + public >> ListenerRegistration registerRouteChangeListener( + L listener) { + return getSALService(RpcProviderRegistry.class).registerRouteChangeListener(listener); + } + + @Override + public RoutedRpcRegistration addRoutedRpcImplementation(Class type, + T implementation) throws IllegalStateException { + return getSALService(RpcProviderRegistry.class).addRoutedRpcImplementation(type, implementation); + } + + @Override + public RpcRegistration addRpcImplementation(Class 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 + } + } +} diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java index 738a14a9bd..17de595a8b 100644 --- a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java @@ -6,33 +6,27 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class TypeSafeDataReader { - - private final DataReader,DataObject> delegate; - - - + private final DataReader, DataObject> delegate; + public DataReader, DataObject> getDelegate() { return delegate; } - - public TypeSafeDataReader(DataReader, DataObject> delegate) { + public TypeSafeDataReader(DataReader, DataObject> delegate) { this.delegate = delegate; } - @SuppressWarnings("unchecked") public D readConfigurationData(InstanceIdentifier path) { return (D) delegate.readConfigurationData(path); } - - + @SuppressWarnings("unchecked") - public D readOperationalData(InstanceIdentifier path) { + public D readOperationalData(InstanceIdentifier path) { return (D) delegate.readOperationalData(path); } - - public static TypeSafeDataReader forReader(DataReader, DataObject> delegate) { + + public static TypeSafeDataReader forReader(DataReader, DataObject> delegate) { return new TypeSafeDataReader(delegate); } } diff --git a/opendaylight/md-sal/sal-common-util/pom.xml b/opendaylight/md-sal/sal-common-util/pom.xml index ff15e72ba6..adbe3d2a49 100644 --- a/opendaylight/md-sal/sal-common-util/pom.xml +++ b/opendaylight/md-sal/sal-common-util/pom.xml @@ -27,6 +27,12 @@ com.google.guava guava + + org.opendaylight.controller + sal-common-api + ${project.version} + + bundle diff --git a/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java index 2d10fba8a5..902665d1a6 100644 --- a/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java +++ b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java @@ -1,3 +1,10 @@ +/* + * 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 { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/CommitHandlerTransactions.java similarity index 89% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java rename to opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/CommitHandlerTransactions.java index 254b8725b9..bffeb59fab 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java +++ b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/CommitHandlerTransactions.java @@ -1,15 +1,14 @@ -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

,D> implements DataCommitTransaction { @@ -33,7 +32,6 @@ public class CommitHandlersTransactions { } } - public static final

,D> AllwaysSuccessfulTransaction allwaysSuccessfulTransaction(DataModification modification) { return new AllwaysSuccessfulTransaction<>(modification); } diff --git a/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Futures.java b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Futures.java index d9cf5cc477..42b00ba03d 100644 --- a/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Futures.java +++ b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Futures.java @@ -1,3 +1,10 @@ +/* + * 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; diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcProvisionRegistry.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcProvisionRegistry.java index c326bab7a4..951d5b142e 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcProvisionRegistry.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcProvisionRegistry.java @@ -4,7 +4,7 @@ import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration; 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. diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java index 1596165601..18c854646c 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java @@ -6,7 +6,6 @@ * 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; @@ -16,8 +15,13 @@ import org.opendaylight.controller.sal.core.api.notify.NotificationService; 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> rpc(QName type, CompositeNode input); + + SchemaContext getSchemaContext(); } diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java index 92542bc345..e5fc4b7aa4 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java @@ -3,6 +3,8 @@ package org.opendaylight.controller.sal.core.api.mount; 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,// @@ -10,4 +12,6 @@ public interface MountProvisionInstance extends // RpcProvisionRegistry,// DataProviderService { + void setSchemaContext(SchemaContext optional); + } diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionService.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionService.java index fade7d341b..c1f873c3af 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionService.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionService.java @@ -1,5 +1,8 @@ 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 { @@ -10,4 +13,14 @@ public interface MountProvisionService extends MountService { MountProvisionInstance createMountPoint(InstanceIdentifier path); MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path); + + ListenerRegistration registerProvisionListener(MountProvisionListener listener); + + public interface MountProvisionListener extends EventListener { + + void onMountPointCreated(InstanceIdentifier path); + + void onMountPointRemoved(InstanceIdentifier path); + + } } diff --git a/opendaylight/md-sal/sal-dom-broker/pom.xml b/opendaylight/md-sal/sal-dom-broker/pom.xml index 4740b0d569..10e7946a7b 100644 --- a/opendaylight/md-sal/sal-dom-broker/pom.xml +++ b/opendaylight/md-sal/sal-dom-broker/pom.xml @@ -30,11 +30,6 @@ sal-common-impl 1.0-SNAPSHOT - - org.opendaylight.controller - sal-common-impl - 1.0-SNAPSHOT - org.opendaylight.controller sal-core-spi diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java new file mode 100644 index 0000000000..3cc5a61afb --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java @@ -0,0 +1,6 @@ +package org.opendaylight.controller.sal.dom.broker; + +public class $ModuleInfo { + + +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java index 56eae97848..8f62be97d8 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java @@ -13,6 +13,8 @@ import org.opendaylight.yangtools.concepts.Registration; 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 implements DataProviderService, AutoCloseable { @@ -21,6 +23,7 @@ public class DataBrokerImpl extends AbstractDataBroker 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(); } @@ -121,15 +124,13 @@ public class MountPointImpl implements MountProvisionInstance { @Override public DataModificationTransaction beginTransaction() { - // TODO Auto-generated method stub - return null; + return dataReader.beginTransaction(); } @Override public ListenerRegistration registerDataChangeListener(InstanceIdentifier path, DataChangeListener listener) { - // TODO Auto-generated method stub - return null; + return dataReader.registerDataChangeListener(path, listener); } @Override @@ -140,8 +141,7 @@ public class MountPointImpl implements MountProvisionInstance { @Override public Registration> registerCommitHandler( InstanceIdentifier path, DataCommitHandler commitHandler) { - // TODO Auto-generated method stub - return null; + return dataReader.registerCommitHandler(path, commitHandler); } @Override @@ -163,6 +163,14 @@ public class MountPointImpl implements MountProvisionInstance { // NOOP } + public SchemaContext getSchemaContext() { + return schemaContext; + } + + public void setSchemaContext(SchemaContext schemaContext) { + this.schemaContext = schemaContext; + } + class ReadWrapper implements DataReader { @@ -197,7 +205,6 @@ public class MountPointImpl implements MountProvisionInstance { @Override public ListenerRegistration>> registerCommitHandlerListener( RegistrationListener> commitHandlerListener) { - // TODO Auto-generated method stub - return null; + return dataReader.registerCommitHandlerListener(commitHandlerListener); } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend index 19634d79c2..5d441bddbd 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend @@ -7,12 +7,16 @@ import java.util.concurrent.ConcurrentMap 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 listeners = ListenerRegistry.create() + ConcurrentMap mounts = new ConcurrentHashMap(); override createMountPoint(InstanceIdentifier path) { @@ -20,15 +24,26 @@ class MountPointManagerImpl implements MountProvisionService { 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); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java index 0d18cb323a..0021dd8f0f 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java @@ -3,6 +3,7 @@ package org.opendaylight.controller.sal.dom.broker.osgi; 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; @@ -24,4 +25,9 @@ public class MountProviderServiceProxy extends AbstractBrokerServiceProxy registerProvisionListener(MountProvisionListener listener) { + return getDelegate().registerProvisionListener(listener); + } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/yangtools/yang/util/YangSchemaUtils.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/yangtools/yang/util/YangSchemaUtils.java index 3ff1d1d6cb..3b31380afb 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/yangtools/yang/util/YangSchemaUtils.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/yangtools/yang/util/YangSchemaUtils.java @@ -121,7 +121,6 @@ public class YangSchemaUtils { // TODO Auto-generated constructor stub } - @Override public YangNode getParent() { // TODO Auto-generated method stub return null; diff --git a/opendaylight/md-sal/sal-netconf-connector/pom.xml b/opendaylight/md-sal/sal-netconf-connector/pom.xml index fe613565a6..67e2934a0e 100644 --- a/opendaylight/md-sal/sal-netconf-connector/pom.xml +++ b/opendaylight/md-sal/sal-netconf-connector/pom.xml @@ -98,12 +98,6 @@ test ${netconf.version} - - ${project.groupId} - yang-test - test - ${netconf.version} - ${project.groupId} config-manager @@ -170,6 +164,24 @@ org.slf4j slf4j-api + + org.opendaylight.controller + sal-binding-broker-impl + 1.0-SNAPSHOT + test + + + org.opendaylight.controller + sal-binding-broker-impl + 1.0-SNAPSHOT + test-jar + test + + + org.opendaylight.controller + ietf-netconf-monitoring + 0.2.3-SNAPSHOT + org.opendaylight.yangtools.model ietf-inet-types diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java index 55a1fbfe48..2403027e01 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java @@ -12,8 +12,12 @@ package org.opendaylight.controller.config.yang.md.sal.connector.netconf; 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; @@ -24,6 +28,10 @@ import org.opendaylight.controller.netconf.util.handler.ssh.authentication.Login 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.*; @@ -37,6 +45,8 @@ import com.google.common.net.InetAddresses; 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 GLOBAL_NETCONF_SOURCE_PROVIDER = null; private BundleContext bundleContext; public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { @@ -74,31 +84,57 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co } 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 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 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) { diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend index 7c4bf5faca..21500e1da6 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend @@ -1,37 +1,61 @@ 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, // - DataCommitHandler, // - 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, // +DataCommitHandler, // +RpcImplementation, // +AutoCloseable { var NetconfClient client; @@ -41,35 +65,105 @@ class NetconfDevice implements @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 schemaSourceProvider; + + @Property + private NetconfDeviceSchemaContextProvider deviceContextProvider + + protected val Logger logger Registration> operReaderReg Registration> confReaderReg Registration> commitHandlerReg - + val String name MountProvisionService mountService - - + + int messegeRetryCount = 5; + + int messageTimeoutCount = 5 * 1000; + + Set cachedCapabilities + + @Property + var NetconfClientDispatcher dispatcher + + static val InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance(); + + @Property + var SchemaSourceProvider 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; + + //commitHandlerReg = mountInstance.registerCommitHandler(path,this); + } + + def Optional 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 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.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; } @@ -84,10 +178,30 @@ class NetconfDevice implements 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() { @@ -96,35 +210,33 @@ class NetconfDevice implements 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) { @@ -132,12 +244,17 @@ class NetconfDevice implements 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; } } @@ -146,7 +263,38 @@ class NetconfDevice implements } override requestCommit(DataModification 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() { @@ -156,3 +304,53 @@ class NetconfDevice implements } } + +package class NetconfDeviceSchemaContextProvider { + + @Property + val NetconfDevice device; + + @Property + val SchemaSourceProvider sourceProvider; + + @Property + var Optional currentContext; + + new(NetconfDevice device, SchemaSourceProvider sourceProvider) { + _device = device + _sourceProvider = sourceProvider + _currentContext = Optional.absent(); + } + + def createContextFromCapabilities(Iterable 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 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; + } + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java new file mode 100644 index 0000000000..8623d90fe5 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java @@ -0,0 +1,155 @@ +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 messagePromise; + private ConcurrentMap> 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> _children = node.getChildren(); + for (final Node child : _children) { + if ((child instanceof CompositeNode)) { + return ((CompositeNode) child); + } + } + return null; + } + + public NetconfMessage getLastMessage(final int attempts, final int attemptMsDelay) throws InterruptedException { + final Promise 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 promiseReply() { + this.device.logger.debug("Promising reply."); + this.promiseLock.lock(); + try { + boolean _equals = Objects.equal(this.messagePromise, null); + if (_equals) { + Promise _newPromise = this.eventExecutor. 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); + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java new file mode 100644 index 0000000000..6df34cdb9e --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java @@ -0,0 +1,143 @@ +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 { + + private NetconfDevice device; + private final DataModification modification; + private boolean candidateSupported = true; + + public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device, + DataModification modification) { + super(); + this.device = device; + this.modification = modification; + } + + public void prepare() { + for (InstanceIdentifier toRemove : modification.getRemovedConfigurationData()) { + sendRemove(toRemove); + } + for(Entry toUpdate : modification.getUpdatedConfigurationData().entrySet()) { + sendMerge(toUpdate.getKey(),toUpdate.getValue()); + } + + } + + private void sendMerge(InstanceIdentifier key, CompositeNode value) { + sendEditRpc(createEditStructure(key, Optional.absent(), Optional.of(value))); + } + + private void sendRemove(InstanceIdentifier toRemove) { + sendEditRpc(createEditStructure(toRemove, Optional.of("remove"), Optional. absent())); + } + + private void sendEditRpc(CompositeNode editStructure) { + CompositeNodeBuilder builder = configurationRpcBuilder(); + builder.setQName(NETCONF_EDIT_CONFIG_QNAME); + builder.add(editStructure); + + RpcResult rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance()); + Preconditions.checkState(rpcResult.isSuccessful(),"Rpc Result was unsuccessful"); + + } + + private CompositeNodeBuilder configurationRpcBuilder() { + CompositeNodeBuilder ret = ImmutableCompositeNode.builder(); + + Node targetNode; + if(candidateSupported) { + targetNode = ImmutableCompositeNode.create(NETCONF_CANDIDATE_QNAME, ImmutableList.>of()); + } else { + targetNode = ImmutableCompositeNode.create(NETCONF_RUNNING_QNAME, ImmutableList.>of()); + } + Node targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.>of(targetNode)); + ret.add(targetWrapperNode); + return ret; + } + + private CompositeNode createEditStructure(InstanceIdentifier dataPath, Optional action, + Optional lastChildOverride) { + List path = dataPath.getPath(); + List reversed = Lists.reverse(path); + CompositeNode previous = null; + boolean isLast = true; + for (PathArgument arg : reversed) { + CompositeNodeBuilder builder = ImmutableCompositeNode.builder(); + builder.setQName(arg.getNodeType()); + Map predicates = Collections.emptyMap(); + if (arg instanceof NodeIdentifierWithPredicates) { + predicates = ((NodeIdentifierWithPredicates) arg).getKeyValues(); + } + for (Entry 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> 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.>of(previous)); + } + + @Override + public RpcResult finish() throws IllegalStateException { + CompositeNodeBuilder commitInput = ImmutableCompositeNode.builder(); + commitInput.setQName(NETCONF_COMMIT_QNAME); + RpcResult rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance()); + return (RpcResult) rpcResult; + } + + @Override + public DataModification getModification() { + return this.modification; + } + + @Override + public RpcResult rollback() throws IllegalStateException { + // TODO Auto-generated method stub + return null; + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend index 78f6d59f77..c151e42fbb 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend @@ -20,93 +20,179 @@ import org.w3c.dom.Element 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> RUNNING = Collections.>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> RUNNING = Collections.>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>(); - 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 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 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 toRpcResult(NetconfMessage message) { - val rawRpc = message.document.toCompositeNode() as CompositeNode; + static def RpcResult toRpcResult(NetconfMessage message,QName rpc,Optional 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."); + + } + } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java new file mode 100644 index 0000000000..12be689cb9 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java @@ -0,0 +1,69 @@ +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 { + + 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 getSchemaSource(String moduleName, Optional revision) { + CompositeNodeBuilder 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 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 capabilities) { + return capabilities.contains(IETF_NETCONF_MONITORING); + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java deleted file mode 100644 index 3f6b4e1f4c..0000000000 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -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> 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); - } -} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java new file mode 100644 index 0000000000..0c0070ce9c --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java @@ -0,0 +1,88 @@ +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 { + + 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 ); + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang b/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang index 9238514110..2fae7ee021 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang @@ -81,6 +81,14 @@ module odl-sal-netconf-connector-cfg { } } } + + container event-executor { + uses config:service-ref { + refine type { + config:required-identity netty:netty-event-executor; + } + } + } } } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml b/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml index c973498e85..d5648a0625 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml @@ -14,7 +14,7 @@ 0.3.1 - 1.9.8 + 2.3.0 1.0.1 @@ -61,10 +61,6 @@ org.opendaylight.yangtools yang-data-impl - - org.opendaylight.yangtools - yang-common - @@ -84,16 +80,25 @@ org.slf4j slf4j-api + - org.codehaus.jackson - jackson-core-asl + com.fasterxml.jackson.core + jackson-annotations ${jackson.version} + - org.codehaus.jackson - jackson-mapper-asl + com.fasterxml.jackson.core + jackson-core ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + stax stax-api diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java index 6c5e5fbf11..06107a8773 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java @@ -7,15 +7,15 @@ */ 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,Serializable { transient ObjectMapper mapper = new ObjectMapper(); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java index 550d9ef125..f6b9004eae 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java @@ -1,6 +1,8 @@ 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; @@ -8,8 +10,6 @@ import org.opendaylight.yangtools.yang.common.QName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.net.URI; - public class RouteIdentifierImplTest { Logger _logger = LoggerFactory.getLogger(RouteIdentifierImplTest.class); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml index 4305a283e2..8ee61c3a3f 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml +++ b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml @@ -14,6 +14,7 @@ + 2.3.0 3.0.0 1.5.0 0.2.3-SNAPSHOT @@ -389,20 +390,29 @@ - org.codehaus.jackson - jackson-mapper-asl - 1.9.2 + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + - org.codehaus.jackson - jackson-core-asl - 1.9.2 + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + org.zeromq jeromq 0.3.1 + org.opendaylight.yangtools.thirdparty xtend-lib-osgi diff --git a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java index 62c094d7a6..dd910ea34b 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java @@ -416,8 +416,9 @@ public class RouterTest { 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 diff --git a/opendaylight/md-sal/sal-rest-connector/pom.xml b/opendaylight/md-sal/sal-rest-connector/pom.xml index 5e798b6720..0bd86a3ead 100644 --- a/opendaylight/md-sal/sal-rest-connector/pom.xml +++ b/opendaylight/md-sal/sal-rest-connector/pom.xml @@ -42,7 +42,7 @@ yang-data-impl ${yang.version} - + org.opendaylight.yangtools yang-model-util ${yang.version} @@ -82,11 +82,6 @@ 2.4 test - - org.opendaylight.yangtools - yang-model-util - 0.5.9-SNAPSHOT - diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java index 012b51fb5e..60a8f285a2 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java @@ -7,6 +7,8 @@ */ 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; @@ -66,30 +68,50 @@ public interface RestconfService extends RestconfServiceLegacy { @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); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java index 35da98b1a0..9b69c1f09a 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java @@ -1,5 +1,6 @@ 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; @@ -33,14 +34,14 @@ public interface RestconfServiceLegacy { @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); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java index fb7872f8bc..7f7e8606c3 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java @@ -43,7 +43,7 @@ class JsonMapper { private final Set foundLeafLists = new HashSet<>(); private final Set 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); @@ -184,16 +184,23 @@ class JsonMapper { 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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java index 242f18d240..1bceee88cb 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java @@ -9,6 +9,7 @@ import org.opendaylight.controller.sal.core.api.Provider; 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; @@ -37,6 +38,7 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack SchemaService schemaService = session.getService(SchemaService.class); listenerRegistration = schemaService.registerSchemaServiceListener(ControllerContext.getInstance()); ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext()); + ControllerContext.getInstance().setMountService(session.getService(MountService.class)); } @Override diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java index a3d658e7bf..0dd4668a74 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java @@ -1,142 +1,60 @@ 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. absent()); - public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException { - Preconditions.checkNotNull(data); - Preconditions.checkNotNull(schema); + private static class LeafrefCodecImpl extends TypeDefinitionAwareCodec implements + LeafrefCodec { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - Document doc = null; - try { - DocumentBuilder bob = dbf.newDocumentBuilder(); - doc = bob.newDocument(); - } catch (ParserConfigurationException e) { - return null; + protected LeafrefCodecImpl(Optional 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> codecFor(TypeDefinition baseType) { + TypeDefinitionAwareCodec> 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) { - 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); + } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend index df6b58c897..c57505829c 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend @@ -10,6 +10,7 @@ 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.slf4j.LoggerFactory +import org.opendaylight.controller.sal.core.api.mount.MountInstance class BrokerFacade implements DataReader { @@ -41,15 +42,27 @@ class BrokerFacade implements DataReader { 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 invokeRpc(QName type, CompositeNode payload) { checkPreconditions @@ -60,15 +73,55 @@ class BrokerFacade implements DataReader { 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 + } + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java index 0ded60dae4..74a32d452e 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java @@ -78,6 +78,11 @@ public final class CompositeNodeWrapper implements NodeWrapper, C 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() { @@ -230,4 +235,5 @@ public final class CompositeNodeWrapper implements NodeWrapper, C public Set>>> entrySet() { return unwrap().entrySet(); } + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index eec2d452a1..61237f01a1 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -10,8 +10,8 @@ import java.util.HashMap 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 @@ -26,21 +26,32 @@ import org.opendaylight.yangtools.yang.model.api.ChoiceNode 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 uriToModuleName = HashBiMap.create(); private val Map moduleNameToUri = uriToModuleName.inverse(); @@ -57,8 +68,8 @@ class ControllerContext implements SchemaServiceListener { } 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) } } @@ -67,7 +78,7 @@ class ControllerContext implements SchemaServiceListener { } public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) { - val ret = InstanceIdentifier.builder(); + checkPreconditions val pathArgs = restconfInstance.split("/"); if (pathArgs.empty) { return null; @@ -75,29 +86,26 @@ class ControllerContext implements SchemaServiceListener { 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 modules) { var latestModule = modules.head for (module : modules) { if (module.revision.after(latestModule.revision)) { @@ -106,13 +114,38 @@ class ControllerContext implements SchemaServiceListener { } 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); @@ -135,18 +168,13 @@ class ControllerContext implements SchemaServiceListener { 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; @@ -154,16 +182,10 @@ class ControllerContext implements SchemaServiceListener { 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) @@ -175,7 +197,7 @@ class ControllerContext implements SchemaServiceListener { 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; @@ -232,38 +254,92 @@ class ControllerContext implements SchemaServiceListener { if(object === null) return ""; return URLEncoder.encode(object.toString) } - - private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List strings, - DataNodeContainer parentNode) { + + private def InstanceIdWithSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List 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) { @@ -272,7 +348,7 @@ class ControllerContext implements SchemaServiceListener { // 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(); @@ -282,7 +358,9 @@ class ControllerContext implements SchemaServiceListener { // 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; @@ -296,11 +374,42 @@ class ControllerContext implements SchemaServiceListener { } 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 map, DataSchemaNode node, String uriValue) { @@ -319,31 +428,31 @@ class ControllerContext implements SchemaServiceListener { 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); @@ -354,7 +463,7 @@ class ControllerContext implements SchemaServiceListener { } override onGlobalContextUpdated(SchemaContext context) { - this.schemas = context; + this.globalSchema = context; for (operation : context.operations) { val qname = operation.QName; qnameToRpc.put(qname, operation); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/EmptyNodeWrapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/EmptyNodeWrapper.java index c146954dce..cdb9599a46 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/EmptyNodeWrapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/EmptyNodeWrapper.java @@ -64,6 +64,11 @@ public final class EmptyNodeWrapper implements NodeWrapper>, Node this.namespace = namespace; } + @Override + public boolean isChangeAllowed() { + return unwrapped == null ? true : false; + } + @Override public Node unwrap() { if (unwrapped == null) { diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java index ad0654af78..1c958b901b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java @@ -1,5 +1,6 @@ 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; @@ -7,10 +8,12 @@ public class InstanceIdWithSchemaNode { 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() { @@ -21,4 +24,8 @@ public class InstanceIdWithSchemaNode { return schemaNode; } + public MountInstance getMountPoint() { + return mountPoint; + } + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/NodeWrapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/NodeWrapper.java index 675e119439..6b8665f765 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/NodeWrapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/NodeWrapper.java @@ -11,6 +11,8 @@ public interface NodeWrapper> { T unwrap(); + boolean isChangeAllowed(); + URI getNamespace(); void setNamespace(URI namespace); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java index 450ba02b56..45f3f7f30b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java @@ -19,16 +19,16 @@ public class RestCodec { private RestCodec() { } - + public static final Codec from(TypeDefinition typeDefinition) { return new ObjectCodec(typeDefinition); } - + @SuppressWarnings("rawtypes") public static final class ObjectCodec implements Codec { 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(); @@ -37,7 +37,7 @@ public class RestCodec { private ObjectCodec(TypeDefinition typeDefinition) { type = RestUtil.resolveBaseTypeFrom(typeDefinition); } - + @SuppressWarnings("unchecked") @Override public Object deserialize(Object input) { @@ -47,16 +47,21 @@ public class RestCodec { } else if (type instanceof LeafrefTypeDefinition) { return LEAFREF_DEFAULT_CODEC.deserialize(input); } else { - TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec.from(type); + TypeDefinitionAwareCodec> 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; } } @@ -70,22 +75,27 @@ public class RestCodec { } else if (type instanceof LeafrefTypeDefinition) { return LEAFREF_DEFAULT_CODEC.serialize(input); } else { - TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec.from(type); + TypeDefinitionAwareCodec> 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 { @Override @@ -97,7 +107,7 @@ public class RestCodec { 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); } @@ -105,7 +115,7 @@ public class RestCodec { } } - + public static class LeafrefCodecImpl implements LeafrefCodec { @Override @@ -117,7 +127,7 @@ public class RestCodec { public Object deserialize(String data) { return data; } - + } - + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend index 4645a411c1..5ad6f1eea8 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend @@ -1,13 +1,20 @@ 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 @@ -17,6 +24,8 @@ 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.TypeDefinition import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition @@ -55,41 +64,27 @@ class RestconfImpl implements RestconfService { 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> 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> 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") @@ -100,46 +95,221 @@ class RestconfImpl implements RestconfService { 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 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 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 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 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(); + 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; @@ -148,15 +318,20 @@ class RestconfImpl implements RestconfService { } 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) { @@ -164,7 +339,7 @@ class RestconfImpl implements RestconfService { 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 @@ -177,7 +352,7 @@ class RestconfImpl implements RestconfService { } 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 + "\"") } } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java index 97f8102127..6aa8ada5ee 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java @@ -58,6 +58,11 @@ public final class SimpleNodeWrapper implements NodeWrapper>, Simp this.namespace = namespace; } + @Override + public boolean isChangeAllowed() { + return simpleNode == null ? true : false; + } + @Override public SimpleNode unwrap() { if (simpleNode == null) { diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java similarity index 90% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java index b01d4104b2..e754fdec5f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java @@ -1,22 +1,44 @@ 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 @@ -24,9 +46,16 @@ public class ToJsonBasicYangTypesTest { */ @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); } /** @@ -35,13 +64,21 @@ public class ToJsonBasicYangTypesTest { */ @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); @@ -60,6 +97,7 @@ public class ToJsonBasicYangTypesTest { } private void verifyJsonOutput(String jsonOutput) { + assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java similarity index 86% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java index b745411bf4..1eb3779730 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java @@ -8,11 +8,13 @@ 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 ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { +public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialization() { @@ -111,10 +113,11 @@ public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { } 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); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java similarity index 56% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java index 73d0c82521..c45c0b3288 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java @@ -1,153 +1,57 @@ 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 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> 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 bits = new HashSet(); - 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 bits2 = new HashSet(); - 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); @@ -178,7 +82,6 @@ public class ToJsonBasicDataTypesTest { private void jsonReadContElements(JsonReader jReader) throws IOException { jReader.beginObject(); List loadedLfs = new ArrayList<>(); - boolean exceptForDecimal5Raised = false; boolean enumChecked = false; boolean bitsChecked = false; boolean lfdecimal6Checked = false; @@ -190,7 +93,6 @@ public class ToJsonBasicDataTypesTest { boolean lfbool2Checked = false; boolean lfstrChecked = false; boolean lfbinaryChecked = false; - // boolean lfref1Checked = false; boolean lfemptyChecked = false; boolean lfstr1Checked = false; boolean lfidentityrefChecked = false; @@ -201,11 +103,7 @@ public class ToJsonBasicDataTypesTest { 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")) { diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java similarity index 56% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java index 6d30559ccd..6920b0f1ff 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java @@ -11,12 +11,14 @@ 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.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() { @@ -27,7 +29,9 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { 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); @@ -40,15 +44,35 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { 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(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java new file mode 100644 index 0000000000..47222571b8 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java @@ -0,0 +1,163 @@ +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 getUnknownSchemaNodes() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set 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 getGroupings() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set> getTypeDefinitions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set 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); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java new file mode 100644 index 0000000000..3215e81719 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java @@ -0,0 +1,103 @@ +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 ""; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java new file mode 100644 index 0000000000..7fdd6cac47 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java @@ -0,0 +1,75 @@ +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) 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(); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java new file mode 100644 index 0000000000..3c2325c0f3 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java @@ -0,0 +1,51 @@ +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\": [")); + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java new file mode 100644 index 0000000000..fdc10b7150 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java @@ -0,0 +1,108 @@ +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; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java deleted file mode 100644 index 1ac81a332f..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java +++ /dev/null @@ -1,161 +0,0 @@ -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()); - } - -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java deleted file mode 100644 index 73bd178ff3..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java +++ /dev/null @@ -1,30 +0,0 @@ -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\": [")); - } -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java new file mode 100644 index 0000000000..555f2b3e3c --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java @@ -0,0 +1,69 @@ +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) 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(); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java index d04337865a..96e03a5a3c 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java @@ -1,24 +1,21 @@ 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; /** * @@ -27,25 +24,31 @@ import org.w3c.dom.Document; * XML file * */ -public class CnSnToXmlTest { - - private static Set 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(), "x:iden"); + serializeToXml(prepareIdentityrefData(null, true), "x:iden"); + } + + @Test + public void snAsYangIdentityrefWithQNamePrefixToXMLTest() { + serializeToXml(prepareIdentityrefData("prefix", true), + "prefix:iden"); + } + + @Test + public void snAsYangIdentityrefWithPrefixToXMLTest() { + serializeToXml(prepareIdentityrefData("prefix", false), "no qname value"); + } + + @Test + public void snAsYangLeafrefWithPrefixToXMLTest() { + serializeToXml(prepareLeafrefData(), "true", "true"); } @Test @@ -186,22 +189,13 @@ public class CnSnToXmlTest { 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) { @@ -215,16 +209,21 @@ public class CnSnToXmlTest { } - 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 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(); @@ -244,4 +243,19 @@ public class CnSnToXmlTest { return cont; } + private CompositeNode prepareLeafrefData() { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, + ModifyAction.CREATE, null); + + MutableSimpleNode lfBoolean = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfBoolean"), + cont, Boolean.TRUE, ModifyAction.CREATE, null); + MutableSimpleNode lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont, + "true", ModifyAction.CREATE, null); + cont.getChildren().add(lfBoolean); + cont.getChildren().add(lfLfref); + cont.init(); + + return cont; + } + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java new file mode 100644 index 0000000000..a23501cbe6 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java @@ -0,0 +1,64 @@ +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("String data1")); + + try { + xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput( + prepareCnStructForYangData("lf2", "String data2"), modules, dataSchemaNode, + StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + assertTrue(xmlOutput.contains("String data2")); + + } + + private CompositeNode prepareCnStructForYangData(String lfName, Object data) { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, + ModifyAction.CREATE, null); + + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data, + ModifyAction.CREATE, null); + cont.getChildren().add(lf1); + cont.init(); + + return cont; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java new file mode 100644 index 0000000000..57a149516f --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java @@ -0,0 +1,107 @@ +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("" + +// "\n" + +// "\n\t" + +// "\n\t\tlf1 m1 value" + +// "\n\t" + +// "\n" + +// "\n" + +// "\n\t" + +// "\n\t\tlf1 m2 value" + +// "\n\t" + +// "\n" + +// "\n"); + + StringBuilder regex = new StringBuilder(); + regex.append("^"); + + regex.append(".*"); + + + regex.append(".*"); + regex.append(".*xmlns=\"module:one\""); + regex.append(".*>"); + regex.append(".*"); + regex.append(".*<\\/lf1_m1>"); + regex.append(".*<\\/cont_m1>"); + + regex.append(".*"); + regex.append(".*"); + regex.append(".*"); + 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; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java new file mode 100644 index 0000000000..e9b1dbe1a5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java @@ -0,0 +1,74 @@ +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> 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()); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java new file mode 100644 index 0000000000..2bb42d903a --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java @@ -0,0 +1,48 @@ +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()); + + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java index b02ea9a3a2..afe458d6e0 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java @@ -1,9 +1,10 @@ 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; @@ -14,8 +15,9 @@ import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; 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; @@ -28,7 +30,7 @@ public class JsonToCnSnTest { @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"); } @@ -43,7 +45,8 @@ public class JsonToCnSnTest { */ @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()); @@ -76,9 +79,10 @@ public class JsonToCnSnTest { */ @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); @@ -86,7 +90,8 @@ public class JsonToCnSnTest { @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()); @@ -103,7 +108,8 @@ public class JsonToCnSnTest { 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; } @@ -117,7 +123,8 @@ public class JsonToCnSnTest { 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; } @@ -126,7 +133,8 @@ public class JsonToCnSnTest { 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; } @@ -145,7 +153,8 @@ public class JsonToCnSnTest { */ @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); @@ -158,7 +167,7 @@ public class JsonToCnSnTest { 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(); } @@ -176,24 +185,20 @@ public class JsonToCnSnTest { @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 modules1 = new HashSet<>(); + Set 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(); @@ -201,26 +206,20 @@ public class JsonToCnSnTest { 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 modules = TestUtils.resolveModules("/json-to-cnsn/identityref"); + Set 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()); @@ -268,19 +267,14 @@ public class JsonToCnSnTest { 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 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(); @@ -331,7 +325,8 @@ public class JsonToCnSnTest { 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")) { @@ -369,34 +364,16 @@ public class JsonToCnSnTest { 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")); } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java index 39c0d3b34f..4c5922d73f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java @@ -1,14 +1,20 @@ 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; @@ -17,16 +23,26 @@ public class ControllerContextTest { private static final ControllerContext controllerContext = ControllerContext.getInstance(); + @Rule + public ExpectedException exception = ExpectedException.none(); + @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs").getPath()); + Set 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"); @@ -40,13 +56,20 @@ public class ControllerContextTest { 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 @@ -54,23 +77,35 @@ public class ControllerContextTest { 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"); } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java new file mode 100644 index 0000000000..0876584cab --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java @@ -0,0 +1,64 @@ +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 { + 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 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; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java index d58b7e9dab..c5f5a1eddc 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java @@ -7,15 +7,25 @@ import static org.mockito.Matchers.any; 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; @@ -33,7 +43,7 @@ public class InvokeRpcMethodTest { @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); @@ -50,7 +60,7 @@ public class InvokeRpcMethodTest { 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); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java new file mode 100644 index 0000000000..bbedd2b42b --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java @@ -0,0 +1,225 @@ +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(); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/NormalizeNodeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/NormalizeNodeTest.java new file mode 100644 index 0000000000..83e6ae51d0 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/NormalizeNodeTest.java @@ -0,0 +1,83 @@ +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; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java deleted file mode 100644 index cac77eb368..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java +++ /dev/null @@ -1,118 +0,0 @@ -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 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 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; - } -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java new file mode 100644 index 0000000000..fcc4c02a6f --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java @@ -0,0 +1,33 @@ +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 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 codec = RestCodec.from(mockedIidentityrefType); + String serializedValue = (String) codec.deserialize("incorrect value"); // IdentityValuesDTO + // object + // expected + assertEquals("incorrect value", serializedValue); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestConfigDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestConfigDataTest.java new file mode 100644 index 0000000000..c6d0a93a6f --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestConfigDataTest.java @@ -0,0 +1,212 @@ +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 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 rpcResult = new DummyRpcResult.Builder().result( + TransactionStatus.COMMITED).build(); + Future> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build(); + + when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class))) + .thenReturn(dummyFuture); + + ArgumentCaptor instanceIdCaptor = ArgumentCaptor.forClass(InstanceIdentifier.class); + ArgumentCaptor compNodeCaptor = ArgumentCaptor.forClass(CompositeNode.class); + + // Test URI_1 + Entity 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 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 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 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 createEntity(final String relativePathToXml) { + InputStream inputStream = XmlMapper.class.getResourceAsStream(relativePathToXml); + String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(inputStream)); + Entity 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; + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java new file mode 100644 index 0000000000..4b36d63539 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java @@ -0,0 +1,85 @@ +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 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> 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> createFuture(TransactionStatus statusName) { + RpcResult rpcResult = new DummyRpcResult.Builder().result(statusName).build(); + return DummyFuture.builder().rpcResult(rpcResult).build(); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java new file mode 100644 index 0000000000..ebc8a09f15 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java @@ -0,0 +1,183 @@ +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> 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; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestOperationUtils.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestOperationUtils.java new file mode 100644 index 0000000000..186dafb168 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestOperationUtils.java @@ -0,0 +1,20 @@ +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(); + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java new file mode 100644 index 0000000000..833d030b92 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java @@ -0,0 +1,203 @@ +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 rpcResult = new DummyRpcResult.Builder().result(TransactionStatus.COMMITED) + .build(); + Future> 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 rpcResult = new DummyRpcResult.Builder().result(result) + .isSuccessful(sucessful).build(); + when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(rpcResult); + } + + private void mockCommitConfigurationDataPostMethod(TransactionStatus statusName) { + RpcResult rpcResult = new DummyRpcResult.Builder().result(statusName) + .build(); + Future> 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; + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java new file mode 100644 index 0000000000..2df68af62f --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java @@ -0,0 +1,153 @@ +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 rpcResult = new DummyRpcResult.Builder().result(TransactionStatus.COMMITED) + .build(); + Future> 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 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 rpcResult = new DummyRpcResult.Builder().result(statusName) + .build(); + Future> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build(); + when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))) + .thenReturn(dummyFuture); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java index 41cc0ddb51..c15cd53082 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java @@ -1,17 +1,20 @@ 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; @@ -23,8 +26,8 @@ public class RestconfImplTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs") - .getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); ControllerContext controllerContext = ControllerContext.getInstance(); controllerContext.setSchemas(schemaContext); @@ -33,8 +36,7 @@ public class RestconfImplTest { @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)); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java index 366d99dbcb..5ef66c3b25 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java @@ -1,32 +1,52 @@ 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; @@ -38,11 +58,11 @@ import com.google.common.base.Preconditions; 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 loadModules(String resourceDirectory) throws FileNotFoundException { + private static Set loadModules(String resourceDirectory) throws FileNotFoundException { final File testDir = new File(resourceDirectory); final String[] fileList = testDir.list(); final List testFiles = new ArrayList(); @@ -58,34 +78,40 @@ public final class TestUtils { return parser.parseYangModels(testFiles); } + public static Set 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 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 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; } } @@ -107,288 +133,84 @@ public final class TestUtils { 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 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 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 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 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 resolveModules(String yangPath) { - Set 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 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 rpcResult = new DummyRpcResult.Builder().result( - TransactionStatus.COMMITED).build(); - Future> 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 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()) { @@ -397,56 +219,77 @@ public final class TestUtils { } } - public static void prepareMockForRestconfBeforeNormalization(Set modules, DataSchemaNode dataSchemaNode, - RestconfImpl restconf) { - ControllerContext instance = ControllerContext.getInstance(); - instance.setSchemas(TestUtils.loadSchemaContext(modules)); - restconf.setControllerContext(ControllerContext.getInstance()); - + private static void prepareMocksForRestconf(Set 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().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 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 reader) { + return readInputToCnSn(path, false, reader); + } + + public static String writeCompNodeWithSchemaContextToOutput(CompositeNode compositeNode, Set modules, + DataSchemaNode dataSchemaNode, MessageBodyWriter 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(); + } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java deleted file mode 100644 index 4cea120d4d..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java +++ /dev/null @@ -1,216 +0,0 @@ -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 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 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> 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("", MEDIA_TYPE)); - assertEquals(400, response.getStatus()); - - response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post( - Entity.entity("", 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 entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02); - RpcResult rpcResult = new DummyRpcResult.Builder().result( - TransactionStatus.COMMITED).build(); - Future> 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 entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02); - RpcResult rpcResult = new DummyRpcResult.Builder().result( - TransactionStatus.FAILED).build(); - Future> 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; - } - -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java index 7e3da0e4b4..3d24c6ba67 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java @@ -4,24 +4,32 @@ import static org.junit.Assert.assertEquals; 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 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; } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java new file mode 100644 index 0000000000..beff5724eb --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java @@ -0,0 +1,351 @@ +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 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 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 x:identity + */ + @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 identity + */ + + @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 identity + */ + @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 + * x:identity + */ + @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) x:identity + * + */ + @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) identity + * + */ + @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 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> 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; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java index 50ab0857b7..7c7df56133 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java @@ -2,391 +2,43 @@ package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test; 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 x:identity - */ - @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 identity - */ - - @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 identity - */ - @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 - * x:identity - */ - @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) x:identity - * - */ - @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) identity - * - */ - @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 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> 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()); } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang new file mode 100644 index 0000000000..a9df486b13 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang @@ -0,0 +1,13 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module new file mode 100644 index 0000000000..9bdea81579 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module @@ -0,0 +1,274 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang new file mode 100644 index 0000000000..84547847ee --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang @@ -0,0 +1,25 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang index 7023c94f2f..81d77329c6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang @@ -91,6 +91,12 @@ module basic-module { } } + leaf lfLfref { + type leafref { + path "/cont/lfBoolean"; + } + } + } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.json new file mode 100644 index 0000000000..0eae37ac21 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.json @@ -0,0 +1,10 @@ +{ + "test-module:input":{ + "cont":{ + "cont1":{ + "lf11":"lf1 data", + "lf12":"lf2 data" + } + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.xml new file mode 100644 index 0000000000..5954c091e3 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.xml @@ -0,0 +1,8 @@ + + + + lf1 data + lf2 data + + + \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data2.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data2.xml new file mode 100644 index 0000000000..8fbc0a99c4 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data2.xml @@ -0,0 +1,6 @@ + + + lf1 data + lf2 data + + diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-module/test-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-module/test-module new file mode 100644 index 0000000000..ad0716bc11 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-module/test-module @@ -0,0 +1,43 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang index 674b8b09be..0dec051ac7 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang @@ -54,6 +54,11 @@ module simple-nodes { leaf beer { type string; } + container nonalcoholic { + leaf beer { + type string; + } + } } case late-night { leaf chocolate { diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json new file mode 100644 index 0000000000..235666eed4 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json @@ -0,0 +1,6 @@ +{ + "cont":{ + "lf1":121, + "lf2":121 + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module new file mode 100644 index 0000000000..8ca9f09096 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module @@ -0,0 +1,19 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/1/simple-list1.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/1/simple-list1.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/2/simple-list2.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/2/simple-list2.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json new file mode 100644 index 0000000000..abc626739e --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json @@ -0,0 +1 @@ +fffff \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/normalize-node/yang/normalize-node-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/normalize-node/yang/normalize-node-module new file mode 100644 index 0000000000..15e68ef225 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/normalize-node/yang/normalize-node-module @@ -0,0 +1,14 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.json new file mode 100644 index 0000000000..0b39dc7241 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.json @@ -0,0 +1,10 @@ +{ + "interface":[ + { + "name":"eth0", + "type":"ethernetCsmacd", + "enabled":false, + "description": "some interface" + } + ] +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json new file mode 100644 index 0000000000..7de7fac444 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json @@ -0,0 +1,12 @@ +{ + "ietf-interfaces:interfaces":{ + "interface":[ + { + "name":"eth0", + "type":"ethernetCsmacd", + "enabled":false, + "description": "some interface" + } + ] + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml new file mode 100644 index 0000000000..7e3aa97987 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml @@ -0,0 +1,8 @@ + + + eth0 + ethernetCsmacd + false + some interface + + \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface.xml new file mode 100644 index 0000000000..755c8a9b0f --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface.xml @@ -0,0 +1,8 @@ + + + eth0 + ethernetCsmacd + false + + + diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface2.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface2.xml new file mode 100644 index 0000000000..05db4a5ccc --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface2.xml @@ -0,0 +1,5 @@ + + eth0 + ethernetCsmacd + false + diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface3.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface3.xml new file mode 100644 index 0000000000..e59ba178b7 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface3.xml @@ -0,0 +1,6 @@ + + + Thomas + 23 + + diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang1/test-interface.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang1/test-interface.yang new file mode 100644 index 0000000000..f683a69444 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang1/test-interface.yang @@ -0,0 +1,30 @@ +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; + } + } + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang2/test-interface2.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang2/test-interface2.yang new file mode 100644 index 0000000000..13bc0ebf9d --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang2/test-interface2.yang @@ -0,0 +1,27 @@ +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; + } + } + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module1.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module1.yang new file mode 100644 index 0000000000..f6a81ae664 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module1.yang @@ -0,0 +1,16 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module2.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module2.yang new file mode 100644 index 0000000000..bdd8ece24c --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module2.yang @@ -0,0 +1,17 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module new file mode 100644 index 0000000000..8ca9f09096 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module @@ -0,0 +1,19 @@ +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 diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml new file mode 100644 index 0000000000..06200a69b5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml @@ -0,0 +1,4 @@ + + 121 + 121 + \ No newline at end of file diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java index 521de7e394..738c2cb9a8 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java @@ -5,12 +5,7 @@ * 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; diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java index 95ba01cd54..bb5dea3bd5 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java @@ -44,8 +44,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111. 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; @@ -177,42 +177,32 @@ public class StatisticsProvider implements AutoCloseable { for (Node targetNode : targetNodes){ - InstanceIdentifier 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 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); } @@ -268,32 +258,19 @@ public class StatisticsProvider implements AutoCloseable { 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> 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> response = - portStatsService.getAllPortsStatistics(input.build()); + Future> response = + portStatsService.getAllNodeConnectorsStatistics(input.build()); this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId() , StatsRequestType.ALL_PORT); @@ -384,7 +361,7 @@ public class StatisticsProvider implements AutoCloseable { private List getTablesFromNode(NodeKey nodeKey){ InstanceIdentifier 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 tablesId = new ArrayList(); if(node != null && node.getTable()!=null){ spLogger.info("Number of tables {} supported by node {}",node.getTable().size(),nodeKey); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java index edffb976c6..62ba04687e 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java @@ -7,10 +7,6 @@ */ 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; @@ -29,10 +25,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.A 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; @@ -48,6 +41,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.q 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; @@ -90,12 +84,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111. 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; @@ -109,6 +107,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdenti 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. @@ -485,7 +487,7 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList .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(); @@ -495,10 +497,10 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList } 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 flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key) .augmentation(FlowCapableNode.class) .child(Table.class, new TableKey(tableId)) @@ -554,7 +556,7 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList } @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; @@ -714,28 +716,6 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList } - @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()); @@ -770,14 +750,8 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList 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) { @@ -810,5 +784,177 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList } 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; + } } diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml b/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml index 8569783ad7..e49fb33780 100644 --- a/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml +++ b/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml @@ -622,11 +622,7 @@ jersey-client ${jersey.version} - - com.sun.jersey - jersey-json - ${jersey.version} - + eclipselink javax.resource diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java b/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java index fda1e264e6..b8ebedfdfb 100644 --- a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java +++ b/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java @@ -182,10 +182,13 @@ public class ServiceProviderController { // 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(), @@ -318,8 +321,6 @@ public class ServiceProviderController { 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()); } diff --git a/opendaylight/md-sal/topology-lldp-discovery/pom.xml b/opendaylight/md-sal/topology-lldp-discovery/pom.xml new file mode 100644 index 0000000000..ed94c8dfb7 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/pom.xml @@ -0,0 +1,129 @@ + + 4.0.0 + + org.opendaylight.controller + sal-parent + 1.0-SNAPSHOT + ../ + + org.opendaylight.controller.md + topology-lldp-discovery + bundle + + scm:git:ssh://git.opendaylight.org:29418/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + + + 14.0.1 + 2.4.3 + 2.4.0 + 2.5 + + + + com.google.guava + guava + + + org.opendaylight.controller + sal-binding-api + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-flow-service + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-flow-base + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-flow-management + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-inventory + 1.0-SNAPSHOT + + + org.eclipse.xtend + org.eclipse.xtend.lib + + + equinoxSDK381 + org.eclipse.osgi + 3.8.1.v20120830-144521 + + + commons-lang + commons-lang + 2.6 + + + com.google.guava + guava + + + commons-codec + commons-codec + 1.8 + + + org.opendaylight.controller + sal + 0.7.0-SNAPSHOT + + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.opendaylight.md.controller.topology.lldp.LLDPActivator + org.opendaylight.md.controller.topology.lldp.utils + commons-lang> + ${project.groupId}.${project.artifactId} + + ${project.basedir}/META-INF + + + + org.eclipse.xtend + xtend-maven-plugin + + + + compile + + + ${basedir}/src/main/xtend-gen + + + + + + maven-clean-plugin + + + + ${basedir}/src/main/xtend-gen + + ** + + + + + + + + diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend new file mode 100644 index 0000000000..674e919cd7 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend @@ -0,0 +1,30 @@ +/* + * 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(); + } + +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java new file mode 100644 index 0000000000..095d12e6ef --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java @@ -0,0 +1,34 @@ +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); + } + } + +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend new file mode 100644 index 0000000000..fc724ac680 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend @@ -0,0 +1,46 @@ +/* + * 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 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(); + } + +} + + diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java new file mode 100644 index 0000000000..171783b0a2 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java @@ -0,0 +1,65 @@ +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 linkToDate = new ConcurrentHashMap(); + 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 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); + } + } + } + + } + + } +} + diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java new file mode 100644 index 0000000000..c0bcbaa8ad --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java @@ -0,0 +1,72 @@ +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 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; + } +} diff --git a/opendaylight/md-sal/topology-manager/pom.xml b/opendaylight/md-sal/topology-manager/pom.xml index 6e50f9ce73..76300864fd 100644 --- a/opendaylight/md-sal/topology-manager/pom.xml +++ b/opendaylight/md-sal/topology-manager/pom.xml @@ -42,7 +42,7 @@ org.opendaylight.controller.model - model-topology-view + model-topology 1.0-SNAPSHOT @@ -58,8 +58,8 @@ maven-bundle-plugin - org.opendaylight.controller.md.inventory.manager.InventoryActivator - org.opendaylight.controller.md.inventory.manager + org.opendaylight.md.controller.topology.manager.FlowCapableTopologyProvider + org.opendaylight.md.controller.topology.manager diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend index 46f5d2b406..05f7fe1272 100644 --- a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend @@ -5,7 +5,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon 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 @@ -14,6 +14,17 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. 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 { @@ -29,12 +40,6 @@ class FlowCapableNodeMapping { (ref?.value?.path?.get(2) as IdentifiableItem).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); } @@ -42,4 +47,36 @@ class FlowCapableNodeMapping { 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(); + } } diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend index fb129e4710..92a2277b4c 100644 --- a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend @@ -1,101 +1,135 @@ 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 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; } @@ -107,7 +141,7 @@ OpendaylightInventoryListener // 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; @@ -115,18 +149,52 @@ OpendaylightInventoryListener // 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 nodePath(NodeId nodeId) { + val nodeKey = new NodeKey(nodeId); + return InstanceIdentifier.builder(NetworkTopology) + .child(Topology, topology) + .child(Node, nodeKey) + .toInstance; + } + private def InstanceIdentifier 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 linkPath(Link link) { + val linkInstanceId = InstanceIdentifier.builder(NetworkTopology) + .child(Topology, topology) + .child(Link, link.key) + .toInstance; + return linkInstanceId; + } } diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend new file mode 100644 index 0000000000..036fe733aa --- /dev/null +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend @@ -0,0 +1,49 @@ +/* + * 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 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); + } + +} + + diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java deleted file mode 100644 index 23cdabf69f..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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"; -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java index a1f46dde54..dbc1b48d4f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java @@ -43,7 +43,6 @@ public class AttributeConfigElement { 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) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java index fb385221c8..506d7d61c3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java @@ -16,7 +16,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu 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; @@ -27,9 +27,9 @@ import java.util.Map.Entry; public class ObjectMapper extends AttributeIfcSwitchStatement>> { - private final Services dependencyTracker; + private final ServiceRegistryWrapper dependencyTracker; - public ObjectMapper(Services depTracker) { + public ObjectMapper(ServiceRegistryWrapper depTracker) { this.dependencyTracker = depTracker; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java index 8426341636..83e8086eef 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java @@ -10,8 +10,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri 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; @@ -20,11 +20,11 @@ import javax.management.openmbean.SimpleType; public class ObjectNameAttributeMappingStrategy extends AbstractAttributeMappingStrategy> { - 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; @@ -44,10 +44,7 @@ public class ObjectNameAttributeMappingStrategy extends ObjectName on = (ObjectName) value; - String expectedRefName = on.getKeyProperty(AttributesConstants.REF_NAME_ON_PROPERTY_KEY); - - String refName = expectedRefName == null ? tracker.getRefName(namespace, serviceName, on, Optional. absent()) - : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName)); + String refName = ObjectNameUtil.getReferenceName(on); return Optional.of(new MappedDependency(namespace, serviceName, refName)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java index d8f0e2357e..57a44d8af0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java @@ -9,11 +9,8 @@ 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; @@ -23,10 +20,10 @@ import javax.management.openmbean.SimpleType; public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy> { - 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; } @@ -45,9 +42,7 @@ public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResol 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); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java index a3e2813fa0..82c8c1ec6b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java @@ -15,7 +15,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu 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; @@ -26,9 +26,9 @@ import java.util.Map.Entry; public class ObjectResolver extends AttributeIfcSwitchStatement>> { - private final Services serviceTracker; + private final ServiceRegistryWrapper serviceTracker; - public ObjectResolver(Services serviceTracker) { + public ObjectResolver(ServiceRegistryWrapper serviceTracker) { this.serviceTracker = serviceTracker; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index 3a5fa1170f..ec73cd6068 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -14,7 +14,6 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import 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; @@ -99,7 +98,7 @@ public class Config { // } public Element toXml(Set instancesToMap, Optional maybeNamespace, Document document, - Element dataElement, Services serviceTracker) { + Element dataElement, ServiceRegistryWrapper serviceTracker) { Map>> moduleToInstances = getMappedInstances(instancesToMap, moduleConfigs); @@ -120,81 +119,84 @@ public class Config { 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> 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> retVal = Maps.newHashMap(); - List recognisedChildren = Lists.newArrayList(); + public Map> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient); - List moduleElements = fromXmlModules(xml, recognisedChildren); - - xml.checkUnrecognisedElements(recognisedChildren); + Map> retVal = Maps.newHashMap(); for (XmlElement moduleElement : moduleElements) { - resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType); - } + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @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> fromXmlModulesMap(XmlElement xml, + EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - private final Map> resolvedModules; - private final Services services; + Map> retVal = Maps.newHashMap(); - public ConfigElementResolved(Map> retVal, Services serviceTracker) { - this.resolvedModules = retVal; - this.services = serviceTracker; - } + for (XmlElement moduleElement : moduleElements) { + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @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> getResolvedModules() { - return resolvedModules; + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); } + return retVal; + } - public Services getServices() { - return services; - } + private static Optional getModulesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); } - private List fromXmlModules(XmlElement xml, List recognisedChildren) { - Optional modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + private List getModulesElementList(Optional modulesElement) { List moduleElements; + if (modulesElement.isPresent()) { moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY); - recognisedChildren.add(modulesElement.get()); modulesElement.get().checkUnrecognisedElements(moduleElements); } else { moduleElements = Lists.newArrayList(); @@ -202,8 +204,8 @@ public class Config { return moduleElements; } - private void resolveModule(Map> retVal, Services serviceTracker, - XmlElement moduleElement, EditStrategyType defaultStrategy) { + private void resolveModule(Map> retVal, ServiceRegistryWrapper serviceTracker, + XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy resolvingStrategy) { XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Entry prefixToNamespace = typeElement.findNamespaceOfTextContent(); String moduleNamespace = prefixToNamespace.getValue(); @@ -215,35 +217,49 @@ public class Config { ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName); - Multimap innerMap = retVal.get(moduleNamespace); + Multimap 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 recognisedChildren, - ServiceReferenceReadableRegistry taClient) { - Optional servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + public Services fromXmlServices(XmlElement xml) { + Optional servicesElement = getServicesElement(xml); - Map>> 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 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 servicesOpt = getServicesElement(parent); + Optional modulesOpt = getModulesElement(parent); + + List 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), @@ -271,4 +287,8 @@ public class Config { return moduleMapping; } + private interface ResolvingStrategy { + public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, + String instanceName, String moduleNamespace, EditStrategyType defaultStrategy); + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java index aae1636165..b8870e51ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java @@ -52,7 +52,7 @@ public final class InstanceConfig { this.configRegistryClient = configRegistryClient; } - private Map getMappedConfiguration(ObjectName on, Services depTracker) { + private Map getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) { // TODO make field, mappingStrategies can be instantiated only once Map>> mappingStrategies = new ObjectMapper(depTracker) @@ -84,7 +84,7 @@ public final class InstanceConfig { 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; @@ -104,7 +104,7 @@ public final class InstanceConfig { 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>> resolvingStrategies = new ObjectResolver( @@ -128,7 +128,7 @@ public final class InstanceConfig { } } - public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace, + public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace, EditStrategyType defaultStrategy, Multimap providedServices) { Map retVal = Maps.newHashMap(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java index 55cb60bed5..0bb4191bf2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java @@ -28,7 +28,7 @@ public class InstanceConfigElementResolved { private final Multimap providedServices; public InstanceConfigElementResolved(String currentStrategy, Map configuration, EditStrategyType defaultStrategy, Multimap providedServices) { - EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy); + EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy); this.editStrategy = valueOf; this.configuration = configuration; this.providedServices = providedServices; @@ -41,19 +41,19 @@ public class InstanceConfigElementResolved { } - 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; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index 2ac6fe0a9b..48ff835a45 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -53,7 +53,7 @@ public class ModuleConfig { 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); @@ -84,7 +84,7 @@ public class ModuleConfig { } - 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); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java new file mode 100644 index 0000000000..9111701ba0 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java @@ -0,0 +1,48 @@ +/* + * 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; + } + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java new file mode 100644 index 0000000000..7df671297c --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java @@ -0,0 +1,159 @@ +/* + * 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 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> serviceNameToRefNameToInstance = getMappedServices().get(namespace); + + Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); + + Map 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>> getMappedServices() { + Map>> retVal = Maps.newHashMap(); + + Map> 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> serviceToRefs = retVal.get(namespace); + if(serviceToRefs==null) { + serviceToRefs = Maps.newHashMap(); + retVal.put(namespace, serviceToRefs); + } + +// String localName = qname.getLocalName(); + Map 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> serviceNameToRefNameToInstance = getMappedServices().get(namespace); + + Map refNameToInstance; + if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { + refNameToInstance = Collections.emptyMap(); + } else + refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + + final Set refNamesAsSet = toSet(refNameToInstance.keySet()); + if (refNamesAsSet.contains(refName)) { + refName = findAvailableRefName(refName, refNamesAsSet); + } + + return refName; + } + + + private Set toSet(Collection values) { + Set 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 refNamesAsSet) { + String intitialRefName = refName; + + while (true) { + refName = intitialRefName + "_" + suffix++; + if (refNamesAsSet.contains(refName) == false) + return refName; + } + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index 77f3cf283f..7de7ea8c71 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -8,14 +8,8 @@ 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; @@ -27,12 +21,9 @@ import org.w3c.dom.Document; 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; @@ -45,124 +36,8 @@ public final class Services { public static final String TYPE_KEY = "type"; public static final String SERVICE_KEY = "service"; - private long suffix = 1; - private final Map>> 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> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - - Map refNameToInstance; - if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { - refNameToInstance = Collections.emptyMap(); - } else - refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - - final Set refNamesAsSet = toSet(refNameToInstance.keySet()); - if (refNamesAsSet.contains(refName)) { - refName = findAvailableRefName(refName, refNamesAsSet); - } - - return refName; - } - - private Set toSet(Collection values) { - Set 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> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - - Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); - - Map 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>> getMappedServices() { - Map>> retVal = Maps.newHashMap(); - - for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) { - - Map> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance - .get(namespace); - Map> innerRetVal = Maps.newHashMap(); - - for (String serviceName : serviceNameToRefNameToInstance.keySet()) { - - Map innerInnerRetVal = Maps.newHashMap(); - for (Entry refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) { - innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString()); - } - innerRetVal.put(serviceName, innerInnerRetVal); - } - retVal.put(namespace, innerRetVal); - } - - Map> 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> serviceToRefs = retVal.get(namespace); - if(serviceToRefs==null) { - serviceToRefs = Maps.newHashMap(); - retVal.put(namespace, serviceToRefs); - } - - Map 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; - } /** * @@ -171,10 +46,8 @@ public final class Services { return namespaceToServiceNameToRefNameToInstance; } - // TODO hide resolveServices, call it explicitly in fromXml - - public static Services resolveServices(Map>> mappedServices, ServiceReferenceReadableRegistry taClient) { - Services tracker = new Services(taClient); + private static Services resolveServices(Map>> mappedServices) { + Services tracker = new Services(); for (Entry>> namespaceEntry : mappedServices.entrySet()) { String namespace = namespaceEntry.getKey(); @@ -210,7 +83,7 @@ public final class Services { // TODO support edit strategies on services - public static Map>> fromXml(XmlElement xml) { + public static Services fromXml(XmlElement xml) { Map>> retVal = Maps.newHashMap(); List services = xml.getChildElements(SERVICE_KEY); @@ -250,23 +123,14 @@ public final class Services { } } - return retVal; - } - - private String findAvailableRefName(String refName, Set refNamesAsSet) { - String intitialRefName = refName; - - while (true) { - refName = intitialRefName + "_" + suffix++; - if (refNamesAsSet.contains(refName) == false) - return refName; - } + return resolveServices(retVal); } - public Element toXml(Map>> 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>> mappedServices = serviceRegistryWrapper.getMappedServices(); for (String namespace : mappedServices.keySet()) { for (Entry> serviceEntry : mappedServices.get(namespace).entrySet()) { @@ -294,51 +158,6 @@ public final class Services { return root; } - public String getRefName(String namespace, String serviceName, ObjectName on, Optional expectedRefName) { - Optional 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 getRefNameOptional(String namespace, String serviceName, ObjectName on, - Optional expectedRefName) { - Map> services = getMappedServices().get(namespace); - - if(services == null) return Optional.absent(); - Map refs = services.get(serviceName); - - if(refs == null) return Optional.absent(); - Multimap reverted = revertMap(refs); - - ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on); - Collection 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 revertMap(Map refs) { - Multimap multimap = HashMultimap.create(); - - for (Entry 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.absent()).isPresent(); - } - public static final class ServiceInstance { public ServiceInstance(String moduleName, String instanceName) { this.moduleName = moduleName; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java index 70b10d0019..6a0d7508c8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java @@ -88,7 +88,6 @@ public class InstanceRuntime { public Element toXml(ObjectName rootOn, Set childRbeOns, Document document, String instanceIndex, Element parentElement, String namespace) { - // TODO namespace Element xml = instanceMapping.toXml(rootOn, null, namespace, document, parentElement); if (instanceIndex != null) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java index 11e97ebdbb..4936d1dbcd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti 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; @@ -41,7 +41,7 @@ public class ModuleRuntime { } public Element toXml(String namespace, Collection 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); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java index 89c782c51c..129143835f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java @@ -11,11 +11,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti 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; @@ -61,9 +60,7 @@ public class Runtime { return retVal; } - public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) { - Services serviceTracker = new Services(serviceRegistry); - + public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceRegistryWrapper serviceRegistry) { Element root = document.createElement(XmlNetconfConstants.DATA_KEY); Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY); @@ -88,11 +85,11 @@ public class Runtime { 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); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java index 65df965afd..1d37fcd493 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed 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; @@ -24,7 +24,7 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { @Override public void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) { try { ObjectName on = ta.lookupConfigBean(module, instance); @@ -36,10 +36,13 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { } + // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR + // edit configs should not handle missing + abstract void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services); + String module, String instance, ServiceRegistryWrapper services); abstract void executeStrategy(Map configuration, ConfigTransactionClient ta, - ObjectName objectName, Services services); + ObjectName objectName, ServiceRegistryWrapper services); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java index 12beaf8f8e..13e8c30211 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java @@ -12,7 +12,7 @@ import com.google.common.collect.HashMultimap; 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; @@ -36,12 +36,12 @@ public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map 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 configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { try { ta.destroyModule(on); logger.debug("ServiceInstance {} deleted successfully", on); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index 1bb1d9bfba..709573c241 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config 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; @@ -105,8 +106,8 @@ public class EditConfig extends 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 { @@ -115,8 +116,11 @@ public class EditConfig extends AbstractConfigNetconfOperation { 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); @@ -132,14 +136,16 @@ public class EditConfig extends AbstractConfigNetconfOperation { 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>> namespaceToServiceNameToRefNameToInstance = services .getNamespaceToServiceNameToRefNameToInstance(); @@ -153,9 +159,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { 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); } @@ -168,11 +175,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { return ta.getServiceInterfaceName(namespace, serviceName); } - private void setOnTransaction(ConfigRegistryClient configRegistryClient, - Map> resolvedXmlElements, Services services, ObjectName taON) { - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + + for (Multimap modulesToResolved : execution.getResolvedXmlElements(ta).values()) { - for (Multimap modulesToResolved : resolvedXmlElements.values()) { for (Entry moduleToResolved : modulesToResolved.entries()) { String moduleName = moduleToResolved.getKey(); @@ -181,7 +187,22 @@ public class EditConfig extends AbstractConfigNetconfOperation { 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 modulesToResolved : execution.getModulesDefinition(ta).values()) { + for (Entry 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)); } } } @@ -189,32 +210,38 @@ public class EditConfig extends AbstractConfigNetconfOperation { public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, Map> mBeanEntries) { - Map> factories = transform(configRegistryClient, mBeanEntries); + Map> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries); return new Config(factories); } - // TODO refactor - private static Map> transform - (final ConfigRegistryClient configRegistryClient, Map> transformMbeToModuleConfigs + (final ConfigRegistryClient configRegistryClient, Map> mBeanEntries) { - return Maps.transformEntries(mBeanEntries, - new Maps.EntryTransformer, Map>() { - - @Override - public Map transformEntry(String arg0, Map arg1) { - return Maps.transformEntries(arg1, - new Maps.EntryTransformer() { - - @Override - public ModuleConfig transformEntry(String key, ModuleMXBeanEntry moduleMXBeanEntry) { - return new ModuleConfig(key, new InstanceConfig(configRegistryClient, moduleMXBeanEntry - .getAttributes()), moduleMXBeanEntry.getProvidedServices().values()); - } - }); - } - }); + + Map> namespaceToModuleNameToModuleConfig = Maps.newHashMap(); + + for (String namespace : mBeanEntries.keySet()) { + for (Entry 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 moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespace); + if(moduleNameToModuleConfig == null) { + moduleNameToModuleConfig = Maps.newHashMap(); + namespaceToModuleNameToModuleConfig.put(namespace, moduleNameToModuleConfig); + } + + moduleNameToModuleConfig.put(moduleName, moduleConfig); + } + } + + return namespaceToModuleNameToModuleConfig; } @Override diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java index 23166e8cca..cebcb0239b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java @@ -10,13 +10,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed 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 configuration, - ConfigTransactionClient ta, Services services); + ConfigTransactionClient ta, ServiceRegistryWrapper services); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java index 81327133b8..e481bbe57f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java @@ -14,10 +14,11 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.util.ConfigRegistryClient; -import org.opendaylight.controller.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; @@ -26,7 +27,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.ObjectName; import java.util.Arrays; import java.util.Map; @@ -98,11 +98,7 @@ public class EditConfigXmlParser { 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 @@ -132,15 +128,17 @@ public class EditConfigXmlParser { @VisibleForTesting static class EditConfigExecution { - private final Map> 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; } @@ -153,8 +151,17 @@ public class EditConfigXmlParser { return testOption == TestOption.set || testOption == TestOption.testThenSet; } - Map> getResolvedXmlElements() { - return resolvedXmlElements; + Map> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) { + return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); + } + + ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) { + // TODO cache service registry + return new ServiceRegistryWrapper(serviceRegistry); + } + + Map> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) { + return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); } EditStrategyType getDefaultStrategy() { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java index 676467553b..06560b2d27 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java @@ -13,7 +13,6 @@ import com.google.common.collect.Multimap; import java.util.EnumSet; import java.util.Set; -//FIXME: make thread safe public enum EditStrategyType { // can be default merge, replace, none, diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java index 06befb0565..f2e2b193a8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java @@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed 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; @@ -38,22 +38,13 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map 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 providedServices, String module, - String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { + private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), @@ -61,14 +52,20 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { 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 configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map 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 configAttributeEntry : configuration.entrySet()) { try { AttributeConfigElement ace = configAttributeEntry.getValue(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java new file mode 100644 index 0000000000..8ed9eb8731 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java @@ -0,0 +1,42 @@ +/* + * 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 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 configuration, ConfigTransactionClient ta, + ObjectName objectName, ServiceRegistryWrapper services) { + return; + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java index 8347c6b88e..bd182a4267 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java @@ -8,21 +8,21 @@ 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 configuration, - ConfigTransactionClient ta, Services services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) { logger.debug("Skipping configuration element for {}:{}", module, instance); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java index 64f082da40..df1f65372a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed 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; @@ -22,7 +22,7 @@ public class RemoveEditConfigStrategy extends DeleteEditConfigStrategy { @Override void handleMissingInstance(Map 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); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java index 43d852e76a..4976244eae 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java @@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed 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; @@ -39,23 +39,13 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map 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 providedServices, String module, - String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { + private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), @@ -63,13 +53,20 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { 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 configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map 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 configAttributeEntry : configuration.entrySet()) { try { AttributeConfigElement ace = configAttributeEntry.getValue(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java index efe4f7dde9..ea602091a0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java @@ -20,12 +20,13 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorT 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; @@ -143,14 +144,14 @@ public class Get extends AbstractConfigNetconfOperation { final Map> moduleRuntimes = createModuleRuntimes(configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap()); - final Map> moduleConfigs = GetConfig.transform(configRegistryClient, - yangStoreSnapshot.getModuleMXBeanEntryMap()); + final Map> 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); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java index d75cfd5d6f..16dd5ad80a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java @@ -9,21 +9,18 @@ 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; @@ -83,14 +80,14 @@ public class GetConfig extends AbstractConfigNetconfOperation { final Set 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); @@ -98,27 +95,6 @@ public class GetConfig extends AbstractConfigNetconfOperation { return dataElement; } - // TODO refactor ... duplicate code - public static Map> transform(final ConfigRegistryClient configRegistryClient, - Map> mBeanEntries) { - return Maps.transformEntries(mBeanEntries, - new Maps.EntryTransformer, Map>() { - - @Override - public Map transformEntry(String arg0, Map arg1) { - return Maps.transformEntries(arg1, - new Maps.EntryTransformer() { - - @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; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java index 7463bdd429..f838c6f9f5 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java @@ -127,7 +127,6 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { 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); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java index 35695f7510..2db3c9d4f1 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java @@ -45,6 +45,7 @@ public class NetconfOperationServiceFactoryImpl implements NetconfOperationServi try { Thread.sleep(ATTEMPT_TIMEOUT_MS); } catch (InterruptedException e1) { + Thread.currentThread().interrupt(); throw new RuntimeException(e1); } continue; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java index 1c806742e9..fc8ddc01bd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java @@ -9,13 +9,6 @@ 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; @@ -41,15 +34,4 @@ public final class Util { + " 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); - } - } - } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index 11cf1aae6a..f236a8d36e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -143,12 +143,19 @@ public class NetconfMappingTest extends AbstractConfigTest { "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); @@ -229,6 +236,7 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); Element configCandidate = getConfigCandidate(); + System.err.println(XmlUtil.toString(configCandidate)); checkBinaryLeafEdited(configCandidate); @@ -252,10 +260,8 @@ public class NetconfMappingTest extends AbstractConfigTest { 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") diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java index 6e7a225f38..505a91c6ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java @@ -23,7 +23,9 @@ import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.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; @@ -35,7 +37,7 @@ import java.util.Collections; 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; @@ -82,8 +84,8 @@ public class EditConfigTest { 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); @@ -96,20 +98,44 @@ public class EditConfigTest { 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> result = Maps.newHashMap(); + + Multimap innerMultimap = HashMultimap.create(); + Map 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( @@ -120,8 +146,8 @@ public class EditConfigTest { return mock; } - static Services mockServices() { - return new Services(mockServiceRegistry()); + static ServiceRegistryWrapper mockServices() { + return new ServiceRegistryWrapper(mockServiceRegistry()); } private Map> getMapping(EditConfigStrategy editStrat) { diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java index 1c3ac7a455..b66a1a57c2 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java @@ -8,6 +8,7 @@ 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; @@ -36,11 +37,11 @@ public class ConfigPersisterNotificationHandler implements NotificationListener, 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; @@ -72,8 +73,9 @@ public class ConfigPersisterNotificationHandler implements NotificationListener, 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; } diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java index 811ba38c10..86a024a240 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java @@ -40,8 +40,6 @@ public final class Util { return true; } - - // TODO: check if closing in correct order public static void closeClientAndDispatcher(NetconfClient client) { NetconfClientDispatcher dispatcher = client.getNetconfClientDispatcher(); Exception fromClient = null; diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java index 656091115c..3c901c3f59 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java @@ -78,7 +78,10 @@ public class ConfigPersisterActivator implements BundleActivator { 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); } } }; diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java index 15ed5c48fa..2a95cca937 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java @@ -1,10 +1,9 @@ -/** - * @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; diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java index 2ce779a1f5..67d95bb90f 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java @@ -71,6 +71,10 @@ public class NetconfClient implements Closeable { 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, @@ -83,6 +87,17 @@ public class NetconfClient implements Closeable { 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 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); } @@ -90,10 +105,12 @@ public class NetconfClient implements Closeable { 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); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java index 1d2e039b29..8dbdb26bff 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java @@ -15,6 +15,8 @@ import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; 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; @@ -24,6 +26,8 @@ public class CapabilityProviderImpl implements CapabilityProvider { private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot; private final Set capabilityURIs; + private static final Logger logger = LoggerFactory.getLogger(DefaultCommitNotificationProducer.class); + public CapabilityProviderImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) { this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot; Map urisToCapabilitiesInternalMap = getCapabilitiesInternal(netconfOperationServiceSnapshot); @@ -38,7 +42,11 @@ public class CapabilityProviderImpl implements CapabilityProvider { final Set 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); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java index 4f60788975..7c5bd0cb21 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java @@ -12,12 +12,13 @@ import io.netty.channel.ChannelFuture; 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 { private final ServerChannelInitializer initializer; @@ -28,7 +29,6 @@ public class NetconfServerDispatcher extends AbstractDispatcher() { diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java index e74723032d..91734beacb 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java @@ -8,6 +8,7 @@ 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; @@ -28,9 +29,12 @@ import org.w3c.dom.Node; 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(); @@ -45,8 +49,11 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF } 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 diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java index 1b3542595f..505c74714a 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java @@ -68,6 +68,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S @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)); } @@ -78,6 +79,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S 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()); } @@ -115,8 +117,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S 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; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java index ee474dbba0..d70a15c18b 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java @@ -185,7 +185,6 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { private NetconfOperationExecution getNetconfOperationWithHighestPriority( Document message, NetconfSession session) { - // TODO test TreeMap> sortedPriority = getSortedNetconfOperationsWithCanHandle( message, session); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java index f2c70d6101..621c8eaa86 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java @@ -1,11 +1,13 @@ +/* + * 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; @@ -13,12 +15,18 @@ import org.slf4j.LoggerFactory; 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) { @@ -28,6 +36,7 @@ public class NetconfUtil { } public static NetconfMessage createMessage(final InputStream is) { + Preconditions.checkNotNull(is, "InputStream parameter was null"); Document doc = null; try { doc = XmlUtil.readXmlToDocument(is); diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ExiEncodeDecodeTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ExiEncodeDecodeTest.java index 6b0316b6fc..73eb608f0b 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ExiEncodeDecodeTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ExiEncodeDecodeTest.java @@ -1,3 +1,10 @@ +/* + * 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; import static junit.framework.Assert.assertNotNull; diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java index 0140b65c14..0ecc1cb383 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java @@ -24,21 +24,14 @@ import java.net.InetSocketAddress; 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(); @@ -50,13 +43,20 @@ public class NetconfDispatcherImplTest { 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(); } } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java new file mode 100644 index 0000000000..14f70d398c --- /dev/null +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java @@ -0,0 +1,286 @@ +/* + * 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 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, " caps = Sets.newHashSet(); + doReturn(caps).when(service).getCapabilities(); + Set 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 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 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, ""); + assertEquals("Expected modules count", expectedModulesSize, modulesSize); + int servicesSize = StringUtils.countMatches(configSnapshot, ""); + assertEquals("Expected services count", expectedServicesSize, servicesSize); + } + + @Override + public void persistConfig(ConfigSnapshotHolder configSnapshotHolder) throws IOException { + mockedPersister.persistConfig(configSnapshotHolder); + } + + @Override + public List loadLastConfigs() throws IOException { + return mockedPersister.loadLastConfigs(); + } + + @Override + public void close() { + mockedPersister.close(); + } + } +} diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index 4818b5f0a3..36f30dd328 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -16,19 +16,6 @@ import io.netty.channel.ChannelFuture; 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; @@ -74,6 +61,21 @@ import org.w3c.dom.Element; 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; @@ -215,20 +217,6 @@ public class NetconfITTest extends AbstractConfigTest { } } - - //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 { @@ -432,7 +420,8 @@ public class NetconfITTest extends AbstractConfigTest { 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(); diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java index 3a7b7de7a0..b0821799b0 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java @@ -7,27 +7,14 @@ */ 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; @@ -61,9 +48,20 @@ import org.slf4j.Logger; 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 { @@ -177,7 +175,6 @@ public class NetconfMonitoringITTest extends AbstractConfigTest { responseBuilder.append(line); responseBuilder.append(System.lineSeparator()); - System.out.println(responseBuilder.toString()); if(line.contains("")) break; @@ -197,7 +194,7 @@ public class NetconfMonitoringITTest extends AbstractConfigTest { 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); diff --git a/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk b/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk new file mode 100644 index 0000000000..c0266c7bd2 --- /dev/null +++ b/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk @@ -0,0 +1,27 @@ +-----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----- diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/DefaultNetconfOperation.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/DefaultNetconfOperation.java index f6f05f6bde..816650c4bb 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/DefaultNetconfOperation.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/DefaultNetconfOperation.java @@ -1,3 +1,10 @@ +/* + * 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.mapping.api; import org.opendaylight.controller.netconf.api.NetconfSession; diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java index 5a0688c8d1..176cf2d28c 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java @@ -36,8 +36,6 @@ public class HandlingPriority implements Comparable { return Optional.of(priority).or(Optional. absent()); } - // TODO test - @Override public int compareTo(HandlingPriority o) { if (this == o) diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/package-info.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/package-info.java index 8771421a11..85da5975d1 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/package-info.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/package-info.java @@ -1,3 +1,10 @@ +/* + * 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 = { diff --git a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java index 1e3f343624..d4462f85d9 100644 --- a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java +++ b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java @@ -7,15 +7,10 @@ */ 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; @@ -30,7 +25,10 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types. 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 { @@ -51,7 +49,6 @@ public class JaxBSerializerTest { }; NetconfState model = new NetconfState(service); Element xml = new JaxBSerializer().toXml(model); - System.out.println(XmlUtil.toString(xml)); } private Session getMockSession() { diff --git a/opendaylight/netconf/netconf-ssh/pom.xml b/opendaylight/netconf/netconf-ssh/pom.xml index 5dde0448bd..d91564ba0b 100644 --- a/opendaylight/netconf/netconf-ssh/pom.xml +++ b/opendaylight/netconf/netconf-ssh/pom.xml @@ -61,22 +61,15 @@ org.opendaylight.controller.netconf.osgi.NetconfSSHActivator - - org.opendaylight.controller.netconf.ssh, - 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, diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java index 3b513790bd..1bce3143d5 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java @@ -8,6 +8,8 @@ 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; @@ -42,7 +44,7 @@ public class NetconfSSHActivator implements BundleActivator{ ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer(){ @Override public IUserManager addingService(ServiceReference 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); @@ -53,13 +55,13 @@ public class NetconfSSHActivator implements BundleActivator{ } @Override public void modifiedService(ServiceReference 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 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(); } }; @@ -85,7 +87,28 @@ public class NetconfSSHActivator implements BundleActivator{ 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); diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java index a73dfdfd49..22dda95064 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java @@ -7,8 +7,6 @@ */ 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; @@ -17,26 +15,30 @@ import org.opendaylight.controller.sal.authorization.AuthResultEnum; 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 roles = new ArrayList(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 { @@ -51,15 +53,10 @@ public class AuthProvider implements AuthProviderInterface { } @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 diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java index 71f1cc350f..8e40578a0e 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java @@ -13,7 +13,7 @@ import org.opendaylight.controller.usermanager.IUserManager; 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); } diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java index e5da03b4cf..d159f59f1a 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java @@ -1,3 +1,10 @@ +/* + * 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; @@ -59,8 +66,8 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser 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); @@ -108,6 +115,7 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser netconf_ssh_input.join(); } } catch (InterruptedException e) { + Thread.currentThread().interrupt(); logger.error("netconf_ssh_input join error ",e); } @@ -116,6 +124,7 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser netconf_ssh_output.join(); } } catch (InterruptedException e) { + Thread.currentThread().interrupt(); logger.error("netconf_ssh_output join error ",e); } diff --git a/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java b/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java index 62396ed87a..91783ff755 100644 --- a/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java +++ b/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java @@ -8,6 +8,7 @@ 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; @@ -33,7 +34,8 @@ public class SSHServerTest { 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); diff --git a/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk b/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk new file mode 100644 index 0000000000..c0266c7bd2 --- /dev/null +++ b/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk @@ -0,0 +1,27 @@ +-----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----- diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java index 4fee930eff..26ea7ceb79 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java @@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; public abstract class AbstractNetconfSessionNegotiator

extends AbstractSessionNegotiator { - // 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); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/Invoker.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/Invoker.java index 12d1129daf..8636e5ecb5 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/Invoker.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/Invoker.java @@ -1,3 +1,10 @@ +/* + * 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; diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java index 07c81b0ccb..4b9bfbf5f8 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java @@ -57,6 +57,7 @@ public class ChannelInputStream extends InputStream implements ChannelInboundHan try { lock.wait(); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java index 987708d67e..55ed7e0744 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java @@ -23,6 +23,7 @@ public class NetconfConfigUtil { 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) { @@ -38,6 +39,16 @@ public class NetconfConfigUtil { 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. diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiParameters.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiParameters.java index 63dfcde0c6..7109971b5d 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiParameters.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiParameters.java @@ -1,3 +1,10 @@ +/* + * 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.xml; import com.siemens.ct.exi.CodingMode; diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiUtil.java index 8baa68e494..82bbb66c02 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiUtil.java @@ -1,3 +1,10 @@ +/* + * 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.xml; import io.netty.buffer.ByteBuf; diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml new file mode 100644 index 0000000000..6e68326382 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml @@ -0,0 +1,38 @@ + + + + + + + test-only + + merge + + + + + instance-from-code_dep + + test-impl:impl-dep + + + + + + + prefix:testing + + ref_dep_user_another_test1 + /modules/module[type='impl-dep'][name='instance-from-code_dep'] + + + + ref_dep_user_another_test2 + /modules/module[type='impl-dep'][name='instance-from-code_dep'] + + + + + + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml index 7f884dc43c..36f79a50bc 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml @@ -1,19 +1,6 @@ - - - - - + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml index a7f1c86391..ade40f6a49 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml @@ -21,12 +21,11 @@ - test-impl:impl-netconf - test1 + instance-from-code 44 8ad1 @@ -72,7 +71,7 @@ test-impl:impl-netconf - test2 + test3 diff --git a/opendaylight/netconf/pom.xml b/opendaylight/netconf/pom.xml index c4b1467220..21a1ffe81d 100644 --- a/opendaylight/netconf/pom.xml +++ b/opendaylight/netconf/pom.xml @@ -48,7 +48,7 @@ 5.0.0 - 2.3.7 + 2.4.0 1.7.2 4.0.10.Final 0.9.2 diff --git a/opendaylight/networkconfiguration/neutron/implementation/pom.xml b/opendaylight/networkconfiguration/neutron/implementation/pom.xml index 3b335463d9..150f602802 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/pom.xml +++ b/opendaylight/networkconfiguration/neutron/implementation/pom.xml @@ -50,6 +50,7 @@ org.opendaylight.controller.clustering.services, + org.opendaylight.controller.configuration, org.opendaylight.controller.sal.core, org.opendaylight.controller.sal.utils, org.apache.felix.dm, @@ -76,6 +77,11 @@ org.opendaylight.controller clustering.services + 0.5.0-SNAPSHOT + + + org.opendaylight.controller + configuration 0.4.1-SNAPSHOT @@ -86,7 +92,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java index 4202856774..351496abb3 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java @@ -10,11 +10,12 @@ package org.opendaylight.controller.networkconfig.neutron.implementation; 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; @@ -32,6 +33,7 @@ public class Activator extends ComponentActivatorAbstractBase { * ComponentActivatorAbstractBase. * */ + @Override public void init() { } @@ -41,6 +43,7 @@ public class Activator extends ComponentActivatorAbstractBase { * cleanup done by ComponentActivatorAbstractBase * */ + @Override public void destroy() { } @@ -54,6 +57,7 @@ public class Activator extends ComponentActivatorAbstractBase { * instantiated in order to get an fully working implementation * Object */ + @Override public Object[] getImplementations() { Object[] res = { NeutronFloatingIPInterface.class, NeutronRouterInterface.class, @@ -76,11 +80,13 @@ public class Activator extends ComponentActivatorAbstractBase { * 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 props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) @@ -91,7 +97,8 @@ public class Activator extends ComponentActivatorAbstractBase { 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 props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) @@ -102,7 +109,8 @@ public class Activator extends ComponentActivatorAbstractBase { 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 props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) @@ -113,7 +121,8 @@ public class Activator extends ComponentActivatorAbstractBase { 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 props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) @@ -124,7 +133,8 @@ public class Activator extends ComponentActivatorAbstractBase { 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 props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java index 7d9a2e6576..ceb009bf2c 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java @@ -8,6 +8,9 @@ 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; @@ -16,6 +19,7 @@ import java.util.HashSet; 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; @@ -23,6 +27,7 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; 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; @@ -31,11 +36,20 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces; 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; @@ -103,6 +117,9 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (floatingIPDB.isEmpty()) { + loadConfiguration(); + } } /** @@ -119,6 +136,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { // In the Global instance case the containerName is empty this.containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -178,16 +196,19 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { // 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 getAllFloatingIPs() { Set allIPs = new HashSet(); for (Entry entry : floatingIPDB.entrySet()) { @@ -200,6 +221,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { return ans; } + @Override public boolean addFloatingIP(NeutronFloatingIP input) { INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this); INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this); @@ -223,6 +245,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { return true; } + @Override public boolean removeFloatingIP(String uuid) { INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this); INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this); @@ -242,6 +265,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { return true; } + @Override public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) { INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this); @@ -263,4 +287,30 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { target.setFixedIPAddress(delta.getFixedIPAddress()); return true; } + + @SuppressWarnings("unchecked") + private void loadConfiguration() { + ObjectReader objReader = new ObjectReader(); + ConcurrentMap confList = (ConcurrentMap) + 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(floatingIPDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java index b1e382107a..de9b9d1bc4 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java @@ -8,6 +8,9 @@ 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; @@ -16,6 +19,7 @@ import java.util.HashSet; 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; @@ -23,13 +27,23 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; 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 networkDB; @@ -85,6 +99,9 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (networkDB.isEmpty()) { + loadConfiguration(); + } } /** @@ -101,6 +118,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { // In the Global instance case the containerName is empty this.containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -170,16 +188,19 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { // 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 getAllNetworks() { Set allNetworks = new HashSet(); for (Entry entry : networkDB.entrySet()) { @@ -192,6 +213,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return ans; } + @Override public boolean addNetwork(NeutronNetwork input) { if (networkExists(input.getID())) return false; @@ -200,6 +222,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return true; } + @Override public boolean removeNetwork(String uuid) { if (!networkExists(uuid)) return false; @@ -208,6 +231,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return true; } + @Override public boolean updateNetwork(String uuid, NeutronNetwork delta) { if (!networkExists(uuid)) return false; @@ -215,6 +239,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return overwrite(target, delta); } + @Override public boolean networkInUse(String netUUID) { if (!networkExists(netUUID)) return true; @@ -223,4 +248,31 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return true; return false; } + + @SuppressWarnings("unchecked") + private void loadConfiguration() { + ObjectReader objReader = new ObjectReader(); + ConcurrentMap confList = (ConcurrentMap) + 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(networkDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java index fd030e178b..ec439bb927 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java @@ -8,6 +8,9 @@ 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; @@ -17,6 +20,7 @@ import java.util.Iterator; 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; @@ -24,6 +28,7 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; 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; @@ -32,11 +37,20 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; 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; @@ -104,6 +118,10 @@ public class NeutronPortInterface implements INeutronPortCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (portDB.isEmpty()) { + loadConfiguration(); + } + } /** @@ -120,6 +138,7 @@ public class NeutronPortInterface implements INeutronPortCRUD { // In the Global instance case the containerName is empty containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -329,4 +348,30 @@ public class NeutronPortInterface implements INeutronPortCRUD { return null; } + @SuppressWarnings("unchecked") + private void loadConfiguration() { + ObjectReader objReader = new ObjectReader(); + ConcurrentMap confList = (ConcurrentMap) + 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(portDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java index 0e64dc5a09..850cc02163 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java @@ -8,6 +8,9 @@ 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; @@ -16,6 +19,7 @@ import java.util.HashSet; 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; @@ -23,13 +27,23 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; 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; @@ -96,6 +110,10 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (routerDB.isEmpty()) { + loadConfiguration(); + } + } /** @@ -112,6 +130,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { // In the Global instance case the containerName is empty this.containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -172,16 +191,19 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { // 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 getAllRouters() { Set allRouters = new HashSet(); for (Entry entry : routerDB.entrySet()) { @@ -194,6 +216,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { return ans; } + @Override public boolean addRouter(NeutronRouter input) { if (routerExists(input.getID())) return false; @@ -201,6 +224,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { return true; } + @Override public boolean removeRouter(String uuid) { if (!routerExists(uuid)) return false; @@ -208,6 +232,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { return true; } + @Override public boolean updateRouter(String uuid, NeutronRouter delta) { if (!routerExists(uuid)) return false; @@ -215,10 +240,38 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { 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 confList = (ConcurrentMap) + 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(routerDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java index 62ef64c74c..f908a95c31 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java @@ -8,6 +8,9 @@ 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; @@ -16,6 +19,7 @@ import java.util.HashSet; 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; @@ -23,16 +27,27 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; 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; @@ -100,6 +115,10 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (subnetDB.isEmpty()) { + loadConfiguration(); + } + } /** @@ -116,6 +135,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { // In the Global instance case the containerName is empty this.containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -176,16 +196,19 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { // 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 getAllSubnets() { Set allSubnets = new HashSet(); for (Entry entry : subnetDB.entrySet()) { @@ -198,6 +221,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { return ans; } + @Override public boolean addSubnet(NeutronSubnet input) { String id = input.getID(); if (subnetExists(id)) @@ -210,6 +234,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { return true; } + @Override public boolean removeSubnet(String uuid) { if (!subnetExists(uuid)) return false; @@ -222,6 +247,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { return true; } + @Override public boolean updateSubnet(String uuid, NeutronSubnet delta) { if (!subnetExists(uuid)) return false; @@ -229,10 +255,38 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { 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 confList = (ConcurrentMap) + 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(subnetDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + } diff --git a/opendaylight/networkconfiguration/neutron/pom.xml b/opendaylight/networkconfiguration/neutron/pom.xml index 588a61653a..b6cdd2512b 100644 --- a/opendaylight/networkconfiguration/neutron/pom.xml +++ b/opendaylight/networkconfiguration/neutron/pom.xml @@ -67,12 +67,12 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT commons-net diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java index 4d029dccf3..9c8c91b284 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.Iterator; import java.util.List; @@ -19,7 +20,9 @@ import javax.xml.bind.annotation.XmlRootElement; @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 diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java index 9d7ba5d58a..1277436e23 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -20,10 +21,12 @@ import javax.xml.bind.annotation.XmlRootElement; @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 diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java index 536fc3fd6e..bcadba202a 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -22,7 +23,9 @@ import javax.xml.bind.annotation.XmlRootElement; @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 diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java index 1ef48bd95b..ed65c5c91b 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java @@ -8,9 +8,11 @@ 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; @@ -19,7 +21,9 @@ import javax.xml.bind.annotation.XmlRootElement; @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") diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java index 5b5e0ce9cc..e2df13b9aa 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java @@ -8,6 +8,8 @@ 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; @@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement; @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 diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java index 07f165dc7e..8583d44531 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java @@ -8,6 +8,8 @@ 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; @@ -16,7 +18,9 @@ import javax.xml.bind.annotation.XmlRootElement; @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 diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java index 1dbe253a58..fbaa63a148 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -23,7 +24,9 @@ import org.apache.commons.net.util.SubnetUtils.SubnetInfo; @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 diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java index 75238c1ad9..07744061e6 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java @@ -8,6 +8,8 @@ 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; @@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement; @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 diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java index 7829ba2199..15ff548a53 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -18,7 +19,9 @@ import javax.xml.bind.annotation.XmlRootElement; @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 @@ -28,7 +31,8 @@ public class NeutronSubnet_IPAllocationPool { @XmlElement(name="end") String poolEnd; - public NeutronSubnet_IPAllocationPool() { } + public NeutronSubnet_IPAllocationPool() { + } public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) { poolStart = lowAddress; diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java index 6fe7c52994..e862a59e8a 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java @@ -8,6 +8,8 @@ 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; @@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement; @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 diff --git a/opendaylight/northbound/bundlescanner/implementation/pom.xml b/opendaylight/northbound/bundlescanner/implementation/pom.xml index baa0755dc9..03cb9c20de 100644 --- a/opendaylight/northbound/bundlescanner/implementation/pom.xml +++ b/opendaylight/northbound/bundlescanner/implementation/pom.xml @@ -67,12 +67,12 @@ org.opendaylight.controller bundlescanner - 0.4.1-SNAPSHOT + ${bundlescanner.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} diff --git a/opendaylight/northbound/commons/pom.xml b/opendaylight/northbound/commons/pom.xml index 8e769a2349..2169f3f3e7 100644 --- a/opendaylight/northbound/commons/pom.xml +++ b/opendaylight/northbound/commons/pom.xml @@ -52,9 +52,10 @@ 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 @@ -71,30 +72,44 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller usermanager - 0.4.1-SNAPSHOT + ${usermanager.version} org.opendaylight.controller bundlescanner - 0.4.1-SNAPSHOT + ${bundlescanner.version} + - org.codehaus.jackson - jackson-core-asl + com.fasterxml.jackson.core + jackson-annotations + - org.codehaus.jackson - jackson-mapper-asl + com.fasterxml.jackson.core + jackson-core + - org.codehaus.jackson - jackson-jaxrs + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + + junit junit @@ -114,10 +129,6 @@ jersey-client ${jersey.version} - - com.sun.jersey - jersey-json - ${jersey.version} - + diff --git a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java index 5e5dee3279..eb43920826 100644 --- a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java +++ b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java @@ -15,7 +15,8 @@ import javax.ws.rs.core.Response; 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 diff --git a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java index e164abaf95..47bb3ffd7c 100644 --- a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java +++ b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java @@ -12,15 +12,14 @@ import java.util.Dictionary; 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; @@ -78,7 +77,7 @@ public class NorthboundApplication extends Application { 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; } diff --git a/opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java b/opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java index 65790ad17c..0a282b9b28 100644 --- a/opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java +++ b/opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java @@ -23,7 +23,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new InternalServerErrorException("Internal Server Exception"); } catch (InternalServerErrorException e) { - Assert.assertTrue(e instanceof InternalServerErrorException); Assert.assertTrue(e.getResponse().getEntity() .equals("Internal Server Exception")); } @@ -34,7 +33,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { 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")); } @@ -45,7 +43,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new NotAcceptableException("Not Acceptable Exception"); } catch (NotAcceptableException e) { - Assert.assertTrue(e instanceof NotAcceptableException); Assert.assertTrue(e.getResponse().getEntity() .equals("Not Acceptable Exception")); } @@ -56,7 +53,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new ResourceConflictException("Resource Conflict Exception"); } catch (ResourceConflictException e) { - Assert.assertTrue(e instanceof ResourceConflictException); Assert.assertTrue(e.getResponse().getEntity() .equals("Resource Conflict Exception")); } @@ -67,7 +63,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new ResourceForbiddenException("Resource Forbidden Exception"); } catch (ResourceForbiddenException e) { - Assert.assertTrue(e instanceof ResourceForbiddenException); Assert.assertTrue(e.getResponse().getEntity() .equals("Resource Forbidden Exception")); } @@ -78,7 +73,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new ResourceGoneException("Resource Gone Exception"); } catch (ResourceGoneException e) { - Assert.assertTrue(e instanceof ResourceGoneException); Assert.assertTrue(e.getResponse().getEntity() .equals("Resource Gone Exception")); } @@ -89,7 +83,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { 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")); } @@ -101,7 +94,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { throw new ServiceUnavailableException( "Service Unavailable Exception"); } catch (ServiceUnavailableException e) { - Assert.assertTrue(e instanceof ServiceUnavailableException); Assert.assertTrue(e.getResponse().getEntity() .equals("Service Unavailable Exception")); } @@ -112,7 +104,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new UnauthorizedException("Unauthorized Exception"); } catch (UnauthorizedException e) { - Assert.assertTrue(e instanceof UnauthorizedException); Assert.assertTrue(e.getResponse().getEntity() .equals("Unauthorized Exception")); } @@ -124,7 +115,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { 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")); } diff --git a/opendaylight/northbound/connectionmanager/pom.xml b/opendaylight/northbound/connectionmanager/pom.xml index 0ddfcdb3e1..8ade6134e6 100644 --- a/opendaylight/northbound/connectionmanager/pom.xml +++ b/opendaylight/northbound/connectionmanager/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -58,7 +58,8 @@ 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 @@ -75,22 +76,22 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller sal.connection - 0.1.1-SNAPSHOT + ${sal.connection.version} org.opendaylight.controller connectionmanager - 0.1.1-SNAPSHOT + ${connectionmanager.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.codehaus.enunciate @@ -100,7 +101,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} diff --git a/opendaylight/northbound/containermanager/pom.xml b/opendaylight/northbound/containermanager/pom.xml index 517f2e76a3..a8b8f2a5d0 100644 --- a/opendaylight/northbound/containermanager/pom.xml +++ b/opendaylight/northbound/containermanager/pom.xml @@ -52,7 +52,8 @@ 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 /controller/nb/v2/containermanager @@ -66,7 +67,7 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -81,7 +82,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.codehaus.enunciate @@ -91,7 +92,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} diff --git a/opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java b/opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java index 10559a2bbd..b9d2200180 100644 --- a/opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java +++ b/opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java @@ -13,7 +13,7 @@ import java.util.HashSet; 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 diff --git a/opendaylight/northbound/controllermanager/pom.xml b/opendaylight/northbound/controllermanager/pom.xml index d1299a2559..5baaeb0dcc 100644 --- a/opendaylight/northbound/controllermanager/pom.xml +++ b/opendaylight/northbound/controllermanager/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -43,6 +43,7 @@ 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, @@ -59,8 +60,9 @@ 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 /controller/nb/v2/controllermanager @@ -75,30 +77,30 @@ org.opendaylight.controller.thirdparty com.sun.jersey.jersey-servlet - 1.18-SNAPSHOT + ${jersey-servlet.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller switchmanager - 0.6.1-SNAPSHOT + ${switchmanager.api.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} @@ -120,7 +122,7 @@ org.opendaylight.controller.thirdparty org.apache.catalina.filters.CorsFilter - 7.0.43-SNAPSHOT + ${corsfilter.version} diff --git a/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java b/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java index c515396212..003f8b3b95 100644 --- a/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java +++ b/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java @@ -29,6 +29,7 @@ import javax.ws.rs.core.UriInfo; 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; @@ -254,6 +255,44 @@ public class ControllerManagerNorthbound { 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; diff --git a/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java b/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java index ac0d039746..1560f96072 100644 --- a/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java +++ b/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java @@ -4,15 +4,14 @@ import java.util.HashMap; 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; /** diff --git a/opendaylight/northbound/flowprogrammer/pom.xml b/opendaylight/northbound/flowprogrammer/pom.xml index 1b81ccb450..565bd5f6aa 100644 --- a/opendaylight/northbound/flowprogrammer/pom.xml +++ b/opendaylight/northbound/flowprogrammer/pom.xml @@ -28,7 +28,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -57,7 +57,8 @@ 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 @@ -74,7 +75,7 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -83,12 +84,12 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + ${forwardingrulesmanager.version} org.opendaylight.controller sal - 0.7.0-SNAPSHOT + ${sal.version} org.codehaus.enunciate @@ -98,7 +99,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} junit diff --git a/opendaylight/northbound/hosttracker/pom.xml b/opendaylight/northbound/hosttracker/pom.xml index 541dfcfe2d..aab519e5f6 100644 --- a/opendaylight/northbound/hosttracker/pom.xml +++ b/opendaylight/northbound/hosttracker/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -59,7 +59,8 @@ 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 /controller/nb/v2/hosttracker @@ -74,7 +75,7 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -88,12 +89,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.codehaus.enunciate diff --git a/opendaylight/northbound/integrationtest/pom.xml b/opendaylight/northbound/integrationtest/pom.xml index 793af2f5d7..d1815bbf8c 100644 --- a/opendaylight/northbound/integrationtest/pom.xml +++ b/opendaylight/northbound/integrationtest/pom.xml @@ -266,26 +266,32 @@ logback-classic ${logback.version} + - org.codehaus.jackson - jackson-mapper-asl - ${jackson.version} + com.fasterxml.jackson.core + jackson-databind + - org.codehaus.jackson - jackson-core-asl - ${jackson.version} + com.fasterxml.jackson.core + jackson-annotations + - org.codehaus.jackson - jackson-jaxrs - ${jackson.version} + com.fasterxml.jackson.core + jackson-core + - org.codehaus.jackson - jackson-xc - ${jackson.version} + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + org.codehaus.jettison jettison @@ -672,11 +678,7 @@ jersey-client ${jersey.version} - - com.sun.jersey - jersey-json - ${jersey.version} - + eclipselink javax.resource diff --git a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java index 602de9a1c6..cabfb0ee5a 100644 --- a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java +++ b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java @@ -15,7 +15,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; - import javax.inject.Inject; import org.apache.commons.codec.binary.Base64; @@ -44,8 +43,8 @@ import org.opendaylight.controller.sal.topology.IListenTopoUpdates; 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; @@ -63,7 +62,7 @@ public class NorthboundIT { 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) { @@ -187,7 +186,6 @@ public class NorthboundIT { System.out.println("HTTP response code: " + response.getStatus()); System.out.println("HTTP response message: " + response.getEntity()); } - return response.getEntity(); } catch (Exception e) { if (debugMsg) { @@ -269,7 +267,7 @@ public class NorthboundIT { @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"; @@ -412,7 +410,7 @@ public class NorthboundIT { @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"; @@ -493,7 +491,7 @@ public class NorthboundIT { @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; @@ -644,7 +642,7 @@ public class NorthboundIT { "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); @@ -835,7 +833,7 @@ public class NorthboundIT { @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"); @@ -863,7 +861,7 @@ public class NorthboundIT { // 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); @@ -974,7 +972,7 @@ public class NorthboundIT { 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(); @@ -1128,14 +1126,14 @@ public class NorthboundIT { } 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; @@ -1391,10 +1389,13 @@ public class NorthboundIT { 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(), @@ -1493,7 +1494,7 @@ public class NorthboundIT { 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()); } } diff --git a/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml b/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml index aa9fea5467..483d993d04 100644 --- a/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml +++ b/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -59,7 +59,8 @@ 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 @@ -76,27 +77,27 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller sal.connection - 0.1.1-SNAPSHOT + ${sal.connection.version} org.opendaylight.controller sal.networkconfiguration - 0.0.2-SNAPSHOT + ${sal.networkconfiguration.version} org.opendaylight.controller connectionmanager - 0.1.1-SNAPSHOT + ${connectionmanager.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.codehaus.enunciate @@ -106,7 +107,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} diff --git a/opendaylight/northbound/networkconfiguration/neutron/pom.xml b/opendaylight/northbound/networkconfiguration/neutron/pom.xml index f8342f935c..d54f2c5b28 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/pom.xml +++ b/opendaylight/northbound/networkconfiguration/neutron/pom.xml @@ -89,17 +89,17 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.opendaylight.controller diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java index d3c262f222..642b3bb197 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java @@ -30,7 +30,6 @@ import org.codehaus.enunciate.jaxrs.StatusCodes; 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; @@ -268,7 +267,7 @@ public class NeutronPortsNorthbound { List bulk = input.getBulk(); Iterator i = bulk.iterator(); HashMap testMap = new HashMap(); - Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null); while (i.hasNext()) { NeutronPort test = i.next(); diff --git a/opendaylight/northbound/staticrouting/pom.xml b/opendaylight/northbound/staticrouting/pom.xml index d169de9f2a..c020e6b2a2 100644 --- a/opendaylight/northbound/staticrouting/pom.xml +++ b/opendaylight/northbound/staticrouting/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -57,7 +57,8 @@ 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 @@ -74,12 +75,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -94,7 +95,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} junit diff --git a/opendaylight/northbound/statistics/pom.xml b/opendaylight/northbound/statistics/pom.xml index 8df02c976b..95410b0d3a 100644 --- a/opendaylight/northbound/statistics/pom.xml +++ b/opendaylight/northbound/statistics/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -65,7 +65,8 @@ 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 @@ -82,22 +83,22 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller statisticsmanager - 0.4.1-SNAPSHOT + ${statisticsmanager.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.codehaus.enunciate diff --git a/opendaylight/northbound/subnets/pom.xml b/opendaylight/northbound/subnets/pom.xml index bdf0b988f8..c7108b2efa 100644 --- a/opendaylight/northbound/subnets/pom.xml +++ b/opendaylight/northbound/subnets/pom.xml @@ -27,22 +27,22 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + ${clustering.services.version} org.opendaylight.controller configuration - 0.4.1-SNAPSHOT + ${configuration.version} org.opendaylight.controller switchmanager - 0.5.1-SNAPSHOT + ${switchmanager.api.version} @@ -72,7 +72,8 @@ 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 @@ -89,12 +90,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -103,7 +104,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.codehaus.enunciate diff --git a/opendaylight/northbound/switchmanager/pom.xml b/opendaylight/northbound/switchmanager/pom.xml index e4447fee2d..a1932f521b 100644 --- a/opendaylight/northbound/switchmanager/pom.xml +++ b/opendaylight/northbound/switchmanager/pom.xml @@ -28,7 +28,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -59,8 +59,8 @@ 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 /controller/nb/v2/switchmanager @@ -75,7 +75,7 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -85,13 +85,13 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} diff --git a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java index 43d3aae57c..00f0d4b054 100644 --- a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java +++ b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java @@ -13,15 +13,15 @@ import java.util.HashMap; 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; diff --git a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java index 58a024c928..51e96c49ea 100644 --- a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java +++ b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java @@ -13,15 +13,15 @@ import java.util.HashMap; 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; diff --git a/opendaylight/northbound/topology/pom.xml b/opendaylight/northbound/topology/pom.xml index 3b3abc3436..4cdfb02d58 100644 --- a/opendaylight/northbound/topology/pom.xml +++ b/opendaylight/northbound/topology/pom.xml @@ -29,7 +29,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -56,14 +56,15 @@ 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 /controller/nb/v2/topology @@ -83,22 +84,22 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller topologymanager - 0.4.1-SNAPSHOT + ${topologymanager.version} junit diff --git a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java index 6614bbe640..1d4a8a66ee 100644 --- a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java +++ b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java @@ -13,7 +13,6 @@ import java.util.HashMap; 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; @@ -21,8 +20,8 @@ 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.Edge; import org.opendaylight.controller.sal.core.Property; diff --git a/opendaylight/northbound/usermanager/pom.xml b/opendaylight/northbound/usermanager/pom.xml index 8a85dbb622..b48d67252e 100644 --- a/opendaylight/northbound/usermanager/pom.xml +++ b/opendaylight/northbound/usermanager/pom.xml @@ -47,7 +47,8 @@ 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 @@ -64,17 +65,17 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller usermanager - 0.4.1-SNAPSHOT + ${usermanager.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.codehaus.enunciate diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java index 8a86d2f256..27a7ae6ffb 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java @@ -748,7 +748,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, IInventoryShim 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 list = new ArrayList(); list.add(stats); return list; @@ -757,7 +757,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, IInventoryShim } 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 list = new ArrayList(); list.add(stats); return list; diff --git a/opendaylight/protocol_plugins/stub/pom.xml b/opendaylight/protocol_plugins/stub/pom.xml index 2457ddeb67..b7d7b05b60 100644 --- a/opendaylight/protocol_plugins/stub/pom.xml +++ b/opendaylight/protocol_plugins/stub/pom.xml @@ -57,7 +57,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/InventoryService.java b/opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/InventoryService.java index ec050fa305..9f2454bbff 100644 --- a/opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/InventoryService.java +++ b/opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/InventoryService.java @@ -65,6 +65,12 @@ public class InventoryService implements IPluginInInventoryService { } } + @Override + public Set getConfiguredNotConnectedNodes() { + // TODO + return null; + } + /** * Function called by the dependency manager when all the required * dependencies are satisfied diff --git a/opendaylight/routing/dijkstra_implementation/pom.xml b/opendaylight/routing/dijkstra_implementation/pom.xml index eeea5d91d7..aa3f625939 100644 --- a/opendaylight/routing/dijkstra_implementation/pom.xml +++ b/opendaylight/routing/dijkstra_implementation/pom.xml @@ -59,7 +59,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java index 969aa630a1..0cd1612808 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java @@ -45,8 +45,8 @@ abstract public class ComponentActivatorAbstractBase implements Logger logger = LoggerFactory .getLogger(ComponentActivatorAbstractBase.class); private DependencyManager dm; - private ConcurrentMap, Component> dbInstances = (ConcurrentMap, Component>) new ConcurrentHashMap, Component>(); - private ConcurrentMap dbGlobalInstances = (ConcurrentMap) new ConcurrentHashMap(); + private ConcurrentMap, Component> dbInstances = new ConcurrentHashMap, Component>(); + private ConcurrentMap dbGlobalInstances = new ConcurrentHashMap(); /** * Method that should be overriden by the derived class for customization @@ -253,6 +253,11 @@ abstract public class ComponentActivatorAbstractBase implements 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); diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/Flow.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/Flow.java index 0df6d4cec4..a823864a67 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/Flow.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/Flow.java @@ -8,17 +8,6 @@ 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; @@ -29,6 +18,16 @@ import org.opendaylight.controller.sal.utils.EtherTypes; 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 */ @@ -305,4 +304,5 @@ public class Flow implements Cloneable, Serializable { } return true; } + } diff --git a/opendaylight/sal/connection/api/pom.xml b/opendaylight/sal/connection/api/pom.xml index d60e7abe70..006334edfe 100644 --- a/opendaylight/sal/connection/api/pom.xml +++ b/opendaylight/sal/connection/api/pom.xml @@ -50,7 +50,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/sal/connection/implementation/pom.xml b/opendaylight/sal/connection/implementation/pom.xml index e171a8de59..4a7e70b836 100644 --- a/opendaylight/sal/connection/implementation/pom.xml +++ b/opendaylight/sal/connection/implementation/pom.xml @@ -58,7 +58,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/sal/networkconfiguration/api/pom.xml b/opendaylight/sal/networkconfiguration/api/pom.xml index 79707cbc57..3c08b439ae 100644 --- a/opendaylight/sal/networkconfiguration/api/pom.xml +++ b/opendaylight/sal/networkconfiguration/api/pom.xml @@ -47,7 +47,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT diff --git a/opendaylight/sal/networkconfiguration/implementation/pom.xml b/opendaylight/sal/networkconfiguration/implementation/pom.xml index 9d7b84ac79..c25ce0fa4f 100644 --- a/opendaylight/sal/networkconfiguration/implementation/pom.xml +++ b/opendaylight/sal/networkconfiguration/implementation/pom.xml @@ -50,7 +50,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/samples/loadbalancer/pom.xml b/opendaylight/samples/loadbalancer/pom.xml index cf7a18ea65..6f951ca2f6 100644 --- a/opendaylight/samples/loadbalancer/pom.xml +++ b/opendaylight/samples/loadbalancer/pom.xml @@ -85,7 +85,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -95,7 +95,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java b/opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java index 45d041c3e1..4fd3f4a32d 100644 --- a/opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java +++ b/opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java @@ -29,7 +29,6 @@ public class LoadBalancerTest extends TestCase { public void testRoundRobinPolicy() { ConfigManager cm = null; cm = new ConfigManager(); - Assert.assertFalse(cm== null); Pool pool = cm.createPool("TestPool","roundrobin"); VIP vip = cm.createVIP("TestVIP","10.0.0.9","TCP",(short)5550,"TestPool"); diff --git a/opendaylight/samples/northbound/loadbalancer/pom.xml b/opendaylight/samples/northbound/loadbalancer/pom.xml index 543aa8ca54..3b054b6339 100644 --- a/opendaylight/samples/northbound/loadbalancer/pom.xml +++ b/opendaylight/samples/northbound/loadbalancer/pom.xml @@ -28,7 +28,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT @@ -59,7 +59,8 @@ 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 /one/nb/v2/lb @@ -89,7 +90,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/samples/simpleforwarding/pom.xml b/opendaylight/samples/simpleforwarding/pom.xml index edd146e615..a4bb76d5ab 100644 --- a/opendaylight/samples/simpleforwarding/pom.xml +++ b/opendaylight/samples/simpleforwarding/pom.xml @@ -68,12 +68,12 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller hosttracker - 0.4.1-SNAPSHOT + 0.5.1-SNAPSHOT org.opendaylight.controller @@ -86,7 +86,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT diff --git a/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java b/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java index a34cbb5db8..7a3625a229 100644 --- a/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java +++ b/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java @@ -800,8 +800,7 @@ public class SimpleForwardingImpl implements IfNewHostNotify, log.debug("Host Facing Port in a container came up, install the rules for all hosts from this port !"); Set 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, diff --git a/opendaylight/security/pom.xml b/opendaylight/security/pom.xml index 2e7466daf0..ef45e76833 100644 --- a/opendaylight/security/pom.xml +++ b/opendaylight/security/pom.xml @@ -58,7 +58,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT orbit diff --git a/opendaylight/statisticsmanager/api/pom.xml b/opendaylight/statisticsmanager/api/pom.xml index 0dca7396e7..3a1367901b 100644 --- a/opendaylight/statisticsmanager/api/pom.xml +++ b/opendaylight/statisticsmanager/api/pom.xml @@ -47,7 +47,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller @@ -57,12 +57,12 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT diff --git a/opendaylight/statisticsmanager/implementation/pom.xml b/opendaylight/statisticsmanager/implementation/pom.xml index 54ba4865b2..c69e752549 100644 --- a/opendaylight/statisticsmanager/implementation/pom.xml +++ b/opendaylight/statisticsmanager/implementation/pom.xml @@ -100,7 +100,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller @@ -110,12 +110,12 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/statisticsmanager/integrationtest/pom.xml b/opendaylight/statisticsmanager/integrationtest/pom.xml index d04371461f..026811f75b 100644 --- a/opendaylight/statisticsmanager/integrationtest/pom.xml +++ b/opendaylight/statisticsmanager/integrationtest/pom.xml @@ -45,7 +45,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/switchmanager/api/pom.xml b/opendaylight/switchmanager/api/pom.xml index b9cac8f2f8..a4e96dd6a0 100644 --- a/opendaylight/switchmanager/api/pom.xml +++ b/opendaylight/switchmanager/api/pom.xml @@ -92,7 +92,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -102,7 +102,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/Subnet.java b/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/Subnet.java index 16c09fe3f6..56df8e26bd 100644 --- a/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/Subnet.java +++ b/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/Subnet.java @@ -161,15 +161,11 @@ public class Subnet implements Cloneable, Serializable { } 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() { @@ -248,17 +244,7 @@ public class Subnet implements Cloneable, Serializable { } 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())); } /** diff --git a/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SubnetConfig.java b/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SubnetConfig.java index 189476a5d1..4f06b79f49 100644 --- a/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SubnetConfig.java +++ b/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SubnetConfig.java @@ -1,4 +1,3 @@ - /* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * @@ -35,8 +34,8 @@ import org.opendaylight.controller.sal.utils.StatusCode; @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 @@ -44,14 +43,13 @@ public class SubnetConfig implements Cloneable, Serializable { @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 nodeConnectors; @@ -68,7 +66,8 @@ public class SubnetConfig implements Cloneable, Serializable { public SubnetConfig(SubnetConfig subnetConfig) { name = subnetConfig.name; subnet = subnetConfig.subnet; - nodeConnectors = (subnetConfig.nodeConnectors == null) ? null : new ArrayList(subnetConfig.nodeConnectors); + nodeConnectors = (subnetConfig.nodeConnectors == null) ? null : new ArrayList( + subnetConfig.nodeConnectors); } public String getName() { @@ -96,22 +95,43 @@ public class SubnetConfig implements Cloneable, Serializable { 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); } @@ -158,7 +178,8 @@ public class SubnetConfig implements Cloneable, Serializable { } 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()); } @@ -180,8 +201,7 @@ public class SubnetConfig implements Cloneable, Serializable { @Override public String toString() { - return ("SubnetConfig [Name=" + name + ", Subnet=" + subnet - + ", NodeConnectors=" + nodeConnectors + "]"); + return ("SubnetConfig [Name=" + name + ", Subnet=" + subnet + ", NodeConnectors=" + nodeConnectors + "]"); } /** diff --git a/opendaylight/switchmanager/api/src/test/java/org/opendaylight/controller/switchmanager/SubnetTest.java b/opendaylight/switchmanager/api/src/test/java/org/opendaylight/controller/switchmanager/SubnetTest.java index 41a1f1ab06..8b6a149917 100644 --- a/opendaylight/switchmanager/api/src/test/java/org/opendaylight/controller/switchmanager/SubnetTest.java +++ b/opendaylight/switchmanager/api/src/test/java/org/opendaylight/controller/switchmanager/SubnetTest.java @@ -8,8 +8,13 @@ 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; @@ -26,19 +31,19 @@ public class SubnetTest { 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 ncSet = new HashSet(); Node node = NodeCreator.createOFNode(((long) 10)); @@ -53,10 +58,10 @@ public class SubnetTest { 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 resultncSet = subnet.getNodeConnectors(); Assert.assertEquals(resultncSet, ncSet); @@ -69,24 +74,61 @@ public class SubnetTest { Set ncSet2 = new HashSet(); 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)); } + + } diff --git a/opendaylight/switchmanager/implementation/pom.xml b/opendaylight/switchmanager/implementation/pom.xml index 76bfd56c29..93c076dcba 100644 --- a/opendaylight/switchmanager/implementation/pom.xml +++ b/opendaylight/switchmanager/implementation/pom.xml @@ -97,7 +97,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -117,7 +117,7 @@ org.opendaylight.controller statisticsmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT junit diff --git a/opendaylight/topologymanager/implementation/pom.xml b/opendaylight/topologymanager/implementation/pom.xml index a91e7275ba..10b1a7243b 100644 --- a/opendaylight/topologymanager/implementation/pom.xml +++ b/opendaylight/topologymanager/implementation/pom.xml @@ -61,12 +61,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java b/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java index 97966255a0..fa01fa6a60 100644 --- a/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java +++ b/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java @@ -35,10 +35,10 @@ import org.opendaylight.controller.sal.core.State; 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; @@ -55,7 +55,7 @@ public class TopologyManagerImplTest { private final class TestSwitchManager implements ISwitchManager { private final Set nodeSet = new HashSet(); private final Set nodeConnectorSet = - new HashSet(); + new HashSet(); private void addNodeConnectors(NodeConnector ... connectors) { for (NodeConnector nc: connectors) { @@ -69,9 +69,9 @@ public class TopologyManagerImplTest { 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); } } @@ -292,6 +292,35 @@ public class TopologyManagerImplTest { public String getNodeDescription(Node node) { return null; } + + @Override + public Status removeControllerProperty(String propertyName){ + return null; + } + + @Override + public Set getConfiguredNotConnectedSwitches() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map 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; + } } /* @@ -485,13 +514,13 @@ public class TopologyManagerImplTest { 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 @@ -559,7 +588,7 @@ public class TopologyManagerImplTest { 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()); } diff --git a/opendaylight/topologymanager/integrationtest/pom.xml b/opendaylight/topologymanager/integrationtest/pom.xml index 5dfa1632f7..93e8dcc89f 100644 --- a/opendaylight/topologymanager/integrationtest/pom.xml +++ b/opendaylight/topologymanager/integrationtest/pom.xml @@ -32,52 +32,52 @@ org.opendaylight.controller sal - 0.5.0-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller sal.implementation - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT org.opendaylight.controller containermanager - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT org.opendaylight.controller containermanager.it.implementation - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT org.opendaylight.controller forwardingrulesmanager - 0.4.0-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller clustering.services - 0.4.0-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller clustering.stub - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT org.opendaylight.controller statisticsmanager - 0.4.0-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller statisticsmanager.implementation - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT org.opendaylight.controller switchmanager.implementation - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT org.opendaylight.controller @@ -87,12 +87,12 @@ org.opendaylight.controller configuration - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT org.opendaylight.controller configuration.implementation - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT org.opendaylight.controller @@ -102,7 +102,7 @@ org.opendaylight.controller topologymanager - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT diff --git a/opendaylight/usermanager/api/pom.xml b/opendaylight/usermanager/api/pom.xml index 5d9e6c70ce..f7064a3c6d 100644 --- a/opendaylight/usermanager/api/pom.xml +++ b/opendaylight/usermanager/api/pom.xml @@ -76,7 +76,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -86,7 +86,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT junit diff --git a/opendaylight/usermanager/implementation/pom.xml b/opendaylight/usermanager/implementation/pom.xml index dcdc2f6d50..dbf71fec68 100644 --- a/opendaylight/usermanager/implementation/pom.xml +++ b/opendaylight/usermanager/implementation/pom.xml @@ -79,7 +79,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -89,7 +89,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.springframework.security diff --git a/opendaylight/web/devices/pom.xml b/opendaylight/web/devices/pom.xml index d66381f6ce..82abfbadb0 100644 --- a/opendaylight/web/devices/pom.xml +++ b/opendaylight/web/devices/pom.xml @@ -66,10 +66,8 @@ 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, @@ -95,7 +93,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -114,7 +112,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller @@ -126,9 +124,10 @@ forwarding.staticrouting ${forwarding.staticrouting} + - org.codehaus.jackson - jackson-mapper-asl + com.fasterxml.jackson.core + jackson-databind diff --git a/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java b/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java index 3d33edcbf2..a118ccfbba 100644 --- a/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java +++ b/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java @@ -23,7 +23,7 @@ import java.util.concurrent.ConcurrentMap; 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; diff --git a/opendaylight/web/devices/src/main/resources/js/page.js b/opendaylight/web/devices/src/main/resources/js/page.js index cc142bf967..855dc90aa9 100644 --- a/opendaylight/web/devices/src/main/resources/js/page.js +++ b/opendaylight/web/devices/src/main/resources/js/page.js @@ -37,11 +37,11 @@ one.f.dashlet = { 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 : { @@ -1361,7 +1361,7 @@ one.f.switchmanager.spanPortConfig = { $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); diff --git a/opendaylight/web/flows/pom.xml b/opendaylight/web/flows/pom.xml index f0393c19cb..5812c0e861 100644 --- a/opendaylight/web/flows/pom.xml +++ b/opendaylight/web/flows/pom.xml @@ -63,10 +63,9 @@ 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, @@ -92,7 +91,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -111,7 +110,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/web/flows/src/main/resources/js/page.js b/opendaylight/web/flows/src/main/resources/js/page.js index 6b4cfa0025..094562fac0 100644 --- a/opendaylight/web/flows/src/main/resources/js/page.js +++ b/opendaylight/web/flows/src/main/resources/js/page.js @@ -390,8 +390,8 @@ one.f.flows = { $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 { diff --git a/opendaylight/web/root/pom.xml b/opendaylight/web/root/pom.xml index 85388d9b05..1a801a2fe4 100644 --- a/opendaylight/web/root/pom.xml +++ b/opendaylight/web/root/pom.xml @@ -61,10 +61,9 @@ 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, @@ -98,7 +97,7 @@ org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -113,7 +112,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java index 1d4211a926..ca37f4b7c1 100644 --- a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java +++ b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java @@ -8,8 +8,10 @@ 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; @@ -28,6 +30,7 @@ import org.opendaylight.controller.sal.utils.StatusCode; 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; @@ -52,6 +55,23 @@ public class DaylightWeb { 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> bundles(HttpServletRequest request) { diff --git a/opendaylight/web/root/src/main/resources/WEB-INF/web.xml b/opendaylight/web/root/src/main/resources/WEB-INF/web.xml index 89812af53d..072f08f581 100644 --- a/opendaylight/web/root/src/main/resources/WEB-INF/web.xml +++ b/opendaylight/web/root/src/main/resources/WEB-INF/web.xml @@ -46,6 +46,7 @@ /images/* /css/* /favicon.ico + /versionProperty/* diff --git a/opendaylight/web/topology/pom.xml b/opendaylight/web/topology/pom.xml index 226dcc87b7..358ea21ad9 100644 --- a/opendaylight/web/topology/pom.xml +++ b/opendaylight/web/topology/pom.xml @@ -66,10 +66,9 @@ 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, @@ -110,7 +109,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller diff --git a/opendaylight/web/troubleshoot/pom.xml b/opendaylight/web/troubleshoot/pom.xml index bb5e9f1f18..033cc6d9e9 100644 --- a/opendaylight/web/troubleshoot/pom.xml +++ b/opendaylight/web/troubleshoot/pom.xml @@ -65,10 +65,9 @@ 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, @@ -94,7 +93,7 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller @@ -108,21 +107,22 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + 0.7.0-SNAPSHOT org.opendaylight.controller statisticsmanager - 0.4.1-SNAPSHOT + 0.5.0-SNAPSHOT org.opendaylight.controller web 0.4.1-SNAPSHOT - - org.codehaus.jackson - jackson-mapper-asl - + + + com.fasterxml.jackson.core + jackson-databind +