From: Tony Tkacik Date: Mon, 19 May 2014 09:50:34 +0000 (+0000) Subject: Merge "Trigger a GC once initial configuration has been pushed" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~68 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=fe87aace8123cc8988acfc74c0208472359a4f55;hp=c0b10c35abcdf8038546aa89bf29264720f12a75 Merge "Trigger a GC once initial configuration has been pushed" --- diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolver.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolver.java index b020000d3d..40ff7e1703 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolver.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolver.java @@ -7,12 +7,15 @@ */ package org.opendaylight.controller.config.api; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.ObjectName; +import javax.management.ReflectionException; import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.binding.BaseIdentity; -import javax.management.ObjectName; - /** * Each new {@link org.opendaylight.controller.config.spi.Module} can receive * resolver from {@link org.opendaylight.controller.config.spi.ModuleFactory} @@ -26,15 +29,13 @@ public interface DependencyResolver extends Identifiable { * To be used during validation phase to validate serice interface of * dependent module. * - * @param expectedServiceInterface - * MBean/MXBean interface which will back the proxy object. - * @param objectName - * ObjectName of dependent module without transaction name - * (platformON). - * @param jmxAttribute - * @throws {@link IllegalArgumentException} when module is not found - * @throws {@link IllegalStateException} if module does not export this - * service interface. + * @param expectedServiceInterface MBean/MXBean interface which will back the proxy object. + * @param objectName ObjectName of dependent module without transaction name + * (platformON). + * @param jmxAttribute for reporting + * @throws IllegalArgumentException when module is not found + * @throws IllegalStateException if module does not export this + * service interface. */ void validateDependency( Class expectedServiceInterface, @@ -44,13 +45,11 @@ public interface DependencyResolver extends Identifiable { * To be used during commit phase to wire actual dependencies. * * @return dependency instance using - * {@link org.opendaylight.controller.config.spi.Module#getInstance()} - * @throws {@link IllegalArgumentException} when module is not found + * {@link org.opendaylight.controller.config.spi.Module#getInstance()} + * @throws IllegalArgumentException when module is not found */ T resolveInstance(Class expectedType, ObjectName objectName, - JmxAttribute jmxAttribute); - - // TODO finish javadoc + JmxAttribute jmxAttribute); /** * To be used during commit phase to resolve identity-ref config attributes. @@ -59,6 +58,32 @@ public interface DependencyResolver extends Identifiable { */ Class resolveIdentity(IdentityAttributeRef identityRef, Class expectedBaseClass); + + /** + * Validate identity-ref config attribute. + */ void validateIdentity(IdentityAttributeRef identityRef, Class expectedBaseClass, JmxAttribute jmxAttribute); + /** + * Can be used during validation or commit phase to get attribute value of dependent module. + * + * @param name either direct ObjectName of a Module (type=Module) or service reference (type=ServiceReference) of dependent Module + * @param attribute String identifying attribute name in JMX. Note that attributes start with upper case. See {@link org.opendaylight.controller.config.api.JmxAttribute#getAttributeName()} + */ + Object getAttribute(ObjectName name, String attribute) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException; + + + /** + * Helper method around {@link javax.management.JMX#newMXBeanProxy(javax.management.MBeanServerConnection, javax.management.ObjectName, Class)} }. + * Returns MXBean proxy for dependent module. Can be used during validation or commit phase to inspect dependent module's attributes. + * + * @param objectName either direct ObjectName of a Module (type=Module) or service reference (type=ServiceReference) of dependent Module + * @param interfaceClass MXBean interface to be used as a proxy + * @param type of proxy for type safe return value + * @return instance of MXBean proxy + */ + T newMXBeanProxy(ObjectName objectName, Class interfaceClass); + } diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/JmxAttribute.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/JmxAttribute.java index 244f22f58e..649b1eb467 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/JmxAttribute.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/JmxAttribute.java @@ -21,6 +21,9 @@ public class JmxAttribute { this.attributeName = attributeName; } + /** + * Name of attribute in JMX. + */ public String getAttributeName() { return attributeName; } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java index 3e23120182..39eef8741b 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.config.manager.impl; +import static com.google.common.base.Preconditions.checkNotNull; import static java.lang.String.format; import java.util.ArrayList; @@ -43,8 +44,6 @@ import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import static com.google.common.base.Preconditions.checkNotNull; /** * This is a JMX bean representing current transaction. It contains * transaction identifier, unique version and parent version for @@ -96,7 +95,7 @@ class ConfigTransactionControllerImpl implements this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories); this.transactionStatus = new TransactionStatus(); this.dependencyResolverManager = new DependencyResolverManager(txLookupRegistry.getTransactionIdentifier(), - transactionStatus, writableSRRegistry, codecRegistry); + transactionStatus, writableSRRegistry, codecRegistry, transactionsMBeanServer); this.transactionsMBeanServer = transactionsMBeanServer; this.configMBeanServer = configMBeanServer; this.blankTransaction = blankTransaction; diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java index c229450c30..4f60a673f5 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java @@ -7,6 +7,19 @@ */ package org.opendaylight.controller.config.manager.impl.dependencyresolver; +import static java.lang.String.format; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import javax.annotation.concurrent.GuardedBy; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceNotFoundException; +import javax.management.JMX; +import javax.management.MBeanException; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.ReflectionException; import org.opendaylight.controller.config.api.DependencyResolver; import org.opendaylight.controller.config.api.IdentityAttributeRef; import org.opendaylight.controller.config.api.JmxAttribute; @@ -25,14 +38,6 @@ import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.concurrent.GuardedBy; -import javax.management.ObjectName; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; - -import static java.lang.String.format; - /** * Protect {@link org.opendaylight.controller.config.spi.Module#getInstance()} * by creating proxy that would throw exception if those methods are called @@ -49,15 +54,20 @@ final class DependencyResolverImpl implements DependencyResolver, private final Set dependencies = new HashSet<>(); private final ServiceReferenceReadableRegistry readableRegistry; private final CodecRegistry codecRegistry; + private final String transactionName; + private final MBeanServer mBeanServer; DependencyResolverImpl(ModuleIdentifier currentModule, TransactionStatus transactionStatus, ModulesHolder modulesHolder, - ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry) { + ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry, + String transactionName, MBeanServer mBeanServer) { this.codecRegistry = codecRegistry; this.name = currentModule; this.transactionStatus = transactionStatus; this.modulesHolder = modulesHolder; this.readableRegistry = readableRegistry; + this.transactionName = transactionName; + this.mBeanServer = mBeanServer; } /** @@ -80,7 +90,8 @@ final class DependencyResolverImpl implements DependencyResolver, JmxAttributeValidationException.checkNotNull(dependentReadOnlyON, "is null, expected dependency implementing " - + expectedServiceInterface, jmxAttribute); + + expectedServiceInterface, jmxAttribute + ); // check that objectName belongs to this transaction - this should be @@ -91,8 +102,10 @@ final class DependencyResolverImpl implements DependencyResolver, JmxAttributeValidationException.checkCondition( hasTransaction == false, format("ObjectName should not contain " - + "transaction name. %s set to %s. ", jmxAttribute, - dependentReadOnlyON), jmxAttribute); + + "transaction name. %s set to %s. ", jmxAttribute, + dependentReadOnlyON + ), jmxAttribute + ); dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON); @@ -110,7 +123,8 @@ final class DependencyResolverImpl implements DependencyResolver, + "attribute %s", foundFactory.getImplementationName(), foundFactory, expectedServiceInterface, dependentReadOnlyON, - jmxAttribute); + jmxAttribute + ); throw new JmxAttributeValidationException(message, jmxAttribute); } synchronized (this) { @@ -157,7 +171,8 @@ final class DependencyResolverImpl implements DependencyResolver, String message = format( "Error while %s resolving instance %s. getInstance() returned null. " + "Expected type %s , attribute %s", name, - dependentModuleIdentifier, expectedType, jmxAttribute); + dependentModuleIdentifier, expectedType, jmxAttribute + ); throw new JmxAttributeValidationException(message, jmxAttribute); } try { @@ -166,7 +181,8 @@ final class DependencyResolverImpl implements DependencyResolver, String message = format( "Instance cannot be cast to expected type. Instance class is %s , " + "expected type %s , attribute %s", - instance.getClass(), expectedType, jmxAttribute); + instance.getClass(), expectedType, jmxAttribute + ); throw new JmxAttributeValidationException(message, e, jmxAttribute); } } @@ -258,4 +274,20 @@ final class DependencyResolverImpl implements DependencyResolver, return name; } + @Override + public Object getAttribute(ObjectName name, String attribute) + throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException { + name = translateServiceRefIfPossible(name); + // add transaction name + name = ObjectNameUtil.withTransactionName(name, transactionName); + return mBeanServer.getAttribute(name, attribute); + } + + @Override + public T newMXBeanProxy(ObjectName name, Class interfaceClass) { + name = translateServiceRefIfPossible(name); + // add transaction name + name = ObjectNameUtil.withTransactionName(name, transactionName); + return JMX.newMXBeanProxy(mBeanServer, name, interfaceClass); + } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java index 0c1531728f..2a1a908e7a 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import javax.annotation.concurrent.GuardedBy; import javax.management.InstanceAlreadyExistsException; +import javax.management.MBeanServer; import org.opendaylight.controller.config.api.DependencyResolver; import org.opendaylight.controller.config.api.DependencyResolverFactory; import org.opendaylight.controller.config.api.JmxAttribute; @@ -45,19 +46,25 @@ import org.osgi.framework.BundleContext; public class DependencyResolverManager implements DependencyResolverFactory, AutoCloseable { @GuardedBy("this") private final Map moduleIdentifiersToDependencyResolverMap = new HashMap<>(); + private final TransactionIdentifier transactionIdentifier; private final ModulesHolder modulesHolder; private final TransactionStatus transactionStatus; private final ServiceReferenceReadableRegistry readableRegistry; private final CodecRegistry codecRegistry; private final DeadlockMonitor deadlockMonitor; + private final MBeanServer mBeanServer; public DependencyResolverManager(TransactionIdentifier transactionIdentifier, - TransactionStatus transactionStatus, ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry) { + TransactionStatus transactionStatus, + ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry, + MBeanServer mBeanServer) { + this.transactionIdentifier = transactionIdentifier; this.modulesHolder = new ModulesHolder(transactionIdentifier); this.transactionStatus = transactionStatus; this.readableRegistry = readableRegistry; this.codecRegistry = codecRegistry; this.deadlockMonitor = new DeadlockMonitor(transactionIdentifier); + this.mBeanServer = mBeanServer; } @Override @@ -69,7 +76,8 @@ public class DependencyResolverManager implements DependencyResolverFactory, Aut DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap.get(name); if (dependencyResolver == null) { transactionStatus.checkNotCommitted(); - dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry, codecRegistry); + dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry, + codecRegistry, transactionIdentifier.getName(), mBeanServer); moduleIdentifiersToDependencyResolverMap.put(name, dependencyResolver); } return dependencyResolver; diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java index d5d3823ef0..48d7de0e82 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java @@ -21,6 +21,7 @@ import org.opendaylight.controller.config.api.JmxAttribute; import org.opendaylight.controller.config.api.ModuleIdentifier; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.config.manager.impl.AbstractLockedPlatformMBeanServerTest; import org.opendaylight.controller.config.manager.impl.ModuleInternalInfo; import org.opendaylight.controller.config.manager.impl.TransactionIdentifier; import org.opendaylight.controller.config.manager.impl.TransactionStatus; @@ -29,7 +30,7 @@ import org.opendaylight.controller.config.spi.Module; import org.opendaylight.controller.config.spi.ModuleFactory; import org.osgi.framework.BundleContext; -public class DependencyResolverManagerTest { +public class DependencyResolverManagerTest extends AbstractLockedPlatformMBeanServerTest { final ModuleIdentifier apspName = new ModuleIdentifier("apsp", "apsp"); // depends // on: @@ -45,7 +46,8 @@ public class DependencyResolverManagerTest { public void setUp() { transactionStatus = mock(TransactionStatus.class); ServiceReferenceReadableRegistry mockedRegistry = mock(ServiceReferenceReadableRegistry.class); - tested = new DependencyResolverManager(new TransactionIdentifier("txName"), transactionStatus, mockedRegistry, null); + tested = new DependencyResolverManager(new TransactionIdentifier("txName"), transactionStatus, mockedRegistry, + null, platformMBeanServer); doNothing().when(transactionStatus).checkCommitStarted(); doNothing().when(transactionStatus).checkNotCommitted(); } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModule.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModule.java index df6dce1243..5c320ae2c1 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModule.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModule.java @@ -7,25 +7,25 @@ */ package org.opendaylight.controller.config.manager.testingservices.parallelapsp; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + import com.google.common.base.Strings; +import java.io.Closeable; +import javax.annotation.Nullable; +import javax.annotation.concurrent.NotThreadSafe; +import javax.management.ObjectName; import org.opendaylight.controller.config.api.DependencyResolver; import org.opendaylight.controller.config.api.JmxAttribute; import org.opendaylight.controller.config.api.ModuleIdentifier; import org.opendaylight.controller.config.api.annotations.RequireInterface; import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface; +import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolConfigMXBean; import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc; import org.opendaylight.controller.config.spi.Module; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nullable; -import javax.annotation.concurrent.NotThreadSafe; -import javax.management.ObjectName; -import java.io.Closeable; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - /** * Represents service that has dependency to thread pool. */ @@ -102,6 +102,17 @@ public class TestingParallelAPSPModule implements Module, checkState("Commit was not triggered".equals(e.getMessage()), e.getMessage()); } + + // test retrieving dependent module's attribute + int threadCount; + try { + threadCount = (Integer)dependencyResolver.getAttribute(threadPoolON, "ThreadCount"); + } catch (Exception e) { + throw new IllegalStateException(e); + } + checkState(threadCount > 0); + TestingThreadPoolConfigMXBean proxy = dependencyResolver.newMXBeanProxy(threadPoolON, TestingThreadPoolConfigMXBean.class); + checkState(threadCount == proxy.getThreadCount()); } @Override diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java index f42b9559c4..c9810d0521 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java @@ -7,6 +7,14 @@ */ package org.opendaylight.controller.config.manager.testingservices.parallelapsp.test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.internal.matchers.StringContains.containsString; + +import java.util.Map; +import javax.management.ObjectName; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -17,20 +25,12 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPConfigMXBean; import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPImpl; import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory; +import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface; import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool; import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolConfigMXBean; import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; -import javax.management.ObjectName; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.internal.matchers.StringContains.containsString; - public class DependentWiringTest extends AbstractParallelAPSPTest { private final String fixed1 = "fixed1"; private final String apsp1 = "apsp-parallel"; @@ -132,4 +132,17 @@ public class DependentWiringTest extends AbstractParallelAPSPTest { parallelAPSPRuntimeProxy.getMaxNumberOfThreads()); } + + @Test + public void testUsingServiceReferences() throws Exception { + ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); + ObjectName threadPoolON = createFixed1(transaction, 10); + transaction.lookupConfigBean(getThreadPoolImplementationName(), fixed1); + String refName = "ref"; + ObjectName serviceReferenceON = transaction.saveServiceReference(TestingThreadPoolServiceInterface.QNAME, refName, + threadPoolON); + createParallelAPSP(transaction, serviceReferenceON); + transaction.commit(); + + } } diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini index 234e0feb45..c958039b5f 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini @@ -143,3 +143,9 @@ java.util.logging.config.file=configuration/tomcat-logging.properties #Hosttracker hostsdb key scheme setting hosttracker.keyscheme=IP + +# LISP Flow Mapping configuration +# Map-Register messages overwrite existing RLOC sets in EID-to-RLOC mappings +lisp.mappingOverwrite = true +# Enable the Solicit-Map-Request (SMR) mechanism +lisp.smr = false diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf-connector.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/99-netconf-connector.xml similarity index 100% rename from opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf-connector.xml rename to opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/99-netconf-connector.xml diff --git a/opendaylight/md-sal/clustered-data-store/implementation/pom.xml b/opendaylight/md-sal/clustered-data-store/implementation/pom.xml deleted file mode 100644 index fe0b516a8b..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/pom.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - 4.0.0 - - org.opendaylight.controller - sal-parent - 1.1-SNAPSHOT - ../.. - - - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main - HEAD - - - clustered-datastore-implementation - 0.4.1-SNAPSHOT - bundle - - - - - org.apache.felix - maven-bundle-plugin - true - - - - ${project.basedir}/META-INF - - - - org.opendaylight.yangtools - yang-maven-plugin - - - - generate-sources - - - - - - org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - - ${project.build.directory}/generated-sources/config - - - urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang - - - - - org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl - target/site/models - - - true - - - - - - org.opendaylight.controller - yang-jmx-generator-plugin - 0.2.3-SNAPSHOT - - - org.opendaylight.yangtools - maven-sal-api-gen-plugin - ${yangtools.version} - jar - - - - - - - - - com.google.guava - guava - - - org.opendaylight.controller - sal-core-api - - - org.opendaylight.controller - sal-common-util - - - org.opendaylight.controller - config-api - - - - org.opendaylight.controller - sal - - - org.opendaylight.controller - clustering.services - - - junit - junit - test - - - org.mockito - mockito-all - test - - - org.opendaylight.yangtools - yang-binding - - - org.opendaylight.yangtools - yang-data-api - - - - diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/cluster/store/ClusteredDataStoreImplModule.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/cluster/store/ClusteredDataStoreImplModule.java deleted file mode 100644 index 5fc2c015ed..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/cluster/store/ClusteredDataStoreImplModule.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -/** -* Generated file - -* Generated from: yang module name: odl-sal-dom-clustered-store-cfg yang module local name: dom-clustered-store-impl -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Wed Nov 27 17:09:17 CET 2013 -* -* Do not modify this file unless it is present under src/main directory -*/ -package org.opendaylight.controller.config.yang.md.sal.dom.cluster.store; - -import org.opendaylight.controller.datastore.internal.ClusteredDataStoreManager; -import org.osgi.framework.BundleContext; - -/** -* -*/ -public final class ClusteredDataStoreImplModule extends org.opendaylight.controller.config.yang.md.sal.dom.cluster.store.AbstractClusteredDataStoreImplModule -{ - - private BundleContext bundleContext; - - public ClusteredDataStoreImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { - super(identifier, dependencyResolver); - } - - public ClusteredDataStoreImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, ClusteredDataStoreImplModule oldModule, java.lang.AutoCloseable oldInstance) { - super(identifier, dependencyResolver, oldModule, oldInstance); - } - - @Override - public void validate(){ - super.validate(); - // Add custom validation for module attributes here. - } - - @Override - public java.lang.AutoCloseable createInstance() { - ClusteredDataStoreManager manager = new ClusteredDataStoreManager(); - manager.setContext(bundleContext); - manager.start(); - return manager; - } - - public void setBundleContext(BundleContext bundleContext) { - this.bundleContext = bundleContext; - } -} diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/cluster/store/ClusteredDataStoreImplModuleFactory.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/cluster/store/ClusteredDataStoreImplModuleFactory.java deleted file mode 100644 index 40c558726d..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/cluster/store/ClusteredDataStoreImplModuleFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -/** -* Generated file - -* Generated from: yang module name: odl-sal-dom-clustered-store-cfg yang module local name: dom-clustered-store-impl -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Wed Nov 27 17:09:17 CET 2013 -* -* Do not modify this file unless it is present under src/main directory -*/ -package org.opendaylight.controller.config.yang.md.sal.dom.cluster.store; - -import org.opendaylight.controller.config.api.DependencyResolver; -import org.opendaylight.controller.config.api.DynamicMBeanWithInstance; -import org.opendaylight.controller.config.spi.Module; -import org.osgi.framework.BundleContext; - -/** -* -*/ -public class ClusteredDataStoreImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.dom.cluster.store.AbstractClusteredDataStoreImplModuleFactory -{ - - @Override - public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) { - ClusteredDataStoreImplModule module = - (ClusteredDataStoreImplModule) super.createModule(instanceName, dependencyResolver, bundleContext); - module.setBundleContext(bundleContext); - return module; - } - - @Override - public Module createModule(String instanceName, DependencyResolver dependencyResolver, - DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception { - ClusteredDataStoreImplModule module = - (ClusteredDataStoreImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext); - module.setBundleContext(bundleContext); - return module; - } - -} diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/ClusteredDataStore.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/ClusteredDataStore.java deleted file mode 100644 index 1aecb967f1..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/ClusteredDataStore.java +++ /dev/null @@ -1,22 +0,0 @@ - -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - - -package org.opendaylight.controller.datastore; - -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler; -import org.opendaylight.controller.md.sal.common.api.data.DataReader; -import org.opendaylight.controller.sal.core.api.data.DataStore; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -public interface ClusteredDataStore extends DataStore { - - -} diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImpl.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImpl.java deleted file mode 100644 index 0809ba347b..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImpl.java +++ /dev/null @@ -1,160 +0,0 @@ - -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.datastore.internal; - -import com.google.common.base.Preconditions; - -import org.opendaylight.controller.clustering.services.CacheConfigException; -import org.opendaylight.controller.clustering.services.CacheExistException; -import org.opendaylight.controller.clustering.services.IClusterGlobalServices; -import org.opendaylight.controller.clustering.services.IClusterServices; -import org.opendaylight.controller.datastore.ClusteredDataStore; -import org.opendaylight.controller.md.sal.common.api.data.DataModification; -import org.opendaylight.controller.sal.common.util.Rpcs; -import org.opendaylight.yangtools.yang.common.RpcError; -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.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collections; -import java.util.EnumSet; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; - -/** - * The ClusteredDataStoreImpl stores global data to be shared across a controller cluster. It uses Clustering Services. - */ -public class ClusteredDataStoreImpl implements ClusteredDataStore { - - - public static final String OPERATIONAL_DATA_CACHE = "clustered_data_store.operational_data_cache"; - public static final String CONFIGURATION_DATA_CACHE = "clustered_data_store.configuration_data_cache"; - - private final ConcurrentMap operationalDataCache; - private final ConcurrentMap configurationDataCache; - - private Logger logger = LoggerFactory.getLogger(ClusteredDataStoreImpl.class); - - public ClusteredDataStoreImpl(IClusterGlobalServices clusterGlobalServices) throws CacheConfigException { - logger.trace("Constructing clustered data store"); - Preconditions.checkNotNull(clusterGlobalServices, "clusterGlobalServices cannot be null"); - - operationalDataCache = getOrCreateCache(clusterGlobalServices, OPERATIONAL_DATA_CACHE); - - Preconditions.checkNotNull(operationalDataCache, "operationalDataCache cannot be null"); - - configurationDataCache = getOrCreateCache(clusterGlobalServices, CONFIGURATION_DATA_CACHE); - - Preconditions.checkNotNull(configurationDataCache, "configurationDataCache cannot be null"); - } - - @Override - public DataCommitTransaction requestCommit(DataModification modification) { - return new ClusteredDataStoreTransaction(modification); - } - - @Override - public CompositeNode readOperationalData(InstanceIdentifier path) { - Preconditions.checkNotNull(path, "path cannot be null"); - return operationalDataCache.get(path); - } - - @Override - public boolean containsConfigurationPath(InstanceIdentifier path) { - return configurationDataCache.containsKey(path); - } - - @Override - public boolean containsOperationalPath(InstanceIdentifier path) { - return operationalDataCache.containsKey(path); - } - - @Override - public Iterable getStoredConfigurationPaths() { - return configurationDataCache.keySet(); - } - - @Override - public Iterable getStoredOperationalPaths() { - return operationalDataCache.keySet(); - } - - - - @Override - public CompositeNode readConfigurationData(InstanceIdentifier path) { - Preconditions.checkNotNull(path, "path cannot be null"); - return configurationDataCache.get(path); - } - - private RpcResult finish(final ClusteredDataStoreTransaction transaction) { - final DataModification modification = transaction.getModification(); - - this.configurationDataCache.putAll(modification.getUpdatedConfigurationData()); - this.operationalDataCache.putAll(modification.getUpdatedOperationalData()); - - for (final InstanceIdentifier removal : modification.getRemovedConfigurationData()) { - this.configurationDataCache.remove(removal); - } - - for (final InstanceIdentifier removal : modification.getRemovedOperationalData()) { - this.operationalDataCache.remove(removal ); - } - - Set _emptySet = Collections.emptySet(); - return Rpcs.getRpcResult(true, null, _emptySet); - } - - private RpcResult rollback(final ClusteredDataStoreTransaction transaction) { - Set _emptySet = Collections.emptySet(); - return Rpcs.getRpcResult(true, null, _emptySet); - } - - - private ConcurrentMap getOrCreateCache(IClusterGlobalServices clusterGlobalServices, String name) throws CacheConfigException { - ConcurrentMap cache = clusterGlobalServices.getCache(name); - - if(cache == null) { - try { - cache = clusterGlobalServices.createCache(name, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL)); - } catch (CacheExistException e) { - cache = clusterGlobalServices.getCache(name); - } - } - return cache; - } - - private class ClusteredDataStoreTransaction implements DataCommitTransaction { - private final DataModification modification; - - public ClusteredDataStoreTransaction(DataModification modification){ - Preconditions.checkNotNull(modification, "modification cannot be null"); - - this.modification = modification; - } - - @Override - public DataModification getModification() { - return this.modification; - } - - @Override - public RpcResult finish() throws IllegalStateException { - return ClusteredDataStoreImpl.this.finish(this); - } - - @Override - public RpcResult rollback() throws IllegalStateException { - return ClusteredDataStoreImpl.this.rollback(this); - } - } -} diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManager.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManager.java deleted file mode 100644 index b0a099ff90..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManager.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.datastore.internal; - -import java.util.Hashtable; - -import com.google.common.base.Preconditions; - -import org.opendaylight.controller.clustering.services.CacheConfigException; -import org.opendaylight.controller.clustering.services.IClusterGlobalServices; -import org.opendaylight.controller.datastore.ClusteredDataStore; -import org.opendaylight.controller.md.sal.common.api.data.DataModification; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.ServiceTracker; -import org.osgi.util.tracker.ServiceTrackerCustomizer; - -public class ClusteredDataStoreManager implements // - ClusteredDataStore, // - ServiceTrackerCustomizer, // - AutoCloseable { - - private ClusteredDataStore clusteredDataStore = null; - private IClusterGlobalServices clusterGlobalServices = null; - private BundleContext context; - - private ServiceReference firstClusterGlobalReference; - private ServiceTracker clusterTracker; - - @Override - public DataCommitTransaction requestCommit( - DataModification modification) { - Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null"); - return clusteredDataStore.requestCommit(modification); - } - - @Override - public CompositeNode readOperationalData(InstanceIdentifier path) { - Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null"); - return clusteredDataStore.readOperationalData(path); - } - - @Override - public CompositeNode readConfigurationData(InstanceIdentifier path) { - Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null"); - return clusteredDataStore.readConfigurationData(path); - } - - public Iterable getStoredConfigurationPaths() { - Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null"); - return clusteredDataStore.getStoredConfigurationPaths(); - } - - public Iterable getStoredOperationalPaths() { - Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null"); - return clusteredDataStore.getStoredOperationalPaths(); - } - - public boolean containsConfigurationPath(InstanceIdentifier path) { - Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null"); - return clusteredDataStore.containsConfigurationPath(path); - } - - public boolean containsOperationalPath(InstanceIdentifier path) { - Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null"); - return clusteredDataStore.containsOperationalPath(path); - } - - public void setClusterGlobalServices(IClusterGlobalServices clusterGlobalServices) { - this.clusterGlobalServices = clusterGlobalServices; - try { - // Adding creation of the clustered data store in its own method - // to make the method unit testable - clusteredDataStore = createClusteredDataStore(); - } catch (CacheConfigException e) { - throw new IllegalStateException("could not construct clusteredDataStore"); - } - } - - @Override - public IClusterGlobalServices addingService(ServiceReference reference) { - if (clusterGlobalServices == null) { - setClusterGlobalServices(context.getService(reference)); - return clusterGlobalServices; - } - return null; - } - - @Override - public void modifiedService(ServiceReference reference, IClusterGlobalServices service) { - - } - - @Override - public void removedService(ServiceReference reference, IClusterGlobalServices service) { - if (clusterGlobalServices == service) { - clusterGlobalServices = null; - clusteredDataStore = null; - } - } - - public BundleContext getContext() { - return context; - } - - public void setContext(BundleContext context) { - this.context = context; - } - - - /** - * Function called by the dependency manager when all the required - * dependencies are satisfied - * - */ - public void start() { - if (context != null) { - clusterTracker = new ServiceTracker<>(context, IClusterGlobalServices.class, this); - clusterTracker.open(); - - context.registerService(ClusteredDataStore.class, this, new Hashtable()); - } - } - - protected ClusteredDataStore createClusteredDataStore() throws CacheConfigException { - return new ClusteredDataStoreImpl(clusterGlobalServices); - } - - @Override - public void close() throws Exception { - clusterTracker.close(); - } -} diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/yang/odl-sal-dom-clustered-store-cfg.yang b/opendaylight/md-sal/clustered-data-store/implementation/src/main/yang/odl-sal-dom-clustered-store-cfg.yang deleted file mode 100644 index 95a26d7f41..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/src/main/yang/odl-sal-dom-clustered-store-cfg.yang +++ /dev/null @@ -1,29 +0,0 @@ -module odl-sal-dom-clustered-store-cfg { - yang-version 1; - namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store"; - prefix "binding-impl"; - - import config { prefix config; revision-date 2013-04-05; } - import opendaylight-md-sal-dom {prefix sal;} - - description - "Service definition for MD-SAL Clustered Store."; - - revision "2013-10-28" { - description - "Initial revision"; - } - - identity dom-clustered-store-impl { - base config:module-type; - config:provided-service sal:dom-data-store; - config:java-name-prefix ClusteredDataStoreImpl; - } - - augment "/config:modules/config:module/config:state" { - case dom-clustered-store-impl { - when "/config:modules/config:module/config:type = 'dom-clustered-store-impl'"; - } - } - -} \ No newline at end of file diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImplTest.java b/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImplTest.java deleted file mode 100644 index 4c97b19bac..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImplTest.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.datastore.internal; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.controller.clustering.services.CacheConfigException; -import org.opendaylight.controller.clustering.services.CacheExistException; -import org.opendaylight.controller.clustering.services.IClusterGlobalServices; -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.DataModification; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -import java.util.EnumSet; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class ClusteredDataStoreImplTest { - @Before - public void setUp(){ - - } - - @Test - public void constructor_WhenPassedANullClusteringServices_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException { - try { - new ClusteredDataStoreImpl(null); - } catch(NullPointerException npe){ - assertEquals("clusterGlobalServices cannot be null", npe.getMessage()); - } - } - - @Test - public void constructor_WhenClusteringServicesReturnsANullOperationalDataCache_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException { - try { - new ClusteredDataStoreImpl(mock(IClusterGlobalServices.class)); - } catch(NullPointerException npe){ - assertEquals("operationalDataCache cannot be null", npe.getMessage()); - } - } - - @Test - public void constructor_WhenClusteringServicesReturnsANullOConfigurationDataCache_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class); - - // Confused about the following line? - // See this http://stackoverflow.com/questions/10952629/a-strange-generics-edge-case-with-mockito-when-and-generic-type-inference - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(new ConcurrentHashMap()); - - - try { - new ClusteredDataStoreImpl(mockClusterGlobalServices); - } catch(NullPointerException npe){ - assertEquals("configurationDataCache cannot be null", npe.getMessage()); - } - } - - @Test - public void constructor_WhenOperationalDataCacheIsAlreadyPresent_ShouldNotAttemptToCreateCache() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class); - - Mockito.>when(mockClusterGlobalServices.getCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE)).thenReturn(new ConcurrentHashMap()); - Mockito.>when(mockClusterGlobalServices.getCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE)).thenReturn(new ConcurrentHashMap()); - - new ClusteredDataStoreImpl(mockClusterGlobalServices); - - verify(mockClusterGlobalServices, never()).createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL)); - } - - @Test - public void constructor_WhenConfigurationDataCacheIsAlreadyPresent_ShouldNotAttemptToCreateCache() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class); - - Mockito.>when(mockClusterGlobalServices.getCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE)).thenReturn(new ConcurrentHashMap()); - Mockito.>when(mockClusterGlobalServices.getCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE)).thenReturn(new ConcurrentHashMap()); - - new ClusteredDataStoreImpl(mockClusterGlobalServices); - - verify(mockClusterGlobalServices, never()).createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL)); - } - - - @Test - public void constructor_WhenPassedAValidClusteringServices_ShouldNotThrowAnyExceptions() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices(); - - new ClusteredDataStoreImpl(mockClusterGlobalServices); - } - - - @Test - public void readOperationalData_WhenPassedANullPath_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices(); - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - try { - store.readOperationalData(null); - } catch(NullPointerException npe){ - assertEquals("path cannot be null", npe.getMessage()); - } - } - - @Test - public void readOperationalData_WhenPassedAKeyThatDoesNotExistInTheCache_ShouldReturnNull() throws CacheExistException, CacheConfigException { - InstanceIdentifier path = InstanceIdentifier.builder().toInstance(); - - IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices(); - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - assertNull(store.readOperationalData(path)); - } - - @Test - public void readOperationalData_WhenPassedAKeyThatDoesExistInTheCache_ShouldReturnTheValueObject() throws CacheExistException, CacheConfigException { - InstanceIdentifier path = InstanceIdentifier.builder().toInstance(); - - IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices(); - - ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class); - - CompositeNode valueObject = mock(CompositeNode.class); - - when(mockOperationalDataCache.get(path)).thenReturn(valueObject); - - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache); - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(new ConcurrentHashMap()); - - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - assertEquals(valueObject, store.readOperationalData(path)); - } - - - - @Test - public void readConfigurationData_WhenPassedANullPath_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException { - - IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices(); - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - try { - store.readConfigurationData(null); - } catch(NullPointerException npe){ - assertEquals("path cannot be null", npe.getMessage()); - } - } - - - @Test - public void readConfigurationData_WhenPassedAKeyThatDoesNotExistInTheCache_ShouldReturnNull() throws CacheExistException, CacheConfigException { - InstanceIdentifier path = InstanceIdentifier.builder().toInstance(); - - IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices(); - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - assertNull(store.readConfigurationData(path)); - } - - @Test - public void readConfigurationData_WhenPassedAKeyThatDoesExistInTheCache_ShouldReturnTheValueObject() throws CacheExistException, CacheConfigException { - InstanceIdentifier path = InstanceIdentifier.builder().toInstance(); - - IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices(); - - ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class); - - CompositeNode valueObject = mock(CompositeNode.class); - - when(mockConfigurationDataCache.get(path)).thenReturn(valueObject); - - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class)); - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache); - - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - assertEquals(valueObject, store.readConfigurationData(path)); - } - - - @Test - public void requestCommit_ShouldReturnADataTransaction() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices(); - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - assertNotNull(store.requestCommit(mock(DataModification.class))); - - - } - - @Test - public void finishingADataTransaction_ShouldUpdateTheUnderlyingCache() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class); - - ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class); - ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class); - - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache); - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache); - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - DataModification mockModification = mock(DataModification.class); - - Map configurationData = mock(Map.class); - Map operationalData = mock(Map.class); - - when(mockModification.getUpdatedConfigurationData()).thenReturn(configurationData); - when(mockModification.getUpdatedOperationalData()).thenReturn(operationalData); - - DataCommitHandler.DataCommitTransaction transaction = store.requestCommit(mockModification); - - transaction.finish(); - - verify(mockConfigurationDataCache).putAll(mockModification.getUpdatedConfigurationData()); - verify(mockOperationalDataCache).putAll(mockModification.getUpdatedOperationalData()); - } - - - @Test - public void rollingBackADataTransaction_ShouldDoNothing() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class); - - ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class); - ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class); - - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache); - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache); - - ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices); - - DataModification mockModification = mock(DataModification.class); - - Map configurationData = mock(Map.class); - Map operationalData = mock(Map.class); - - when(mockModification.getUpdatedConfigurationData()).thenReturn(configurationData); - when(mockModification.getUpdatedOperationalData()).thenReturn(operationalData); - - DataCommitHandler.DataCommitTransaction transaction = store.requestCommit(mockModification); - - transaction.rollback(); - - verify(mockConfigurationDataCache, never()).putAll(mockModification.getUpdatedConfigurationData()); - verify(mockOperationalDataCache, never()).putAll(mockModification.getUpdatedOperationalData()); - - } - - - private IClusterGlobalServices createClusterGlobalServices() throws CacheExistException, CacheConfigException { - IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class); - - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class)); - Mockito.>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class)); - - return mockClusterGlobalServices; - } -} diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManagerTest.java b/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManagerTest.java deleted file mode 100644 index 10f9622c7a..0000000000 --- a/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManagerTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.datastore.internal; - -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.felix.dm.Component; -import org.junit.BeforeClass; -import org.junit.Test; -import org.opendaylight.controller.clustering.services.CacheConfigException; -import org.opendaylight.controller.clustering.services.CacheExistException; -import org.opendaylight.controller.clustering.services.IClusterGlobalServices; -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction; -import org.opendaylight.controller.md.sal.common.api.data.DataModification; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -import static junit.framework.Assert.assertNotNull; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -public class ClusteredDataStoreManagerTest { - - private static ClusteredDataStoreManager clusteredDSMgr = null; - private IClusterGlobalServices icClusterGlbServices = mock(IClusterGlobalServices.class); - - @BeforeClass - public static void construct() { - clusteredDSMgr = new ClusteredDataStoreManager(); - assertNotNull(clusteredDSMgr); - } - - @Test - public void construct_OnSetClusterGlobalServices_AssertNoException() { - doReturn(new ConcurrentHashMap()).when(icClusterGlbServices).getCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE); - doReturn(new ConcurrentHashMap()).when(icClusterGlbServices).getCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE); - clusteredDSMgr.setClusterGlobalServices(icClusterGlbServices); - } - - @Test - public void construct_init_AssertNoException() throws CacheExistException, CacheConfigException { - ClusteredDataStoreImpl clusteredDSImpl = mock(ClusteredDataStoreImpl.class); - - ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager()); - doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(); - clusteredDSManager.start(); - } - - - @Test - public void construct_readOperationalData_AssertNoException() throws CacheExistException, CacheConfigException { - ClusteredDataStoreImpl clusteredDSImpl = mock(ClusteredDataStoreImpl.class); - - ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager()); - doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(); - Component c = mock(Component.class); - - clusteredDSManager.start(); - clusteredDSManager.setClusterGlobalServices(icClusterGlbServices); - CompositeNode o = mock(CompositeNode.class); - - when(clusteredDSImpl.readOperationalData(any(InstanceIdentifier.class))).thenReturn(o); - assertEquals(o, clusteredDSManager.readOperationalData(any(InstanceIdentifier.class))); - } - - @Test - public void construct_readConfigurationData_AssertNoException() throws CacheExistException, CacheConfigException { - ClusteredDataStoreImpl clusteredDSImpl = mock(ClusteredDataStoreImpl.class); - - ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager()); - doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(); - Component c = mock(Component.class); - - clusteredDSManager.start(); - clusteredDSManager.setClusterGlobalServices(icClusterGlbServices); - - CompositeNode o = mock(CompositeNode.class); - - when(clusteredDSImpl.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(o); - assertEquals(o, clusteredDSManager.readConfigurationData(any(InstanceIdentifier.class))); - } - - @Test - public void construct_requestCommit_AssertNoException() throws CacheExistException, CacheConfigException { - ClusteredDataStoreImpl clusteredDSImpl = mock(ClusteredDataStoreImpl.class); - - ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager()); - doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(); - IClusterGlobalServices globalServices = mock(IClusterGlobalServices.class); - clusteredDSManager.setClusterGlobalServices(globalServices); - clusteredDSManager.start(); - DataCommitTransaction dataCommitTransaction = mock(DataCommitTransaction.class); - - when(clusteredDSImpl.requestCommit(any(DataModification.class))).thenReturn(dataCommitTransaction); - assertEquals(dataCommitTransaction, clusteredDSManager.requestCommit(any(DataModification.class))); - } -} diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml b/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml deleted file mode 100644 index 2d68b47869..0000000000 --- a/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml +++ /dev/null @@ -1,358 +0,0 @@ - - - 4.0.0 - - org.opendaylight.controller - commons.integrationtest - 0.5.1-SNAPSHOT - ../../../commons/integrationtest - - - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main - - - clustered-datastore.integrationtest - 0.4.0-SNAPSHOT - - - - - xml-apis - xml-apis - 1.4.01 - - - - - - - com.google.guava - guava - - - org.opendaylight.controller - sal-binding-it - 1.0-SNAPSHOT - - - org.opendaylight.controller - sal-common-api - 1.0-SNAPSHOT - - - org.opendaylight.controller - sal-common-util - 1.0-SNAPSHOT - - - org.opendaylight.controller - sal-common-impl - 1.0-SNAPSHOT - - - org.opendaylight.controller - sal-binding-broker-impl - 1.0-SNAPSHOT - - - xml-apis - xml-apis - - - reflections - org.reflections - - - - - org.opendaylight.controller - sal - 0.7.0-SNAPSHOT - - - org.opendaylight.controller - clustering.services - 0.5.0-SNAPSHOT - - - org.opendaylight.yangtools - yang-binding - - - org.opendaylight.yangtools.thirdparty - antlr4-runtime-osgi-nohead - 4.0 - - - org.opendaylight.controller - protocol_plugins.stub - 0.4.1-SNAPSHOT - - - org.opendaylight.controller - sal.implementation - 0.4.1-SNAPSHOT - - - org.opendaylight.controller - containermanager - 0.5.1-SNAPSHOT - - - org.opendaylight.controller - containermanager.it.implementation - 0.5.1-SNAPSHOT - - - org.opendaylight.controller - clustering.stub - 0.4.1-SNAPSHOT - - - org.opendaylight.controller - clustered-datastore-implementation - 0.4.1-SNAPSHOT - - - org.opendaylight.yangtools.thirdparty - xtend-lib-osgi - 2.4.3 - test - - - org.opendaylight.controller - sal-binding-broker-impl - 1.0-SNAPSHOT - provided - - - org.ops4j.pax.exam - pax-exam-container-native - ${exam.version} - test - - - org.ops4j.pax.exam - pax-exam-junit4 - ${exam.version} - test - - - org.opendaylight.controller - config-netconf-connector - ${netconf.version} - test - - - xml-apis - xml-apis - - - - - org.opendaylight.controller - logback-config - - - org.opendaylight.controller - config-persister-impl - - - org.opendaylight.controller - config-persister-file-xml-adapter - - - org.opendaylight.controller - netconf-impl - ${netconf.version} - - - org.opendaylight.controller - netconf-client - ${netconf.version} - - - org.opendaylight.controller - sal-common - 1.0-SNAPSHOT - - - org.opendaylight.yangtools - yang-common - - - org.opendaylight.yangtools - concepts - - - org.opendaylight.yangtools - yang-data-api - - - org.mockito - mockito-all - 1.9.5 - test - - - org.opendaylight.controller - config-manager - 0.2.3-SNAPSHOT - - - org.opendaylight.controller.model - model-flow-management - 1.0-SNAPSHOT - provided - - - org.opendaylight.yangtools.thirdparty - antlr4-runtime-osgi-nohead - 4.0 - - - org.opendaylight.yangtools.thirdparty - xtend-lib-osgi - 2.4.3 - test - - - org.opendaylight.controller - sal-binding-broker-impl - 1.0-SNAPSHOT - provided - - - org.ops4j.pax.exam - pax-exam-container-native - ${exam.version} - test - - - org.ops4j.pax.exam - pax-exam-junit4 - ${exam.version} - test - - - org.opendaylight.controller - config-netconf-connector - ${netconf.version} - test - - - - org.opendaylight.yangtools - yang-parser-impl - ${yangtools.version} - - - org.opendaylight.yangtools - yang-model-util - ${yangtools.version} - - - - org.opendaylight.controller - logback-config - - - org.opendaylight.controller - config-persister-impl - - - org.opendaylight.controller - netconf-impl - ${netconf.version} - - - org.opendaylight.controller - netconf-client - ${netconf.version} - - - org.ops4j.pax.exam - pax-exam-link-mvn - ${exam.version} - test - - - equinoxSDK381 - org.eclipse.osgi - 3.8.1.v20120830-144521 - test - - - org.slf4j - log4j-over-slf4j - 1.7.2 - - - ch.qos.logback - logback-core - 1.0.9 - - - ch.qos.logback - logback-classic - 1.0.9 - - - org.opendaylight.controller.model - model-flow-service - 1.0-SNAPSHOT - provided - - - org.opendaylight.controller - config-manager - 0.2.3-SNAPSHOT - - - org.opendaylight.controller.model - model-flow-management - 1.0-SNAPSHOT - provided - - - org.opendaylight.yangtools.thirdparty - antlr4-runtime-osgi-nohead - 4.0 - - - - - ../implementation/target/jacoco.exec - ../implementaiton/target/jacoco-it.exec - - - - - org.jacoco - jacoco-maven-plugin - - ../implementation/target/jacoco-it.exec - org.opendaylight.controller.* - - - - pre-test - - prepare-agent - - - - post-test - - true - - - - - - - diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/java/org/opendaylight/controller/datastore/ClusteredDataStoreIT.java b/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/java/org/opendaylight/controller/datastore/ClusteredDataStoreIT.java deleted file mode 100644 index a1fa9e31b8..0000000000 --- a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/java/org/opendaylight/controller/datastore/ClusteredDataStoreIT.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.datastore; - -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.ops4j.pax.exam.CoreOptions.junitBundles; -import static org.ops4j.pax.exam.CoreOptions.mavenBundle; -import static org.ops4j.pax.exam.CoreOptions.options; -import static org.ops4j.pax.exam.CoreOptions.systemPackages; -import static org.ops4j.pax.exam.CoreOptions.systemProperty; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import javax.inject.Inject; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -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.test.sal.binding.it.TestHelper; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.util.Filter; -import org.ops4j.pax.exam.util.PathUtils; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@RunWith(PaxExam.class) -//@ExamReactorStrategy(PerClass.class) -public class ClusteredDataStoreIT { - private Logger log = LoggerFactory.getLogger(ClusteredDataStoreIT.class); - // get the OSGI bundle context - @Inject - private BundleContext bc; - @Inject - @Filter(timeout=60*1000) - private ClusteredDataStore clusteredDS; - - // Configure the OSGi container - @Configuration - public Option[] config() { - return options( - // - systemProperty("logback.configurationFile").value( - "file:" + PathUtils.getBaseDir() + "/src/test/resources/logback.xml"), - // To start OSGi console for inspection remotely - systemProperty("osgi.console").value("2401"), - // Set the systemPackages (used by clustering) - systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"), - systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("DEBUG"), - // List framework bundles - mavenBundle("equinoxSDK381", "org.eclipse.equinox.console").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.equinox.util").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.osgi.services").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell").versionAsInProject(), - // List logger bundles - mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(), - mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), - mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), - mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), - // needed by statisticsmanager - mavenBundle("org.opendaylight.controller", "containermanager").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "containermanager.it.implementation").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "clustering.services").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "clustering.stub").versionAsInProject(), - - // List all the bundles on which the test case depends - mavenBundle("org.opendaylight.controller", "sal").versionAsInProject(), - TestHelper.baseModelBundles(), - TestHelper.configMinumumBundles(), - TestHelper.bindingIndependentSalBundles(), - TestHelper.bindingAwareSalBundles(), - TestHelper.mdSalCoreBundles(), - mavenBundle("org.opendaylight.controller", "config-api").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "sal.implementation").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "protocol_plugins.stub").versionAsInProject(), - - mavenBundle("org.osgi", "org.osgi.core").versionAsInProject(), - // adding new maven bundles - mavenBundle("org.mockito", "mockito-all").versionAsInProject(), - - // needed by hosttracker - mavenBundle("org.opendaylight.controller", "clustered-datastore-implementation").versionAsInProject(), - mavenBundle("org.jboss.spec.javax.transaction", "jboss-transaction-api_1.1_spec").versionAsInProject(), - mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(), - mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager").versionAsInProject(), - junitBundles()); - } - - private String stateToString(int state) { - switch (state) { - case Bundle.ACTIVE: - return "ACTIVE"; - case Bundle.INSTALLED: - return "INSTALLED"; - case Bundle.RESOLVED: - return "RESOLVED"; - case Bundle.UNINSTALLED: - return "UNINSTALLED"; - default: - return "Not CONVERTED"; - } - } - - @Test - public void testBundleContextClusteredDS_NotNull() throws Exception { - ServiceReference serviceReference = bc.getServiceReference(ClusteredDataStore.class); - ClusteredDataStore store = ClusteredDataStore.class.cast(bc.getService(serviceReference)); - assertNotNull(store); - } - - @Test - public void testInjected_ClusteredDS_NotNull() { - assertNotNull(clusteredDS); - } - - @Test - public void requestCommit_readConfigurationData_ShouldVerifyDataAndNoException() { - DataModification dataModification = mock(DataModification.class); - HashMap map = new HashMap(); - List list = new ArrayList(); - list.add("key"); - InstanceIdentifier key = new InstanceIdentifier(list); - map.put(key, mock(CompositeNode.class)); - when(dataModification.getUpdatedConfigurationData()).thenReturn(map); - DataCommitTransaction dataCommitTrans = clusteredDS.requestCommit(dataModification); - dataCommitTrans.finish(); - Object value = clusteredDS.readConfigurationData(key); - Assert.assertNotNull(value); - } - - @Test(expected = NullPointerException.class) - public void requestCommit_ShouldThrowException() { - DataModification dataModification = null; - DataCommitTransaction dataCommitTrans = clusteredDS.requestCommit(dataModification); - dataCommitTrans.finish(); - } - - @Test - public void requestCommit_readOperationalData_ShouldVerifyDataAndNoException() { - DataModification dataModification = mock(DataModification.class); - HashMap map = new HashMap(); - List list = new ArrayList(); - list.add("key"); - InstanceIdentifier key = new InstanceIdentifier(list); - map.put(key, mock(CompositeNode.class)); - when(dataModification.getUpdatedOperationalData()).thenReturn(map); - DataCommitTransaction dataCommitTrans = clusteredDS.requestCommit(dataModification); - dataCommitTrans.finish(); - Object value = clusteredDS.readOperationalData(key); - Assert.assertNotNull(value); - } - - @Test - public void requestCommit_readConfigurationData_NonExistingKey_ShouldVerifyNoMappedValueAndNoException() { - DataModification dataModification = mock(DataModification.class); - HashMap map = new HashMap(); - List list = new ArrayList(); - list.add("key"); - InstanceIdentifier key = new InstanceIdentifier(list); - map.put(key, "value"); - when(dataModification.getUpdatedConfigurationData()).thenReturn(map); - DataCommitTransaction dataCommitTrans = clusteredDS.requestCommit(dataModification); - dataCommitTrans.finish(); - list = new ArrayList(); - list.add("key1"); - InstanceIdentifier key1 = new InstanceIdentifier(list); - - Object value = clusteredDS.readConfigurationData(key1); - assertNull(value); - } - - @Test - public void requestCommit_readOperationalData_NonExistingKey_ShouldVerifyNoMappedValueAndNoException() { - DataModification dataModification = mock(DataModification.class); - HashMap map = new HashMap(); - List list = new ArrayList(); - list.add("key"); - InstanceIdentifier key = new InstanceIdentifier(list); - map.put(key, mock(CompositeNode.class)); - when(dataModification.getUpdatedOperationalData()).thenReturn(map); - DataCommitTransaction dataCommitTrans = clusteredDS.requestCommit(dataModification); - dataCommitTrans.finish(); - list = new ArrayList(); - list.add("key1"); - InstanceIdentifier key1 = new InstanceIdentifier(list); - - Object value = clusteredDS.readOperationalData(key1); - assertNull(value); - } - - @Test(expected = NullPointerException.class) - public void requestCommit_readConfigurationData_WithNullPathShouldThrowException() { - DataModification dataModification = mock(DataModification.class); - HashMap map = new HashMap(); - List list = new ArrayList(); - list.add("key"); - InstanceIdentifier key = new InstanceIdentifier(list); - map.put(key, "value"); - when(dataModification.getUpdatedConfigurationData()).thenReturn(map); - DataCommitTransaction dataCommitTrans = clusteredDS.requestCommit(dataModification); - dataCommitTrans.finish(); - Object value = clusteredDS.readConfigurationData(null); - } - - @Test(expected = NullPointerException.class) - public void requestCommit_readOperationalData_WithNullPathShouldThrowException() { - DataModification dataModification = mock(DataModification.class); - HashMap map = new HashMap(); - List list = new ArrayList(); - list.add("key"); - InstanceIdentifier key = new InstanceIdentifier(list); - map.put(key, "value"); - when(dataModification.getOriginalOperationalData()).thenReturn(map); - DataCommitTransaction dataCommitTrans = clusteredDS.requestCommit(dataModification); - dataCommitTrans.finish(); - Object value = clusteredDS.readOperationalData(null); - } - -} 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 deleted file mode 100644 index 5f43ddc16d..0000000000 --- a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28 - - - - - - - - - prefix:dom-clustered-store-impl - - cluster-data-store - - - - - - - - - - - - diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/logback.xml b/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/logback.xml deleted file mode 100644 index 5246f01d05..0000000000 --- a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java index c4c1ee9351..9276238e01 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java @@ -54,10 +54,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.No import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; -import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; import com.google.common.base.Objects; import com.google.common.base.Preconditions; @@ -83,32 +80,20 @@ public final class NodeMapping { return new org.opendaylight.controller.sal.core.Node(NodeMapping.MD_SAL_TYPE, aDNodeId); } - public static NodeId toNodeId(final InstanceIdentifier node) { - Preconditions.>checkNotNull(node); - List path = node.getPath(); - Preconditions.>checkNotNull(path); - int size = path.size(); - Preconditions.checkArgument(size >= 2); - final PathArgument arg = path.get(1); - final IdentifiableItem item = Arguments.checkInstanceOf(arg, IdentifiableItem.class); - Identifier key = item.getKey(); - final NodeKey nodeKey = Arguments.checkInstanceOf(key, NodeKey.class); - return nodeKey.getId(); + public static NodeId toNodeId(final InstanceIdentifier id) { + final NodeKey key = id.firstKeyOf(Node.class, NodeKey.class); + Preconditions.checkArgument(key != null, "No node identifier found in %s", id); + return key.getId(); } public static String toADNodeId(final NodeId nodeId) { - Preconditions.checkNotNull(nodeId); return nodeId.getValue(); } public static org.opendaylight.controller.sal.core.NodeConnector toADNodeConnector(final NodeConnectorRef source) throws ConstructionException { - Preconditions.checkNotNull(source); - final InstanceIdentifier path = Preconditions.>checkNotNull(source.getValue()); - Preconditions.checkArgument(path.getPath().size() >= 3); - final PathArgument arg = path.getPath().get(2); - final IdentifiableItem item = Arguments.checkInstanceOf(arg,IdentifiableItem.class); - final NodeConnectorKey connectorKey = Arguments.checkInstanceOf(item.getKey(), NodeConnectorKey.class); - return NodeMapping.toADNodeConnector(connectorKey.getId(), NodeMapping.toNodeId(path)); + final InstanceIdentifier id = Preconditions.checkNotNull(source.getValue()); + final NodeConnectorKey key = id.firstKeyOf(NodeConnector.class, NodeConnectorKey.class); + return NodeMapping.toADNodeConnector(key.getId(), NodeMapping.toNodeId(id)); } public static org.opendaylight.controller.sal.core.NodeConnector toADNodeConnector(final NodeConnectorId ncid, final NodeId nid) throws ConstructionException { @@ -161,6 +146,7 @@ public final class NodeMapping { public static NodeConnectorRef toNodeConnectorRef(final org.opendaylight.controller.sal.core.NodeConnector nodeConnector) { final NodeRef node = NodeMapping.toNodeRef(nodeConnector.getNode()); + @SuppressWarnings("unchecked") final InstanceIdentifier nodePath = ((InstanceIdentifier) node.getValue()); NodeConnectorId nodeConnectorId = null; diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index a13d2bb06f..94bd0731aa 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -57,8 +57,6 @@ remoterpc-routingtable/implementation sal-remoterpc-connector/implementation - sal-rest-docgen @@ -206,10 +204,6 @@ sal-binding-it sal-binding-dom-it - - - - diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareConsumer.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareConsumer.java index fc297261b7..871abb2117 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareConsumer.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareConsumer.java @@ -15,7 +15,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerCo * component of the controller or application supplies a concrete implementation * of this interface. * - * A user-implemented component (application) which faciliates the SAL and SAL + * A user-implemented component (application) which facilitates the SAL and SAL * services to access infrastructure services or providers' functionality. * * diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java index 53615ad7de..3f9d5c7854 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java @@ -142,27 +142,46 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener { return potential; } + int normalizedCount = getAugmentationCount(normalized); AugmentationIdentifier lastArgument = (AugmentationIdentifier) Iterables.getLast(normalized.getPath()); // Here we employ small trick - Binding-aware Codec injects an pointer // to augmentation class // if child is referenced - so we will reference child and then shorten // path. + LOG.trace("Looking for candidates to match {}", normalized); for (QName child : lastArgument.getPossibleChildNames()) { org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier( ImmutableList. builder().addAll(normalized.getPath()).add(new NodeIdentifier(child)) .build()); try { - if (!isChoiceOrCasePath(childPath)) { - InstanceIdentifier potentialPath = shortenToLastAugment(toBindingImpl( - childPath).get()); - return Optional.> of(potentialPath); + if (isNotRepresentable(childPath)) { + LOG.trace("Path {} is not BI-representable, skipping it", childPath); + continue; } - } catch (Exception e) { - LOG.trace("Unable to deserialize aug. child path for {}", childPath, e); + } catch (DataNormalizationException e) { + LOG.warn("Failed to denormalize path {}, skipping it", childPath, e); + continue; + } + + Optional> baId = toBindingImpl(childPath); + if (!baId.isPresent()) { + LOG.debug("No binding-aware identifier found for path {}, skipping it", childPath); + continue; + } + + InstanceIdentifier potentialPath = shortenToLastAugment(baId.get()); + int potentialAugmentCount = getAugmentationCount(potentialPath); + if (potentialAugmentCount == normalizedCount) { + LOG.trace("Found matching path {}", potentialPath); + return Optional.> of(potentialPath); } + + LOG.trace("Skipping mis-matched potential path {}", potentialPath); } - return toBindingImpl(normalized); + + LOG.trace("Failed to find augmentation matching {}", normalized); + return Optional.absent(); } private Optional> toBindingImpl( @@ -171,7 +190,7 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener { org.opendaylight.yangtools.yang.data.api.InstanceIdentifier legacyPath; try { - if (isChoiceOrCasePath(normalized)) { + if (isNotRepresentable(normalized)) { return Optional.absent(); } legacyPath = legacyToNormalized.toLegacy(normalized); @@ -183,10 +202,16 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener { return Optional.> of(bindingToLegacy.fromDataDom(legacyPath)); } - private boolean isChoiceOrCasePath(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized) + private boolean isNotRepresentable(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized) throws DataNormalizationException { DataNormalizationOperation op = findNormalizationOperation(normalized); - return op.isMixin() && op.getIdentifier() instanceof NodeIdentifier; + if( op.isMixin() && op.getIdentifier() instanceof NodeIdentifier) { + return true; + } + if(op.isLeaf()) { + return true; + } + return false; } private DataNormalizationOperation findNormalizationOperation( @@ -256,7 +281,7 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener { if (isAugmentationIdentifier(processed)) { return processed; } - // Here we employ small trick - DataNormalizer injecst augmentation + // Here we employ small trick - DataNormalizer injects augmentation // identifier if child is // also part of the path (since using a child we can safely identify // augmentation) @@ -340,10 +365,8 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener { try { return ClassLoaderUtils.withClassLoader(method.getDeclaringClass().getClassLoader(), new Callable() { - - @SuppressWarnings("rawtypes") @Override - public Class call() throws Exception { + public Class call() { Type listResult = ClassLoaderUtils.getFirstGenericParameter(method .getGenericReturnType()); if (listResult instanceof Class @@ -383,4 +406,25 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener { private boolean isAugmentationIdentifier(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier processed) { return Iterables.getLast(processed.getPath()) instanceof AugmentationIdentifier; } + + private static int getAugmentationCount(final InstanceIdentifier potential) { + int count = 0; + for(org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : potential.getPathArguments()) { + if(isAugmentation(arg.getType())) { + count++; + } + + } + return count; + } + + private static int getAugmentationCount(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier potential) { + int count = 0; + for(PathArgument arg : potential.getPath()) { + if(arg instanceof AugmentationIdentifier) { + count++; + } + } + return count; + } } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.java new file mode 100644 index 0000000000..c1eba3ee25 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.java @@ -0,0 +1,96 @@ +package org.opendaylight.controller.sal.binding.test.bugfix; + +import static org.junit.Assert.assertFalse; + +import java.util.concurrent.ExecutionException; + +import org.junit.Test; +import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +import com.google.common.util.concurrent.SettableFuture; + +public class DeleteNestedAugmentationListenParentTest extends AbstractDataServiceTest { + + private static final NodeKey NODE_KEY = new NodeKey(new NodeId("foo")); + + private static final TableKey TABLE_KEY = new TableKey((short) 0); + + private static final FlowKey FLOW_KEY = new FlowKey(new FlowId("100")); + + private static final InstanceIdentifier LISTENER_PATH = InstanceIdentifier.builder(Nodes.class) // + .child(Node.class) + .augmentation(FlowCapableNode.class).build(); + + + private static final InstanceIdentifier NODE_AUGMENT_PATH = InstanceIdentifier.builder(Nodes.class) + .child(Node.class,NODE_KEY) + .augmentation(FlowCapableNode.class) + .build(); + + private static final InstanceIdentifier FLOW_PATH = NODE_AUGMENT_PATH.builder() + .child(Table.class,TABLE_KEY) + .child(Flow.class,FLOW_KEY) + .build(); + + + @Test + public void deleteChildListenParent() throws InterruptedException, ExecutionException { + DataModificationTransaction initTx = baDataService.beginTransaction(); + + initTx.putOperationalData(FLOW_PATH, flow()); + initTx.commit().get(); + + final SettableFuture, DataObject>> event = SettableFuture.create(); + + ListenerRegistration listenerReg = baDataService.registerDataChangeListener(FLOW_PATH, new DataChangeListener() { + + @Override + public void onDataChanged(final DataChangeEvent, DataObject> change) { + event.set(change); + } + }); + + DataModificationTransaction deleteTx = baDataService.beginTransaction(); + deleteTx.removeOperationalData(FLOW_PATH.augmentation(FlowStatisticsData.class)); + deleteTx.commit().get(); + + DataChangeEvent, DataObject> receivedEvent = event.get(); + assertFalse(receivedEvent.getRemovedOperationalData().contains(NODE_AUGMENT_PATH)); + } + + private Flow flow() { + FlowBuilder builder = new FlowBuilder() + .setKey(FLOW_KEY) + .addAugmentation(FlowStatisticsData.class,new FlowStatisticsDataBuilder() + .setFlowStatistics(new FlowStatisticsBuilder() + .setBarrier(true) + .setMatch(new MatchBuilder() + .build()) + .build()) + .build()) + ;//.build(); + return builder.build(); + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-spi/pom.xml b/opendaylight/md-sal/sal-binding-spi/pom.xml deleted file mode 100644 index 22397a80b4..0000000000 --- a/opendaylight/md-sal/sal-binding-spi/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - 4.0.0 - - org.opendaylight.controller - sal-parent - 1.0-SNAPSHOT - - sal-binding-spi - - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL - - - - - org.opendaylight.controller - sal-binding-api - 1.0-SNAPSHOT - - - org.opendaylight.controller - sal-core-api - 1.0-SNAPSHOT - - - org.opendaylight.controller - concepts-lang - 0.5-SNAPSHOT - - - diff --git a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/DataDomToJavaTransformer.java b/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/DataDomToJavaTransformer.java deleted file mode 100644 index bdcb2c2171..0000000000 --- a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/DataDomToJavaTransformer.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.spi; - -import org.opendaylight.controller.concepts.lang.Transformer; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; - -public interface DataDomToJavaTransformer

extends Transformer { - - /** - * Returns a QName of valid input composite node. - * - * @return - */ - QName getQName(); -} diff --git a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/JavaToDataDomTransformer.java b/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/JavaToDataDomTransformer.java deleted file mode 100644 index 21154b4078..0000000000 --- a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/JavaToDataDomTransformer.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.spi; - -import org.opendaylight.controller.concepts.lang.InputClassBasedTransformer; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; - -public interface JavaToDataDomTransformer extends - InputClassBasedTransformer { -} diff --git a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/Mapper.java b/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/Mapper.java deleted file mode 100644 index 44ca27e89f..0000000000 --- a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/Mapper.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.spi; - -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; -/** - * Translator between Binding-Independent format and generated Binding Data Objects - * - * - * - * - * @param Result Type - */ -public interface Mapper { - - QName getQName(); - Class getDataObjectClass(); - T objectFromDom(CompositeNode object); - - /** - * - * @param obj - * @return - * @throws IllegalArgumentException - */ - CompositeNode domFromObject(DataObject obj) throws IllegalArgumentException; - -} diff --git a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/MappingProvider.java b/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/MappingProvider.java deleted file mode 100644 index b3eded9939..0000000000 --- a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/MappingProvider.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.spi; - -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; - -public interface MappingProvider { - - Mapper mapperForClass(Class type); - Mapper mapperForQName(QName name); - - /** - * Returns {@link RpcMapper} associated to class - * - * @param type Class for which RpcMapper should provide mapping - * @return - */ - RpcMapper rpcMapperForClass(Class type); - - /** - * Returns {@link RpcMapper} associated to the {@link RpcService} proxy. - * - * @param proxy - * @return - */ - RpcMapper rpcMapperForProxy(RpcService proxy); - - /** - * - * - * @param rpc - * @param inputNode - * @return - */ - RpcMapper rpcMapperForData(QName rpc, - CompositeNode inputNode); - - MappingExtensionFactory getExtensionFactory(Class cls); - - public interface MappingExtension { - - } - - public interface MappingExtensionFactory { - T forClass(Class obj); - } - - - -} diff --git a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcMapper.java b/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcMapper.java deleted file mode 100644 index 3e32ebc479..0000000000 --- a/opendaylight/md-sal/sal-binding-spi/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcMapper.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.spi; - -import java.util.Set; -import java.util.concurrent.Future; - -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcResult; - -public interface RpcMapper { - - Set getRpcQNames(); - - /** - * Returns a class object representing subinterface - * to whom, this mapper is assigned. - * - * @return - */ - Class getServiceClass(); - - /** - * Returns a Binding Mapper for Rpc Input Data - * @return - */ - Mapper getInputMapper(); - /** - * Returns a Binding Mapper for Rpc Output Data - * - * @return - */ - Mapper getOutputMapper(); - - /** - * Returns a consumer proxy, which is responsible - * for invoking the rpc functionality of {@link BindingAwareBroker} implementation. - * - * @return Proxy of {@link RpcService} assigned to this mapper. - */ - T getConsumerProxy(RpcProxyInvocationHandler handler); - - /** - * Invokes the method of RpcService representing the supplied rpc. - * - * @param rpc QName of Rpc - * @param impl Implementation of RpcService on which the method should be invoked - * @param baInput Input Data to RPC method - * @return Result of RPC invocation. - */ - RpcResult invokeRpcImplementation(QName rpc, - RpcService impl, DataObject baInput); - - public interface RpcProxyInvocationHandler { - - Future> invokeRpc(RpcService proxy, QName rpc, DataObject input); - } -} diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java index a36d984fa7..f869254dcf 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java @@ -45,6 +45,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -82,6 +83,8 @@ public abstract class DataNormalizationOperation impleme public abstract NormalizedNode normalize(Node legacyData); + public abstract boolean isLeaf(); + private static abstract class SimpleTypeNormalization extends DataNormalizationOperation { protected SimpleTypeNormalization(final T identifier) { @@ -112,6 +115,11 @@ public abstract class DataNormalizationOperation impleme return null; } + @Override + public boolean isLeaf() { + return true; + } + } private static final class LeafNormalization extends SimpleTypeNormalization { @@ -198,6 +206,11 @@ public abstract class DataNormalizationOperation impleme return builder.build(); } + @Override + public boolean isLeaf() { + return false; + } + @SuppressWarnings("rawtypes") protected abstract NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode); @@ -223,20 +236,32 @@ public abstract class DataNormalizationOperation impleme if (potential != null) { return potential; } - potential = fromSchema(schema, child); + potential = fromLocalSchema(child); return register(potential); } + private DataNormalizationOperation fromLocalSchema(final PathArgument child) throws DataNormalizationException { + if (child instanceof AugmentationIdentifier) { + return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames() + .iterator().next()); + } + return fromSchemaAndQNameChecked(schema, child.getNodeType()); + } + @Override public DataNormalizationOperation getChild(final QName child) throws DataNormalizationException { DataNormalizationOperation potential = byQName.get(child); if (potential != null) { return potential; } - potential = fromSchemaAndPathArgument(schema, child); + potential = fromLocalSchemaAndQName(schema, child); return register(potential); } + protected DataNormalizationOperation fromLocalSchemaAndQName(final DataNodeContainer schema2, final QName child) throws DataNormalizationException { + return fromSchemaAndQNameChecked(schema2, child); + } + private DataNormalizationOperation register(final DataNormalizationOperation potential) { if (potential != null) { byArg.put(potential.getIdentifier(), potential); @@ -398,38 +423,34 @@ public abstract class DataNormalizationOperation impleme } } - private static final class AugmentationNormalization extends MixinNormalizationOp { - - private final Map> byQName; - private final Map> byArg; + private static final class AugmentationNormalization extends DataContainerNormalizationOperation { public AugmentationNormalization(final AugmentationSchema augmentation, final DataNodeContainer schema) { - super(augmentationIdentifierFrom(augmentation)); - - ImmutableMap.Builder> byQNameBuilder = ImmutableMap.builder(); - ImmutableMap.Builder> byArgBuilder = ImmutableMap.builder(); - - for (DataSchemaNode augNode : augmentation.getChildNodes()) { - DataSchemaNode resolvedNode = schema.getDataChildByName(augNode.getQName()); - DataNormalizationOperation resolvedOp = fromDataSchemaNode(resolvedNode); - byArgBuilder.put(resolvedOp.getIdentifier(), resolvedOp); - for (QName resQName : resolvedOp.getQNameIdentifiers()) { - byQNameBuilder.put(resQName, resolvedOp); - } - } - byQName = byQNameBuilder.build(); - byArg = byArgBuilder.build(); - + //super(); + super(augmentationIdentifierFrom(augmentation), augmentationProxy(augmentation,schema)); } @Override - public DataNormalizationOperation getChild(final PathArgument child) { - return byArg.get(child); + public boolean isMixin() { + return true; } + + @Override - public DataNormalizationOperation getChild(final QName child) { - return byQName.get(child); + protected DataNormalizationOperation fromLocalSchemaAndQName(final DataNodeContainer schema, final QName child) + throws DataNormalizationException { + Optional potential = findChildSchemaNode(schema, child); + if (!potential.isPresent()) { + return null; + } + + DataSchemaNode result = potential.get(); + // We try to look up if this node was added by augmentation + if ((schema instanceof DataSchemaNode) && result.isAugmenting()) { + return fromAugmentation(schema, (AugmentationTarget) schema, result); + } + return fromDataSchemaNode(result); } @Override @@ -591,23 +612,30 @@ public abstract class DataNormalizationOperation impleme } } - private static DataNormalizationOperation fromSchemaAndPathArgument(final DataNodeContainer schema, - final QName child) throws DataNormalizationException { - DataSchemaNode potential = schema.getDataChildByName(child); + private static final Optional findChildSchemaNode(final DataNodeContainer parent,final QName child) { + DataSchemaNode potential = parent.getDataChildByName(child); if (potential == null) { Iterable choices = FluentIterable.from( - schema.getChildNodes()).filter(org.opendaylight.yangtools.yang.model.api.ChoiceNode.class); + parent.getChildNodes()).filter(org.opendaylight.yangtools.yang.model.api.ChoiceNode.class); potential = findChoice(choices, child); } + return Optional.fromNullable(potential); + } - if (potential == null) { + private static DataNormalizationOperation fromSchemaAndQNameChecked(final DataNodeContainer schema, + final QName child) throws DataNormalizationException { + + Optional potential = findChildSchemaNode(schema, child); + if (!potential.isPresent()) { throw new DataNormalizationException(String.format("Supplied QName %s is not valid according to schema %s, potential children nodes: %s", child, schema,schema.getChildNodes())); } - if ((schema instanceof DataSchemaNode) && !((DataSchemaNode) schema).isAugmenting() && potential.isAugmenting()) { - return fromAugmentation(schema, (AugmentationTarget) schema, potential); + DataSchemaNode result = potential.get(); + // We try to look up if this node was added by augmentation + if ((schema instanceof DataSchemaNode) && result.isAugmenting()) { + return fromAugmentation(schema, (AugmentationTarget) schema, result); } - return fromDataSchemaNode(potential); + return fromDataSchemaNode(result); } private static org.opendaylight.yangtools.yang.model.api.ChoiceNode findChoice( @@ -615,7 +643,7 @@ public abstract class DataNormalizationOperation impleme org.opendaylight.yangtools.yang.model.api.ChoiceNode foundChoice = null; choiceLoop: for (org.opendaylight.yangtools.yang.model.api.ChoiceNode choice : choices) { for (ChoiceCaseNode caze : choice.getCases()) { - if (caze.getDataChildByName(child) != null) { + if (findChildSchemaNode(caze, child).isPresent()) { foundChoice = choice; break choiceLoop; } @@ -632,30 +660,44 @@ public abstract class DataNormalizationOperation impleme return new AugmentationIdentifier(null, potentialChildren.build()); } - private static AugmentationNormalization fromAugmentation(final DataNodeContainer schema, - final AugmentationTarget augments, final DataSchemaNode potential) { + private static DataNodeContainer augmentationProxy(final AugmentationSchema augmentation, final DataNodeContainer schema) { + Set children = new HashSet<>(); + for (DataSchemaNode augNode : augmentation.getChildNodes()) { + children.add(schema.getDataChildByName(augNode.getQName())); + } + return new DataSchemaContainerProxy(children); + } + + /** + * Returns a DataNormalizationOperation for provided child node + * + * If supplied child is added by Augmentation this operation returns + * a DataNormalizationOperation for augmentation, + * otherwise returns a DataNormalizationOperation for child as + * call for {@link #fromDataSchemaNode(DataSchemaNode)}. + * + * + * @param parent + * @param parentAug + * @param child + * @return + */ + private static DataNormalizationOperation fromAugmentation(final DataNodeContainer parent, + final AugmentationTarget parentAug, final DataSchemaNode child) { AugmentationSchema augmentation = null; - for (AugmentationSchema aug : augments.getAvailableAugmentations()) { - DataSchemaNode child = aug.getDataChildByName(potential.getQName()); - if (child != null) { + for (AugmentationSchema aug : parentAug.getAvailableAugmentations()) { + DataSchemaNode potential = aug.getDataChildByName(child.getQName()); + if (potential != null) { augmentation = aug; break; } } if (augmentation != null) { - return new AugmentationNormalization(augmentation, schema); + return new AugmentationNormalization(augmentation, parent); } else { - return null; - } - } - - private static DataNormalizationOperation fromSchema(final DataNodeContainer schema, final PathArgument child) throws DataNormalizationException { - if (child instanceof AugmentationIdentifier) { - return fromSchemaAndPathArgument(schema, ((AugmentationIdentifier) child).getPossibleChildNames() - .iterator().next()); + return fromDataSchemaNode(child); } - return fromSchemaAndPathArgument(schema, child.getNodeType()); } public static DataNormalizationOperation fromDataSchemaNode(final DataSchemaNode potential) { diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataSchemaContainerProxy.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataSchemaContainerProxy.java new file mode 100644 index 0000000000..d243c888bd --- /dev/null +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataSchemaContainerProxy.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.common.impl.util.compat; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UsesNode; + +class DataSchemaContainerProxy implements DataNodeContainer { + + private final Set realChildSchemas; + private final Map mappedChildSchemas; + + public DataSchemaContainerProxy(final Set realChildSchema) { + realChildSchemas = realChildSchema; + mappedChildSchemas = new HashMap(); + for(DataSchemaNode schema : realChildSchemas) { + mappedChildSchemas.put(schema.getQName(),schema); + } + } + + @Override + public DataSchemaNode getDataChildByName(final QName name) { + return mappedChildSchemas.get(name); + } + + @Override + public Set getChildNodes() { + return realChildSchemas; + } + + @Override + public DataSchemaNode getDataChildByName(final String arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public Set getGroupings() { + return Collections.emptySet(); + } + + @Override + public Set> getTypeDefinitions() { + return Collections.emptySet(); + } + + @Override + public Set getUses() { + return Collections.emptySet(); + } + +} diff --git a/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java index 902665d1a6..a4017c23a8 100644 --- a/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java +++ b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java @@ -7,16 +7,16 @@ */ package org.opendaylight.controller.sal.common.util; -public class Arguments { +public final class Arguments { private Arguments() { throw new UnsupportedOperationException("Utility class"); } - + /** * Checks if value is instance of provided class - * - * + * + * * @param value Value to check * @param type Type to check * @return Reference which was checked @@ -24,7 +24,7 @@ public class Arguments { @SuppressWarnings("unchecked") public static T checkInstanceOf(Object value, Class type) { if(!type.isInstance(value)) - throw new IllegalArgumentException(); + throw new IllegalArgumentException(String.format("Value %s is not of type %s", value, type)); return (T) value; } } diff --git a/opendaylight/md-sal/sal-data-api/pom.xml b/opendaylight/md-sal/sal-data-api/pom.xml deleted file mode 100644 index 6b73e29e7d..0000000000 --- a/opendaylight/md-sal/sal-data-api/pom.xml +++ /dev/null @@ -1,15 +0,0 @@ - - 4.0.0 - - org.opendaylight.controller - sal-parent - 1.0-SNAPSHOT - - sal-data-api - - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL - - - diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Consumer.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Consumer.java index 0006953542..3127df521f 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Consumer.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Consumer.java @@ -17,7 +17,7 @@ import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession; * component of the controller or application supplies a concrete implementation * of this interface. * - * A user-implemented component (application) which faciliates the SAL and SAL + * A user-implemented component (application) which facilitates the SAL and SAL * services to access infrastructure services or providers' functionality. * * diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Provider.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Provider.java index e2df70baea..fef8618b2c 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Provider.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Provider.java @@ -18,7 +18,7 @@ import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; * of this interface. * *

- * A user-implemented component (application) which faciliates the SAL and SAL + * A user-implemented component (application) which facilitates the SAL and SAL * services to access infrastructure services and to provide functionality to * {@link Consumer}s and other providers. * diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataAndMetadataSnapshot.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataAndMetadataSnapshot.java deleted file mode 100644 index 11028dc842..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataAndMetadataSnapshot.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.md.sal.dom.store.impl; - -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.impl.schema.Builders; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -import com.google.common.base.Optional; - -class DataAndMetadataSnapshot { - - private final StoreMetadataNode metadataTree; - private final Optional schemaContext; - - private DataAndMetadataSnapshot(final StoreMetadataNode metadataTree, final Optional schemaCtx) { - this.metadataTree = metadataTree; - this.schemaContext = schemaCtx; - } - - public static Builder builder() { - return new Builder(); - } - - public static DataAndMetadataSnapshot createEmpty() { - return createEmpty(new NodeIdentifier(SchemaContext.NAME)); - } - - - public static DataAndMetadataSnapshot createEmpty(final NodeIdentifier rootNode) { - NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(rootNode).build(); - StoreMetadataNode metadata = StoreMetadataNode.createEmpty(data); - return new DataAndMetadataSnapshot(metadata,Optional.absent()); - } - - public static DataAndMetadataSnapshot createEmpty(final SchemaContext ctx) { - NodeIdentifier rootNodeIdentifier = new NodeIdentifier(ctx.getQName()); - NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(rootNodeIdentifier).build(); - StoreMetadataNode metadata = StoreMetadataNode.createEmpty(data); - return new DataAndMetadataSnapshot(metadata, Optional.of(ctx)); - } - - public Optional getSchemaContext() { - return schemaContext; - } - - public NormalizedNode getDataTree() { - return metadataTree.getData(); - } - - public StoreMetadataNode getMetadataTree() { - return metadataTree; - } - - public Optional read(final InstanceIdentifier path) { - return TreeNodeUtils.findNode(metadataTree, path); - } - - public static class Builder { - private NormalizedNode dataTree; - private StoreMetadataNode metadataTree; - private SchemaContext schemaContext; - - public NormalizedNode getDataTree() { - return dataTree; - } - - public Builder setMetadataTree(final StoreMetadataNode metadataTree) { - this.metadataTree = metadataTree; - return this; - } - - public Builder setSchemaContext(final SchemaContext schemaContext) { - this.schemaContext = schemaContext; - return this; - } - - public DataAndMetadataSnapshot build() { - return new DataAndMetadataSnapshot(metadataTree, Optional.fromNullable(schemaContext)); - } - - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java new file mode 100644 index 0000000000..3124199006 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl; + +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; + +/** + * Read-only snapshot of the data tree. + */ +final class DataTree { + public static final class Snapshot { + private final SchemaContext schemaContext; + private final StoreMetadataNode rootNode; + + @VisibleForTesting + Snapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode) { + this.schemaContext = Preconditions.checkNotNull(schemaContext); + this.rootNode = Preconditions.checkNotNull(rootNode); + } + + public SchemaContext getSchemaContext() { + return schemaContext; + } + + public Optional> readNode(final InstanceIdentifier path) { + return NormalizedNodeUtils.findNode(rootNode.getData(), path); + } + + // FIXME: this is a leak of information + @Deprecated + StoreMetadataNode getRootNode() { + return rootNode; + } + + @Override + public String toString() { + return rootNode.getSubtreeVersion().toString(); + } + } + + private static final Logger LOG = LoggerFactory.getLogger(DataTree.class); + private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true); + private StoreMetadataNode rootNode; + private SchemaContext currentSchemaContext; + + private DataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) { + this.rootNode = Preconditions.checkNotNull(rootNode); + this.currentSchemaContext = schemaContext; + } + + public synchronized void setSchemaContext(final SchemaContext newSchemaContext) { + Preconditions.checkNotNull(newSchemaContext); + + LOG.info("Attepting to install schema context {}", newSchemaContext); + + /* + * FIXME: we should walk the schema contexts, both current and new and see + * whether they are compatible here. Reject incompatible changes. + */ + + // Ready to change the context now, make sure no operations are running + rwLock.writeLock().lock(); + try { + this.currentSchemaContext = newSchemaContext; + } finally { + rwLock.writeLock().unlock(); + } + } + + public static DataTree create(final SchemaContext schemaContext) { + final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME); + final NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(root).build(); + + return new DataTree(StoreMetadataNode.createEmpty(data), schemaContext); + } + + public Snapshot takeSnapshot() { + rwLock.readLock().lock(); + + try { + return new Snapshot(currentSchemaContext, rootNode); + } finally { + rwLock.readLock().unlock(); + } + } + + public void commitSnapshot(Snapshot currentSnapshot, StoreMetadataNode newDataTree) { + // Ready to change the context now, make sure no operations are running + rwLock.writeLock().lock(); + try { + Preconditions.checkState(currentSnapshot.rootNode == rootNode, + String.format("Store snapshot %s and transaction snapshot %s differ.", + rootNode, currentSnapshot.rootNode)); + + this.rootNode = newDataTree; + } finally { + rwLock.writeLock().unlock(); + } + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java index 005e3b772d..7d2ff30b1f 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java @@ -14,7 +14,6 @@ import static org.opendaylight.controller.md.sal.dom.store.impl.StoreUtils.incre import java.util.Collections; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener; @@ -34,7 +33,6 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.slf4j.Logger; @@ -57,19 +55,13 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch private final ListeningExecutorService executor; private final String name; private final AtomicLong txCounter = new AtomicLong(0); - private final ListenerTree listenerTree; - private final AtomicReference snapshot; - - private ModificationApplyOperation operationTree; - - private SchemaContext schemaContext; + private final ListenerTree listenerTree = ListenerTree.create(); + private final DataTree dataTree = DataTree.create(null); + private ModificationApplyOperation operationTree = new AlwaysFailOperation(); public InMemoryDOMDataStore(final String name, final ListeningExecutorService executor) { this.name = Preconditions.checkNotNull(name); this.executor = Preconditions.checkNotNull(executor); - this.listenerTree = ListenerTree.create(); - this.snapshot = new AtomicReference(DataAndMetadataSnapshot.createEmpty()); - this.operationTree = new AlwaysFailOperation(); } @Override @@ -79,23 +71,30 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch @Override public DOMStoreReadTransaction newReadOnlyTransaction() { - return new SnapshotBackedReadTransaction(nextIdentifier(), snapshot.get()); + return new SnapshotBackedReadTransaction(nextIdentifier(), dataTree.takeSnapshot()); } @Override public DOMStoreReadWriteTransaction newReadWriteTransaction() { - return new SnapshotBackedReadWriteTransaction(nextIdentifier(), snapshot.get(), this, operationTree); + return new SnapshotBackedReadWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this, operationTree); } @Override public DOMStoreWriteTransaction newWriteOnlyTransaction() { - return new SnapshotBackedWriteTransaction(nextIdentifier(), snapshot.get(), this, operationTree); + return new SnapshotBackedWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this, operationTree); } @Override public synchronized void onGlobalContextUpdated(final SchemaContext ctx) { - operationTree = SchemaAwareApplyOperationRoot.from(ctx); - schemaContext = ctx; + /* + * Order of operations is important: dataTree may reject the context + * and creation of ModificationApplyOperation may fail. So pre-construct + * the operation, then update the data tree and then move the operation + * into view. + */ + final ModificationApplyOperation newOperationTree = SchemaAwareApplyOperationRoot.from(ctx); + dataTree.setSchemaContext(ctx); + operationTree = newOperationTree; } @Override @@ -115,9 +114,9 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch reg = listenerTree.registerDataChangeListener(path, listener, scope); - Optional currentState = snapshot.get().read(path); + Optional> currentState = dataTree.takeSnapshot().readNode(path); if (currentState.isPresent()) { - final NormalizedNode data = currentState.get().getData(); + final NormalizedNode data = currentState.get(); final DOMImmutableDataChangeEvent event = DOMImmutableDataChangeEvent.builder(DataChangeScope.BASE) // .setAfter(data) // @@ -146,27 +145,20 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch return name + "-" + txCounter.getAndIncrement(); } - private void commit(final DataAndMetadataSnapshot currentSnapshot, final StoreMetadataNode newDataTree, + private void commit(final DataTree.Snapshot currentSnapshot, final StoreMetadataNode newDataTree, final ResolveDataChangeEventsTask listenerResolver) { - LOG.debug("Updating Store snaphot version: {} with version:{}", currentSnapshot.getMetadataTree() - .getSubtreeVersion(), newDataTree.getSubtreeVersion()); + LOG.debug("Updating Store snaphot version: {} with version:{}", currentSnapshot, newDataTree.getSubtreeVersion()); if (LOG.isTraceEnabled()) { - LOG.trace("Data Tree is {}", StoreUtils.toStringTree(newDataTree)); + LOG.trace("Data Tree is {}", StoreUtils.toStringTree(newDataTree.getData())); } - final DataAndMetadataSnapshot newSnapshot = DataAndMetadataSnapshot.builder() // - .setMetadataTree(newDataTree) // - .setSchemaContext(schemaContext) // - .build(); - /* * The commit has to occur atomically with regard to listener * registrations. */ synchronized (this) { - final boolean success = snapshot.compareAndSet(currentSnapshot, newSnapshot); - checkState(success, "Store snapshot and transaction snapshot differ. This should never happen."); + dataTree.commitSnapshot(currentSnapshot, newDataTree); for (ChangeListenerNotifyTask task : listenerResolver.call()) { LOG.trace("Scheduling invocation of listeners: {}", task); @@ -204,15 +196,14 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch } } - private static class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements + private static final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements DOMStoreReadTransaction { - private DataAndMetadataSnapshot stableSnapshot; + private DataTree.Snapshot stableSnapshot; - public SnapshotBackedReadTransaction(final Object identifier, final DataAndMetadataSnapshot snapshot) { + public SnapshotBackedReadTransaction(final Object identifier, final DataTree.Snapshot snapshot) { super(identifier); this.stableSnapshot = Preconditions.checkNotNull(snapshot); - LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot.getMetadataTree() - .getSubtreeVersion()); + LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot); } @Override @@ -225,7 +216,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch public ListenableFuture>> read(final InstanceIdentifier path) { checkNotNull(path, "Path must not be null."); checkState(stableSnapshot != null, "Transaction is closed"); - return Futures.immediateFuture(NormalizedNodeUtils.findNode(stableSnapshot.getDataTree(), path)); + return Futures.immediateFuture(stableSnapshot.readNode(path)); } } @@ -235,13 +226,12 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch private InMemoryDOMDataStore store; private boolean ready = false; - public SnapshotBackedWriteTransaction(final Object identifier, final DataAndMetadataSnapshot snapshot, + public SnapshotBackedWriteTransaction(final Object identifier, final DataTree.Snapshot snapshot, final InMemoryDOMDataStore store, final ModificationApplyOperation applyOper) { super(identifier); mutableTree = MutableDataTree.from(snapshot, applyOper); this.store = store; - LOG.debug("Write Tx: {} allocated with snapshot {}", identifier, snapshot.getMetadataTree() - .getSubtreeVersion()); + LOG.debug("Write Tx: {} allocated with snapshot {}", identifier, snapshot); } @Override @@ -318,7 +308,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch private static class SnapshotBackedReadWriteTransaction extends SnapshotBackedWriteTransaction implements DOMStoreReadWriteTransaction { - protected SnapshotBackedReadWriteTransaction(final Object identifier, final DataAndMetadataSnapshot snapshot, + protected SnapshotBackedReadWriteTransaction(final Object identifier, final DataTree.Snapshot snapshot, final InMemoryDOMDataStore store, final ModificationApplyOperation applyOper) { super(identifier, snapshot, store, applyOper); } @@ -340,7 +330,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch private final SnapshotBackedWriteTransaction transaction; private final NodeModification modification; - private DataAndMetadataSnapshot storeSnapshot; + private DataTree.Snapshot storeSnapshot; private Optional proposedSubtree; private ResolveDataChangeEventsTask listenerResolver; @@ -351,7 +341,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch @Override public ListenableFuture canCommit() { - final DataAndMetadataSnapshot snapshotCapture = snapshot.get(); + final DataTree.Snapshot snapshotCapture = dataTree.takeSnapshot(); final ModificationApplyOperation snapshotOperation = operationTree; return executor.submit(new Callable() { @@ -361,7 +351,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch Boolean applicable = false; try { snapshotOperation.checkApplicable(PUBLIC_ROOT_PATH, modification, - Optional.of(snapshotCapture.getMetadataTree())); + Optional.of(snapshotCapture.getRootNode())); applicable = true; } catch (DataPreconditionFailedException e) { LOG.warn("Store Tx: {} Data Precondition failed for {}.",transaction.getIdentifier(),e.getPath(),e); @@ -375,7 +365,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch @Override public ListenableFuture preCommit() { - storeSnapshot = snapshot.get(); + storeSnapshot = dataTree.takeSnapshot(); if (modification.getModificationType() == ModificationType.UNMODIFIED) { return Futures.immediateFuture(null); } @@ -383,7 +373,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch @Override public Void call() throws Exception { - StoreMetadataNode metadataTree = storeSnapshot.getMetadataTree(); + StoreMetadataNode metadataTree = storeSnapshot.getRootNode(); proposedSubtree = operationTree.apply(modification, Optional.of(metadataTree), increase(metadataTree.getSubtreeVersion())); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java index b711163b46..1002cd54b5 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java @@ -34,13 +34,13 @@ class MutableDataTree { private static final Logger LOG = LoggerFactory.getLogger(MutableDataTree.class); private final AtomicBoolean sealed = new AtomicBoolean(); private final ModificationApplyOperation strategyTree; - private final DataAndMetadataSnapshot snapshot; private final NodeModification rootModification; + private final DataTree.Snapshot snapshot; - private MutableDataTree(final DataAndMetadataSnapshot snapshot, final ModificationApplyOperation strategyTree) { - this.snapshot = snapshot; - this.strategyTree = strategyTree; - this.rootModification = NodeModification.createUnmodified(snapshot.getMetadataTree()); + private MutableDataTree(final DataTree.Snapshot snapshot, final ModificationApplyOperation strategyTree) { + this.snapshot = Preconditions.checkNotNull(snapshot); + this.strategyTree = Preconditions.checkNotNull(strategyTree); + this.rootModification = NodeModification.createUnmodified(snapshot.getRootNode()); } public void write(final InstanceIdentifier path, final NormalizedNode value) { @@ -97,7 +97,7 @@ class MutableDataTree { return potentialSnapshot.get(); } return resolveModificationStrategy(path).apply(modification, modification.getOriginal(), - StoreUtils.increase(snapshot.getMetadataTree().getSubtreeVersion())); + StoreUtils.increase(snapshot.getRootNode().getSubtreeVersion())); } catch (Exception e) { LOG.error("Could not create snapshot for {}:{}", path,modification,e); throw e; @@ -119,7 +119,7 @@ class MutableDataTree { return OperationWithModification.from(operation, modification); } - public static MutableDataTree from(final DataAndMetadataSnapshot snapshot, final ModificationApplyOperation resolver) { + public static MutableDataTree from(final DataTree.Snapshot snapshot, final ModificationApplyOperation resolver) { return new MutableDataTree(snapshot, resolver); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java index 2af522ea86..afe9653394 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java @@ -166,7 +166,16 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper protected void checkMergeApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { Optional original = modification.getOriginal(); if (original.isPresent() && current.isPresent()) { - checkNotConflicting(path,original.get(), current.get()); + /* + * We need to do conflict detection only and only if the value of leaf changed + * before two transactions. If value of leaf is unchanged between two transactions + * it should not cause transaction to fail, since result of this merge + * leads to same data. + */ + if(!original.get().getData().equals(current.get().getData())) { + + checkNotConflicting(path,original.get(), current.get()); + } } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/StoreUtils.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/StoreUtils.java index 0f77ac504a..e1da9a7381 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/StoreUtils.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/StoreUtils.java @@ -7,12 +7,8 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl; -import java.util.Collections; -import java.util.Map; import java.util.Set; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; @@ -25,10 +21,10 @@ import com.google.common.base.Function; import com.google.common.base.Strings; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.primitives.UnsignedLong; public final class StoreUtils { + private static final int STRINGTREE_INDENT = 4; private final static Function, Object> EXTRACT_IDENTIFIER = new Function, Object>() { @Override @@ -37,18 +33,8 @@ public final class StoreUtils { } }; - public static final UnsignedLong increase(final UnsignedLong original) { - return original.plus(UnsignedLong.ONE); - } - - public static final InstanceIdentifier append(final InstanceIdentifier parent, final PathArgument arg) { - - return new InstanceIdentifier(ImmutableList. builder().addAll(parent.getPath()).add(arg).build()); - } - - public static AsyncDataChangeEvent> initialChangeEvent( - final InstanceIdentifier path, final StoreMetadataNode data) { - return new InitialDataChangeEvent(path, data.getData()); + private StoreUtils() { + throw new UnsupportedOperationException("Utility class should not be instantiated"); } /* @@ -61,70 +47,39 @@ public final class StoreUtils { return (Function) EXTRACT_IDENTIFIER; } - private static final class InitialDataChangeEvent implements - AsyncDataChangeEvent> { - - private final ImmutableMap> payload; - private final NormalizedNode data; - - public InitialDataChangeEvent(final InstanceIdentifier path, final NormalizedNode data) { - payload = ImmutableMap.> of(path, data); - this.data = data; - } - - @Override - public Map> getCreatedData() { - return payload; - } - - @Override - public Map> getOriginalData() { - return Collections.emptyMap(); - } - - @Override - public NormalizedNode getOriginalSubtree() { - return null; - } - - @Override - public Set getRemovedPaths() { - return Collections.emptySet(); - } - - @Override - public Map> getUpdatedData() { - return payload; - } + public static final UnsignedLong increase(final UnsignedLong original) { + return original.plus(UnsignedLong.ONE); + } - @Override - public NormalizedNode getUpdatedSubtree() { - return data; - } + public static final InstanceIdentifier append(final InstanceIdentifier parent, final PathArgument arg) { + return new InstanceIdentifier(ImmutableList. builder().addAll(parent.getPath()).add(arg).build()); } public static Set toIdentifierSet(final Iterable> children) { return FluentIterable.from(children).transform(StoreUtils. identifierExtractor()).toSet(); } - public static String toStringTree(final StoreMetadataNode metaNode) { + public static String toStringTree(final NormalizedNode node) { StringBuilder builder = new StringBuilder(); - toStringTree(builder, metaNode, 0); + toStringTree(builder, node, 0); return builder.toString(); } - private static void toStringTree(final StringBuilder builder, final StoreMetadataNode metaNode, final int offset) { - String prefix = Strings.repeat(" ", offset); - builder.append(prefix).append(toStringTree(metaNode.getIdentifier())); - NormalizedNode dataNode = metaNode.getData(); - if (dataNode instanceof NormalizedNodeContainer) { + private static void toStringTree(final StringBuilder builder, final NormalizedNode node, final int offset) { + final String prefix = Strings.repeat(" ", offset); + + builder.append(prefix).append(toStringTree(node.getIdentifier())); + if (node instanceof NormalizedNodeContainer) { + final NormalizedNodeContainer container = (NormalizedNodeContainer) node; + builder.append(" {\n"); - for (StoreMetadataNode child : metaNode.getChildren()) { - toStringTree(builder, child, offset + 4); + for (NormalizedNode child : container.getValue()) { + toStringTree(builder, child, offset + STRINGTREE_INDENT); } + builder.append(prefix).append('}'); } else { - builder.append(' ').append(dataNode.getValue()); + builder.append(' ').append(node.getValue()); } builder.append('\n'); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreMetadataNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreMetadataNode.java index 455777b7fb..b8ad7368b5 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreMetadataNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreMetadataNode.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree; import static com.google.common.base.Preconditions.checkState; import java.util.Collections; -import java.util.LinkedHashMap; +import java.util.HashMap; import java.util.Map; import org.opendaylight.yangtools.concepts.Identifiable; @@ -21,7 +21,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; import com.google.common.primitives.UnsignedLong; public class StoreMetadataNode implements Immutable, Identifiable, StoreTreeNode { @@ -82,10 +81,6 @@ public class StoreMetadataNode implements Immutable, Identifiable, return this.data; } - public Iterable getChildren() { - return Iterables.unmodifiableIterable(children.values()); - } - @Override public Optional getChild(final PathArgument key) { return Optional.fromNullable(children.get(key)); @@ -137,11 +132,11 @@ public class StoreMetadataNode implements Immutable, Identifiable, private boolean dirty = false; private Builder() { - children = new LinkedHashMap<>(); + children = new HashMap<>(); } public Builder(StoreMetadataNode node) { - children = new LinkedHashMap<>(node.children); + children = new HashMap<>(node.children); } public UnsignedLong getVersion() { @@ -166,7 +161,7 @@ public class StoreMetadataNode implements Immutable, Identifiable, public Builder add(final StoreMetadataNode node) { if (dirty) { - children = new LinkedHashMap<>(children); + children = new HashMap<>(children); dirty = false; } children.put(node.getIdentifier(), node); @@ -175,7 +170,7 @@ public class StoreMetadataNode implements Immutable, Identifiable, public Builder remove(final PathArgument id) { if (dirty) { - children = new LinkedHashMap<>(children); + children = new HashMap<>(children); dirty = false; } children.remove(id); diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationMetadataTreeTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationMetadataTreeTest.java index e14699311b..0445c47c6b 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationMetadataTreeTest.java +++ b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationMetadataTreeTest.java @@ -137,11 +137,9 @@ public class ModificationMetadataTreeTest { @Test public void basicReadWrites() { - MutableDataTree modificationTree = MutableDataTree.from( - DataAndMetadataSnapshot.builder() // - .setMetadataTree(StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5))) // - .setSchemaContext(schemaContext) // - .build(), new SchemaAwareApplyOperationRoot(schemaContext)); + MutableDataTree modificationTree = MutableDataTree.from(new DataTree.Snapshot(schemaContext, + StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5))), + new SchemaAwareApplyOperationRoot(schemaContext)); Optional> originalBarNode = modificationTree.read(OUTER_LIST_2_PATH); assertTrue(originalBarNode.isPresent()); assertSame(BAR_NODE, originalBarNode.get()); @@ -166,7 +164,7 @@ public class ModificationMetadataTreeTest { /** * Creates empty Snapshot with associated schema context. */ - DataAndMetadataSnapshot emptySnapshot = DataAndMetadataSnapshot.createEmpty(schemaContext); + DataTree t = DataTree.create(schemaContext); /** * @@ -174,7 +172,7 @@ public class ModificationMetadataTreeTest { * context. * */ - MutableDataTree modificationTree = MutableDataTree.from(emptySnapshot, new SchemaAwareApplyOperationRoot( + MutableDataTree modificationTree = MutableDataTree.from(t.takeSnapshot(), new SchemaAwareApplyOperationRoot( schemaContext)); return modificationTree; } diff --git a/opendaylight/md-sal/sal-dom-demo/pom.xml b/opendaylight/md-sal/sal-dom-demo/pom.xml deleted file mode 100644 index 322bad787b..0000000000 --- a/opendaylight/md-sal/sal-dom-demo/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - 4.0.0 - - org.opendaylight.controller - sal-parent - 1.0-SNAPSHOT - - sal-core-demo - - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL - - - - - org.opendaylight.controller - sal-broker-impl - 1.0-SNAPSHOT - - - org.opendaylight.controller - yang-data-util - - - org.slf4j - slf4j-simple - 1.7.2 - runtime - - - - - - maven-assembly-plugin - 2.4 - - - jar-with-dependencies - - - - org.opendaylight.controller.sal.demo.SALDemo - - - - - - make-assembly - package - - single - - - - - - - - - diff --git a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoConsumerImpl.java b/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoConsumerImpl.java deleted file mode 100644 index e0752dca02..0000000000 --- a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoConsumerImpl.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.demo; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import org.opendaylight.controller.sal.core.api.Consumer; -import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession; -import org.opendaylight.controller.sal.core.api.notify.NotificationListener; -import org.opendaylight.controller.sal.core.api.notify.NotificationService; -import org.opendaylight.controller.yang.common.QName; -import org.opendaylight.controller.yang.data.api.CompositeNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class DemoConsumerImpl implements Consumer { - - private ConsumerSession session; - private NotificationService notificationService; - private final String name; - private static Logger log = LoggerFactory.getLogger("AlertLogger"); - - private boolean changeAware; - - public DemoConsumerImpl(String name) { - this.name = name; - } - - private NotificationListener alertLogger = new NotificationListener() { - - @Override - public void onNotification(CompositeNode notification) { - System.out.println(name - + ": Received alert: " - + notification.getFirstSimpleByName( - DemoUtils.contentNodeName).getValue()); - log.info("AlertLogger: Received notification: " + notification); - } - - @Override - public Set getSupportedNotifications() { - Set supported = new HashSet(); - supported.add(DemoUtils.alertNotification); - return supported; - } - }; - - private NotificationListener changeLogger = new NotificationListener() { - - @Override - public void onNotification(CompositeNode notification) { - System.out.println(name - + ": Received change: " - + notification.getFirstSimpleByName( - DemoUtils.contentNodeName).getValue()); - log.info("ChangeLogger: Received notification: " + notification); - } - - @Override - public Set getSupportedNotifications() { - Set supported = new HashSet(); - supported.add(DemoUtils.alertNotification); - return supported; - } - }; - - @Override - public void onSessionInitiated(ConsumerSession session) { - this.session = session; - this.notificationService = session - .getService(NotificationService.class); - notificationService.addNotificationListener( - DemoUtils.alertNotification, alertLogger); - if (isChangeAware()) { - notificationService.addNotificationListener( - DemoUtils.changeNotification, changeLogger); - } - } - - @Override - public Collection getConsumerFunctionality() { - Set func = new HashSet(); - func.add(alertLogger); - return func; - } - - public void closeSession() { - session.close(); - } - - public boolean isChangeAware() { - return changeAware; - } - - public void setChangeAware(boolean changeAware) { - this.changeAware = changeAware; - } - -} diff --git a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoProviderImpl.java b/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoProviderImpl.java deleted file mode 100644 index 8a393be43d..0000000000 --- a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoProviderImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.demo; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; -import org.opendaylight.controller.sal.core.api.notify.NotificationProviderService; -import org.opendaylight.controller.yang.data.api.Node; -import org.opendaylight.controller.yang.data.util.Nodes; - - -public class DemoProviderImpl implements - org.opendaylight.controller.sal.core.api.Provider { - - private ProviderSession session; - private NotificationProviderService notifier; - - @Override - public void onSessionInitiated(ProviderSession session) { - this.session = session; - notifier = session.getService(NotificationProviderService.class); - } - - @Override - public Collection getProviderFunctionality() { - return Collections.emptySet(); - } - - public void sendAlertNotification(String content) { - List> nodes = new ArrayList>(); - nodes.add(DemoUtils.contentNode(content)); - - if (notifier == null) { - System.out.println("Provider: Error: Session not available"); - System.out - .println(" Notification Service not available"); - return; - } - notifier.sendNotification(Nodes.containerNode( - DemoUtils.alertNotification, nodes)); - } - - public void sendChangeNotification(String content) { - List> nodes = new ArrayList>(); - nodes.add(DemoUtils.contentNode(content)); - - if (notifier == null) { - System.out.println("Provider: Error: Session not available"); - System.out - .println(" Notification Service not available"); - return; - } - notifier.sendNotification(Nodes.containerNode( - DemoUtils.changeNotification, nodes)); - } - - public void closeSession() { - session.close(); - } -} diff --git a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoUtils.java b/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoUtils.java deleted file mode 100644 index 3b0430935f..0000000000 --- a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/DemoUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.demo; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Date; - -import org.opendaylight.controller.yang.common.QName; -import org.opendaylight.controller.yang.data.api.Node; -import org.opendaylight.controller.yang.data.util.Nodes; - - -public class DemoUtils { - - public static final URI namespace = uri("urn:cisco:prototype:sal:demo"); - public static final Date revision = new Date(); - - public static final QName alertNotification = qName("alert"); - public static final QName changeNotification = qName("change"); - - public static final QName contentNodeName = qName("content"); - - public static URI uri(String str) { - try { - return new URI(str); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - } - - public static QName qName(String str) { - return new QName(namespace, revision, str); - } - - public static Node contentNode(String content) { - return Nodes.leafNode(contentNodeName, content); - } -} diff --git a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/SALDemo.java b/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/SALDemo.java deleted file mode 100644 index 9e50059972..0000000000 --- a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/SALDemo.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.demo; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -import org.opendaylight.controller.sal.core.impl.BrokerImpl; -import org.opendaylight.controller.sal.core.impl.NotificationModule; - - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SALDemo { - protected static final Logger logger = LoggerFactory - .getLogger(SALDemo.class); - - static BrokerImpl broker; - static DemoProviderImpl provider; - static DemoConsumerImpl consumer1; - static DemoConsumerImpl consumer2; - - public static void main(String[] args) { - - initialize(); - initializeProvider(); - displayHelp(); - - BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); - String s; - try { - while (true) { - - System.out.print("\nEnter your choice (0 - list): "); - s = in.readLine(); - int choice = Integer.parseInt(s.trim()); - try { - switch (choice) { - case 0: - displayHelp(); - break; - case 1: - registerProvider(); - break; - case 2: - registerConsumer1(); - break; - case 3: - registerConsumer2(); - break; - case 4: - sendAlert(in); - break; - case 5: - sendChange(in); - break; - case 6: - unregisterConsumer1(); - break; - case 7: - unregisterConsumer2(); - break; - case 8: - unregisterProvider(); - break; - case 9: - return; - default: - System.out.println("Please enter valid input."); - break; - } - } catch (Exception e) { - System.out - .println("Operation failed. Reason exception raised: " - + e.getClass().getSimpleName()); - System.out.println(" Message: " + e.getMessage()); - } - - } - } catch (IOException e) { - - logger.error("",e); - } - } - - private static void registerConsumer1() { - broker.registerConsumer(consumer1); - } - - private static void registerConsumer2() { - broker.registerConsumer(consumer2); - } - - private static void sendAlert(BufferedReader in) throws IOException { - System.out.print("Please enter notification content:"); - String content = in.readLine(); - provider.sendAlertNotification(content); - } - - private static void sendChange(BufferedReader in) throws IOException { - System.out.print("Please enter notification content:"); - String content = in.readLine(); - provider.sendChangeNotification(content); - } - - private static void unregisterConsumer1() { - consumer1.closeSession(); - } - - private static void unregisterConsumer2() { - consumer2.closeSession(); - } - - private static void unregisterProvider() { - provider.closeSession(); - } - - private static void displayHelp() { - System.out.println("Usage: "); - System.out.println(" 0) Display Help"); - System.out.println(" 1) Register Provider"); - System.out.println(" 2) Register Consumer 1 (listening on alert)"); - System.out - .println(" 3) Register Consumer 2 (listening on alert,change)"); - System.out.println(" 4) Send Alert Notification"); - System.out.println(" 5) Send Change Notification"); - System.out.println(" 6) Unregister Consumer 1"); - System.out.println(" 7) Unregister Consumer 2"); - System.out.println(" 8) Unregister Provider"); - System.out.println(" 9) Exit"); - - } - - private static void initializeProvider() { - provider = new DemoProviderImpl(); - } - - private static void initialize() { - System.out.println("Initializing broker"); - broker = new BrokerImpl(); - NotificationModule notifyModule = new NotificationModule(); - broker.addModule(notifyModule); - - consumer1 = new DemoConsumerImpl("Consumer 1"); - consumer2 = new DemoConsumerImpl("Consumer 2"); - consumer2.setChangeAware(true); - } - - private static void registerProvider() { - broker.registerProvider(provider); - } -} diff --git a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/package-info.java b/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/package-info.java deleted file mode 100644 index 09d4bfb8e4..0000000000 --- a/opendaylight/md-sal/sal-dom-demo/src/main/java/org/opendaylight/controller/sal/demo/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.demo; \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java index 68c9340bb1..1cc1f783d6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java @@ -7,9 +7,6 @@ */ package org.opendaylight.controller.sal.restconf.impl; -import com.google.common.base.Objects; - -import java.util.Map; import java.util.concurrent.Future; import javax.ws.rs.core.Response.Status; @@ -22,7 +19,6 @@ 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.rest.impl.RestconfProvider; -import org.opendaylight.controller.sal.restconf.impl.ResponseException; import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.common.QName; @@ -133,23 +129,22 @@ public class BrokerFacade implements DataReader> commitConfigurationDataPost( final InstanceIdentifier path, - final CompositeNode payload ) { + final CompositeNode payload) { this.checkPreconditions(); final DataModificationTransaction transaction = dataService.beginTransaction(); - transaction.putConfigurationData( path, payload ); - Map createdConfigurationData = - transaction.getCreatedConfigurationData(); - CompositeNode createdNode = createdConfigurationData.get( path ); - - if( Objects.equal( payload, createdNode ) ) { - LOG.trace( "Post Configuration via Restconf: {}", path ); - return transaction.commit(); + /* check for available Node in Configuration DataStore by path */ + CompositeNode availableNode = transaction.readConfigurationData( path ); + if (availableNode != null) { + String errMsg = "Post Configuration via Restconf was not executed because data already exists"; + BrokerFacade.LOG.warn((new StringBuilder(errMsg)).append(" : ").append(path).toString()); + // FIXME: return correct ietf-restconf:errors -> follow specification + // (http://tools.ietf.org/html/draft-bierman-netconf-restconf-03#page-48) + throw new ResponseException(Status.CONFLICT, errMsg); } - - LOG.trace( "Post Configuration via Restconf was not executed because data already exists: {}", - path ); - return null; + BrokerFacade.LOG.trace( "Post Configuration via Restconf: {}", path ); + transaction.putConfigurationData( path, payload ); + return transaction.commit(); } public Future> commitConfigurationDataPostBehindMountPoint( @@ -157,19 +152,18 @@ public class BrokerFacade implements DataReader createdConfigurationData = - transaction.getCreatedConfigurationData(); - CompositeNode createdNode = createdConfigurationData.get( path ); - - if( Objects.equal( payload, createdNode ) ) { - LOG.trace( "Post Configuration via Restconf: {}", path ); - return transaction.commit(); + /* check for available Node in Configuration DataStore by path */ + CompositeNode availableNode = transaction.readConfigurationData( path ); + if (availableNode != null) { + String errMsg = "Post Configuration via Restconf was not executed because data already exists"; + BrokerFacade.LOG.warn((new StringBuilder(errMsg)).append(" : ").append(path).toString()); + // FIXME: return correct ietf-restconf:errors -> follow specification + // (http://tools.ietf.org/html/draft-bierman-netconf-restconf-03#page-48) + throw new ResponseException(Status.CONFLICT, errMsg); } - - LOG.trace( "Post Configuration via Restconf was not executed because data already exists: {}", - path ); - return null; + BrokerFacade.LOG.trace( "Post Configuration via Restconf: {}", path ); + transaction.putConfigurationData( path, payload ); + return transaction.commit(); } public Future> commitConfigurationDataDelete( final InstanceIdentifier path ) { diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java index 2e198ec053..0b7b693b0c 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java @@ -7,14 +7,6 @@ */ package org.opendaylight.controller.sal.restconf.impl; -import com.google.common.base.Objects; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - import java.net.URI; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -34,17 +26,6 @@ import javax.ws.rs.core.UriInfo; 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.controller.sal.restconf.impl.BrokerFacade; -import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; -import org.opendaylight.controller.sal.restconf.impl.ControllerContext; -import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper; -import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO; -import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode; -import org.opendaylight.controller.sal.restconf.impl.NodeWrapper; -import org.opendaylight.controller.sal.restconf.impl.ResponseException; -import org.opendaylight.controller.sal.restconf.impl.RestCodec; -import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper; -import org.opendaylight.controller.sal.restconf.impl.StructuredData; import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter; import org.opendaylight.controller.sal.streams.listeners.Notificator; import org.opendaylight.controller.sal.streams.websockets.WebSocketServer; @@ -76,6 +57,14 @@ import org.opendaylight.yangtools.yang.model.util.EmptyType; import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + @SuppressWarnings("all") public class RestconfImpl implements RestconfService { private final static RestconfImpl INSTANCE = new RestconfImpl(); @@ -681,6 +670,7 @@ public class RestconfImpl implements RestconfService { status = future == null ? null : future.get(); } } + catch( ResponseException e) { throw e; } catch( Exception e ) { throw new ResponseException( e, "Error creating data" ); } @@ -730,6 +720,7 @@ public class RestconfImpl implements RestconfService { status = future == null ? null : future.get(); } } + catch( ResponseException e) { throw e; } catch( Exception e ) { throw new ResponseException( e, "Error creating data" ); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/BrokerFacadeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/BrokerFacadeTest.java index 987beb072b..18199de8c6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/BrokerFacadeTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/BrokerFacadeTest.java @@ -8,13 +8,19 @@ package org.opendaylight.controller.sal.restconf.impl.test; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; -import java.util.Collections; import java.util.Map; import java.util.concurrent.Future; +import javax.ws.rs.core.Response.Status; + import org.junit.Before; import org.junit.Test; import org.mockito.InOrder; @@ -212,18 +218,20 @@ public class BrokerFacadeTest { inOrder.verify( mockTransaction ).commit(); } - @Test + @Test(expected=ResponseException.class) public void testCommitConfigurationDataPostAlreadyExists() { when( dataBroker.beginTransaction() ).thenReturn( mockTransaction ); mockTransaction.putConfigurationData( instanceID, dataNode ); - when( mockTransaction.getCreatedConfigurationData() ) - .thenReturn( Collections.emptyMap() ); - - Future> actualFuture = - brokerFacade.commitConfigurationDataPost( instanceID, dataNode ); - - assertNull( "Retruned non-null Future", actualFuture ); - verify( mockTransaction, never() ).commit(); + when ( mockTransaction.readConfigurationData( instanceID ) ) + .thenReturn( dataNode ); + try { + brokerFacade.commitConfigurationDataPost( instanceID, dataNode ); + } catch (ResponseException e) { + assertEquals("Unexpect Exception Status -> " + + "http://tools.ietf.org/html/draft-bierman-netconf-restconf-03#page-48", + (e.getResponse().getStatus()), Status.CONFLICT.getStatusCode()); + throw e; + } } @Test @@ -251,20 +259,22 @@ public class BrokerFacadeTest { inOrder.verify( mockTransaction ).commit(); } - @Test + @Test(expected=ResponseException.class) public void testCommitConfigurationDataPostBehindMountPointAlreadyExists() { when( mockMountInstance.beginTransaction() ).thenReturn( mockTransaction ); mockTransaction.putConfigurationData( instanceID, dataNode ); - when( mockTransaction.getCreatedConfigurationData() ) - .thenReturn( Collections.emptyMap() ); - - Future> actualFuture = - brokerFacade.commitConfigurationDataPostBehindMountPoint( mockMountInstance, - instanceID, dataNode ); - - assertNull( "Retruned non-null Future", actualFuture ); - verify( mockTransaction, never() ).commit(); + when ( mockTransaction.readConfigurationData( instanceID ) ) + .thenReturn( dataNode ); + try { + brokerFacade.commitConfigurationDataPostBehindMountPoint( mockMountInstance, + instanceID, dataNode ); + } catch (ResponseException e) { + assertEquals("Unexpect Exception Status -> " + + "http://tools.ietf.org/html/draft-bierman-netconf-restconf-03#page-48", + e.getResponse().getStatus(), Status.CONFLICT.getStatusCode()); + throw e; + } } @Test diff --git a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/inventory/InventoryService.java b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/inventory/InventoryService.java index a12f394e66..1ec65e8f81 100644 --- a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/inventory/InventoryService.java +++ b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/inventory/InventoryService.java @@ -21,7 +21,11 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * InventoryService provides functions related to Nodes & NodeConnectors. diff --git a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/packet/PacketHandler.java b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/packet/PacketHandler.java index ecf116b171..b4ea94242c 100644 --- a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/packet/PacketHandler.java +++ b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/packet/PacketHandler.java @@ -19,7 +19,8 @@ import org.opendaylight.controller.sal.packet.RawPacket; import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.NetUtils; 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.inventory.rev130819.*; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.address.tracker.rev140402.l2.addresses.L2Address; diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml b/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml deleted file mode 100644 index 4a0a02561f..0000000000 --- a/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml +++ /dev/null @@ -1,683 +0,0 @@ - - 4.0.0 - - sal-test-parent - org.opendaylight.controller.tests - 1.0-SNAPSHOT - - sal-rest-connector-it - - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL - - - - - - org.ops4j.pax.exam - maven-paxexam-plugin - 1.2.4 - - - generate-config - - generate-depends-file - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - org.ops4j.pax.exam - - - maven-paxexam-plugin - - - [1.2.4,) - - - - generate-depends-file - - - - - - - - - - - - - - - - - - org.opendaylight.controller - logging.bridge - 0.4.1-SNAPSHOT - - - org.opendaylight.yangtools.thirdparty - xtend-lib-osgi - 2.4.3 - - - org.opendaylight.controller - bundlescanner.implementation - 0.4.1-SNAPSHOT - - - org.opendaylight.controller - sal-broker-impl - 1.0-SNAPSHOT - test - - - org.opendaylight.controller - sal-rest-connector - 1.0-SNAPSHOT - test - - - org.opendaylight.controller - sal-netconf-connector - 1.0-SNAPSHOT - test - - - org.opendaylight.controller - sal-binding-it - 1.0-SNAPSHOT - test - - - org.ops4j.pax.exam - pax-exam-container-native - ${exam.version} - test - - - org.ops4j.pax.exam - pax-exam-junit4 - ${exam.version} - test - - - io.netty - netty-all - ${netty.version} - test - - - org.ops4j.pax.exam - pax-exam-link-mvn - ${exam.version} - test - - - equinoxSDK381 - org.eclipse.osgi - 3.8.1.v20120830-144521 - test - - - org.slf4j - log4j-over-slf4j - 1.7.2 - - - ch.qos.logback - logback-core - 1.0.9 - - - ch.qos.logback - logback-classic - 1.0.9 - - - org.opendaylight.controller - sal-binding-api - 1.0-SNAPSHOT - - - org.opendaylight.controller - sal-common-util - 1.0-SNAPSHOT - - - org.opendaylight.controller - sal-core-api - 1.0-SNAPSHOT - - - org.opendaylight.controller.model - model-flow-service - 1.0-SNAPSHOT - provided - - - org.opendaylight.controller - config-manager - 0.2.2-SNAPSHOT - - - org.opendaylight.controller.model - model-flow-management - 1.0-SNAPSHOT - provided - - - org.opendaylight.yangtools.thirdparty - antlr4-runtime-osgi-nohead - 4.0 - - - org.opendaylight.yangtools - yang-binding - - - org.opendaylight.yangtools - yang-common - - - org.opendaylight.yangtools - yang-data-api - - - org.opendaylight.controller - commons.northbound - 0.4.1-SNAPSHOT - runtime - - - org.opendaylight.controller - sal-common-util - 1.0-SNAPSHOT - - - org.slf4j - jcl-over-slf4j - 1.7.2 - - - org.slf4j - slf4j-api - - - - org.slf4j - log4j-over-slf4j - 1.7.2 - - - ch.qos.logback - logback-core - 1.0.9 - - - ch.qos.logback - logback-classic - 1.0.9 - - - commons-codec - commons-codec - 1.7 - - - equinoxSDK381 - javax.servlet - 3.0.0.v201112011016 - - - equinoxSDK381 - javax.servlet.jsp - 2.2.0.v201112011158 - - - equinoxSDK381 - org.eclipse.equinox.ds - 1.4.0.v20120522-1841 - - - equinoxSDK381 - org.eclipse.equinox.util - 1.0.400.v20120522-2049 - - - equinoxSDK381 - org.eclipse.osgi.services - 3.3.100.v20120522-1822 - - - equinoxSDK381 - org.eclipse.osgi - 3.8.1.v20120830-144521 - - - equinoxSDK381 - org.apache.felix.gogo.command - 0.8.0.v201108120515 - - - equinoxSDK381 - org.apache.felix.gogo.runtime - 0.8.0.v201108120515 - - - equinoxSDK381 - org.apache.felix.gogo.shell - 0.8.0.v201110170705 - - - equinoxSDK381 - org.eclipse.equinox.cm - 1.0.400.v20120522-1841 - - - equinoxSDK381 - org.eclipse.equinox.console - 1.0.0.v20120522-1841 - - - equinoxSDK381 - org.eclipse.equinox.launcher - 1.3.0.v20120522-1813 - - - - geminiweb - org.eclipse.gemini.web.core - ${geminiweb.version} - - - geminiweb - org.eclipse.gemini.web.extender - ${geminiweb.version} - - - geminiweb - org.eclipse.gemini.web.tomcat - ${geminiweb.version} - - - geminiweb - org.eclipse.virgo.kernel.equinox.extensions - ${virgo.version} - - - geminiweb - org.eclipse.virgo.util.common - ${virgo.version} - - - geminiweb - org.eclipse.virgo.util.io - ${virgo.version} - - - geminiweb - org.eclipse.virgo.util.math - ${virgo.version} - - - geminiweb - org.eclipse.virgo.util.osgi - ${virgo.version} - - - geminiweb - org.eclipse.virgo.util.osgi.manifest - ${virgo.version} - - - geminiweb - org.eclipse.virgo.util.parser.manifest - ${virgo.version} - - - org.apache.felix - org.apache.felix.dependencymanager - 3.1.0 - - - org.apache.felix - org.apache.felix.dependencymanager.shell - 3.0.1 - - - org.jboss.spec.javax.transaction - jboss-transaction-api_1.1_spec - 1.0.1.Final - - - org.apache.felix - org.apache.felix.fileinstall - 3.1.6 - - - org.apache.commons - commons-lang3 - 3.1 - - - virgomirror - org.eclipse.jdt.core.compiler.batch - 3.8.0.I20120518-2145 - - - eclipselink - javax.persistence - 2.0.4.v201112161009 - - - orbit - javax.activation - 1.1.0.v201211130549 - - - orbit - javax.annotation - 1.1.0.v201209060031 - - - orbit - javax.ejb - 3.1.1.v201204261316 - - - orbit - javax.el - 2.2.0.v201108011116 - - - orbit - javax.mail.glassfish - 1.4.1.v201108011116 - - - orbit - javax.xml.rpc - 1.1.0.v201005080400 - - - orbit - org.apache.catalina - 7.0.32.v201211201336 - - - orbit - org.apache.catalina.ha - 7.0.32.v201211201952 - - - orbit - org.apache.catalina.tribes - 7.0.32.v201211201952 - - - orbit - org.apache.coyote - 7.0.32.v201211201952 - - - orbit - org.apache.el - 7.0.32.v201211081135 - - - orbit - org.apache.jasper - 7.0.32.v201211201952 - - - orbit - org.apache.juli.extras - 7.0.32.v201211081135 - - - orbit - org.apache.tomcat.api - 7.0.32.v201211081135 - - - orbit - org.apache.tomcat.util - 7.0.32.v201211201952 - - - orbit - javax.servlet.jsp.jstl - 1.2.0.v201105211821 - - - orbit - javax.servlet.jsp.jstl.impl - 1.2.0.v201210211230 - - - - org.ops4j.pax.exam - pax-exam-container-native - ${exam.version} - test - - - org.ops4j.pax.exam - pax-exam-junit4 - ${exam.version} - test - - - org.ops4j.pax.exam - pax-exam-link-mvn - ${exam.version} - test - - - org.ops4j.pax.url - pax-url-aether - ${url.version} - test - - - org.ow2.asm - asm-all - 4.1 - - - org.springframework - org.springframework.asm - ${spring.version} - - - org.springframework - org.springframework.aop - ${spring.version} - - - org.springframework - org.springframework.context - ${spring.version} - - - org.springframework - org.springframework.context.support - ${spring.version} - - - org.springframework - org.springframework.core - ${spring.version} - - - org.springframework - org.springframework.beans - ${spring.version} - - - org.springframework - org.springframework.expression - ${spring.version} - - - org.springframework - org.springframework.web - ${spring.version} - - - org.aopalliance - com.springsource.org.aopalliance - 1.0.0 - - - org.springframework - org.springframework.web.servlet - ${spring.version} - - - - org.springframework.security - spring-security-config - ${spring-security.version} - - - org.springframework.security - spring-security-core - ${spring-security.version} - - - org.springframework.security - spring-security-web - ${spring-security.version} - - - org.springframework.security - spring-security-taglibs - ${spring-security.version} - - - org.springframework - org.springframework.transaction - ${spring-security.version} - - - - org.ow2.chameleon.management - chameleon-mbeans - 1.0.0 - - - - com.sun.jersey - jersey-core - ${jersey.version} - - - - com.sun.jersey - jersey-server - ${jersey.version} - - - com.sun.jersey - jersey-client - ${jersey.version} - - - - eclipselink - javax.resource - 1.5.0.v200906010428 - - - org.opendaylight.controller.thirdparty - com.sun.jersey.jersey-servlet - 1.17 - - - org.opendaylight.controller.thirdparty - org.apache.catalina.filters.CorsFilter - 7.0.42 - - - - - org.opendaylight.controller - config-api - - - org.opendaylight.controller - config-manager - - - org.opendaylight.controller - config-util - - - org.opendaylight.controller - yang-jmx-generator - - - org.opendaylight.controller - logback-config - - - org.opendaylight.controller - config-persister-api - - - org.opendaylight.controller - config-persister-file-xml-adapter - - - org.opendaylight.controller - netconf-api - - - org.opendaylight.controller - netconf-impl - - - org.opendaylight.controller - netconf-util - - - org.opendaylight.controller - netconf-client - - - org.opendaylight.controller - netconf-mapping-api - - - org.opendaylight.controller - config-netconf-connector - - - org.opendaylight.controller - config-persister-impl - - - diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java b/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java deleted file mode 100644 index 4a43e0cf82..0000000000 --- a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.test.restconf.it; - -import static junit.framework.Assert.assertEquals; -import static org.junit.Assert.*; -import static org.ops4j.pax.exam.CoreOptions.junitBundles; -import static org.ops4j.pax.exam.CoreOptions.mavenBundle; -import static org.ops4j.pax.exam.CoreOptions.options; -import static org.ops4j.pax.exam.CoreOptions.systemPackages; -import static org.ops4j.pax.exam.CoreOptions.systemProperty; -import static org.ops4j.pax.exam.CoreOptions.maven; - -import java.net.InetSocketAddress; -import java.net.URI; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; - -import javax.inject.Inject; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; -import org.opendaylight.controller.sal.connect.netconf.InventoryUtils; -import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils; -import org.opendaylight.controller.sal.core.api.data.DataBrokerService; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; -import org.opendaylight.controller.test.sal.binding.it.TestHelper; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.CoreOptions; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.util.PathUtils; -import org.osgi.framework.BundleContext; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; - -import static org.opendaylight.controller.test.sal.binding.it.TestHelper.*; - -@RunWith(PaxExam.class) -public class ServiceProviderController { - - public static final String ODL = "org.opendaylight.controller"; - public static final String YANG = "org.opendaylight.yangtools"; - public static final String SAMPLE = "org.opendaylight.controller.samples"; - - private static QName CONFIG_MODULES = new QName( - URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules"); - private static QName CONFIG_SERVICES = new QName( - URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules"); - @Inject - BundleContext context; - - @Inject - MountProvisionService mountService; - - @Inject - DataBrokerService dataBroker; - - @Test - public void properInitialized() throws Exception { - - Map arg = Collections.singletonMap(InventoryUtils.INVENTORY_ID, "foo"); - - InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH) - .nodeWithKey(InventoryUtils.INVENTORY_NODE, InventoryUtils.INVENTORY_ID, "foo").toInstance(); - - - InstanceIdentifier mountPointPath = path; - - /** We retrive a mountpoint **/ - MountProvisionInstance mountPoint = mountService.getMountPoint(mountPointPath); - CompositeNode data = mountPoint.readOperationalData(InstanceIdentifier.builder().node(CONFIG_MODULES) - .toInstance()); - assertNotNull(data); - assertEquals(CONFIG_MODULES, data.getNodeType()); - - CompositeNode data2 = mountPoint.readOperationalData(InstanceIdentifier.builder().toInstance()); - assertNotNull(data2); - - InstanceIdentifier fullPath = InstanceIdentifier.builder(mountPointPath).node(CONFIG_MODULES).toInstance(); - - CompositeNode data3 = dataBroker.readOperationalData(fullPath); - assertNotNull(data3); - assertEquals(CONFIG_MODULES, data.getNodeType()); - - //Thread.sleep(30 * 60 * 1000); // Waiting for services to get wired. - //assertTrue(true); - // assertTrue(consumer.createToast(WhiteBread.class, 5)); - } - - @Configuration - public Option[] config() { - return options( - mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(), // - mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), // - mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), // - mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), // - - mdSalCoreBundles(), - baseModelBundles(), - flowCapableModelBundles(), - configMinumumBundles(), - - // mavenBundle(ODL, - // "sal-binding-broker-impl").versionAsInProject().update(), // - mavenBundle(ODL, "sal-common").versionAsInProject(), // - mavenBundle(ODL, "sal-common-api").versionAsInProject(),// - mavenBundle(ODL, "sal-common-impl").versionAsInProject(), // - mavenBundle(ODL, "sal-common-util").versionAsInProject(), // - - mavenBundle(ODL, "sal-core-api").versionAsInProject().update(), // - mavenBundle(ODL, "sal-broker-impl").versionAsInProject(), // - mavenBundle(ODL, "sal-core-spi").versionAsInProject().update(), // - - mavenBundle(ODL, "sal-connector-api").versionAsInProject(), // - // mavenBundle(SAMPLE, - // "zeromq-test-provider").versionAsInProject(), // - mavenBundle(ODL, "sal-rest-connector").versionAsInProject(), // - mavenBundle(ODL, "sal-netconf-connector").versionAsInProject(), // - - mavenBundle(YANG, "concepts").versionAsInProject(), - mavenBundle(YANG, "yang-binding").versionAsInProject(), // - mavenBundle(YANG, "yang-common").versionAsInProject(), // - mavenBundle(YANG, "yang-data-api").versionAsInProject(), // - mavenBundle(YANG, "yang-data-impl").versionAsInProject(), // - mavenBundle(YANG, "yang-model-api").versionAsInProject(), // - mavenBundle(YANG, "yang-model-util").versionAsInProject(), // - mavenBundle(YANG, "yang-parser-api").versionAsInProject(), - mavenBundle(YANG, "yang-parser-impl").versionAsInProject(), - - mavenBundle(YANG + ".thirdparty", "xtend-lib-osgi").versionAsInProject(), // - mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), // - mavenBundle("com.google.guava", "guava").versionAsInProject(), // - - // systemProperty("logback.configurationFile").value( - // "file:" + PathUtils.getBaseDir() + - // "/src/test/resources/logback.xml"), - // To start OSGi console for inspection remotely - systemProperty("osgi.console").value("2401"), - systemProperty("org.eclipse.gemini.web.tomcat.config.path").value( - PathUtils.getBaseDir() + "/src/test/resources/tomcat-server.xml"), - - // setting default level. Jersey bundles will need to be started - // earlier. - systemProperty("osgi.bundles.defaultStartLevel").value("4"), - - systemProperty("netconf.tcp.address").value("127.0.0.1"), - systemProperty("netconf.tcp.port").value("8383"), - - systemProperty("netconf.tcp.client.address").value("127.0.0.1"), - systemProperty("netconf.tcp.client.port").value("8383"), - - // Set the systemPackages (used by clustering) - systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"), - - mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.xerces", "2.11.0_1"), - mavenBundle("org.eclipse.birt.runtime.3_7_1", "org.apache.xml.resolver", "1.2.0"), - - mavenBundle("org.slf4j", "jcl-over-slf4j").versionAsInProject(), - mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(), - mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), - mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), - mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), - mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(), - mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "clustering.services").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "containermanager").versionAsInProject(), - // List all the opendaylight modules - mavenBundle("org.opendaylight.controller", "configuration").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "sal").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "switchmanager").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "usermanager").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "logging.bridge").versionAsInProject(), - // mavenBundle("org.opendaylight.controller", - // "clustering.test").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "bundlescanner").versionAsInProject(), - mavenBundle("org.opendaylight.controller", "bundlescanner.implementation").versionAsInProject(), - - // Northbound bundles - mavenBundle("org.opendaylight.controller", "commons.northbound").versionAsInProject(), - - mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(), - mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(), - mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(), - mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider").versionAsInProject(), - mavenBundle("com.fasterxml.jackson.module", "jackson-module-jaxb-annotations").versionAsInProject(), - - mavenBundle("org.codehaus.jettison", "jettison").versionAsInProject(), - - mavenBundle("commons-io", "commons-io").versionAsInProject(), - - // mavenBundle("commons-fileupload", - // "commons-fileupload").versionAsInProject(), - - mavenBundle("io.netty", "netty-handler").versionAsInProject(), - mavenBundle("io.netty", "netty-codec").versionAsInProject(), - mavenBundle("io.netty", "netty-buffer").versionAsInProject(), - mavenBundle("io.netty", "netty-transport").versionAsInProject(), - mavenBundle("io.netty", "netty-common").versionAsInProject(), - - mavenBundle(ODL, "config-api").versionAsInProject(), - mavenBundle(ODL, "config-manager").versionAsInProject(), - mavenBundle(ODL, "config-util").versionAsInProject(), - mavenBundle(ODL, "yang-jmx-generator").versionAsInProject(), - mavenBundle(ODL, "logback-config").versionAsInProject(), - mavenBundle(ODL, "config-persister-api").versionAsInProject(), - // mavenBundle(ODL,"config-persister-file-xml-adapter").versionAsInProject(), - mavenBundle(ODL, "protocol-framework").versionAsInProject(), - mavenBundle(ODL, "netconf-api").versionAsInProject(), - mavenBundle(ODL, "netconf-impl").versionAsInProject(), - mavenBundle(ODL, "netconf-client").versionAsInProject(), - mavenBundle(ODL, "netconf-util").versionAsInProject(), - mavenBundle(ODL + ".thirdparty", "ganymed").versionAsInProject(), - mavenBundle(ODL, "netconf-mapping-api").versionAsInProject(), - mavenBundle(ODL, "config-netconf-connector").versionAsInProject(), - mavenBundle(ODL, "config-persister-impl").versionAsInProject(), - - mavenBundle(YANG, "binding-generator-spi").versionAsInProject(), // - mavenBundle(YANG, "binding-model-api").versionAsInProject(), // - mavenBundle(YANG, "binding-generator-util").versionAsInProject(), - mavenBundle(YANG, "yang-parser-impl").versionAsInProject(), - mavenBundle(YANG, "binding-type-provider").versionAsInProject(), - - mavenBundle("equinoxSDK381", "javax.servlet").versionAsInProject(), - mavenBundle("equinoxSDK381", "javax.servlet.jsp").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds").versionAsInProject(), - mavenBundle("orbit", "javax.xml.rpc").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.equinox.util").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.osgi.services").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.equinox.cm").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.equinox.console").versionAsInProject(), - mavenBundle("equinoxSDK381", "org.eclipse.equinox.launcher").versionAsInProject(), - - mavenBundle("geminiweb", "org.eclipse.gemini.web.core").versionAsInProject(), - mavenBundle("geminiweb", "org.eclipse.gemini.web.extender").versionAsInProject(), - mavenBundle("geminiweb", "org.eclipse.gemini.web.tomcat").versionAsInProject(), - mavenBundle("geminiweb", "org.eclipse.virgo.kernel.equinox.extensions").versionAsInProject().noStart(), - mavenBundle("geminiweb", "org.eclipse.virgo.util.common").versionAsInProject(), - mavenBundle("geminiweb", "org.eclipse.virgo.util.io").versionAsInProject(), - mavenBundle("geminiweb", "org.eclipse.virgo.util.math").versionAsInProject(), - mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi").versionAsInProject(), - mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi.manifest").versionAsInProject(), - mavenBundle("geminiweb", "org.eclipse.virgo.util.parser.manifest").versionAsInProject(), - - mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager").versionAsInProject(), - mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager.shell").versionAsInProject(), - - mavenBundle("com.google.code.gson", "gson").versionAsInProject(), - mavenBundle("org.jboss.spec.javax.transaction", "jboss-transaction-api_1.1_spec").versionAsInProject(), - mavenBundle("org.apache.felix", "org.apache.felix.fileinstall").versionAsInProject(), - mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(), - mavenBundle("commons-codec", "commons-codec").versionAsInProject(), - mavenBundle("virgomirror", "org.eclipse.jdt.core.compiler.batch").versionAsInProject(), - mavenBundle("eclipselink", "javax.persistence").versionAsInProject(), - mavenBundle("eclipselink", "javax.resource").versionAsInProject(), - - mavenBundle("orbit", "javax.activation").versionAsInProject(), - mavenBundle("orbit", "javax.annotation").versionAsInProject(), - mavenBundle("orbit", "javax.ejb").versionAsInProject(), - mavenBundle("orbit", "javax.el").versionAsInProject(), - mavenBundle("orbit", "javax.mail.glassfish").versionAsInProject(), - mavenBundle("orbit", "javax.xml.rpc").versionAsInProject(), - mavenBundle("orbit", "org.apache.catalina").versionAsInProject(), - // these are bundle fragments that can't be started on its own - mavenBundle("orbit", "org.apache.catalina.ha").versionAsInProject().noStart(), - mavenBundle("orbit", "org.apache.catalina.tribes").versionAsInProject().noStart(), - mavenBundle("orbit", "org.apache.coyote").versionAsInProject().noStart(), - mavenBundle("orbit", "org.apache.jasper").versionAsInProject().noStart(), - - mavenBundle("orbit", "org.apache.el").versionAsInProject(), - mavenBundle("orbit", "org.apache.juli.extras").versionAsInProject(), - mavenBundle("orbit", "org.apache.tomcat.api").versionAsInProject(), - mavenBundle("orbit", "org.apache.tomcat.util").versionAsInProject().noStart(), - mavenBundle("orbit", "javax.servlet.jsp.jstl").versionAsInProject(), - mavenBundle("orbit", "javax.servlet.jsp.jstl.impl").versionAsInProject(), - - mavenBundle("org.ops4j.pax.exam", "pax-exam-container-native").versionAsInProject(), - mavenBundle("org.ops4j.pax.exam", "pax-exam-junit4").versionAsInProject(), - mavenBundle("org.ops4j.pax.exam", "pax-exam-link-mvn").versionAsInProject(), - mavenBundle("org.ops4j.pax.url", "pax-url-aether").versionAsInProject(), - - mavenBundle("org.ow2.asm", "asm-all").versionAsInProject(), - - mavenBundle("org.springframework", "org.springframework.asm").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.aop").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.context").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.context.support").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.core").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.beans").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.expression").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.web").versionAsInProject(), - - mavenBundle("org.aopalliance", "com.springsource.org.aopalliance").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.web.servlet").versionAsInProject(), - mavenBundle("org.springframework.security", "spring-security-config").versionAsInProject(), - mavenBundle("org.springframework.security", "spring-security-core").versionAsInProject(), - mavenBundle("org.springframework.security", "spring-security-web").versionAsInProject(), - mavenBundle("org.springframework.security", "spring-security-taglibs").versionAsInProject(), - mavenBundle("org.springframework", "org.springframework.transaction").versionAsInProject(), - - mavenBundle("org.ow2.chameleon.management", "chameleon-mbeans").versionAsInProject(), - mavenBundle("org.opendaylight.controller.thirdparty", "com.sun.jersey.jersey-servlet") - .versionAsInProject().startLevel(2), - mavenBundle("org.opendaylight.controller.thirdparty", "org.apache.catalina.filters.CorsFilter") - .versionAsInProject().noStart(), - - // Jersey needs to be started before the northbound application - // bundles, using a lower start level - mavenBundle("com.sun.jersey", "jersey-client").versionAsInProject(), - mavenBundle("com.sun.jersey", "jersey-server").versionAsInProject().startLevel(2), - mavenBundle("com.sun.jersey", "jersey-core").versionAsInProject().startLevel(2), - junitBundles()); - } - -} diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/exam.properties b/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/exam.properties deleted file mode 100644 index d5f9ae1fcd..0000000000 --- a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/exam.properties +++ /dev/null @@ -1,4 +0,0 @@ -#pax.exam.system = default -pax.exam.logging = none -pax.exam.service.timeout = 5000 - diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/logback.xml b/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/logback.xml deleted file mode 100644 index 2d63ce5744..0000000000 --- a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/tomcat-server.xml b/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/tomcat-server.xml deleted file mode 100644 index d6ef6ed926..0000000000 --- a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/resources/tomcat-server.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/opendaylight/sal/connection/implementation/src/main/java/org/opendaylight/controller/sal/connection/implementation/internal/ConnectionService.java b/opendaylight/sal/connection/implementation/src/main/java/org/opendaylight/controller/sal/connection/implementation/internal/ConnectionService.java index a995bf8609..b2cb414303 100644 --- a/opendaylight/sal/connection/implementation/src/main/java/org/opendaylight/controller/sal/connection/implementation/internal/ConnectionService.java +++ b/opendaylight/sal/connection/implementation/src/main/java/org/opendaylight/controller/sal/connection/implementation/internal/ConnectionService.java @@ -150,9 +150,9 @@ public class ConnectionService implements IPluginOutConnectionService, IConnecti */ @Override public void notifyNodeDisconnectFromMaster(Node node) { - for (String pluginType : this.pluginService.keySet()) { - IPluginInConnectionService s = pluginService.get(pluginType); - s.notifyNodeDisconnectFromMaster(node); + IPluginInConnectionService s = pluginService.get(node.getType()); + if (s != null) { + s.notifyNodeDisconnectFromMaster(node); } } -} \ No newline at end of file +} diff --git a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java index e95ab8095d..8372f88e7d 100644 --- a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java +++ b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java @@ -54,6 +54,7 @@ import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates; import org.opendaylight.controller.sal.reader.NodeDescription; import org.opendaylight.controller.sal.utils.GlobalConstants; import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.ServiceHelper; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.controller.statisticsmanager.IStatisticsManager; @@ -1017,6 +1018,18 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa ForwardingMode mode = (ForwardingMode) nodeProperties.get(ForwardingMode.name); forwardingModeChanged = mode.isProactive(); } + } else if ((conf == null) && !(GlobalConstants.DEFAULT.toString().equals(containerName))) { + ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, GlobalConstants.DEFAULT.toString(), this); + if (defaultSwitchManager != null) { + Property defaultContainerSwitchDesc = (Description) defaultSwitchManager.getNodeProp(node, Description.propertyName); + if (defaultContainerSwitchDesc != null) { + Map descPropMap = new HashMap(); + descPropMap.put(Description.propertyName, defaultContainerSwitchDesc); + conf = new SwitchConfig(nodeId, descPropMap); + updateNodeConfig(conf); + propMap.put(Description.propertyName, defaultContainerSwitchDesc); + } + } } }