From: Ed Warnicke Date: Sat, 18 Jan 2014 18:32:37 +0000 (+0000) Subject: Merge "Switch to using yangtools version of mockito-configuration" X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~60 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=7bea173bf1c3c27d5fa366b25a0f83879105c56d;hp=787e73665b11cd1040a1fb078c7a08d8edfa246b Merge "Switch to using yangtools version of mockito-configuration" --- 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 da54a8341a..f27d123995 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 @@ -140,8 +140,7 @@ public class ValidationException extends RuntimeException { @Override public String toString() { - return "ExceptionMessageWithStackTrace [message=" + message - + ", stackTrace=" + stackTrace + "]"; + return message; } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java index ec1a290cd2..b973b92721 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java @@ -38,7 +38,7 @@ public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer< return null; } - private synchronized void blankTransaction() { + synchronized void blankTransaction() { // race condition check: config-persister might push new configuration while server is starting up. ConflictingVersionException lastException = null; for (int i = 0; i < 10; i++) { diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java index 1ee6cca7e2..be602e5b2a 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java @@ -46,11 +46,11 @@ public class ConfigManagerActivator implements BundleActivator { configRegistryJMXRegistrator.registerToJMX(configRegistry); // track bundles containing factories - extenderBundleTracker = new ExtenderBundleTracker(context); + BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker(configRegistry); + extenderBundleTracker = new ExtenderBundleTracker(context, blankTransactionServiceTracker); extenderBundleTracker.open(); - BlankTransactionServiceTracker customizer = new BlankTransactionServiceTracker(configRegistry); - ServiceTracker serviceTracker = new ServiceTracker(context, ModuleFactory.class, customizer); + ServiceTracker serviceTracker = new ServiceTracker(context, ModuleFactory.class, blankTransactionServiceTracker); serviceTracker.open(); } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java index 6663cddacf..b55f3135d2 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java @@ -34,11 +34,12 @@ import org.slf4j.LoggerFactory; * Code based on http://www.toedter.com/blog/?p=236 */ public class ExtenderBundleTracker extends BundleTracker { - + private final BlankTransactionServiceTracker blankTransactionServiceTracker; private static final Logger logger = LoggerFactory.getLogger(ExtenderBundleTracker.class); - public ExtenderBundleTracker(BundleContext context) { + public ExtenderBundleTracker(BundleContext context, BlankTransactionServiceTracker blankTransactionServiceTracker) { super(context, Bundle.ACTIVE, null); + this.blankTransactionServiceTracker = blankTransactionServiceTracker; logger.trace("Registered as extender with context {}", context); } @@ -64,6 +65,8 @@ public class ExtenderBundleTracker extends BundleTracker { @Override public void removedBundle(Bundle bundle, BundleEvent event, Object object) { super.removedBundle(bundle,event,object); + // workaround for service tracker not getting removed service event + blankTransactionServiceTracker.blankTransaction(); } // TODO:test 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 72bd208ff3..3ae29062ed 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 @@ -25,15 +25,18 @@ import static org.junit.Assert.fail; public class DirectoryStorageAdapterTest { Persister tested; + private Persister instantiatePersisterFromAdapter(File file){ + PropertiesProviderTest pp = new PropertiesProviderTest(); + pp.addProperty("directoryStorage",file.getPath()); + DirectoryStorageAdapter dsa = new DirectoryStorageAdapter(); + return dsa.instantiate(pp); + } @Test public void testEmptyDirectory() throws Exception { File folder = new File("target/emptyFolder"); folder.mkdir(); - PropertiesProviderTest pp = new PropertiesProviderTest(); - pp.addProperty("directoryStorage",folder.getPath()); - DirectoryStorageAdapter dsa = new DirectoryStorageAdapter(); - tested = dsa.instantiate(pp); + tested = instantiatePersisterFromAdapter(folder); assertEquals(Collections.emptyList(), tested.loadLastConfigs()); try { @@ -64,10 +67,8 @@ public class DirectoryStorageAdapterTest { @Test public void testOneFile() throws Exception { File folder = getFolder("oneFile"); - PropertiesProviderTest pp = new PropertiesProviderTest(); - pp.addProperty("directoryStorage",folder.getPath()); - DirectoryStorageAdapter dsa = new DirectoryStorageAdapter(); - tested = dsa.instantiate(pp); + + tested = instantiatePersisterFromAdapter(folder); List results = tested.loadLastConfigs(); assertEquals(1, results.size()); @@ -79,10 +80,7 @@ public class DirectoryStorageAdapterTest { @Test public void testTwoFiles() throws Exception { File folder = getFolder("twoFiles"); - PropertiesProviderTest pp = new PropertiesProviderTest(); - pp.addProperty("directoryStorage",folder.getPath()); - DirectoryStorageAdapter dsa = new DirectoryStorageAdapter(); - tested = dsa.instantiate(pp); + tested = instantiatePersisterFromAdapter(folder); List results = tested.loadLastConfigs(); assertEquals(2, results.size()); diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml b/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml index aaf60dd2c8..c94f63355c 100644 --- a/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml @@ -52,6 +52,12 @@ org.opendaylight.yangtools mockito-configuration + + ${project.groupId} + config-persister-api + test-jar + test + 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 index f262952281..2028d62bd0 100644 --- 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 @@ -67,6 +67,8 @@ public class AutodetectDirectoryPersister implements Persister { private ConfigSnapshotHolder loadLastConfig(File file, FileType fileType) throws IOException { switch (fileType) { case plaintext: + logger.warn("Plaintext configuration files are deprecated, and will not be supported in future versions. " + + "Use xml files instead"); return DirectoryPersister.loadLastConfig(file); case xml: try { 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 index 7e423914c2..f833460766 100644 --- 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 @@ -7,21 +7,26 @@ */ package org.opendaylight.controller.config.persist.storage.directory.autodetect; +import java.io.File; +import java.util.List; 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; +import org.opendaylight.controller.config.persist.test.PropertiesProviderTest; public class AutodetectDirectoryPersisterTest { @Test public void testCombined() throws Exception { File resourcePath = FileTypeTest.getResourceAsFile("/combined/1controller.txt.config"); + File parentFile = resourcePath.getParentFile(); + + AutodetectDirectoryStorageAdapter adapter = new AutodetectDirectoryStorageAdapter(); - AutodetectDirectoryPersister persister = new AutodetectDirectoryPersister(resourcePath.getParentFile()); + PropertiesProviderTest pp = new PropertiesProviderTest(); + pp.addProperty("directoryStorage",parentFile.getPath()); + AutodetectDirectoryPersister persister = (AutodetectDirectoryPersister) adapter.instantiate(pp); List configs = persister.loadLastConfigs(); Assert.assertEquals(2, configs.size()); @@ -32,6 +37,5 @@ public class AutodetectDirectoryPersisterTest { String snapFromXml = configs.get(1).getConfigSnapshot(); org.junit.Assert.assertThat(snapFromXml, JUnitMatchers.containsString("xml")); - Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities()); - } + Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities()); } } 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 825eb946c8..8e34bc7990 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 @@ -14,6 +14,8 @@ import java.util.List; import java.util.SortedSet; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.junit.Assert.assertEquals; @@ -21,14 +23,22 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class DirectoryStorageAdapterTest { - XmlDirectoryPersister tested; + Persister tested; Logger logger = LoggerFactory.getLogger(DirectoryStorageAdapterTest.class.toString()); + private Persister instantiatePersisterFromAdapter(File file){ + PropertiesProviderTest pp = new PropertiesProviderTest(); + pp.addProperty("directoryStorage",file.getPath()); + XmlDirectoryStorageAdapter dsa = new XmlDirectoryStorageAdapter(); + return dsa.instantiate(pp); + } + @Test public void testEmptyDirectory() throws Exception { File folder = new File("target/emptyFolder"); folder.mkdir(); - tested = new XmlDirectoryPersister((folder)); + + tested = instantiatePersisterFromAdapter(folder); assertEquals(Collections.emptyList(), tested.loadLastConfigs()); try { @@ -59,7 +69,8 @@ public class DirectoryStorageAdapterTest { @Test public void testOneFile() throws Exception { File folder = getFolder("oneFile"); - tested = new XmlDirectoryPersister(folder); + tested = instantiatePersisterFromAdapter(folder); + logger.info("Testing : "+tested.toString()); List results = tested.loadLastConfigs(); assertEquals(1, results.size()); @@ -78,7 +89,7 @@ public class DirectoryStorageAdapterTest { @Test public void testTwoFiles() throws Exception { File folder = getFolder("twoFiles"); - tested = new XmlDirectoryPersister((folder)); + tested = instantiatePersisterFromAdapter(folder); logger.info("Testing : "+tested.toString()); List results = tested.loadLastConfigs(); assertEquals(2, results.size()); 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 cfc70858c3..d13052a7e2 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 @@ -13,6 +13,7 @@ import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.util.SortedSet; @XmlRootElement(name = ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME) @@ -46,6 +47,7 @@ public class ConfigSnapshot { @XmlElement(name = "capability") @XmlElementWrapper(name = "required-capabilities") + @XmlJavaTypeAdapter(value=StringTrimAdapter.class) public SortedSet getCapabilities() { return capabilities; } @@ -62,4 +64,6 @@ public class ConfigSnapshot { sb.append('}'); return sb.toString(); } + } + diff --git a/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/StringTrimAdapter.java b/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/StringTrimAdapter.java new file mode 100644 index 0000000000..3c544d4e49 --- /dev/null +++ b/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/StringTrimAdapter.java @@ -0,0 +1,26 @@ +/* + * 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.file.xml.model; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +final class StringTrimAdapter extends XmlAdapter { + @Override + public String unmarshal(String v) throws Exception { + if (v == null) + return null; + return v.trim(); + } + + @Override + public String marshal(String v) throws Exception { + if (v == null) + return null; + return v.trim(); + } +} 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 index 104241757f..5cbe4931ef 100644 --- 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 @@ -17,5 +17,5 @@ public interface ShutdownService { * @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); + void shutdown(String inputSecret, Long maxWaitTime, Optional reason); } 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 index f6937f9ef1..d58ebf2895 100644 --- 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 @@ -16,13 +16,11 @@ 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, @@ -30,7 +28,6 @@ public final class ShutdownModule extends AbstractShutdownModule { super(identifier, null, oldModule, oldInstance); singletonCheck(identifier); this.systemBundle = systemBundle; - this.nullableOldModule = oldModule; } private static void singletonCheck(ModuleIdentifier identifier) { @@ -52,40 +49,13 @@ public final class ShutdownModule extends AbstractShutdownModule { 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()); + return new ShutdownServiceImpl(getSecret(), 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 index 637395bc48..0517fafd56 100644 --- 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 @@ -10,28 +10,15 @@ package org.opendaylight.controller.config.yang.shutdown.impl; import org.opendaylight.controller.config.api.DependencyResolver; +import org.opendaylight.controller.config.api.DependencyResolverFactory; 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; - } +import java.util.Arrays; +import java.util.Set; +public class ShutdownModuleFactory extends AbstractShutdownModuleFactory { public ShutdownModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, ShutdownModule oldModule, AutoCloseable oldInstance, @@ -46,4 +33,12 @@ public class ShutdownModuleFactory extends AbstractShutdownModuleFactory { Bundle systemBundle = bundleContext.getBundle(0); return new ShutdownModule(new ModuleIdentifier(NAME, instanceName), systemBundle); } + + @Override + public Set getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) { + ModuleIdentifier id = new ModuleIdentifier(NAME, NAME); + DependencyResolver dependencyResolver = dependencyResolverFactory.createDependencyResolver(id); + ShutdownModule shutdownModule = instantiateModule(NAME, dependencyResolver, bundleContext); + return new java.util.HashSet<>(Arrays.asList(shutdownModule)); + } } 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 index e5b95c812b..6cdcf605b0 100644 --- 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 @@ -14,6 +14,9 @@ import org.osgi.framework.BundleException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; + public class ShutdownServiceImpl implements ShutdownService, AutoCloseable { private final ShutdownService impl; private final ShutdownRuntimeRegistration registration; @@ -28,8 +31,8 @@ public class ShutdownServiceImpl implements ShutdownService, AutoCloseable { } @Override - public void shutdown(String inputSecret, Optional reason) { - impl.shutdown(inputSecret, reason); + public void shutdown(String inputSecret, Long maxWaitTime, Optional reason) { + impl.shutdown(inputSecret, maxWaitTime, reason); } @Override @@ -49,7 +52,7 @@ class Impl implements ShutdownService { } @Override - public void shutdown(String inputSecret, Optional reason) { + public void shutdown(String inputSecret, Long maxWaitTime, Optional reason) { logger.warn("Shutdown issued with secret {} and reason {}", inputSecret, reason); try { Thread.sleep(1000); // prevent brute force attack @@ -60,22 +63,15 @@ class Impl implements ShutdownService { 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(); - + // actual work: + Thread stopSystemBundleThread = new StopSystemBundleThread(systemBundle); + stopSystemBundleThread.start(); + if (maxWaitTime != null && maxWaitTime > 0) { + Thread systemExitThread = new CallSystemExitThread(maxWaitTime); + logger.debug("Scheduling {}", systemExitThread); + systemExitThread.start(); + } + // end } else { logger.warn("Unauthorized attempt to shut down server"); throw new IllegalArgumentException("Invalid secret"); @@ -84,6 +80,70 @@ class Impl implements ShutdownService { } +class StopSystemBundleThread extends Thread { + private static final Logger logger = LoggerFactory.getLogger(StopSystemBundleThread.class); + private final Bundle systemBundle; + + StopSystemBundleThread(Bundle systemBundle) { + super("stop-system-bundle"); + this.systemBundle = systemBundle; + } + + @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); + } + } +} + +class CallSystemExitThread extends Thread { + private static final Logger logger = LoggerFactory.getLogger(CallSystemExitThread.class); + private final long maxWaitTime; + CallSystemExitThread(long maxWaitTime) { + super("call-system-exit-daemon"); + setDaemon(true); + if (maxWaitTime <= 0){ + throw new IllegalArgumentException("Cannot schedule to zero or negative time:" + maxWaitTime); + } + this.maxWaitTime = maxWaitTime; + } + + @Override + public String toString() { + return "CallSystemExitThread{" + + "maxWaitTime=" + maxWaitTime + + '}'; + } + + @Override + public void run() { + try { + // wait specified time + Thread.sleep(maxWaitTime); + logger.error("Since some threads are still running, server is going to shut down via System.exit(1) !"); + // do a thread dump + ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); + StringBuffer sb = new StringBuffer(); + for(ThreadInfo info : threads) { + sb.append(info); + sb.append("\n"); + } + logger.warn("Thread dump:{}", sb); + System.exit(1); + } catch (InterruptedException e) { + logger.info("Interrupted, not going to call System.exit(1)"); + } + } +} + + class MXBeanImpl implements ShutdownRuntimeMXBean { private final ShutdownService impl; @@ -92,13 +152,13 @@ class MXBeanImpl implements ShutdownRuntimeMXBean { } @Override - public void shutdown(String inputSecret, String nullableReason) { + public void shutdown(String inputSecret, Long maxWaitTime, String nullableReason) { Optional optionalReason; if (nullableReason == null) { optionalReason = Optional.absent(); } else { optionalReason = Optional.of(nullableReason); } - impl.shutdown(inputSecret, optionalReason); + impl.shutdown(inputSecret, maxWaitTime, 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 index 78b44abfb2..883735c0c8 100644 --- a/opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang +++ b/opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang @@ -37,10 +37,6 @@ module shutdown-impl { type string; default ""; } - leaf old-secret { - type string; - default ""; - } } } @@ -63,6 +59,10 @@ module shutdown-impl { leaf input-secret { type string; } + leaf max-wait-time { + type uint32; + description "Maximum time in milliseconds before process is forcibly exited. Zero or null cancels this functionality."; + } 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 index 86cd6fa812..5887e98f30 100644 --- 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 @@ -11,8 +11,6 @@ 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; @@ -23,11 +21,8 @@ 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; @@ -49,6 +44,9 @@ public class ShutdownTest extends AbstractConfigTest { doReturn(mockedSysBundle).when(mockedContext).getBundle(0); mockedContext.getBundle(0); doNothing().when(mockedSysBundle).stop(); + ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); + // initialize default instance + transaction.commit(); } @Test @@ -62,21 +60,20 @@ public class ShutdownTest extends AbstractConfigTest { } } + private static final ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.emptyMap()); + @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); + runtime.shutdown("foo", 60000L, null); fail(); } catch (IllegalArgumentException e) { assertEquals("Invalid secret", e.getMessage()); } - runtime.shutdown("", null); + runtime.shutdown("", 60000L, null); assertStopped(); } @@ -84,57 +81,31 @@ public class ShutdownTest extends AbstractConfigTest { @Test public void testWithSecret() throws Exception { ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); - ObjectName on = transaction.createModule(NAME, NAME); + ObjectName on = transaction.lookupConfigBean(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(); + ShutdownRuntimeMXBean runtime = JMX.newMXBeanProxy(platformMBeanServer, runtimeON, ShutdownRuntimeMXBean.class); + runtime.shutdown("foo", 60000L, null); 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()); - + } catch (IllegalArgumentException e) { + assertEquals("Invalid secret", e.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); + runtime.shutdown("", 60000L, null); fail(); } catch (IllegalArgumentException e) { assertEquals("Invalid secret", e.getMessage()); } - runtime.shutdown(secret, null); + runtime.shutdown(secret, 60000L, null); assertStopped(); } diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 5acdec834d..a8dd607f44 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -1462,6 +1462,16 @@ + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle.version} + + **\/target\/,**\/bin\/,**\/target-ide\/,**\/configuration\/initial\/ + + 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 similarity index 100% rename from opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf rename to opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml 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 similarity index 100% rename from opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf rename to opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml diff --git a/opendaylight/distribution/opendaylight/src/main/resources/run.sh b/opendaylight/distribution/opendaylight/src/main/resources/run.sh index ffe53afd4d..1f3e8e20f3 100755 --- a/opendaylight/distribution/opendaylight/src/main/resources/run.sh +++ b/opendaylight/distribution/opendaylight/src/main/resources/run.sh @@ -21,15 +21,15 @@ if [[ $platform == 'linux' ]]; then fi elif [[ $platform == 'osx' ]]; then TARGET_FILE=$0 - cd `dirname $TARGET_FILE` + cd `dirname "$TARGET_FILE"` TARGET_FILE=`basename $TARGET_FILE` # Iterate down a (possible) chain of symlinks while [ -L "$TARGET_FILE" ] do - TARGET_FILE=`readlink $TARGET_FILE` - cd `dirname $TARGET_FILE` - TARGET_FILE=`basename $TARGET_FILE` + TARGET_FILE=`readlink "$TARGET_FILE"` + cd `dirname "$TARGET_FILE"` + TARGET_FILE=`basename "$TARGET_FILE"` done # Compute the canonicalized name by finding the physical path @@ -47,13 +47,13 @@ fi JVM at path ${JAVA_HOME}/bin/java check your JAVA_HOME" && exit -1; if [ -z ${ODL_BASEDIR} ]; then - basedir=`dirname ${fullpath}` + basedir=`dirname "${fullpath}"` else basedir=${ODL_BASEDIR} fi if [ -z ${ODL_DATADIR} ]; then - datadir=`dirname ${fullpath}` + datadir=`dirname "${fullpath}"` else datadir=${ODL_DATADIR} fi @@ -145,8 +145,8 @@ fi ######################################## # Now add to classpath the OSGi JAR ######################################## -CLASSPATH=${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar -FWCLASSPATH=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar +CLASSPATH="${basedir}"/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar +FWCLASSPATH=file:"${basedir}"/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar ######################################## # Now add the extensions @@ -198,19 +198,24 @@ if [ "${statusdaemon}" -eq 1 ]; then fi fi +iotmpdir=`echo "${datadir}" | sed 's/ /\\ /g'` +bdir=`echo "${basedir}" | sed 's/ /\\ /g'` +confarea=`echo "${datadir}" | sed 's/ /\\ /g'` +fwclasspath=`echo "${FWCLASSPATH}" | sed 's/ /\\ /g'` + if [ "${startdaemon}" -eq 1 ]; then if [ -e "${pidfile}" ]; then echo "Another instance of controller running, check with $0 -status" exit -1 fi $JAVA_HOME/bin/java ${extraJVMOpts} \ - -Djava.io.tmpdir=${datadir}/work/tmp \ - -Dosgi.install.area=${basedir} \ - -Dosgi.configuration.area=${datadir}/configuration \ - -Dosgi.frameworkClassPath=${FWCLASSPATH} \ - -Dosgi.framework=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar \ + -Djava.io.tmpdir="${iotmpdir}/work/tmp" \ + -Dosgi.install.area="${bdir}" \ + -Dosgi.configuration.area="${confarea}/configuration" \ + -Dosgi.frameworkClassPath="${fwclasspath}" \ + -Dosgi.framework=file:"${bdir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar" \ -Djava.awt.headless=true \ - -classpath ${CLASSPATH} \ + -classpath "${CLASSPATH}" \ org.eclipse.equinox.launcher.Main \ -console ${daemonport} \ -consoleLog & @@ -222,13 +227,13 @@ elif [ "${consolestart}" -eq 1 ]; then exit -1 fi $JAVA_HOME/bin/java ${extraJVMOpts} \ - -Djava.io.tmpdir=${datadir}/work/tmp \ - -Dosgi.install.area=${basedir} \ - -Dosgi.configuration.area=${datadir}/configuration \ - -Dosgi.frameworkClassPath=${FWCLASSPATH} \ - -Dosgi.framework=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar \ + -Djava.io.tmpdir="${iotmpdir}/work/tmp" \ + -Dosgi.install.area="${bdir}" \ + -Dosgi.configuration.area="${confarea}/configuration" \ + -Dosgi.frameworkClassPath="${fwclasspath}" \ + -Dosgi.framework=file:"${bdir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar" \ -Djava.awt.headless=true \ - -classpath ${CLASSPATH} \ + -classpath "${CLASSPATH}" \ org.eclipse.equinox.launcher.Main \ -console \ -consoleLog diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.config b/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.config deleted file mode 100644 index e49ba67ced..0000000000 --- a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.config +++ /dev/null @@ -1,23 +0,0 @@ -//START OF CONFIG-LAST - - - - prefix:dom-clustered-store-impl - cluster-data-store - - - - - -//END OF SNAPSHOT -urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28 -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:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17 -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:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28 -//END OF CONFIG diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.xml b/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.xml new file mode 100644 index 0000000000..96cf639cba --- /dev/null +++ b/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.xml @@ -0,0 +1,46 @@ + + + + + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28 + + 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:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17 + + 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:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28 + + + + + + + + + prefix:dom-clustered-store-impl + + cluster-data-store + + + + + + + + + + + + diff --git a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyMapping.xtend b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyMapping.xtend index 5a4aae36a8..44c0c04d43 100644 --- a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyMapping.xtend +++ b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyMapping.xtend @@ -2,23 +2,23 @@ package org.opendaylight.controller.md.compatibility.topology import org.opendaylight.yangtools.yang.binding.InstanceIdentifier import org.opendaylight.yangtools.yang.binding.DataObject -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 +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology import org.opendaylight.controller.sal.core.Edge import java.util.Set import org.opendaylight.controller.sal.core.Property import org.opendaylight.controller.sal.core.NodeConnector -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.Link -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.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.LinkKey -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.LinkId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem -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.rev131021.network.topology.topology.Node import org.opendaylight.controller.sal.compatibility.InventoryMapping class TopologyMapping { diff --git a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyReader.xtend b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyReader.xtend index fb9d2b8786..6c0e50e3d2 100644 --- a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyReader.xtend +++ b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyReader.xtend @@ -6,26 +6,26 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader import org.opendaylight.yangtools.yang.binding.InstanceIdentifier import org.opendaylight.yangtools.yang.binding.DataObject import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider -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.Node -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.Link -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.rev131021.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology import org.opendaylight.controller.md.compatibility.topology.TopologyMapping -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.rev131021.network.topology.topology.LinkBuilder -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.rev131021.network.topology.TopologyBuilder import java.util.ArrayList -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.network.topology.topology.NodeKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey import org.opendaylight.controller.sal.core.NodeConnector import org.opendaylight.controller.sal.topology.TopoEdgeUpdate -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.node.TerminationPointBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder import org.opendaylight.controller.sal.core.Edge -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.rev131021.link.attributes.SourceBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.DestinationBuilder class TopologyReader implements RuntimeDataProvider { diff --git a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/AdSalTopologyMapping.xtend b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/AdSalTopologyMapping.xtend index ad7537bc0d..c8050b1526 100644 --- a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/AdSalTopologyMapping.xtend +++ b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/AdSalTopologyMapping.xtend @@ -1,16 +1,16 @@ package org.opendaylight.controller.md.compatibility.topologymanager -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.rev131021.network.topology.TopologyKey import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -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.rev131021.network.topology.topology.node.TerminationPoint import org.opendaylight.controller.sal.core.NodeConnector -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.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology import java.util.Map import org.opendaylight.controller.sal.core.Edge import java.util.Set import java.util.List -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.rev131021.network.topology.topology.Node import java.util.Collections import com.google.common.collect.FluentIterable import java.util.HashSet @@ -18,13 +18,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId import org.opendaylight.controller.sal.compatibility.NodeMapping import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey -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.link.attributes.Source -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.Destination +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.Source +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.Destination import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey 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.TpId -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.rev131021.TpId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey import java.util.HashMap class AdSalTopologyMapping { @@ -69,7 +69,7 @@ class AdSalTopologyMapping { } def org.opendaylight.controller.sal.core.Node toAdNode( - org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId node) { + org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId node) { val key = new NodeKey(new NodeId(node)) return new org.opendaylight.controller.sal.core.Node(NodeMapping.MD_SAL_TYPE, key); } diff --git a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/CompatibleTopologyManager.xtend b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/CompatibleTopologyManager.xtend index c6a4912f2d..23924c864e 100644 --- a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/CompatibleTopologyManager.xtend +++ b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/CompatibleTopologyManager.xtend @@ -8,7 +8,7 @@ import java.util.Set import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader import java.util.HashMap import org.opendaylight.controller.sal.core.Edge -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.rev131021.network.topology.topology.node.TerminationPoint import com.google.common.collect.FluentIterable class CompatibleTopologyManager extends ConfigurableLinkManager implements ITopologyManager { 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 index bd2590f18b..c4a1108e92 100644 --- 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 @@ -4,10 +4,10 @@ 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.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey import org.opendaylight.yangtools.yang.binding.InstanceIdentifier import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.* 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 index 7d05ce60fa..c02067a68a 100644 --- 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 @@ -9,11 +9,11 @@ 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.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.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.* 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 index 62983ccce4..cd4b818037 100644 --- 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 @@ -10,10 +10,10 @@ 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 org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link import static com.google.common.base.Preconditions.* import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* 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 index 1fde2820e2..bf1a23d4bc 100644 --- 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 @@ -2,15 +2,15 @@ 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.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.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.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link import org.slf4j.LoggerFactory class TopologyProvider implements AutoCloseable{ diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMConsumerImpl.java deleted file mode 100644 index bbe771fd9c..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMConsumerImpl.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2013 Ericsson , 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.forwardingrulesmanager.consumer.impl; - -import org.eclipse.osgi.framework.console.CommandProvider; -import org.opendaylight.controller.clustering.services.IClusterContainerServices; -import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider; -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; -import org.opendaylight.controller.sal.binding.api.NotificationService; -import org.opendaylight.controller.sal.binding.api.data.DataBrokerService; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; -import org.opendaylight.controller.sal.core.IContainer; -import org.opendaylight.controller.sal.utils.ServiceHelper; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class FRMConsumerImpl extends AbstractBindingAwareProvider implements CommandProvider { - protected static final Logger logger = LoggerFactory.getLogger(FRMConsumerImpl.class); - private static ProviderContext p_session; - private static DataBrokerService dataBrokerService; - private static NotificationService notificationService; - private FlowConsumerImpl flowImplRef; - private GroupConsumerImpl groupImplRef; - private MeterConsumerImpl meterImplRef; - private static DataProviderService dataProviderService; - private static IClusterContainerServices clusterContainerService = null; - private static IContainer container; - - @Override - public void onSessionInitiated(ProviderContext session) { - FRMConsumerImpl.p_session = session; - - if (!getDependentModule()) { - logger.error("Unable to fetch handlers for dependent modules"); - System.out.println("Unable to fetch handlers for dependent modules"); - return; - } - - if (null != session) { - notificationService = session.getSALService(NotificationService.class); - - if (null != notificationService) { - dataBrokerService = session.getSALService(DataBrokerService.class); - - if (null != dataBrokerService) { - dataProviderService = session.getSALService(DataProviderService.class); - - if (null != dataProviderService) { - flowImplRef = new FlowConsumerImpl(); - groupImplRef = new GroupConsumerImpl(); - meterImplRef = new MeterConsumerImpl(); - registerWithOSGIConsole(); - } else { - logger.error("Data Provider Service is down or NULL. " - + "Accessing data from configuration data store will not be possible"); - System.out.println("Data Broker Service is down or NULL."); - } - - } else { - logger.error("Data Broker Service is down or NULL."); - System.out.println("Data Broker Service is down or NULL."); - } - } else { - logger.error("Notification Service is down or NULL."); - System.out.println("Notification Service is down or NULL."); - } - } else { - logger.error("Consumer session is NULL. Please check if provider is registered"); - System.out.println("Consumer session is NULL. Please check if provider is registered"); - } - - } - - public static IClusterContainerServices getClusterContainerService() { - return clusterContainerService; - } - - public static void setClusterContainerService(IClusterContainerServices clusterContainerService) { - FRMConsumerImpl.clusterContainerService = clusterContainerService; - } - - public static IContainer getContainer() { - return container; - } - - public static void setContainer(IContainer container) { - FRMConsumerImpl.container = container; - } - - private void registerWithOSGIConsole() { - BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); - bundleContext.registerService(CommandProvider.class.getName(), this, null); - } - - private boolean getDependentModule() { - do { - clusterContainerService = (IClusterContainerServices) ServiceHelper.getGlobalInstance( - IClusterContainerServices.class, this); - try { - Thread.sleep(4); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } while (clusterContainerService == null); - - do { - - container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this); - try { - Thread.sleep(5); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } while (container == null); - - return true; - } - - public static DataProviderService getDataProviderService() { - return dataProviderService; - } - - public FlowConsumerImpl getFlowImplRef() { - return flowImplRef; - } - - public GroupConsumerImpl getGroupImplRef() { - return groupImplRef; - } - - public static ProviderContext getProviderSession() { - return p_session; - } - - public static NotificationService getNotificationService() { - return notificationService; - } - - public static DataBrokerService getDataBrokerService() { - return dataBrokerService; - } - - /* - * OSGI COMMANDS - */ - @Override - public String getHelp() { - StringBuffer help = new StringBuffer(); - return help.toString(); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMUtil.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMUtil.java deleted file mode 100644 index ab2e19e9d4..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMUtil.java +++ /dev/null @@ -1,402 +0,0 @@ -package org.opendaylight.controller.forwardingrulesmanager.consumer.impl; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType; -import org.opendaylight.controller.sal.utils.IPProtocols; -import org.opendaylight.controller.sal.utils.NetUtils; -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.action.action.ControllerActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions; -import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match; -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.IpMatch; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match; -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._3.match.Ipv6Match; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; - -public class FRMUtil { - protected static final Logger logger = LoggerFactory.getLogger(FRMUtil.class); - private static final String NAMEREGEX = "^[a-zA-Z0-9]+$"; - - public static enum operation { - ADD, DELETE, UPDATE, GET - }; - - private enum EtherIPType { - ANY, V4, V6; - }; - - public static boolean isNameValid(String name) { - - // Name validation - if (name == null || name.trim().isEmpty() || !name.matches(NAMEREGEX)) { - return false; - } - return true; - - } - - public static boolean validateMatch(Flow flow) { - EtherIPType etype = EtherIPType.ANY; - EtherIPType ipsrctype = EtherIPType.ANY; - EtherIPType ipdsttype = EtherIPType.ANY; - - Match match = flow.getMatch(); - if (match != null) { - EthernetMatch ethernetmatch = match.getEthernetMatch(); - IpMatch ipmatch = match.getIpMatch(); - Layer3Match layer3match = match.getLayer3Match(); - VlanMatch vlanmatch = match.getVlanMatch(); - match.getIcmpv4Match(); - - if (ethernetmatch != null) { - if ((ethernetmatch.getEthernetSource() != null) - && !isL2AddressValid(ethernetmatch.getEthernetSource().getAddress().getValue())) { - - logger.error("Ethernet source address is not valid. Example: 00:05:b9:7c:81:5f", - ethernetmatch.getEthernetSource()); - return false; - } - - if ((ethernetmatch.getEthernetDestination() != null) - && !isL2AddressValid(ethernetmatch.getEthernetDestination().getAddress().getValue())) { - logger.error("Ethernet destination address is not valid. Example: 00:05:b9:7c:81:5f", - ethernetmatch.getEthernetDestination()); - return false; - } - - if (ethernetmatch.getEthernetType() != null) { - long type = ethernetmatch.getEthernetType().getType().getValue().longValue(); - if ((type < 0) || (type > 0xffff)) { - logger.error("Ethernet type is not valid"); - return false; - } else { - if (type == 0x0800) { - etype = EtherIPType.V4; - } else if (type == 0x86dd) { - etype = EtherIPType.V6; - } - } - - } - } - - if (layer3match != null) { - if (layer3match instanceof Ipv4Match) { - if (((Ipv4Match) layer3match).getIpv4Source() != null) { - if (NetUtils.isIPv4AddressValid(((Ipv4Match) layer3match).getIpv4Source().getValue())) { - ipsrctype = EtherIPType.V4; - } else { - logger.error("IP source address is not valid"); - return false; - } - - } else if (((Ipv4Match) layer3match).getIpv4Destination() != null) { - if (NetUtils.isIPv4AddressValid(((Ipv4Match) layer3match).getIpv4Destination().getValue())) { - ipdsttype = EtherIPType.V4; - } else { - logger.error("IP Destination address is not valid"); - return false; - } - - } - } else if (layer3match instanceof Ipv6Match) { - if (((Ipv6Match) layer3match).getIpv6Source() != null) { - if (NetUtils.isIPv6AddressValid(((Ipv6Match) layer3match).getIpv6Source().getValue())) { - ipsrctype = EtherIPType.V6; - } else { - logger.error("IPv6 source address is not valid"); - return false; - } - - } else if (((Ipv6Match) layer3match).getIpv6Destination() != null) { - if (NetUtils.isIPv6AddressValid(((Ipv6Match) layer3match).getIpv6Destination().getValue())) { - ipdsttype = EtherIPType.V6; - } else { - logger.error("IPv6 Destination address is not valid"); - return false; - } - - } - - } - - if (etype != EtherIPType.ANY) { - if ((ipsrctype != EtherIPType.ANY) && (ipsrctype != etype)) { - logger.error("Type mismatch between Ethernet & Src IP"); - return false; - } - if ((ipdsttype != EtherIPType.ANY) && (ipdsttype != etype)) { - logger.error("Type mismatch between Ethernet & Dst IP"); - return false; - } - } - if (ipsrctype != ipdsttype) { - if (!((ipsrctype == EtherIPType.ANY) || (ipdsttype == EtherIPType.ANY))) { - logger.error("IP Src Dest Type mismatch"); - return false; - } - } - } - - if (ipmatch != null) { - if (ipmatch.getIpProtocol() != null && !(isProtocolValid(ipmatch.getIpProtocol().toString()))) { - logger.error("Protocol is not valid"); - return false; - } - - } - - if (vlanmatch != null) { - if (vlanmatch.getVlanId() != null - && !(isVlanIdValid(vlanmatch.getVlanId().getVlanId().getValue().toString()))) { - logger.error("Vlan ID is not in the range 0 - 4095"); - return false; - } - - if (vlanmatch.getVlanPcp() != null - && !(isVlanPriorityValid(vlanmatch.getVlanPcp().getValue().toString()))) { - logger.error("Vlan priority is not in the range 0 - 7"); - return false; - } - } - - } - - return true; - - } - - public static boolean validateActions(List actions) { - - if (actions == null || actions.isEmpty()) { - logger.error("Actions value is null or empty"); - return false; - } - - for (Action curaction : actions) { - org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action = curaction - .getAction(); - if (action instanceof ControllerActionCase) { - Integer length = ((ControllerActionCase) action).getControllerAction().getMaxLength(); - if (length < 0 || length > 65294) { - logger.error("Controller: MaxLength is not valid"); - return false; - } - } else if (action instanceof OutputActionCase) { - Integer length = ((OutputActionCase) action).getOutputAction().getMaxLength(); - Uri outputnodeconnector = ((OutputActionCase) action).getOutputAction().getOutputNodeConnector(); - if (length < 0 || length > 65294) { - logger.error("OutputAction: MaxLength is not valid"); - return false; - } - if (outputnodeconnector != null) { - if (!outputnodeconnector.getValue().equals(NodeConnectorIDType.ALL) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.CONTROLLER) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.HWPATH) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK2OPENFLOW) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK2PCEP) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW2ONEPK) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW2PCEP) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP2ONEPK) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP2OPENFLOW) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PRODUCTION) - || !outputnodeconnector.getValue().equals(NodeConnectorIDType.SWSTACK)) { - logger.error("Output Action: NodeConnector Type is not valid"); - return false; - } - - } - } else if (action instanceof PushMplsActionCase) { - Integer ethertype = ((PushMplsActionCase) action).getPushMplsAction().getEthernetType(); - if (ethertype != null && ethertype != 0x8847 && ethertype != 0x8848) { - logger.error("Ether Type is not valid for PushMplsAction"); - return false; - } - } else if (action instanceof PushPbbActionCase) { - Integer ethertype = ((PushPbbActionCase) action).getPushPbbAction().getEthernetType(); - if (ethertype != null && ethertype != 0x88E7) { - logger.error("Ether type is not valid for PushPbbAction"); - return false; - } - } else if (action instanceof PushVlanActionCase) { - Integer ethertype = ((PushVlanActionCase) action).getPushVlanAction().getEthernetType(); - if (ethertype != null && ethertype != 0x8100 && ethertype != 0x88a8) { - logger.error("Ether Type is not valid for PushVlanAction"); - return false; - } - } else if (action instanceof SetDlDstActionCase || action instanceof SetDlSrcActionCase) { - MacAddress address = ((SetDlDstActionCase) action).getSetDlDstAction().getAddress(); - if (address != null && !isL2AddressValid(address.getValue())) { - logger.error("SetDlDstAction: Address not valid"); - return false; - } - } else if (action instanceof SetDlSrcActionCase) { - MacAddress address = ((SetDlSrcActionCase) action).getSetDlSrcAction().getAddress(); - if (address != null && !isL2AddressValid(address.getValue())) { - logger.error("SetDlSrcAction: Address not valid"); - return false; - } - } else if (action instanceof SetQueueActionCase) { - String queue = ((SetQueueActionCase) action).getSetQueueAction().getQueue(); - if (queue != null && !isQueueValid(queue)) { - logger.error("Queue Id not valid"); - return false; - } - } else if (action instanceof SetTpDstActionCase) { - PortNumber port = ((SetTpDstActionCase) action).getSetTpDstAction().getPort(); - if (port != null && !isPortValid(port)) { - logger.error("Port not valid"); - } - } else if (action instanceof SetTpSrcActionCase) { - PortNumber port = ((SetTpSrcActionCase) action).getSetTpSrcAction().getPort(); - if (port != null && !isPortValid(port)) { - logger.error("Port not valid"); - } - } else if (action instanceof SetVlanIdActionCase) { - VlanId vlanid = ((SetVlanIdActionCase) action).getSetVlanIdAction().getVlanId(); - if (vlanid != null && !isVlanIdValid(vlanid.toString())) { - logger.error("Vlan ID %s is not in the range 0 - 4095"); - return false; - } - } else if (action instanceof SetVlanPcpActionCase) { - VlanPcp vlanpcp = ((SetVlanPcpActionCase) action).getSetVlanPcpAction().getVlanPcp(); - if (vlanpcp != null && !isVlanPriorityValid(vlanpcp.toString())) { - logger.error("Vlan priority %s is not in the range 0 - 7"); - return false; - } - } - } - return true; - - } - - public static boolean validateInstructions(Flow flow) { - List instructionsList = new ArrayList<>(); - Instructions instructions = flow.getInstructions(); - if (instructions == null) { - return false; - } - instructionsList = instructions.getInstruction(); - - for (Instruction instruction : instructionsList) { - org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction - .getInstruction(); - if (curInstruction instanceof GoToTableCase) { - - Short tableid = ((GoToTableCase) curInstruction).getGoToTable().getTableId(); - if (tableid < 0) { - logger.error("table id is not valid"); - return false; - } - } - - else if (curInstruction instanceof WriteActionsCase) { - - List action = ((WriteActionsCase) curInstruction).getWriteActions().getAction(); - validateActions(action); - - } - - else if (curInstruction instanceof ApplyActionsCase) { - List action = ((ApplyActionsCase) curInstruction).getApplyActions().getAction(); - validateActions(action); - } - - else if (curInstruction instanceof ClearActionsCase) { - List action = ((ClearActionsCase) curInstruction).getClearActions().getAction(); - validateActions(action); - } - - else if (curInstruction instanceof MeterCase) { - - MeterId meter = ((MeterCase) curInstruction).getMeter().getMeterId(); - if (meter != null && !isValidMeter(meter)) { - logger.error("Meter Id is not valid"); - return false; - } - } - - } - - return true; - } - - public static boolean isValidMeter(MeterId meter) { - // TODO - return true; - } - - public static boolean isQueueValid(String queue) { - // TODO - return true; - } - - public static boolean isPortValid(PortNumber port) { - // TODO - return true; - } - - public static boolean isL2AddressValid(String mac) { - if (mac == null) { - return false; - } - - Pattern macPattern = Pattern.compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}"); - Matcher mm = macPattern.matcher(mac); - if (!mm.matches()) { - logger.debug("Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f", mac); - return false; - } - return true; - } - - public static boolean isProtocolValid(String protocol) { - IPProtocols proto = IPProtocols.fromString(protocol); - return (proto != null); - } - - public static boolean isVlanIdValid(String vlanId) { - int vlan = Integer.decode(vlanId); - return ((vlan >= 0) && (vlan < 4096)); - } - - public static boolean isVlanPriorityValid(String vlanPriority) { - int pri = Integer.decode(vlanPriority); - return ((pri >= 0) && (pri < 8)); - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java deleted file mode 100644 index d2f2420a7c..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java +++ /dev/null @@ -1,365 +0,0 @@ -package org.opendaylight.controller.forwardingrulesmanager.consumer.impl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; - -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.DataModification; -import org.opendaylight.controller.sal.common.util.Rpcs; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder; -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.FlowTableRef; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved; -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.inventory.rev130819.NodeRef; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.Tables; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.Table; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.TableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.TableKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableRef; -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.NotificationListener; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class FlowConsumerImpl { - protected static final Logger logger = LoggerFactory.getLogger(FlowConsumerImpl.class); - private final FlowEventListener flowEventListener = new FlowEventListener(); - private Registration listener1Reg; - private SalFlowService flowService; - // private FlowDataListener listener; - private FlowDataCommitHandler commitHandler; - - public FlowConsumerImpl() { - InstanceIdentifier path = InstanceIdentifier.builder(Flows.class).toInstance(); - flowService = FRMConsumerImpl.getProviderSession().getRpcService(SalFlowService.class); - - if (null == flowService) { - logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended"); - return; - } - - // For switch events - listener1Reg = FRMConsumerImpl.getNotificationService().registerNotificationListener(flowEventListener); - - if (null == listener1Reg) { - logger.error("Listener to listen on flow data modifcation events"); - return; - } - // addFlowTest(); - commitHandler = new FlowDataCommitHandler(); - FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler); - } - - /** - * Adds flow to the southbound plugin and our internal database - * - * @param path - * @param dataObject - */ - private void addFlow(InstanceIdentifier path, Flow dataObject) { - - AddFlowInputBuilder input = new AddFlowInputBuilder(); - input.fieldsFrom(dataObject); - input.setNode((dataObject).getNode()); - input.setFlowTable(new FlowTableRef(createTableInstance(dataObject.getId(), dataObject.getNode()))); - // We send flow to the sounthbound plugin - flowService.addFlow(input.build()); - } - - /** - * Removes flow to the southbound plugin and our internal database - * - * @param path - * @param dataObject - */ - private void removeFlow(InstanceIdentifier path, Flow dataObject) { - - RemoveFlowInputBuilder input = new RemoveFlowInputBuilder(); - input.fieldsFrom(dataObject); - input.setNode((dataObject).getNode()); - input.setTableId(dataObject.getTableId()); - input.setFlowTable(new FlowTableRef(createTableInstance((long)dataObject.getTableId(), (dataObject).getNode()))); - // We send flow to the sounthbound plugin - flowService.removeFlow(input.build()); - } - - /** - * Update flow to the southbound plugin and our internal database - * - * @param path - * @param dataObject - */ - private void updateFlow(InstanceIdentifier path, Flow updatedFlow, Flow originalFlow) { - - UpdateFlowInputBuilder input = new UpdateFlowInputBuilder(); - UpdatedFlowBuilder updatedflowbuilder = new UpdatedFlowBuilder(); - updatedflowbuilder.fieldsFrom(updatedFlow); - input.setNode(updatedFlow.getNode()); - input.setUpdatedFlow(updatedflowbuilder.build()); - OriginalFlowBuilder ofb = new OriginalFlowBuilder(originalFlow); - input.setOriginalFlow(ofb.build()); - // We send flow to the sounthbound plugin - flowService.updateFlow(input.build()); - } - - private void commitToPlugin(internalTransaction transaction) { - Set, DataObject>> createdEntries = transaction.getModification() - .getCreatedConfigurationData().entrySet(); - - /* - * This little dance is because updatedEntries contains both created and - * modified entries The reason I created a new HashSet is because the - * collections we are returned are immutable. - */ - Set, DataObject>> updatedEntries = new HashSet, DataObject>>(); - updatedEntries.addAll(transaction.getModification().getUpdatedConfigurationData().entrySet()); - updatedEntries.removeAll(createdEntries); - - Set> removeEntriesInstanceIdentifiers = transaction.getModification() - .getRemovedConfigurationData(); - transaction.getModification().getOriginalConfigurationData(); - for (Entry, DataObject> entry : createdEntries) { - if (entry.getValue() instanceof Flow) { - logger.debug("Coming add cc in FlowDatacommitHandler"); - Flow flow = (Flow) entry.getValue(); - boolean status = validate(flow); - if (!status) { - return; - } - addFlow(entry.getKey(), (Flow) entry.getValue()); - } - } - - for (Entry, DataObject> entry : updatedEntries) { - if (entry.getValue() instanceof Flow) { - logger.debug("Coming update cc in FlowDatacommitHandler"); - Flow updatedFlow = (Flow) entry.getValue(); - Flow originalFlow = (Flow) transaction.modification.getOriginalConfigurationData().get(entry.getKey()); - boolean status = validate(updatedFlow); - if (!status) { - return; - } - updateFlow(entry.getKey(), updatedFlow, originalFlow); - } - } - - for (InstanceIdentifier instanceId : removeEntriesInstanceIdentifiers) { - DataObject removeValue = transaction.getModification().getOriginalConfigurationData().get(instanceId); - if (removeValue instanceof Flow) { - logger.debug("Coming remove cc in FlowDatacommitHandler"); - Flow flow = (Flow) removeValue; - boolean status = validate(flow); - - if (!status) { - return; - } - - removeFlow(instanceId, (Flow) removeValue); - } - } - } - - private final class FlowDataCommitHandler implements DataCommitHandler, DataObject> { - - @SuppressWarnings("unchecked") - public DataCommitTransaction, DataObject> requestCommit(DataModification, DataObject> modification) { - // We should verify transaction - logger.debug("Coming in FlowDatacommitHandler"); - internalTransaction transaction = new internalTransaction(modification); - transaction.prepareUpdate(); - return transaction; - } - } - - private final class internalTransaction implements DataCommitTransaction, DataObject> { - - private final DataModification, DataObject> modification; - - @Override - public DataModification, DataObject> getModification() { - return modification; - } - - public internalTransaction(DataModification, DataObject> modification) { - this.modification = modification; - } - - /** - * We create a plan which flows will be added, which will be updated and - * which will be removed based on our internal state. - * - */ - void prepareUpdate() { - - } - - /** - * We are OK to go with execution of plan - * - */ - @Override - public RpcResult finish() throws IllegalStateException { - commitToPlugin(this); - return Rpcs.getRpcResult(true, null, Collections. emptySet()); - } - - /** - * - * We should rollback our preparation - * - */ - @Override - public RpcResult rollback() throws IllegalStateException { - rollBackFlows(modification); - return Rpcs.getRpcResult(true, null, Collections. emptySet()); - - } - } - - private void rollBackFlows(DataModification, DataObject> modification) { - Set, DataObject>> createdEntries = modification.getCreatedConfigurationData().entrySet(); - - /* - * This little dance is because updatedEntries contains both created and modified entries - * The reason I created a new HashSet is because the collections we are returned are immutable. - */ - Set, DataObject>> updatedEntries = new HashSet, DataObject>>(); - updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet()); - updatedEntries.removeAll(createdEntries); - - Set> removeEntriesInstanceIdentifiers = modification.getRemovedConfigurationData(); - for (Entry, DataObject> entry : createdEntries) { - if(entry.getValue() instanceof Flow) { - removeFlow(entry.getKey(),(Flow) entry.getValue()); // because we are rolling back, remove what we would have added. - } - } - - for (Entry, DataObject> entry : updatedEntries) { - if(entry.getValue() instanceof Flow) { - Flow updatedFlow = (Flow) entry.getValue(); - Flow originalFlow = (Flow) modification.getOriginalConfigurationData().get(entry.getKey()); - updateFlow(entry.getKey(), updatedFlow ,originalFlow);// because we are rolling back, replace the updated with the original - } - } - - for (InstanceIdentifier instanceId : removeEntriesInstanceIdentifiers ) { - DataObject removeValue = (Flow) modification.getOriginalConfigurationData().get(instanceId); - if(removeValue instanceof Flow) { - addFlow(instanceId,(Flow) removeValue);// because we are rolling back, add what we would have removed. - - } - } -} - final class FlowEventListener implements SalFlowListener { - - List addedFlows = new ArrayList<>(); - List removedFlows = new ArrayList<>(); - List updatedFlows = new ArrayList<>(); - - @Override - public void onFlowAdded(FlowAdded notification) { - addedFlows.add(notification); - } - - @Override - public void onFlowRemoved(FlowRemoved notification) { - removedFlows.add(notification); - } - - @Override - public void onFlowUpdated(FlowUpdated notification) { - updatedFlows.add(notification); - } - - @Override - public void onNodeErrorNotification(NodeErrorNotification notification) { - // TODO Auto-generated method stub - - } - - @Override - public void onNodeExperimenterErrorNotification(NodeExperimenterErrorNotification notification) { - // TODO Auto-generated method stub - - } - - @Override - public void onSwitchFlowRemoved(SwitchFlowRemoved notification) { - // TODO Auto-generated method stub - - } - } - - public boolean validate(Flow flow) { - String msg = ""; // Specific part of warn/error log - - boolean result = true; - // flow Name validation - if (!FRMUtil.isNameValid(flow.getFlowName())) { - msg = "Invalid Flow name"; - result = false; - } - - // Node Validation - if (result == true && flow.getNode() == null) { - msg = "Node is null"; - result = false; - } - - // TODO: Validate we are seeking to program a flow against a valid - // Node - - if (result == true && flow.getPriority() != null) { - if (flow.getPriority() < 0 || flow.getPriority() > 65535) { - msg = String.format("priority %s is not in the range 0 - 65535", flow.getPriority()); - result = false; - } - } - - if (!FRMUtil.validateMatch(flow)) { - logger.error("Not a valid Match"); - result = false; - } - if (!FRMUtil.validateInstructions(flow)) { - logger.error("Not a valid Instruction"); - result = false; - } - if (result == false) { - logger.warn("Invalid Configuration for flow {}. The failure is {}", flow, msg); - logger.error("Invalid Configuration ({})", msg); - } - return result; - } - - private InstanceIdentifier createTableInstance(Long tableId, NodeRef nodeRef) { - Table table; - InstanceIdentifier tableInstance; - TableBuilder builder = new TableBuilder(); - builder.setId(tableId); - builder.setKey(new TableKey(tableId, nodeRef)); - table = builder.build(); - tableInstance = InstanceIdentifier.builder(Tables.class).child(Table.class, table.getKey()).toInstance(); - return tableInstance; - } -} \ No newline at end of file diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/GroupConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/GroupConsumerImpl.java deleted file mode 100644 index f4064f22ce..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/GroupConsumerImpl.java +++ /dev/null @@ -1,323 +0,0 @@ -package org.opendaylight.controller.forwardingrulesmanager.consumer.impl; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -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.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.DataModification; -import org.opendaylight.controller.sal.common.util.Rpcs; -import org.opendaylight.controller.sal.core.IContainer; -import org.opendaylight.controller.sal.core.Node; -import org.opendaylight.controller.sal.utils.GlobalConstants; -import org.opendaylight.controller.sal.utils.Status; -import org.opendaylight.controller.sal.utils.StatusCode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.Groups; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups.Group; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups.GroupKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupAdded; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemoved; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupListener; -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.GroupId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket; -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.NotificationListener; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@SuppressWarnings("unused") -public class GroupConsumerImpl { - - protected static final Logger logger = LoggerFactory.getLogger(GroupConsumerImpl.class); - private final GroupEventListener groupEventListener = new GroupEventListener(); - private Registration groupListener; - private SalGroupService groupService; - private GroupDataCommitHandler groupCommitHandler; - - private IContainer container; - - public GroupConsumerImpl() { - - InstanceIdentifier path = InstanceIdentifier.builder(Groups.class).toInstance(); - groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class); - - if (null == groupService) { - logger.error("Consumer SAL Group Service is down or NULL. FRM may not function as intended"); - System.out.println("Consumer SAL Group Service is down or NULL."); - return; - } - - // For switch events - groupListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(groupEventListener); - - if (null == groupListener) { - logger.error("Listener to listen on group data modifcation events"); - System.out.println("Listener to listen on group data modifcation events."); - return; - } - - groupCommitHandler = new GroupDataCommitHandler(); - FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, groupCommitHandler); - } - - public Status validateGroup(Group group) { - String groupName; - Iterator bucketIterator; - boolean returnResult; - Buckets groupBuckets; - - if (null != group) { - groupName = group.getGroupName(); - if (!FRMUtil.isNameValid(groupName)) { - logger.error("Group Name is invalid %s" + groupName); - return new Status(StatusCode.BADREQUEST, "Group Name is invalid"); - } - - if (!(group.getGroupType().getIntValue() >= GroupTypes.GroupAll.getIntValue() && group.getGroupType() - .getIntValue() <= GroupTypes.GroupFf.getIntValue())) { - logger.error("Invalid Group type %d" + group.getGroupType().getIntValue()); - return new Status(StatusCode.BADREQUEST, "Invalid Group type"); - } - - groupBuckets = group.getBuckets(); - - if (null != groupBuckets && null != groupBuckets.getBucket()) { - bucketIterator = groupBuckets.getBucket().iterator(); - - while (bucketIterator.hasNext()) { - if (!(FRMUtil.validateActions(bucketIterator.next().getAction()))) { - logger.error("Error in action bucket"); - return new Status(StatusCode.BADREQUEST, "Invalid Group bucket contents"); - } - } - } - } - - return new Status(StatusCode.SUCCESS); - } - - /** - * Update Group entries to the southbound plugin/inventory and our internal - * database - * - * @param path - * @param dataObject - */ - private void updateGroup(InstanceIdentifier path, - Group updatedGroupDataObject, Group originalGroupDataObject) { - UpdatedGroupBuilder updateGroupBuilder = null; - Status groupOperationStatus = validateGroup(updatedGroupDataObject); - - if (!groupOperationStatus.isSuccess()) { - logger.error("Group data object validation failed %s" + updatedGroupDataObject.getGroupName()); - return; - } - - UpdateGroupInputBuilder groupInputBuilder = new UpdateGroupInputBuilder(); - updateGroupBuilder = new UpdatedGroupBuilder(updatedGroupDataObject); - updateGroupBuilder.setGroupId(new GroupId(updatedGroupDataObject.getId())); - groupInputBuilder.setNode(updatedGroupDataObject.getNode()); - groupInputBuilder.setUpdatedGroup(updateGroupBuilder.build()); - OriginalGroupBuilder originalGroupBuilder = new OriginalGroupBuilder(originalGroupDataObject); - groupInputBuilder.setOriginalGroup(originalGroupBuilder.build()); - groupService.updateGroup(groupInputBuilder.build()); - return; - } - - /** - * Adds Group to the southbound plugin and our internal database - * - * @param path - * @param dataObject - */ - private void addGroup(InstanceIdentifier path, Group groupAddDataObject) { - GroupKey groupKey = groupAddDataObject.getKey(); - Status groupOperationStatus = validateGroup(groupAddDataObject); - - if (!groupOperationStatus.isSuccess()) { - logger.error("Group data object validation failed %s" + groupAddDataObject.getGroupName()); - return; - } - - AddGroupInputBuilder groupData = new AddGroupInputBuilder(); - groupData.fieldsFrom(groupAddDataObject); - groupData.setGroupId(new GroupId(groupAddDataObject.getId())); - groupData.setNode(groupAddDataObject.getNode()); - groupService.addGroup(groupData.build()); - return; - } - - /** - * Remove Group to the southbound plugin and our internal database - * - * @param path - * @param dataObject - */ - private void removeGroup(InstanceIdentifier path, Group groupRemoveDataObject) { - GroupKey groupKey = groupRemoveDataObject.getKey(); - Status groupOperationStatus = validateGroup(groupRemoveDataObject); - - if (!groupOperationStatus.isSuccess()) { - logger.error("Group data object validation failed %s" + groupRemoveDataObject.getGroupName()); - return; - } - - RemoveGroupInputBuilder groupData = new RemoveGroupInputBuilder(); - groupData.fieldsFrom(groupRemoveDataObject); - groupData.setGroupId(new GroupId(groupRemoveDataObject.getId())); - groupData.setNode(groupRemoveDataObject.getNode()); - groupService.removeGroup(groupData.build()); - return; - } - - private RpcResult commitToPlugin(InternalTransaction transaction) { - DataModification, DataObject> modification = transaction.modification; - //get created entries - Set, DataObject>> createdEntries = - modification.getCreatedConfigurationData().entrySet(); - - //get updated entries - Set, DataObject>> updatedEntries = - new HashSet, DataObject>>(); - - updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet()); - updatedEntries.removeAll(createdEntries); - - //get removed entries - Set> removeEntriesInstanceIdentifiers = - modification.getRemovedConfigurationData(); - - for (Entry, DataObject> entry : createdEntries) { - if(entry.getValue() instanceof Group) { - addGroup(entry.getKey(), (Group)entry.getValue()); - } - } - - for (Entry, DataObject> entry : updatedEntries) { - if(entry.getValue() instanceof Group) { - Group originalGroup = (Group) modification.getOriginalConfigurationData().get(entry.getKey()); - Group updatedGroup = (Group) entry.getValue(); - updateGroup(entry.getKey(), originalGroup, updatedGroup); - } - } - - for (InstanceIdentifier instanceId : removeEntriesInstanceIdentifiers ) { - DataObject removeValue = modification.getOriginalConfigurationData().get(instanceId); - if(removeValue instanceof Group) { - removeGroup(instanceId, (Group)removeValue); - } - } - - return Rpcs.getRpcResult(true, null, Collections.emptySet()); - } - - private final class GroupDataCommitHandler implements DataCommitHandler, DataObject> { - - @Override - public DataCommitTransaction, DataObject> requestCommit( - DataModification, DataObject> modification) { - InternalTransaction transaction = new InternalTransaction(modification); - transaction.prepareUpdate(); - return transaction; - } - } - - private final class InternalTransaction implements DataCommitTransaction, DataObject> { - - private final DataModification, DataObject> modification; - - public InternalTransaction(DataModification, DataObject> modification) { - this.modification = modification; - } - - /** - * We create a plan which flows will be added, which will be updated and - * which will be removed based on our internal state. - * - */ - void prepareUpdate() { - - } - - /** - * We are OK to go with execution of plan - * - */ - @Override - public RpcResult finish() throws IllegalStateException { - - RpcResult rpcStatus = commitToPlugin(this); - return rpcStatus; - } - - /** - * - * We should rollback our preparation - * - */ - @Override - public RpcResult rollback() throws IllegalStateException { - - ///needs to be implemented as per gerrit 3314 - return Rpcs.getRpcResult(true, null, Collections.emptySet()); - } - - @Override - public DataModification, DataObject> getModification() { - return modification; - } - - } - - final class GroupEventListener implements SalGroupListener { - - List addedGroups = new ArrayList<>(); - List removedGroups = new ArrayList<>(); - List updatedGroups = new ArrayList<>(); - - @Override - public void onGroupAdded(GroupAdded notification) { - addedGroups.add(notification); - } - - @Override - public void onGroupRemoved(GroupRemoved notification) { - // TODO Auto-generated method stub - - } - - @Override - public void onGroupUpdated(GroupUpdated notification) { - // TODO Auto-generated method stub - - } - } - } diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/IForwardingRulesManager.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/IForwardingRulesManager.java deleted file mode 100644 index 85ed8d4844..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/IForwardingRulesManager.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.opendaylight.controller.forwardingrulesmanager.consumer.impl; - -import java.util.List; - -import org.opendaylight.controller.sal.core.Node; -import org.opendaylight.yangtools.yang.binding.DataObject; - -/** - * Interface that describes methods for accessing the flows database. - */ -public interface IForwardingRulesManager { - - /** - * Returns the specifications of all the flows configured for all the - * switches on the current container - * - * @return the list of flow configurations present in the database - */ - public List get(); - - /** - * Returns the specification of the flow configured for the given network - * node on the current container - * - * @param name - * the flow name - * @param n - * the network node identifier - * @return the {@code FlowConfig} object - */ - public DataObject getWithName(String name, Node n); - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/MeterConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/MeterConsumerImpl.java deleted file mode 100644 index bf8c8b7f05..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/MeterConsumerImpl.java +++ /dev/null @@ -1,337 +0,0 @@ -package org.opendaylight.controller.forwardingrulesmanager.consumer.impl; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -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.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.DataModification; -import org.opendaylight.controller.sal.common.util.Rpcs; -import org.opendaylight.controller.sal.core.IContainer; -import org.opendaylight.controller.sal.core.Node; -import org.opendaylight.controller.sal.utils.GlobalConstants; -import org.opendaylight.controller.sal.utils.Status; -import org.opendaylight.controller.sal.utils.StatusCode; -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.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.GroupId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.Meters; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.MeterKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemoved; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterListener; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.BandType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemark; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter; -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.NotificationListener; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MeterConsumerImpl { - protected static final Logger logger = LoggerFactory.getLogger(MeterConsumerImpl.class); - private final MeterEventListener meterEventListener = new MeterEventListener(); - private Registration meterListener; - private SalMeterService meterService; - private MeterDataCommitHandler commitHandler; - - public MeterConsumerImpl() { - InstanceIdentifier path = InstanceIdentifier.builder(Meters.class).toInstance(); - meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class); - - if (null == meterService) { - logger.error("Consumer SAL Meter Service is down or NULL. FRM may not function as intended"); - System.out.println("Consumer SAL Meter Service is down or NULL."); - return; - } - - // For switch/plugin events - meterListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(meterEventListener); - - if (null == meterListener) { - logger.error("Listener to listen on meter data modifcation events"); - System.out.println("Listener to listen on meter data modifcation events."); - return; - } - - commitHandler = new MeterDataCommitHandler(); - FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler); - } - - /** - * Adds Meter to the southbound plugin and our internal database - * - * @param path - * @param dataObject - */ - private Status addMeter(InstanceIdentifier path, Meter meterAddDataObject) { - MeterKey meterKey = meterAddDataObject.getKey(); - - if (null != meterKey && validateMeter(meterAddDataObject).isSuccess()) { - AddMeterInputBuilder meterBuilder = new AddMeterInputBuilder(); - meterBuilder.fieldsFrom(meterAddDataObject); - meterBuilder.setMeterId(new MeterId(meterAddDataObject.getId())); - meterBuilder.setNode(meterAddDataObject.getNode()); - meterService.addMeter(meterBuilder.build()); - } else { - return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed"); - } - - return new Status(StatusCode.SUCCESS); - } - - /* - * Update Meter to the southbound plugin and our internal database - * - * @param path - * - * @param dataObject - */ - private Status updateMeter(InstanceIdentifier path, - Meter updatedMeter, Meter originalMeter) { - UpdatedMeterBuilder updateMeterBuilder = null; - - if (validateMeter(updatedMeter).isSuccess()) { - UpdateMeterInputBuilder updateMeterInputBuilder = new UpdateMeterInputBuilder(); - updateMeterInputBuilder.setNode(updatedMeter.getNode()); - updateMeterBuilder = new UpdatedMeterBuilder(); - updateMeterBuilder.fieldsFrom(updatedMeter); - updateMeterBuilder.setMeterId(new MeterId(updatedMeter.getId())); - updateMeterInputBuilder.setUpdatedMeter(updateMeterBuilder.build()); - OriginalMeterBuilder originalMeterBuilder = new OriginalMeterBuilder(originalMeter); - updateMeterInputBuilder.setOriginalMeter(originalMeterBuilder.build()); - meterService.updateMeter(updateMeterInputBuilder.build()); - } else { - return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed"); - } - - return new Status(StatusCode.SUCCESS); - } - - /* - * Remove Meter to the southbound plugin and our internal database - * - * @param path - * - * @param dataObject - */ - private Status removeMeter(InstanceIdentifier path, Meter meterRemoveDataObject) { - MeterKey meterKey = meterRemoveDataObject.getKey(); - - if (null != meterKey && validateMeter(meterRemoveDataObject).isSuccess()) { - RemoveMeterInputBuilder meterBuilder = new RemoveMeterInputBuilder(); - meterBuilder.fieldsFrom(meterRemoveDataObject); - meterBuilder.setNode(meterRemoveDataObject.getNode()); - meterBuilder.setMeterId(new MeterId(meterRemoveDataObject.getId())); - meterService.removeMeter(meterBuilder.build()); - } else { - return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed"); - } - - return new Status(StatusCode.SUCCESS); - } - - public Status validateMeter(Meter meter) { - String meterName; - Status returnStatus = null; - - if (null != meter) { - meterName = meter.getMeterName(); - if (!FRMUtil.isNameValid(meterName)) { - logger.error("Meter Name is invalid %s" + meterName); - returnStatus = new Status(StatusCode.BADREQUEST, "Meter Name is invalid"); - return returnStatus; - } - - for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) { - if (null != meter.getFlags() && !meter.getFlags().isMeterBurst()) { - if (0 < meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBurstSize()) { - logger.error("Burst size should only be associated when Burst FLAG is set"); - returnStatus = new Status(StatusCode.BADREQUEST, - "Burst size should only be associated when Burst FLAG is set"); - break; - } - } - } - - if (null != returnStatus && !returnStatus.isSuccess()) { - return returnStatus; - } else if (null != meter.getMeterBandHeaders()) { - BandType setBandType = null; - DscpRemark dscpRemark = null; - for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) { - setBandType = meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBandType(); - if (setBandType instanceof DscpRemark) { - dscpRemark = (DscpRemark) setBandType; - if (0 > dscpRemark.getRate()) { - - } - } else if (setBandType instanceof Drop) { - if (0 < dscpRemark.getPercLevel()) { - logger.error("Number of drop Precedence level"); - } - } else if (setBandType instanceof Experimenter) { - - } - } - } - } - return new Status(StatusCode.SUCCESS); - } - - private RpcResult commitToPlugin(InternalTransaction transaction) { - DataModification, DataObject> modification = transaction.modification; - //get created entries - Set, DataObject>> createdEntries = - modification.getCreatedConfigurationData().entrySet(); - - //get updated entries - Set, DataObject>> updatedEntries = - new HashSet, DataObject>>(); - - updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet()); - updatedEntries.removeAll(createdEntries); - - //get removed entries - Set> removeEntriesInstanceIdentifiers = - modification.getRemovedConfigurationData(); - - for (Entry, DataObject> entry : createdEntries) { - if(entry.getValue() instanceof Meter) { - addMeter(entry.getKey(), (Meter)entry.getValue()); - } - } - - for (Entry, DataObject> entry : updatedEntries) { - if(entry.getValue() instanceof Meter) { - Meter originalMeter = (Meter) modification.getOriginalConfigurationData().get(entry.getKey()); - Meter updatedMeter = (Meter) entry.getValue(); - updateMeter(entry.getKey(), originalMeter, updatedMeter); - } - } - - for (InstanceIdentifier instanceId : removeEntriesInstanceIdentifiers ) { - DataObject removeValue = modification.getOriginalConfigurationData().get(instanceId); - if(removeValue instanceof Meter) { - removeMeter(instanceId, (Meter)removeValue); - } - } - - return Rpcs.getRpcResult(true, null, Collections.emptySet()); - } - - final class InternalTransaction implements DataCommitTransaction, DataObject> { - - private final DataModification, DataObject> modification; - - @Override - public DataModification, DataObject> getModification() { - return modification; - } - - public InternalTransaction(DataModification, DataObject> modification) { - this.modification = modification; - } - - /** - * We create a plan which flows will be added, which will be updated and - * which will be removed based on our internal state. - * - */ - void prepareUpdate() { - - } - - /** - * We are OK to go with execution of plan - * - */ - @Override - public RpcResult finish() throws IllegalStateException { - - RpcResult rpcStatus = commitToPlugin(this); - return rpcStatus; - } - - /** - * - * We should rollback our preparation - * - */ - @Override - public RpcResult rollback() throws IllegalStateException { - return Rpcs.getRpcResult(true, null, Collections.emptySet()); - - } - - } - - private final class MeterDataCommitHandler implements DataCommitHandler, DataObject> { - @Override - public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction, DataObject> requestCommit( - DataModification, DataObject> modification) { - // We should verify transaction - InternalTransaction transaction = new InternalTransaction(modification); - transaction.prepareUpdate(); - return transaction; - } - } - - final class MeterEventListener implements SalMeterListener { - - List addedMeter = new ArrayList<>(); - List removeMeter = new ArrayList<>(); - List updatedMeter = new ArrayList<>(); - - @Override - public void onMeterAdded(MeterAdded notification) { - // TODO Auto-generated method stub - - } - - @Override - public void onMeterRemoved(MeterRemoved notification) { - // TODO Auto-generated method stub - - } - - @Override - public void onMeterUpdated(MeterUpdated notification) { - // TODO Auto-generated method stub - - } - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java deleted file mode 100644 index 11d1189573..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java +++ /dev/null @@ -1,193 +0,0 @@ -package org.opendaylight.controller.forwardingrulesmanager.consumer.impl; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.opendaylight.controller.clustering.services.IClusterContainerServices; -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.DataModification; -import org.opendaylight.controller.sal.common.util.Rpcs; -import org.opendaylight.controller.sal.core.IContainer; -import org.opendaylight.controller.sal.utils.ServiceHelper; -import org.opendaylight.controller.sal.utils.Status; -import org.opendaylight.controller.sal.utils.StatusCode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.Tables; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.Table; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.table.update.UpdatedTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TableFeaturesConsumerImpl { - protected static final Logger logger = LoggerFactory.getLogger(TableFeaturesConsumerImpl.class); - private SalTableService tableService; - private TableDataCommitHandler commitHandler; - private final IClusterContainerServices clusterContainerService = null; - private IContainer container; - private static final String NAMEREGEX = "^[a-zA-Z0-9]+$"; - private boolean inContainerMode; // being used by global instance only - - public TableFeaturesConsumerImpl() { - InstanceIdentifier path = InstanceIdentifier.builder(Tables.class).toInstance(); - tableService = FRMConsumerImpl.getProviderSession().getRpcService(SalTableService.class); - - if (null == tableService) { - logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended"); - System.out.println("Consumer SAL Service is down or NULL."); - return; - } - - System.out.println("-------------------------------------------------------------------"); - commitHandler = new TableDataCommitHandler(); - FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler); - container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this); - } - - /** - * Updates TableFeatures to the southbound plugin and our internal database - * - * @param path - * @param dataObject - */ - private void updateTableFeatures(InstanceIdentifier path, TableFeatures dataObject) { - - UpdateTableInputBuilder input = new UpdateTableInputBuilder(); - UpdatedTableBuilder updatedtablebuilder = new UpdatedTableBuilder(); - updatedtablebuilder.fieldsFrom(dataObject); - List features = updatedtablebuilder.build().getTableFeatures(); - for (TableFeatures feature : features) { - if (feature != null && feature.getMaxEntries() != null) { - logger.error("Max Entries field is read-only, cannot be changed"); - return; - } - } - input.setUpdatedTable(updatedtablebuilder.build()); - - // We send table feature update request to the sounthbound plugin - tableService.updateTable(input.build()); - } - - @SuppressWarnings("unchecked") - private void commitToPlugin(internalTransaction transaction) { - - for (@SuppressWarnings("unused") - Entry, TableFeatures> entry : transaction.updates.entrySet()) { - System.out.println("Coming update cc in TableDatacommitHandler"); - updateTableFeatures(entry.getKey(), entry.getValue()); - } - - } - - private final class TableDataCommitHandler implements DataCommitHandler, DataObject> { - - @SuppressWarnings("unchecked") - @Override - public DataCommitTransaction requestCommit(DataModification, DataObject> modification) { - // We should verify transaction - System.out.println("Coming in TableFeaturesDatacommitHandler"); - internalTransaction transaction = new internalTransaction(modification); - transaction.prepareUpdate(); - return transaction; - } - } - - private final class internalTransaction implements DataCommitTransaction, DataObject> { - - private final DataModification, DataObject> modification; - - @Override - public DataModification, DataObject> getModification() { - return modification; - } - - public internalTransaction(DataModification, DataObject> modification) { - this.modification = modification; - } - - Map, TableFeatures> updates = new HashMap<>(); - Map, TableFeatures> createdEntries = new HashMap<>(); - - /** - * We create a plan which table features will be updated. - * - */ - void prepareUpdate() { - Set, DataObject>> createdEntries = modification.getCreatedConfigurationData().entrySet(); - - Set, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet(); - for (Entry, DataObject> entry : puts) { - - // validating the DataObject - - Status status = validate(container, (TableFeatures) entry); - if (!status.isSuccess()) { - logger.warn("Invalid Configuration for table features The failure is {}", entry, - status.getDescription()); - String error = "Invalid Configuration (" + status.getDescription() + ")"; - logger.error(error); - return; - } - if (entry.getValue() instanceof TableFeatures) { - TableFeatures tablefeatures = (TableFeatures) entry.getValue(); - preparePutEntry(entry.getKey(), tablefeatures); - } - - } - } - - private void preparePutEntry(InstanceIdentifier key, TableFeatures tablefeatures) { - if (tablefeatures != null) { - // Updating the Map - System.out.println("Coming update in TableFeaturesDatacommitHandler"); - updates.put(key, tablefeatures); - } - } - - /** - * We are OK to go with execution of plan - * - */ - @Override - public RpcResult finish() throws IllegalStateException { - - commitToPlugin(this); - // We return true if internal transaction is successful. - // return Rpcs.getRpcResult(true, null, Collections.emptySet()); - return Rpcs.getRpcResult(true, null, null); - } - - /** - * - * We should rollback our preparation - * - */ - @Override - public RpcResult rollback() throws IllegalStateException { - // NOOP - we did not modified any internal state during - // requestCommit phase - // return Rpcs.getRpcResult(true, null, Collections.emptySet()); - return Rpcs.getRpcResult(true, null, null); - - } - - public Status validate(IContainer container, TableFeatures dataObject) { - - String tablename = dataObject.getName(); - if (tablename == null || tablename.trim().isEmpty() || !tablename.matches(NAMEREGEX) - || tablename.length() != 32) { - return new Status(StatusCode.BADREQUEST, "Invalid table name"); - } - - return new Status(StatusCode.SUCCESS); - } - } -} 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 index b5cde6ee5b..7914de0f66 100644 --- 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 @@ -10,6 +10,10 @@ module netconf-node-inventory { } grouping netconf-node-fields { + leaf connected { + type boolean; + } + leaf-list initial-capability { type string; } diff --git a/opendaylight/md-sal/model/model-inventory/src/main/yang/node-inventory.yang b/opendaylight/md-sal/model/model-inventory/src/main/yang/node-inventory.yang index 1ffc887327..77c92f91ce 100644 --- a/opendaylight/md-sal/model/model-inventory/src/main/yang/node-inventory.yang +++ b/opendaylight/md-sal/model/model-inventory/src/main/yang/node-inventory.yang @@ -63,7 +63,6 @@ module opendaylight-inventory { uses node-connector; } - } grouping node-connector { 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 87de0f5ae1..9fccb9950b 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"; revision-date "2013-07-12"; } + import network-topology {prefix "topo"; revision-date "2013-10-21"; } organization "TBD"; 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 6bbfd4b479..c39759a2ea 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"; revision-date "2013-07-12"; } + import network-topology {prefix "topo"; revision-date "2013-10-21"; } 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 1a10bf6fdd..21cf8fc8a8 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"; revision-date "2013-07-12"; } + import network-topology {prefix "topo"; revision-date "2013-10-21"; } import opendaylight-topology {prefix "odl";} organization "TBD"; diff --git a/opendaylight/md-sal/sal-binding-it/pom.xml b/opendaylight/md-sal/sal-binding-it/pom.xml index 235e6ac51e..8b2c89a343 100644 --- a/opendaylight/md-sal/sal-binding-it/pom.xml +++ b/opendaylight/md-sal/sal-binding-it/pom.xml @@ -21,6 +21,7 @@ ../sal-binding-broker/target/jacoco-it.exec 0.2.3-SNAPSHOT 0.2.3-SNAPSHOT + 2.5.0 @@ -63,7 +64,7 @@ - org.eclipse.m2e @@ -126,6 +127,7 @@ + org.opendaylight.yangtools.thirdparty xtend-lib-osgi @@ -173,10 +175,20 @@ org.opendaylight.controller - config-persister-file-adapter + config-persister-file-xml-adapter ${config.version} - + + org.eclipse.persistence + org.eclipse.persistence.moxy + ${moxy.controller.version} + + + org.eclipse.persistence + org.eclipse.persistence.core + ${moxy.controller.version} + + org.opendaylight.controller netconf-impl ${netconf.version} @@ -195,8 +207,8 @@ org.ops4j.pax.exam pax-exam ${exam.version} - compile 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 c943226cca..2e2d770872 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 @@ -78,7 +78,9 @@ public class TestHelper { mavenBundle(CONTROLLER, "config-netconf-connector").versionAsInProject(), // mavenBundle(CONTROLLER, "netconf-impl").versionAsInProject(), // - mavenBundle(CONTROLLER, "config-persister-file-adapter").versionAsInProject().noStart()); + mavenBundle(CONTROLLER, "config-persister-file-xml-adapter").versionAsInProject().noStart(), + mavenBundle("org.eclipse.persistence", "org.eclipse.persistence.moxy").versionAsInProject(), + mavenBundle("org.eclipse.persistence", "org.eclipse.persistence.core").versionAsInProject()); } @@ -119,9 +121,9 @@ public class TestHelper { systemProperty("netconf.tcp.client.port").value("18383"), // systemProperty("netconf.config.persister.active").value("1"), // systemProperty("netconf.config.persister.1.storageAdapterClass").value( - "org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter"), // + "org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter"), // systemProperty("netconf.config.persister.1.properties.fileStorage") - .value(PathUtils.getBaseDir() + "/src/test/resources/controller.config"), // + .value(PathUtils.getBaseDir() + "/src/test/resources/controller.xml"), // systemProperty("netconf.config.persister.1.properties.numberOfBackups").value("1") // //systemProperty("yangstore.blacklist").value(".*controller.model.*") // diff --git a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/AbstractTest.java b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/AbstractTest.java index 9b814291b9..302d94bfea 100644 --- a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/AbstractTest.java +++ b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/AbstractTest.java @@ -27,7 +27,7 @@ public abstract class AbstractTest { @Inject @Filter(timeout=60*1000) BindingAwareBroker broker; - + @Inject BundleContext bundleContext; @@ -64,9 +64,12 @@ public abstract class AbstractTest { bindingAwareSalBundles(), configMinumumBundles(), // BASE Models - baseModelBundles(), - flowCapableModelBundles(), + baseModelBundles(), + flowCapableModelBundles(), + + // Set fail if unresolved bundle present + systemProperty("pax.exam.osgi.unresolved.fail").value("true"), junitAndMockitoBundles()); } - + } diff --git a/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config b/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config deleted file mode 100644 index 28c3becc98..0000000000 --- a/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config +++ /dev/null @@ -1,123 +0,0 @@ -//START OF CONFIG-LAST - - - - prefix:schema-service-singleton - yang-schema-service - - - prefix:hash-map-data-store - hash-map-data-store - - - prefix:dom-broker-impl - dom-broker - - dom:dom-data-store - ref_hash-map-data-store - - - - prefix:binding-broker-impl - binding-broker-impl - - binding:binding-notification-service - ref_binding-notification-broker - - - binding:binding-data-broker - ref_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 - ref_dom-broker - - - binding:binding-dom-mapping-service - ref_runtime-mapping-singleton - - - - - - dom:schema-service - - ref_yang-schema-service - /config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service'] - - - - binding:binding-notification-service - - ref_binding-notification-broker - /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker'] - - - - dom:dom-data-store - - ref_hash-map-data-store - /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store'] - - - - binding:binding-broker-osgi-registry - - ref_binding-broker-impl - /config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl'] - - - - binding-impl:binding-dom-mapping-service - - ref_runtime-mapping-singleton - /config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton'] - - - - dom:dom-broker-osgi-registry - - ref_dom-broker - /config/modules/module[name='dom-broker-impl']/instance[name='dom-broker'] - - - - binding:binding-data-broker - - ref_binding-data-broker - /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker'] - - - - - - -//END OF SNAPSHOT -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: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: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:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28 -urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16 -urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09 -urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28 -//END OF CONFIG diff --git a/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml b/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml new file mode 100644 index 0000000000..08d22b96d6 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml @@ -0,0 +1,200 @@ + + + + + + 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: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: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:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28 + + urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16 + urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28 + + + + + + + + + + prefix:schema-service-singleton + + yang-schema-service + + + + prefix:hash-map-data-store + + hash-map-data-store + + + + prefix:dom-broker-impl + + dom-broker + + + dom:dom-data-store + + ref_hash-map-data-store + + + + + prefix:binding-broker-impl + + binding-broker-impl + + + binding:binding-notification-service + + ref_binding-notification-broker + + + + binding:binding-data-broker + + ref_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 + + ref_dom-broker + + + + binding:binding-dom-mapping-service + + ref_runtime-mapping-singleton + + + + + + + + dom:schema-service + + + ref_yang-schema-service + + /config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service'] + + + + + + binding:binding-notification-service + + + ref_binding-notification-broker + + /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker'] + + + + + + dom:dom-data-store + + + ref_hash-map-data-store + + /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store'] + + + + + + binding:binding-broker-osgi-registry + + + ref_binding-broker-impl + + /config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl'] + + + + + + binding-impl:binding-dom-mapping-service + + + ref_runtime-mapping-singleton + + /config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton'] + + + + + + dom:dom-broker-osgi-registry + + + ref_dom-broker + /config/modules/module[name='dom-broker-impl']/instance[name='dom-broker'] + + + + + + binding:binding-data-broker + + + ref_binding-data-broker + + /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker'] + + + + + + + + + + + diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java index 8350e39c21..f2a09d9608 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java @@ -3,7 +3,6 @@ package org.opendaylight.controller.sal.connect.netconf; import java.net.URI; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Calendar; import java.util.Date; import org.opendaylight.yangtools.yang.common.QName; @@ -12,28 +11,33 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; public class InventoryUtils { private static final URI INVENTORY_NAMESPACE = URI.create("urn:opendaylight:inventory"); - private static final Date INVENTORY_REVISION = date(); + private static final URI NETCONF_INVENTORY_NAMESPACE = URI.create("urn:opendaylight:netconf-node-inventory"); + private static final Date INVENTORY_REVISION = dateFromString("2013-08-19"); + private static final Date NETCONF_INVENTORY_REVISION = dateFromString("2014-01-08"); public static final QName INVENTORY_NODES = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "nodes"); public static final QName INVENTORY_NODE = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "node"); public static final QName INVENTORY_ID = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "id"); + public static final QName INVENTORY_CONNECTED = new QName(NETCONF_INVENTORY_NAMESPACE, NETCONF_INVENTORY_REVISION, + "connected"); + public static final QName NETCONF_INVENTORY_INITIAL_CAPABILITY = new QName(NETCONF_INVENTORY_NAMESPACE, + NETCONF_INVENTORY_REVISION, "initial-capability"); public static final InstanceIdentifier INVENTORY_PATH = InstanceIdentifier.builder().node(INVENTORY_NODES) .toInstance(); public static final QName NETCONF_INVENTORY_MOUNT = null; - - - - private static Date date() { + + /** + * Converts date in string format yyyy-MM-dd to java.util.Date. + * + * @return java.util.Date conformant to string formatted date yyyy-MM-dd. + */ + private static Date dateFromString(final String date) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); try { - return formatter.parse("2013-08-19"); + return formatter.parse(date); } catch (ParseException e) { - // TODO Auto-generated catch block e.printStackTrace(); } return null; } - - - } 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 21500e1da6..3799dd245e 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 @@ -17,6 +17,7 @@ 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.controller.netconf.util.xml.XmlUtil import org.opendaylight.controller.sal.core.api.Broker.ProviderSession import org.opendaylight.controller.sal.core.api.Provider import org.opendaylight.controller.sal.core.api.RpcImplementation @@ -25,7 +26,6 @@ import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance import org.opendaylight.controller.sal.core.api.mount.MountProvisionService import org.opendaylight.protocol.framework.ReconnectStrategy -import org.opendaylight.yang.gen.v1.urn.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 @@ -39,7 +39,6 @@ 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 @@ -49,7 +48,6 @@ 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, // @@ -105,6 +103,8 @@ AutoCloseable { @Property var SchemaSourceProvider remoteSourceProvider + + DataBrokerService dataBroker public new(String name) { this.name = name; @@ -121,8 +121,6 @@ AutoCloseable { 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; @@ -138,29 +136,63 @@ AutoCloseable { } 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(); + try { + 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(); + } + updateDeviceState() + if (mountInstance != null && confReaderReg == null && operReaderReg == null) { + confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this); + operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this); + } + } catch (Exception e) { + logger.error("Netconf client NOT started. ", e) } ] } + private def updateDeviceState() { + val transaction = dataBroker.beginTransaction + + val it = ImmutableCompositeNode.builder + setQName(INVENTORY_NODE) + addLeaf(INVENTORY_ID, name) + addLeaf(INVENTORY_CONNECTED, client.clientSession.up) + + logger.debug("Client capabilities {}", client.capabilities) + for (capability : client.capabilities) { + addLeaf(NETCONF_INVENTORY_INITIAL_CAPABILITY, capability) + } + + logger.debug("Update device state transaction " + transaction.identifier + " putting operational data started.") + transaction.putOperationalData(path, it.toInstance) + logger.debug("Update device state transaction " + transaction.identifier + " putting operational data ended.") + val transactionStatus = transaction.commit.get; + + if (transactionStatus.successful) { + logger.debug("Update device state transaction " + transaction.identifier + " SUCCESSFUL.") + } else { + logger.debug("Update device state transaction " + transaction.identifier + " FAILED!") + logger.debug("Update device state transaction status " + transaction.status) + } + } + override readConfigurationData(InstanceIdentifier path) { val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure())); @@ -209,7 +241,7 @@ AutoCloseable { } override onSessionInitiated(ProviderSession session) { - val dataBroker = session.getService(DataBrokerService); + dataBroker = session.getService(DataBrokerService); val transaction = dataBroker.beginTransaction if (transaction.operationalNodeNotExisting) { diff --git a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.config b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.config deleted file mode 100644 index 0d9cd6a9ab..0000000000 --- a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.config +++ /dev/null @@ -1,123 +0,0 @@ -//START OF CONFIG-LAST - - - - prefix:schema-service-singleton - yang-schema-service - - - prefix:hash-map-data-store - hash-map-data-store - - - prefix:dom-broker-impl - dom-broker - - dom:dom-data-store - ref_hash-map-data-store - - - - prefix:binding-broker-impl - binding-broker-impl - - binding:binding-notification-service - ref_binding-notification-broker - - - binding:binding-data-broker - ref_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 - ref_dom-broker - - - binding:binding-dom-mapping-service - ref_runtime-mapping-singleton - - - - prefix:remote-zeromq-rpc-server - remoter - 5666 - - prefix:dom-broker-osgi-registry - ref_dom-broker - - - - - - dom:schema-service - - ref_yang-schema-service - /config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service'] - - - - binding:binding-notification-service - - ref_binding-notification-broker - /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker'] - - - - dom:dom-data-store - - ref_hash-map-data-store - /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store'] - - - - binding:binding-broker-osgi-registry - - ref_binding-broker-impl - /config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl'] - - - - binding-impl:binding-dom-mapping-service - - ref_runtime-mapping-singleton - /config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton'] - - - - dom:dom-broker-osgi-registry - - ref_dom-broker - /config/modules/module[name='dom-broker-impl']/instance[name='dom-broker'] - - - - binding:binding-data-broker - - ref_binding-data-broker - /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker'] - - - - - - -//END OF SNAPSHOT -urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05 -urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28 -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:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28 -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:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&revision=2013-10-28 -//END OF CONFIG diff --git a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.xml b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.xml new file mode 100644 index 0000000000..c8e3b8369d --- /dev/null +++ b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.xml @@ -0,0 +1,197 @@ + + + + + + urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28 + + + 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:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28 + + 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:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&revision=2013-10-28 + + + + + + + + + prefix:schema-service-singleton + + yang-schema-service + + + + prefix:hash-map-data-store + + hash-map-data-store + + + + prefix:dom-broker-impl + + dom-broker + + + dom:dom-data-store + + ref_hash-map-data-store + + + + + prefix:binding-broker-impl + + binding-broker-impl + + + binding:binding-notification-service + + ref_binding-notification-broker + + + + binding:binding-data-broker + + ref_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 + + ref_dom-broker + + + + binding:binding-dom-mapping-service + + ref_runtime-mapping-singleton + + + + + prefix:remote-zeromq-rpc-server + + remoter + 5666 + + + prefix:dom-broker-osgi-registry + + ref_dom-broker + + + + + + + + dom:schema-service + + + ref_yang-schema-service + + /config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service'] + + + + + + binding:binding-notification-service + + + ref_binding-notification-broker + + /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker'] + + + + + + dom:dom-data-store + + + ref_hash-map-data-store + + /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store'] + + + + + + binding:binding-broker-osgi-registry + + + ref_binding-broker-impl + + /config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl'] + + + + + + binding-impl:binding-dom-mapping-service + + + ref_runtime-mapping-singleton + + /config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton'] + + + + + + dom:dom-broker-osgi-registry + + + ref_dom-broker + /config/modules/module[name='dom-broker-impl']/instance[name='dom-broker'] + + + + + + binding:binding-data-broker + + + ref_binding-data-broker + + /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker'] + + + + + + + + + + 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 343601865d..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 { @@ -44,12 +45,24 @@ class BrokerFacade implements DataReader { 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) 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 @@ -64,6 +77,14 @@ class BrokerFacade implements DataReader { 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 @@ -76,6 +97,18 @@ class BrokerFacade implements DataReader { 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); + 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 commitConfigurationDataDelete(InstanceIdentifier path) { checkPreconditions @@ -83,5 +116,12 @@ class BrokerFacade implements DataReader { 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/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index 308975c8c5..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,7 +10,6 @@ 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 @@ -37,12 +36,16 @@ import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition import org.slf4j.LoggerFactory import static com.google.common.base.Preconditions.* -import java.util.ArrayList +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" @Property var SchemaContext globalSchema; @@ -66,7 +69,7 @@ class ControllerContext implements SchemaServiceListener { private def void checkPreconditions() { if (globalSchema === null) { - throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG) + throw new ResponseException(SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG) } } @@ -76,7 +79,6 @@ class ControllerContext implements SchemaServiceListener { public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) { checkPreconditions - val ret = InstanceIdentifier.builder(); val pathArgs = restconfInstance.split("/"); if (pathArgs.empty) { return null; @@ -84,21 +86,19 @@ class ControllerContext implements SchemaServiceListener { if (pathArgs.head.empty) { pathArgs.remove(0) } - val mountPoints = new ArrayList - val schemaNode = ret.collectPathArguments(pathArgs, globalSchema.findModule(pathArgs.head), mountPoints); - 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, mountPoints.last) + val iiWithSchemaNode = collectPathArguments(InstanceIdentifier.builder(), pathArgs, + globalSchema.getLatestModule(startModule), null); + if (iiWithSchemaNode === null) { + throw new ResponseException(BAD_REQUEST, "URI has bad format") + } + return iiWithSchemaNode } - private def findModule(SchemaContext context,String argument) { - checkNotNull(argument); - val startModule = argument.toModuleName(); - return context.getLatestModule(startModule) - } - - private def getLatestModule(SchemaContext schema,String moduleName) { + private def getLatestModule(SchemaContext schema, String moduleName) { checkArgument(schema !== null); checkArgument(moduleName !== null && !moduleName.empty) val modules = schema.modules.filter[m|m.name == moduleName] @@ -121,9 +121,9 @@ class ControllerContext implements SchemaServiceListener { return globalSchema.getLatestModule(moduleName) } - def findModuleByName(String moduleName, InstanceIdentifier partialPath) { - checkArgument(moduleName !== null && !moduleName.empty && partialPath !== null && !partialPath.path.empty) - val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext; + def findModuleByName(MountInstance mountPoint, String moduleName) { + checkArgument(moduleName !== null && mountPoint !== null) + val mountPointSchema = mountPoint.schemaContext; return mountPointSchema?.getLatestModule(moduleName); } @@ -133,9 +133,9 @@ class ControllerContext implements SchemaServiceListener { return moduleSchemas?.filterLatestModule } - def findModuleByNamespace(URI namespace, InstanceIdentifier partialPath) { - checkArgument(namespace !== null && !namespace.toString.empty && partialPath !== null && !partialPath.path.empty) - val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext; + def findModuleByNamespace(MountInstance mountPoint, URI namespace) { + checkArgument(namespace !== null && mountPoint !== null) + val mountPointSchema = mountPoint.schemaContext; val moduleSchemas = mountPointSchema?.findModuleByNamespace(namespace) return moduleSchemas?.filterLatestModule } @@ -254,39 +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, List mountPoints) { + + 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; - } - val nodeRef = strings.head; - - val nodeName = nodeRef.toNodeName; - var targetNode = parentNode.findInstanceDataChild(nodeName); - if (targetNode instanceof ChoiceNode) { - return null + return new InstanceIdWithSchemaNode(builder.toInstance, parentNode as DataSchemaNode, mountPoint) } - if (targetNode === null) { - // Node is possibly in other mount point - val partialPath = builder.toInstance; - val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext; - if(mountPointSchema !== null) { - val module = mountPointSchema.findModule(strings.head) - if (module !== null) { - mountPoints.add(partialPath) + 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.") } - return builder.collectPathArguments(strings, module, mountPoints); + } 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 } - // Number of consumed elements var consumed = 1; if (targetNode instanceof ListSchemaNode) { @@ -295,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(); @@ -305,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; @@ -319,23 +374,28 @@ class ControllerContext implements SchemaServiceListener { } if (targetNode instanceof DataNodeContainer) { val remaining = strings.subList(consumed, strings.length); - val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer, mountPoints); + val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer, mountPoint); return result } - return targetNode + return new InstanceIdWithSchemaNode(builder.toInstance, targetNode, mountPoint) } - - static def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name) { - // FIXME: Add namespace comparison - var potentialNode = container.getDataChildByName(name); - if(potentialNode.instantiatedDataSchema) { + + 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); - if(potentialNode !== null) { + potentialNode = caze.findInstanceDataChild(name, moduleNamespace); + if (potentialNode !== null) { return potentialNode; } } @@ -372,21 +432,21 @@ class ControllerContext implements SchemaServiceListener { 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) { 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 ba0e47ff92..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,9 +8,9 @@ public class InstanceIdWithSchemaNode { private final InstanceIdentifier instanceIdentifier; private final DataSchemaNode schemaNode; - private final InstanceIdentifier mountPoint; + private final MountInstance mountPoint; - public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, InstanceIdentifier mountPoint) { + public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, MountInstance mountPoint) { this.instanceIdentifier = instanceIdentifier; this.schemaNode = schemaNode; this.mountPoint = mountPoint; @@ -23,7 +24,7 @@ public class InstanceIdWithSchemaNode { return schemaNode; } - public InstanceIdentifier getMountPoint() { + public MountInstance getMountPoint() { return mountPoint; } 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 a65c0ff97a..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,17 @@ 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 @@ -21,11 +25,11 @@ 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 import static javax.ws.rs.core.Response.Status.* -import org.opendaylight.yangtools.yang.model.api.RpcDefinition class RestconfImpl implements RestconfService { @@ -92,21 +96,36 @@ class RestconfImpl implements RestconfService { } override readData(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.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) { @@ -114,9 +133,15 @@ class RestconfImpl implements RestconfService { } override updateConfigurationData(String identifier, CompositeNode payload) { - val identifierWithSchemaNode = identifier.resolveInstanceIdentifier - val value = normalizeNode(payload, identifierWithSchemaNode.schemaNode, identifierWithSchemaNode.mountPoint) - val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier, value).get(); + 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 @@ -128,14 +153,21 @@ class RestconfImpl implements RestconfService { } override createConfigurationData(String identifier, CompositeNode payload) { - val uncompleteIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier - var schemaNode = (uncompleteIdentifierWithSchemaNode.schemaNode as DataNodeContainer).getSchemaChildNode(payload) - if (schemaNode === null) { - schemaNode = payload.findModule(uncompleteIdentifierWithSchemaNode.instanceIdentifier)?.getSchemaChildNode(payload) - } - val value = normalizeNode(payload, schemaNode, uncompleteIdentifierWithSchemaNode.instanceIdentifier) - val completeIdentifierWithSchemaNode = uncompleteIdentifierWithSchemaNode.addLastIdentifierFromData(value, schemaNode) - val status = broker.commitConfigurationDataPost(completeIdentifierWithSchemaNode.instanceIdentifier, value)?.get(); + 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 } @@ -146,10 +178,20 @@ class RestconfImpl implements RestconfService { } override createConfigurationData(CompositeNode payload) { - val schemaNode = payload.findModule(null)?.getSchemaChildNode(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 identifierWithSchemaNode = addLastIdentifierFromData(null, value, schemaNode) - val status = broker.commitConfigurationDataPost(identifierWithSchemaNode.instanceIdentifier, value)?.get(); + 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 } @@ -160,36 +202,43 @@ class RestconfImpl implements RestconfService { } override deleteConfigurationData(String identifier) { - val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier - val status = broker.commitConfigurationDataDelete(instanceIdentifierWithSchemaNode.getInstanceIdentifier).get; + 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 InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) { - val identifierWithSchemaNode = identifier.toInstanceIdentifier - if (identifierWithSchemaNode === null) { - throw new ResponseException(BAD_REQUEST, "URI has bad format"); - } - return identifierWithSchemaNode + + 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(CompositeNode data, InstanceIdentifier partialPath) { - if (partialPath !== null && !partialPath.path.empty) { - return data.nodeType.namespace.findModuleByNamespace(partialPath) + private def dispatch Module findModule(MountInstance mountPoint, CompositeNode data) { + if (mountPoint !== null) { + return mountPoint.findModuleByNamespace(data.nodeType.namespace) } else { - return data.nodeType.namespace.findModuleByNamespace + return findModuleByNamespace(data.nodeType.namespace) } } - private def dispatch Module findModule(CompositeNodeWrapper data, InstanceIdentifier partialPath) { + private def dispatch Module findModule(MountInstance mountPoint, CompositeNodeWrapper data) { + Preconditions.checkNotNull(data.namespace) var Module module = null; - if (partialPath !== null && !partialPath.path.empty) { - module = data.namespace.findModuleByNamespace(partialPath) // namespace from XML + if (mountPoint !== null) { + module = mountPoint.findModuleByNamespace(data.namespace) // namespace from XML if (module === null) { - module = data.namespace.toString.findModuleByName(partialPath) // namespace (module name) from JSON + module = mountPoint.findModuleByName(data.namespace.toString) // namespace (module name) from JSON } } else { module = data.namespace.findModuleByNamespace // namespace from XML @@ -208,10 +257,11 @@ class RestconfImpl implements RestconfService { return parentSchemaNode?.getDataChildByName(data.localName) } - private def InstanceIdWithSchemaNode addLastIdentifierFromData(InstanceIdWithSchemaNode identifierWithSchemaNode, CompositeNode data, DataSchemaNode schemaOfData) { + private def InstanceIdWithSchemaNode addLastIdentifierFromData(InstanceIdWithSchemaNode identifierWithSchemaNode, + CompositeNode data, DataSchemaNode schemaOfData) { val iiOriginal = identifierWithSchemaNode?.instanceIdentifier - var InstanceIdentifierBuilder iiBuilder = null - if (iiOriginal === null) { + var InstanceIdentifierBuilder iiBuilder = null + if (iiOriginal === null) { iiBuilder = InstanceIdentifier.builder } else { iiBuilder = InstanceIdentifier.builder(iiOriginal) @@ -230,15 +280,20 @@ class RestconfImpl implements RestconfService { 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 + "\"") + 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, InstanceIdentifier mountPoint) { - if (schema !== null && !schema.containerOrList) { + 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) { @@ -250,12 +305,8 @@ class RestconfImpl implements RestconfService { return node } - private def isContainerOrList(DataSchemaNode schemaNode) { - return (schemaNode instanceof ContainerSchemaNode) || (schemaNode instanceof ListSchemaNode) - } - private def void normalizeNode(NodeWrapper nodeBuilder, DataSchemaNode schema, QName previousAugment, - InstanceIdentifier mountPoint) { + MountInstance mountPoint) { if (schema === null) { throw new ResponseException(BAD_REQUEST, "Data has bad format.\n\"" + nodeBuilder.localName + "\" does not exist in yang schema."); @@ -267,9 +318,11 @@ class RestconfImpl implements RestconfService { } else if (previousAugment !== null && schema.QName.namespace !== previousAugment.namespace) { validQName = QName.create(currentAugment, schema.QName.localName); } - var moduleName = controllerContext.findModuleNameByNamespace(validQName.namespace); - if (moduleName === null && mountPoint !== null && !mountPoint.path.empty) { - moduleName = controllerContext.findModuleByNamespace(validQName.namespace, mountPoint)?.name + 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) { 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/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/test/ControllerContextTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java index c68fcb9071..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 @@ -2,21 +2,19 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; 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.opendaylight.controller.sal.core.api.mount.MountInstance; -import org.opendaylight.controller.sal.core.api.mount.MountService; +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; @@ -25,6 +23,9 @@ 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.loadModulesFrom("/full-versions/yangs"); @@ -33,6 +34,11 @@ public class ControllerContextTest { controllerContext.setSchemas(schemaContext); } + @After + public void releaseMountService() { + controllerContext.setMountService(null); + } + @Test public void testToInstanceIdentifierList() throws FileNotFoundException { InstanceIdWithSchemaNode instanceIdentifier = controllerContext @@ -50,48 +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 testToInstanceIdentifierMountPoint() throws FileNotFoundException { - try { - String mountPointPath = "simple-nodes:user/foo/boo"; - String nestedPath = "simple-nodes:user/foo/boo/simple-nodes:users"; - InstanceIdWithSchemaNode mountInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath); - assertEquals("user", mountInstanceIdentifier.getSchemaNode().getQName().getLocalName()); - - MountInstance mountInstance = mock(MountInstance.class); - MountService mountService = mock(MountService.class); - - controllerContext.setMountService(mountService); - // when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(null); - - when(mountService.getMountPoint(eq(mountInstanceIdentifier.getInstanceIdentifier()))).thenReturn( - mountInstance); - - when(mountInstance.getSchemaContext()).thenReturn(controllerContext.getGlobalSchema()); - - InstanceIdWithSchemaNode mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(nestedPath); - assertEquals("users", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName()); - - mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath + "/" + mountPointPath); - assertEquals("user", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName()); - - mountedInstanceIdentifier = controllerContext - .toInstanceIdentifier("simple-nodes:user/foo/var/simple-nodes:users"); - assertNull(mountedInstanceIdentifier); - - } finally { - controllerContext.setMountService(null); - } + 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 @@ -104,18 +82,30 @@ public class ControllerContextTest { @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); + @Test + public void testToInstanceIdentifierChoiceException() { + exception.expect(ResponseException.class); + exception.expectMessage("HTTP 400 Bad Request"); + controllerContext.toInstanceIdentifier("simple-nodes:food/snack"); + } - instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena"); - assertNull(instanceIdentifier); + @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/DummyMountInstanceImpl.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyMountInstanceImpl.java deleted file mode 100644 index 181aa04811..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyMountInstanceImpl.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.opendaylight.controller.sal.restconf.impl.test; - -import java.util.concurrent.Future; - -import org.opendaylight.controller.sal.core.api.data.DataChangeListener; -import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.core.api.mount.MountInstance; -import org.opendaylight.controller.sal.core.api.notify.NotificationListener; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.Registration; -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; - -class DummyMountInstanceImpl implements MountInstance { - - SchemaContext schemaContext; - - public static class Builder { - SchemaContext schemaContext; - - public Builder setSchemaContext(SchemaContext schemaContext) { - this.schemaContext = schemaContext; - return this; - } - - public MountInstance build() { - DummyMountInstanceImpl instance = new DummyMountInstanceImpl(); - instance.schemaContext = schemaContext; - return instance; - } - } - - @Override - public Registration addNotificationListener(QName notification, NotificationListener listener) { - // TODO Auto-generated method stub - return null; - } - - @Override - public CompositeNode readConfigurationData(InstanceIdentifier path) { - // TODO Auto-generated method stub - return null; - } - - @Override - public CompositeNode readOperationalData(InstanceIdentifier path) { - // TODO Auto-generated method stub - return null; - } - - @Override - public DataModificationTransaction beginTransaction() { - // TODO Auto-generated method stub - return null; - } - - @Override - public ListenerRegistration registerDataChangeListener(InstanceIdentifier path, - DataChangeListener listener) { - // TODO Auto-generated method stub - return null; - } - - @Override - public SchemaContext getSchemaContext() { - return schemaContext; - } - - @Override - public Future> rpc(QName type, CompositeNode input) { - // 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/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/RestConfigDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestConfigDataTest.java index dccf0d3bae..c6d0a93a6f 100644 --- 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 @@ -73,7 +73,8 @@ public class RestConfigDataTest extends JerseyTest { restconfImpl.setControllerContext(controllerContext); } - @Test +// @Test + // TODO public void createConfigurationDataTest() throws UnsupportedEncodingException, ParseException { initMocking(); String URI_1 = createUri("/config", ""); @@ -141,7 +142,8 @@ public class RestConfigDataTest extends JerseyTest { assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString()); } - @Test +// @Test + // TODO public void testExistingData() throws UnsupportedEncodingException { initMocking(); String URI_1 = createUri("/config", ""); 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 index 814c8a3c64..4b36d63539 100644 --- 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 @@ -11,7 +11,6 @@ import java.io.FileNotFoundException; import java.io.UnsupportedEncodingException; import java.util.Set; import java.util.concurrent.Future; -import java.util.logging.Level; import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; @@ -19,7 +18,6 @@ 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.opendaylight.controller.md.sal.common.api.TransactionStatus; @@ -38,7 +36,6 @@ public class RestDeleteOperationTest 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 { @@ -56,13 +53,10 @@ public class RestDeleteOperationTest extends JerseyTest { @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()); - +// 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); @@ -70,24 +64,22 @@ public class RestDeleteOperationTest extends JerseyTest { } @Test - public void testDeleteConfigurationData() throws UnsupportedEncodingException, FileNotFoundException { - String uri2 = createUri("/config/", "test-interface:interfaces"); - - RpcResult rpcResult = new DummyRpcResult.Builder().result( - TransactionStatus.COMMITED).build(); - Future> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build(); + 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(uri2).request(MEDIA_TYPE_DRAFT02).delete(); + Response response = target(uri).request(MediaType.APPLICATION_XML).delete(); assertEquals(200, response.getStatus()); - - rpcResult = new DummyRpcResult.Builder().result(TransactionStatus.FAILED).build(); - dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build(); - + + dummyFuture = createFuture(TransactionStatus.FAILED); when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture); - - response = target(uri2).request(MEDIA_TYPE_DRAFT02).delete(); + 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 index d997a8afb1..ebc8a09f15 100644 --- 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 @@ -4,7 +4,6 @@ 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.JSON; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri; @@ -14,7 +13,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; @@ -22,14 +20,11 @@ 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.core.api.mount.MountInstance; import org.opendaylight.controller.sal.core.api.mount.MountService; -import org.opendaylight.controller.sal.rest.api.Draft01; 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; @@ -50,6 +45,7 @@ public class RestGetOperationTest extends JerseyTest { private static RestconfImpl restconfImpl; private static SchemaContext schemaContextYangsIetf; private static SchemaContext schemaContextTestModule; + private static CompositeNode answerFromGet; @BeforeClass public static void init() throws FileNotFoundException { @@ -61,27 +57,16 @@ public class RestGetOperationTest extends JerseyTest { restconfImpl = RestconfImpl.getInstance(); restconfImpl.setBroker(brokerFacade); restconfImpl.setControllerContext(controllerContext); - } - - @Before - public void logs() { - /* enable/disable Jersey logs to console */ - /* - * List loggedRecords = getLoggedRecords(); for (LogRecord l - * : loggedRecords) { System.out.println(l.getMessage()); } - */ + 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()); - +// 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, @@ -90,184 +75,76 @@ public class RestGetOperationTest extends JerseyTest { } /** - * Tests {@link RestconfImpl#readData() readAllData()} method of - * RestconfImpl with url {@code "/datastore/ identifier}"}. Status codes 200 - * is tested. + * Tests of status codes for "/datastore/{identifier}". */ @Test - public void getDatastoreDataViaUrlTest200() throws FileNotFoundException, UnsupportedEncodingException { + public void getDatastoreStatusCodes() throws FileNotFoundException, UnsupportedEncodingException { mockReadOperationalDataMethod(); - getDataWithUrl("/datastore/", Draft01.MediaTypes.DATA + JSON, 200); - getDataWithUrl("/datastore/", Draft01.MediaTypes.DATA + XML, 200); - getDataWithUrl("/datastore/", MediaType.APPLICATION_JSON, 200); - getDataWithUrl("/datastore/", MediaType.APPLICATION_XML, 200); - getDataWithUrl("/datastore/", MediaType.TEXT_XML, 200); - } - - /** - * Tests {@link RestconfImpl#readData() readAllData()} method of - * RestconfImpl with url {@code "/datastore/ identifier}"}. Status codes 400 - * is tested. - */ - @Test - public void getDatastoreDataViaUrlTest400() throws FileNotFoundException, UnsupportedEncodingException { - mockReadOperationalDataMethod(); - getDataWithUrl("/datastore/", Draft01.MediaTypes.DATA + JSON, 400); - getDataWithUrl("/datastore/", Draft01.MediaTypes.DATA + XML, 400); - getDataWithUrl("/datastore/", MediaType.APPLICATION_JSON, 400); - getDataWithUrl("/datastore/", MediaType.APPLICATION_XML, 400); - getDataWithUrl("/datastore/", MediaType.TEXT_XML, 400); - } - - /** - * Tests {@link RestconfImpl#readOperationalData(String) - * readOperationalData(String)} method of RestconfImpl with url - * {@code "/operational/...identifier..."}. Status codes 200 is tested. - */ - @Test - public void getOperationalDataViaUrl200() throws UnsupportedEncodingException { - mockReadOperationalDataMethod(); - getDataWithUrl("/operational/", Draft02.MediaTypes.DATA + JSON, 200); - getDataWithUrl("/operational/", Draft02.MediaTypes.DATA + XML, 200); - getDataWithUrl("/operational/", MediaType.APPLICATION_JSON, 200); - getDataWithUrl("/operational/", MediaType.APPLICATION_XML, 200); - getDataWithUrl("/operational/", MediaType.TEXT_XML, 200); + 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 {@link RestconfImpl#readOperationalData(String) - * readOperationalData(String)} method of RestconfImpl with url - * {@code "/operational/...identifier..."}. Status codes 400 is tested. + * Tests of status codes for "/operational/{identifier}". */ @Test - public void getOperationalDataViaUrl400() throws UnsupportedEncodingException { + public void getOperationalStatusCodes() throws UnsupportedEncodingException { mockReadOperationalDataMethod(); - getDataWithUrl("/operational/", Draft02.MediaTypes.DATA + JSON, 400); - getDataWithUrl("/operational/", Draft02.MediaTypes.DATA + XML, 400); - getDataWithUrl("/operational/", MediaType.APPLICATION_JSON, 400); - getDataWithUrl("/operational/", MediaType.APPLICATION_XML, 400); - getDataWithUrl("/operational/", MediaType.TEXT_XML, 400); - } - - /** - * Tests {@link RestconfImpl#readOperationalData - * #readConfigurationData(String) readConfigurationData(String)} method of - * RestconfImpl with url {@code "/config/...identifier..."}. Status codes - * 200 is tested. - */ - @Test - public void getConfigDataViaUrl200() throws UnsupportedEncodingException { - mockReadConfigurationDataMethod(); - getDataWithUrl("/config/", Draft02.MediaTypes.DATA + JSON, 200); - getDataWithUrl("/config/", Draft02.MediaTypes.DATA + XML, 200); - getDataWithUrl("/config/", MediaType.APPLICATION_JSON, 200); - getDataWithUrl("/config/", MediaType.APPLICATION_XML, 200); - getDataWithUrl("/config/", MediaType.TEXT_XML, 200); + 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 {@link RestconfImpl#readOperationalData - * #readConfigurationData(String) readConfigurationData(String)} method of - * RestconfImpl with url {@code "/config/...identifier..."}. Status codes - * 400 is tested. + * Tests of status codes for "/config/{identifier}". */ @Test - public void getConfigDataViaUrl400() throws UnsupportedEncodingException { + public void getConfigStatusCodes() throws UnsupportedEncodingException { mockReadConfigurationDataMethod(); - getDataWithUrl("/config/", Draft02.MediaTypes.DATA + JSON, 400); - getDataWithUrl("/config/", Draft02.MediaTypes.DATA + XML, 400); - getDataWithUrl("/config/", MediaType.APPLICATION_JSON, 400); - getDataWithUrl("/config/", MediaType.APPLICATION_XML, 400); - getDataWithUrl("/config/", MediaType.TEXT_XML, 400); - } - - /** - * Tests {@link RestconfImpl#readAllData() readAllData()} method of - * RestconfImpl with url {@code "/datastore"}. Currently the method isn't - * supported so it returns 500 - */ - @Test - public void getDatastoreDataAllTest500() throws UnsupportedEncodingException { - getDatastoreAllDataTest(Draft01.MediaTypes.DATASTORE + XML); - getDatastoreAllDataTest(Draft01.MediaTypes.DATASTORE + JSON); - } - - /** - * - * Tests {@link RestconfImpl#getModules getModules} method of RestconfImpl - * with uri {@code "/modules"}. Currently the method isn't supported so it - * returns 500 - */ - @Test - public void getModulesDataTest500() throws UnsupportedEncodingException { - getModulesDataTest(Draft01.MediaTypes.API + JSON); - getModulesDataTest(Draft01.MediaTypes.API + XML); - getModulesDataTest(Draft02.MediaTypes.API + JSON); - getModulesDataTest(Draft02.MediaTypes.API + XML); - } - - /** - * Test of request for not existing data. Returning status code 404 - */ - @Test - public void getDataWithUrlNoExistingDataTest404() 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()); + 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, FileNotFoundException, - URISyntaxException { - when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn( - prepareCnDataForMountPointTest()); - + 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( - new DummyMountInstanceImpl.Builder().setSchemaContext(schemaContextTestModule).build()); + when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance); ControllerContext.getInstance().setMountService(mockMountService); - String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/test-module:cont/cont1"); + 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 void getDataWithUrl(String mediaTypePrefix, String mediaType, int statusCode) - throws UnsupportedEncodingException { - String uri = null; - switch (statusCode) { - case 400: - uri = createUri(mediaTypePrefix, "wrong-module:interfaces/interface/eth0"); - break; - case 200: - uri = createUri(mediaTypePrefix, "ietf-interfaces:interfaces/interface/eth0"); - break; - } - Response response = target(uri).request(mediaType).get(); - assertEquals("Status is incorrect for media type " + mediaType + ".", statusCode, response.getStatus()); - - } - - private void getModulesDataTest(String mediaType) throws UnsupportedEncodingException { - String uri = createUri("/modules", ""); - Response response = target(uri).request(mediaType).get(); - - assertEquals("Status is incorrect for media type " + mediaType + ".", 500, response.getStatus()); - } - - private void getDatastoreAllDataTest(String mediaType) throws UnsupportedEncodingException { - String uri = createUri("/datastore", ""); - Response response = target(uri).request(mediaType).get(); - - assertEquals(500, response.getStatus()); + + private int get(String uri, String mediaType) { + return target(uri).request(mediaType).get().getStatus(); } private CompositeNode prepareCnDataForMountPointTest() throws URISyntaxException { @@ -277,7 +154,15 @@ public class RestGetOperationTest extends JerseyTest { return cont1.unwrap(); } - private CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() { + 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"); @@ -295,13 +180,4 @@ public class RestGetOperationTest extends JerseyTest { return null; } - private void mockReadOperationalDataMethod() { - CompositeNode loadedCompositeNode = prepareCompositeNodeWithIetfInterfacesInterfacesData(); - when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); - } - - private void mockReadConfigurationDataMethod() { - CompositeNode loadedCompositeNode = prepareCompositeNodeWithIetfInterfacesInterfacesData(); - when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); - } } 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 index 1f0daace70..186dafb168 100644 --- 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 @@ -4,9 +4,6 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.MediaType; - import com.google.common.base.Charsets; public class RestOperationUtils { @@ -17,14 +14,6 @@ public class RestOperationUtils { private RestOperationUtils() { } - static Entity entity(String data, MediaType mediaType) { - return Entity.entity(data, mediaType); - } - - static Entity entity(String data, String mediaType) { - return Entity.entity(data, mediaType); - } - 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 index 9bf6a0f03c..833d030b92 100644 --- 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 @@ -4,34 +4,27 @@ 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.JSON; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri; -import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.entity; -import java.io.FileNotFoundException; 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 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.Before; 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.Draft01; import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; @@ -49,13 +42,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; public class RestPostOperationTest extends JerseyTest { - private static String xmlData; private static String xmlDataAbsolutePath; - private static String jsonData; - private static String jsonDataAbsolutePath; private static String xmlDataRpcInput; private static CompositeNodeWrapper cnSnDataOutput; - private static String jsonDataRpcInput; private static String xmlData2; private static ControllerContext controllerContext; @@ -76,26 +65,13 @@ public class RestPostOperationTest extends JerseyTest { loadData(); } - @Before - public void logs() throws IOException, URISyntaxException { - /* enable/disable Jersey logs to console */ - /* - * List loggedRecords = getLoggedRecords(); for (LogRecord l - * : loggedRecords) { System.out.println(l.getMessage()); } - */ - } - @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()); - +// 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, @@ -104,200 +80,88 @@ public class RestPostOperationTest extends JerseyTest { } @Test - public void postOperationsDataViaUrl200() throws URISyntaxException, IOException { - controllerContext.setSchemas(schemaContextTestModule); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 200); - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 200); - postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 200); - - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 200); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 200); - postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 200); - postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 200); - } - - @Test - public void postOperationsDataViaUrl204() throws URISyntaxException, IOException { - controllerContext.setSchemas(schemaContextTestModule); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 204); - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 204); - postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 204); - - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 204); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 204); - postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 204); - postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 204); - } - - @Test - public void postOperationsDataViaUrl500() throws URISyntaxException, IOException { - controllerContext.setSchemas(schemaContextTestModule); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 500); - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 500); - postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 500); - - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 500); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 500); - postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 500); - postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 500); - } - - @Test - public void postOperationsDataViaUrl400() throws URISyntaxException, IOException { - controllerContext.setSchemas(schemaContextTestModule); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 400); - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 400); - postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 400); - - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 400); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 400); - postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 400); - postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 400); - } - - @Test - public void postOperationsDataViaUrl404() throws URISyntaxException, IOException { + public void postOperationsStatusCodes() throws UnsupportedEncodingException { controllerContext.setSchemas(schemaContextTestModule); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 404); - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 404); - postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 404); - - postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 404); - postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 404); - postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 404); - postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 404); + 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 postConfigDataViaUrlConfigOnlyTest204() throws UnsupportedEncodingException, FileNotFoundException { + public void postConfigOnlyStatusCodes() throws UnsupportedEncodingException { controllerContext.setSchemas(schemaContextYangsIetf); mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED); - postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + JSON, jsonDataAbsolutePath, 204); - postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + XML, xmlDataAbsolutePath, 204); - postDataViaUrlTest("/config", "", MediaType.APPLICATION_JSON, jsonDataAbsolutePath, 204); - postDataViaUrlTest("/config", "", MediaType.APPLICATION_XML, xmlDataAbsolutePath, 204); - postDataViaUrlTest("/config", "", MediaType.TEXT_XML, xmlDataAbsolutePath, 204); - } - - @Test - public void postConfigDataViaUrlConfigOnlyTest202() throws UnsupportedEncodingException, FileNotFoundException { - controllerContext.setSchemas(schemaContextYangsIetf); + String uri = createUri("/config", ""); + assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); + mockCommitConfigurationDataPostMethod(null); - postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + JSON, jsonDataAbsolutePath, 202); - postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + XML, xmlDataAbsolutePath, 202); - postDataViaUrlTest("/config", "", MediaType.APPLICATION_JSON, jsonDataAbsolutePath, 202); - postDataViaUrlTest("/config", "", MediaType.APPLICATION_XML, xmlDataAbsolutePath, 202); - postDataViaUrlTest("/config", "", MediaType.TEXT_XML, xmlDataAbsolutePath, 202); - } - - @Test - public void postConfigDataViaUrlConfigOnlyTest500() throws UnsupportedEncodingException, FileNotFoundException { - controllerContext.setSchemas(schemaContextYangsIetf); + assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); + mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED); - postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + JSON, jsonDataAbsolutePath, 500); - postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + XML, xmlDataAbsolutePath, 500); - postDataViaUrlTest("/config", "", MediaType.APPLICATION_JSON, jsonDataAbsolutePath, 500); - postDataViaUrlTest("/config", "", MediaType.APPLICATION_XML, xmlDataAbsolutePath, 500); - postDataViaUrlTest("/config", "", MediaType.TEXT_XML, xmlDataAbsolutePath, 500); + assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); } @Test - public void postConfigDataViaUrlTest204() throws UnsupportedEncodingException { + public void postConfigStatusCodes() throws UnsupportedEncodingException { controllerContext.setSchemas(schemaContextYangsIetf); mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED); - String urlPath = "ietf-interfaces:interfaces"; - postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + JSON, jsonData, 204); - postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + XML, xmlData, 204); - postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_JSON, jsonData, 204); - postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_XML, xmlData, 204); - postDataViaUrlTest("/config/", urlPath, MediaType.TEXT_XML, xmlData, 204); - } - - @Test - public void postConfigDataViaUrlTest202() throws UnsupportedEncodingException { - controllerContext.setSchemas(schemaContextYangsIetf); + String uri = createUri("/config/", "ietf-interfaces:interfaces"); + assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); + mockCommitConfigurationDataPostMethod(null); - String urlPath = "ietf-interfaces:interfaces"; - postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + JSON, jsonData, 202); - postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + XML, xmlData, 202); - postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_JSON, jsonData, 202); - postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_XML, xmlData, 202); - postDataViaUrlTest("/config/", urlPath, MediaType.TEXT_XML, xmlData, 202); - } - - @Test - public void postConfigDataViaUrlTest500() throws UnsupportedEncodingException { - controllerContext.setSchemas(schemaContextYangsIetf); + assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); + mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED); - String urlPath = "ietf-interfaces:interfaces"; - postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + JSON, jsonData, 500); - postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + XML, xmlData, 500); - postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_JSON, jsonData, 500); - postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_XML, xmlData, 500); - postDataViaUrlTest("/config/", urlPath, MediaType.TEXT_XML, xmlData, 500); + assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); } @Test - public void postDatastoreDataViaUrlTest204() throws UnsupportedEncodingException { + public void postDatastoreStatusCodes() throws UnsupportedEncodingException { controllerContext.setSchemas(schemaContextYangsIetf); mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED); - String urlPath = "ietf-interfaces:interfaces"; - postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + JSON, jsonData, 204); - postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + XML, xmlData, 204); - postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_JSON, jsonData, 204); - postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_XML, xmlData, 204); - postDataViaUrlTest("/datastore/", urlPath, MediaType.TEXT_XML, xmlData, 204); - } - - @Test - public void postDatastoreDataViaUrlTest202() throws UnsupportedEncodingException { - controllerContext.setSchemas(schemaContextYangsIetf); + String uri = createUri("/datastore/", "ietf-interfaces:interfaces"); + assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); + mockCommitConfigurationDataPostMethod(null); - String urlPath = "ietf-interfaces:interfaces"; - postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + JSON, jsonData, 202); - postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + XML, xmlData, 202); - postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_JSON, jsonData, 202); - postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_XML, xmlData, 202); - postDataViaUrlTest("/datastore/", urlPath, MediaType.TEXT_XML, xmlData, 202); - } - - @Test - public void postDatastoreDataViaUrlTest500() throws UnsupportedEncodingException { - controllerContext.setSchemas(schemaContextYangsIetf); + assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); + mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED); - String urlPath = "ietf-interfaces:interfaces"; - postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + JSON, jsonData, 500); - postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + XML, xmlData, 500); - postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_JSON, jsonData, 500); - postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_XML, xmlData, 500); - postDataViaUrlTest("/datastore/", urlPath, MediaType.TEXT_XML, xmlData, 500); + assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath)); } @Test public void postDataViaUrlMountPoint() throws UnsupportedEncodingException { controllerContext.setSchemas(schemaContextYangsIetf); - mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED); + 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); - SchemaContext otherSchemaContext = schemaContextTestModule; - when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn( - new DummyMountInstanceImpl.Builder().setSchemaContext(otherSchemaContext).build()); + when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance); ControllerContext.getInstance().setMountService(mockMountService); - String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/test-module:cont/cont1"); - Response response = target(uri).request(Draft02.MediaTypes.DATA + XML).post( - entity(xmlData2, Draft02.MediaTypes.DATA + XML)); - // 204 code is returned when COMMITED transaction status is put as input - // to mock method - assertEquals(204, response.getStatus()); + 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 postDataViaUrlTest(String urlPrefix, String urlPath, String mediaType, String data, int responseStatus) - throws UnsupportedEncodingException { - String url = createUri(urlPrefix, urlPath); - Response response = target(url).request(mediaType).post(entity(data, mediaType)); - assertEquals(responseStatus, response.getStatus()); + + 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) { @@ -313,72 +177,27 @@ public class RestPostOperationTest extends JerseyTest { when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class))) .thenReturn(dummyFuture); } - - 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; - } - - private void mockInvokeRpc(CompositeNode compositeNode, boolean sucessful) { - RpcResult rpcResult = new DummyRpcResult.Builder().result(compositeNode) - .isSuccessful(sucessful).build(); - when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(rpcResult); - } - - private void postOperationsDataViaUrl(String mediaType, CompositeNode cnSnDataOut, String dataIn, int statusCode) - throws FileNotFoundException, UnsupportedEncodingException { - String url = createUri("/operations/", "test-module:rpc-test"); - Response response = null; - switch (statusCode) { - case 200: - mockInvokeRpc(cnSnDataOut, true); - break; - case 204: - mockInvokeRpc(null, true); - break; - case 500: - mockInvokeRpc(null, false); - break; - case 400: - response = target(url).request(mediaType).post(Entity.entity("{}", mediaType)); - break; - case 404: - url = createUri("/operations/", "test-module:rpc-wrongtest"); - break; - } - response = response == null ? target(url).request(mediaType).post(Entity.entity(dataIn, mediaType)) : response; - assertEquals(statusCode, response.getStatus()); + + 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.xml"); - xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream)); - - xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces_absolute_path.xml"); + InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces_absolute_path.xml"); xmlDataAbsolutePath = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream)); - - String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath(); - jsonData = TestUtils.loadTextFile(jsonPath); - - String jsonFullPath = RestconfImplTest.class - .getResource("/parts/ietf-interfaces_interfaces_absolute_path.json").getPath(); - jsonDataAbsolutePath = TestUtils.loadTextFile(jsonFullPath); - String xmlPathRpcInput = RestconfImplTest.class.getResource("/full-versions/test-data2/data-rpc-input.xml") .getPath(); xmlDataRpcInput = TestUtils.loadTextFile(xmlPathRpcInput); cnSnDataOutput = prepareCnSnRpcOutput(); - - String jsonPathToRpcInput = RestconfImplTest.class.getResource("/full-versions/test-data2/data-rpc-input.json") - .getPath(); - jsonDataRpcInput = TestUtils.loadTextFile(jsonPathToRpcInput); - 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 index 2bef9ba4ef..2df68af62f 100644 --- 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 @@ -4,10 +4,8 @@ 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.JSON; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri; -import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.entity; import java.io.FileNotFoundException; import java.io.IOException; @@ -15,7 +13,6 @@ import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.util.concurrent.Future; -import java.util.logging.Level; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Application; @@ -24,13 +21,11 @@ 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.core.api.mount.MountInstance; import org.opendaylight.controller.sal.core.api.mount.MountService; -import org.opendaylight.controller.sal.rest.api.Draft01; import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; @@ -47,7 +42,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; public class RestPutOperationTest extends JerseyTest { private static String xmlData; - private static String jsonData; private static BrokerFacade brokerFacade; private static RestconfImpl restconfImpl; @@ -67,25 +61,18 @@ public class RestPutOperationTest extends JerseyTest { loadData(); } - @Before - public void logs() throws IOException { - /* enable/disable Jersey logs to console */ - /* - * List loggedRecords = getLoggedRecords(); for (LogRecord l - * : loggedRecords) { System.out.println(l.getMessage()); } - */ + 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()); - +// 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, @@ -94,109 +81,65 @@ public class RestPutOperationTest extends JerseyTest { } /** - * Test method - * {@link RestconfImpl#updateConfigurationData(String, CompositeNode)} of - * RestconfImpl for "/config/...identifier..." URL. Return status code is - * 200. - * + * Tests of status codes for "/config/{identifier}". */ @Test - public void putConfigDataViaUrlTest200() throws UnsupportedEncodingException { + public void putConfigStatusCodes() throws UnsupportedEncodingException { + String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0"); mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED); - putDataViaUrlTest("/config/", Draft02.MediaTypes.DATA + JSON, jsonData, 200); - putDataViaUrlTest("/config/", Draft02.MediaTypes.DATA + XML, xmlData, 200); - putDataViaUrlTest("/config/", MediaType.APPLICATION_JSON, jsonData, 200); - putDataViaUrlTest("/config/", MediaType.APPLICATION_XML, xmlData, 200); - putDataViaUrlTest("/config/", MediaType.TEXT_XML, xmlData, 200); - - } - - /** - * Test method - * {@link RestconfImpl#updateConfigurationData(String, CompositeNode)} of - * RestconfImpl for "/config/...identifier..." URL. Return status code is - * 500. - * - */ - @Test - public void putConfigDataViaUrlTest500() throws UnsupportedEncodingException { + assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData)); + mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED); - putDataViaUrlTest("/config/", Draft02.MediaTypes.DATA + JSON, jsonData, 500); - putDataViaUrlTest("/config/", Draft02.MediaTypes.DATA + XML, xmlData, 500); - putDataViaUrlTest("/config/", MediaType.APPLICATION_JSON, jsonData, 500); - putDataViaUrlTest("/config/", MediaType.APPLICATION_XML, xmlData, 500); - putDataViaUrlTest("/config/", MediaType.TEXT_XML, xmlData, 500); - + assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData)); } - /** - * Test method - * {@link RestconfImpl#updateConfigurationData(String, CompositeNode)} of - * RestconfImpl for "/datastore/...identifier..." URL. Return status code is - * 200. - * - */ - @Test - public void putDatastoreDataViaUrlTest200() throws UnsupportedEncodingException { - mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED); - putDataViaUrlTest("/datastore/", Draft01.MediaTypes.DATA + JSON, jsonData, 200); - putDataViaUrlTest("/datastore/", Draft01.MediaTypes.DATA + XML, xmlData, 200); - putDataViaUrlTest("/datastore/", MediaType.APPLICATION_JSON, jsonData, 200); - putDataViaUrlTest("/datastore/", MediaType.APPLICATION_XML, xmlData, 200); - putDataViaUrlTest("/datastore/", MediaType.TEXT_XML, xmlData, 200); - } /** - * Test method - * {@link RestconfImpl#updateConfigurationData(String, CompositeNode)} of - * RestconfImpl for "/datastore/...identifier..." URL. Return status code is - * 500. - * + * Tests of status codes for "/datastore/{identifier}". */ @Test - public void putDatastoreDataViaUrlTest500() throws UnsupportedEncodingException { + 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); - putDataViaUrlTest("/datastore/", Draft01.MediaTypes.DATA + JSON, jsonData, 500); - putDataViaUrlTest("/datastore/", Draft01.MediaTypes.DATA + XML, xmlData, 500); - putDataViaUrlTest("/datastore/", MediaType.APPLICATION_JSON, jsonData, 500); - putDataViaUrlTest("/datastore/", MediaType.APPLICATION_XML, xmlData, 500); - putDataViaUrlTest("/datastore/", MediaType.TEXT_XML, xmlData, 500); + assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData)); } @Test public void testRpcResultCommitedToStatusCodesWithMountPoint() throws UnsupportedEncodingException, FileNotFoundException, URISyntaxException { - mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED); + 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( - new DummyMountInstanceImpl.Builder().setSchemaContext(schemaContextTestModule).build()); + when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance); ControllerContext.getInstance().setMountService(mockMountService); - String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/test-module:cont"); + 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 void putDataViaUrlTest(String uriPrefix, String mediaType, String data, int responseStatus) - throws UnsupportedEncodingException { - String uri = createUri(uriPrefix, "ietf-interfaces:interfaces/interface/eth0"); - Response response = target(uri).request(mediaType).put(entity(data, mediaType)); - assertEquals(responseStatus, response.getStatus()); - } - - private static void loadData() throws IOException { - InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml"); - xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream)); - - String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath(); - jsonData = TestUtils.loadTextFile(jsonPath); + 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) { 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/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/src/test/resources/controller.xml b/opendaylight/md-sal/src/test/resources/controller.xml new file mode 100644 index 0000000000..e69de29bb2 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 45bc905502..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 @@ -177,34 +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); + 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); - - sendAllNodeConnectorsStatisticsRequest(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); - sendAllMeterStatisticsRequest(targetNodeRef); - sendGroupDescriptionRequest(targetNodeRef); - sendMeterConfigStatisticsRequest(targetNodeRef); + sendAllQueueStatsFromAllNodeConnector (targetNodeRef); + + sendAllGroupStatisticsRequest(targetNodeRef); + + sendAllMeterStatisticsRequest(targetNodeRef); + + sendGroupDescriptionRequest(targetNodeRef); + + sendMeterConfigStatisticsRequest(targetNodeRef); }catch(Exception e){ spLogger.error("Exception occured while sending statistics requests : {}", e); } 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 05f7fe1272..8576b0d1fc 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 @@ -7,19 +7,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey 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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointBuilder -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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.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.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.SourceBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.DestinationBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.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 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 92a2277b4c..bc4e611b5c 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 @@ -18,18 +18,18 @@ 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.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.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.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.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.rev131021.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey import org.opendaylight.yangtools.yang.binding.InstanceIdentifier import static extension org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.* diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java index a8605243af..625e4ab3df 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java @@ -10,10 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Preconditions; import org.opendaylight.controller.netconf.util.xml.XmlElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStrategy { + private static final Logger logger = LoggerFactory.getLogger(SimpleAttributeReadingStrategy.class); + public SimpleAttributeReadingStrategy(String nullableDefault) { super(nullableDefault); @@ -25,7 +29,13 @@ public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStra Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + xmlElement + " but was " + configNodes.size()); - String textContent = xmlElement.getTextContent(); + String textContent = ""; + try{ + textContent = xmlElement.getTextContent(); + }catch(IllegalStateException | NullPointerException e) { + // yuma sends for empty value instead of + logger.warn("Ignoring exception caused by failure to read text element", e); + } Preconditions.checkNotNull(textContent, "This element should contain text %s", xmlElement); return AttributeConfigElement.create(postprocessNullableDefault(getNullableDefault()), diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java index 3340dde883..dd8e3c9664 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java @@ -48,7 +48,8 @@ public class NetconfClientSessionNegotiator extends @Nullable @Override public String apply(@Nullable XmlElement input) { - return input.getTextContent(); + // Trim possible leading/tailing whitespace + return input.getTextContent().trim(); } }); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java index 212214cd2a..18a94c6d07 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java @@ -272,7 +272,9 @@ public class XmlElement { public String getTextContent() { Node textChild = element.getFirstChild(); - Preconditions.checkState(textChild instanceof Text, getName() + " should contain text"); + Preconditions.checkNotNull(textChild, "Child node expected, got null for " + getName() + " : " + element); + Preconditions.checkState(textChild instanceof Text, getName() + " should contain text." + + Text.class.getName() + " expected, got " + textChild); String content = textChild.getTextContent(); // Trim needed return content.trim(); diff --git a/opendaylight/networkconfiguration/neutron/implementation/pom.xml b/opendaylight/networkconfiguration/neutron/implementation/pom.xml index 1590873b70..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, @@ -78,6 +79,11 @@ clustering.services 0.5.0-SNAPSHOT + + org.opendaylight.controller + configuration + 0.4.1-SNAPSHOT + org.opendaylight.controller networkconfig.neutron 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/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/controllermanager/pom.xml b/opendaylight/northbound/controllermanager/pom.xml index 8c3279e6c7..5baaeb0dcc 100644 --- a/opendaylight/northbound/controllermanager/pom.xml +++ b/opendaylight/northbound/controllermanager/pom.xml @@ -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, 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/web/devices/src/main/resources/js/page.js b/opendaylight/web/devices/src/main/resources/js/page.js index d7cb4f6893..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 : {