Merge "BUG 2799: Migration of Message Bus from deprecated Helium MD-SAL APIs to Lithi...
authorTony Tkacik <ttkacik@cisco.com>
Thu, 19 Mar 2015 15:54:25 +0000 (15:54 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 19 Mar 2015 15:54:25 +0000 (15:54 +0000)
43 files changed:
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/BindingContextProvider.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java [deleted file]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/RefreshingSCPModuleInfoRegistryTest.java
opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java
opendaylight/md-sal/md-sal-config/src/main/resources/initial/01-md-sal.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingAsyncDataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationAdapterModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationPublishAdapterModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMAdapterLoader.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMDataBrokerAdapter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBindingDataBroker.java with 77% similarity]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMNotificationPublishServiceAdapter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedNotificationPublishService.java with 92% similarity]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMNotificationServiceAdapter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedNotificationService.java with 92% similarity]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMReadTransactionAdapter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataReadTransactionImpl.java with 86% similarity]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMReadWriteTransactionAdapter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataReadWriteTransactionImpl.java with 82% similarity]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcProviderServiceAdapter.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcServiceAdapter.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMTransactionChainAdapter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingTranslatedTransactionChain.java with 91% similarity]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMWriteTransactionAdapter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataWriteTransactionImpl.java with 95% similarity]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java
opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java
opendaylight/md-sal/sal-binding-config/pom.xml
opendaylight/md-sal/sal-binding-config/src/main/yang/opendaylight-md-sal-binding.yang
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeState.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerNode.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerTree.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerWalker.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/NormalizedNodeJsonBodyWriter.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/NormalizedNodeXmlBodyWriter.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/GetTest.java
opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtilTest.java

index 91c67b8b02317681953287fd8a764b6c0694a4f0..39ea73be55a63788c17c0edcd5a9215e8550a1be 100644 (file)
@@ -44,11 +44,11 @@ import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegist
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager;
 import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager.OsgiRegistration;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
 import org.opendaylight.controller.config.manager.impl.util.LookupBeansUtil;
 import org.opendaylight.controller.config.manager.impl.util.ModuleQNameUtil;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,7 +63,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
     private final ModuleFactoriesResolver resolver;
     private final MBeanServer configMBeanServer;
-    private final CodecRegistry codecRegistry;
+    private final BindingContextProvider bindingContextProvider;
 
     @GuardedBy("this")
     private long version = 0;
@@ -111,20 +111,20 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
-                              MBeanServer configMBeanServer, CodecRegistry codecRegistry) {
+                              MBeanServer configMBeanServer, BindingContextProvider bindingContextProvider) {
         this(resolver, configMBeanServer,
-                new BaseJMXRegistrator(configMBeanServer), codecRegistry);
+                new BaseJMXRegistrator(configMBeanServer), bindingContextProvider);
     }
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
                               MBeanServer configMBeanServer,
-                              BaseJMXRegistrator baseJMXRegistrator, CodecRegistry codecRegistry) {
+                              BaseJMXRegistrator baseJMXRegistrator, BindingContextProvider bindingContextProvider) {
         this.resolver = resolver;
         this.beanToOsgiServiceManager = new BeanToOsgiServiceManager();
         this.configMBeanServer = configMBeanServer;
         this.baseJMXRegistrator = baseJMXRegistrator;
-        this.codecRegistry = codecRegistry;
+        this.bindingContextProvider = bindingContextProvider;
         this.registryMBeanServer = MBeanServerFactory
                 .createMBeanServer("ConfigRegistry" + configMBeanServer.getDefaultDomain());
         this.transactionsMBeanServer = MBeanServerFactory
@@ -179,7 +179,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                 readableSRRegistry, txLookupRegistry, allCurrentFactories);
 
         ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
-                txLookupRegistry, version, codecRegistry,
+                txLookupRegistry, version, bindingContextProvider,
                 versionCounter, allCurrentFactories, transactionsMBeanServer,
                 configMBeanServer, blankTransaction, writableRegistry);
         try {
index 186a7218bae75a8cf7c724b817f95b8f9d41be90..eb63af89d22f66068eb943bfc8ba834304a9c7a6 100644 (file)
@@ -38,10 +38,10 @@ import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtom
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HierarchicalConfigMBeanFactoriesHolder;
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -83,7 +83,7 @@ class ConfigTransactionControllerImpl implements
     private final SearchableServiceReferenceWritableRegistry writableSRRegistry;
 
     public ConfigTransactionControllerImpl(ConfigTransactionLookupRegistry txLookupRegistry,
-                                           long parentVersion, CodecRegistry codecRegistry, long currentVersion,
+                                           long parentVersion, BindingContextProvider bindingContextProvider, long currentVersion,
                                            Map<String, Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
                                            MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer,
                                            boolean blankTransaction, SearchableServiceReferenceWritableRegistry  writableSRRegistry) {
@@ -96,7 +96,7 @@ class ConfigTransactionControllerImpl implements
         this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
         this.transactionStatus = new TransactionStatus();
         this.dependencyResolverManager = new DependencyResolverManager(txLookupRegistry.getTransactionIdentifier(),
-                transactionStatus, writableSRRegistry, codecRegistry, transactionsMBeanServer);
+                transactionStatus, writableSRRegistry, bindingContextProvider, transactionsMBeanServer);
         this.transactionsMBeanServer = transactionsMBeanServer;
         this.configMBeanServer = configMBeanServer;
         this.blankTransaction = blankTransaction;
index 024518ca98f43a544ec2f3f87673033914de3113..8948c56e9b1dfd1bcaa1b07c1d093235790193c4 100644 (file)
@@ -30,12 +30,11 @@ import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,15 +53,15 @@ final class DependencyResolverImpl implements DependencyResolver,
     @GuardedBy("this")
     private final Set<ModuleIdentifier> dependencies = new HashSet<>();
     private final ServiceReferenceReadableRegistry readableRegistry;
-    private final CodecRegistry codecRegistry;
+    private final BindingContextProvider bindingContextProvider;
     private final String transactionName;
     private final MBeanServer mBeanServer;
 
     DependencyResolverImpl(ModuleIdentifier currentModule,
                            TransactionStatus transactionStatus, ModulesHolder modulesHolder,
-                           ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry,
+                           ServiceReferenceReadableRegistry readableRegistry, BindingContextProvider bindingContextProvider,
                            String transactionName, MBeanServer mBeanServer) {
-        this.codecRegistry = codecRegistry;
+        this.bindingContextProvider = bindingContextProvider;
         this.name = currentModule;
         this.transactionStatus = transactionStatus;
         this.modulesHolder = modulesHolder;
@@ -211,11 +210,10 @@ final class DependencyResolverImpl implements DependencyResolver,
     @Override
     public <T extends BaseIdentity> Class<? extends T> resolveIdentity(IdentityAttributeRef identityRef, Class<T> expectedBaseClass) {
         final QName qName = QName.create(identityRef.getqNameOfIdentity());
-        IdentityCodec<?> identityCodec = codecRegistry.getIdentityCodec();
-        Class<? extends BaseIdentity> deserialized = identityCodec.deserialize(qName);
+        Class<?> deserialized  = bindingContextProvider.getBindingContext().getIdentityClass(qName);
         if (deserialized == null) {
             throw new IllegalStateException("Unable to retrieve identity class for " + qName + ", null response from "
-                    + codecRegistry);
+                    + bindingContextProvider.getBindingContext());
         }
         if (expectedBaseClass.isAssignableFrom(deserialized)) {
             return (Class<T>) deserialized;
index 0014a5924d3268bd72182f756868b448389bcd84..3ef6e5d8421ac39834394b34afbf56d58b7eeca8 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
 import static com.google.common.base.Preconditions.checkState;
+
 import com.google.common.base.Preconditions;
 import com.google.common.reflect.AbstractInvocationHandler;
 import com.google.common.reflect.Reflection;
@@ -33,9 +34,9 @@ import org.opendaylight.controller.config.manager.impl.ModuleInternalInfo;
 import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -50,19 +51,19 @@ public class DependencyResolverManager implements DependencyResolverFactory, Aut
     private final ModulesHolder modulesHolder;
     private final TransactionStatus transactionStatus;
     private final ServiceReferenceReadableRegistry readableRegistry;
-    private final CodecRegistry codecRegistry;
+    private final BindingContextProvider bindingContextProvider;
     private final DeadlockMonitor deadlockMonitor;
     private final MBeanServer mBeanServer;
 
     public DependencyResolverManager(final TransactionIdentifier transactionIdentifier,
                                      final TransactionStatus transactionStatus,
-                                     final ServiceReferenceReadableRegistry readableRegistry, final CodecRegistry codecRegistry,
+                                     final ServiceReferenceReadableRegistry readableRegistry, final BindingContextProvider bindingContextProvider,
                                      final MBeanServer mBeanServer) {
         this.transactionIdentifier = transactionIdentifier;
         this.modulesHolder = new ModulesHolder(transactionIdentifier);
         this.transactionStatus = transactionStatus;
         this.readableRegistry = readableRegistry;
-        this.codecRegistry = codecRegistry;
+        this.bindingContextProvider = bindingContextProvider;
         this.deadlockMonitor = new DeadlockMonitor(transactionIdentifier);
         this.mBeanServer = mBeanServer;
     }
@@ -77,7 +78,7 @@ public class DependencyResolverManager implements DependencyResolverFactory, Aut
         if (dependencyResolver == null) {
             transactionStatus.checkNotCommitted();
             dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry,
-                    codecRegistry, transactionIdentifier.getName(), mBeanServer);
+                    bindingContextProvider, transactionIdentifier.getName(), mBeanServer);
             moduleIdentifiersToDependencyResolverMap.put(name, dependencyResolver);
         }
         return dependencyResolver;
index 828fcb01e11bb00a9fde10f064b93cc2cac34863..9941ede445f8d2a707ae3baa5b502b6680a69dcd 100644 (file)
@@ -17,7 +17,7 @@ import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanServer;
 import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
 import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegistrator;
-import org.opendaylight.controller.config.manager.impl.osgi.mapping.CodecRegistryProvider;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
 import org.opendaylight.controller.config.manager.impl.osgi.mapping.ModuleInfoBundleTracker;
 import org.opendaylight.controller.config.manager.impl.osgi.mapping.RefreshingSCPModuleInfoRegistry;
 import org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil;
@@ -38,18 +38,19 @@ public class ConfigManagerActivator implements BundleActivator {
 
         ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();// the inner strategy is backed by thread context cl?
 
+        BindingContextProvider bindingContextProvider = new BindingContextProvider();
+
         RefreshingSCPModuleInfoRegistry moduleInfoRegistryWrapper = new RefreshingSCPModuleInfoRegistry(
-                moduleInfoBackedContext, moduleInfoBackedContext, context);
+                moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, bindingContextProvider, context);
 
         ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker(moduleInfoRegistryWrapper);
 
-        CodecRegistryProvider codecRegistryProvider = new CodecRegistryProvider(moduleInfoBackedContext, context);
 
         // start config registry
         BundleContextBackedModuleFactoriesResolver bundleContextBackedModuleFactoriesResolver = new BundleContextBackedModuleFactoriesResolver(
                 context);
         ConfigRegistryImpl configRegistry = new ConfigRegistryImpl(bundleContextBackedModuleFactoriesResolver, configMBeanServer,
-                codecRegistryProvider.getCodecRegistry());
+                bindingContextProvider);
 
         // track bundles containing factories
         BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker(
@@ -80,7 +81,7 @@ public class ConfigManagerActivator implements BundleActivator {
         serviceTracker.open();
 
         List<AutoCloseable> list = Arrays.asList(
-                codecRegistryProvider, clsReg,configRegistry, wrap(bundleTracker), configRegReg, configRegistryJMXRegistrator, wrap(serviceTracker));
+                bindingContextProvider, clsReg,configRegistry, wrap(bundleTracker), configRegReg, configRegistryJMXRegistrator, wrap(serviceTracker));
         autoCloseable = OsgiRegistrationUtil.aggregate(list);
     }
 
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/BindingContextProvider.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/BindingContextProvider.java
new file mode 100644 (file)
index 0000000..8fc0da0
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.manager.impl.osgi.mapping;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+
+/**
+ * Creates and initializes {@link BindingRuntimeContext}, which is used to resolve Identity classes from QName.
+ * An instance of {@link BindingRuntimeContext} is available only after first schema context was successfully built.
+ */
+// TODO move to yang runtime
+public class BindingContextProvider implements AutoCloseable {
+
+    private BindingRuntimeContext current;
+
+    public synchronized void update(final ClassLoadingStrategy classLoadingStrategy, final SchemaContextProvider ctxProvider) {
+        this.current = BindingRuntimeContext.create(classLoadingStrategy, ctxProvider.getSchemaContext());
+    }
+
+    public synchronized BindingRuntimeContext getBindingContext() {
+        Preconditions.checkState(current != null, "Binding context not yet initialized");
+        return this.current;
+    }
+
+    @Override
+    public synchronized void close() throws Exception {
+        current = null;
+    }
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java
deleted file mode 100644 (file)
index a40ed99..0000000
+++ /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.config.manager.impl.osgi.mapping;
-
-import javassist.ClassPool;
-import org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil;
-import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
-import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-import org.osgi.framework.BundleContext;
-
-/**
- * Creates and initializes {@link RuntimeGeneratedMappingServiceImpl}, which is used to get {@link CodecRegistry}.
- * Also maintains service registrations of {@link RuntimeGeneratedMappingServiceImpl}.
- */
-// TODO move to yang runtime
-public class CodecRegistryProvider implements AutoCloseable {
-    private static final ClassPool CLASS_POOL = ClassPool.getDefault();
-
-    private final RuntimeGeneratedMappingServiceImpl service;
-    private final AutoCloseable registration;
-
-    public CodecRegistryProvider(final ClassLoadingStrategy classLoadingStrategy, final BundleContext context) {
-        service = new RuntimeGeneratedMappingServiceImpl(CLASS_POOL, classLoadingStrategy);
-        registration = OsgiRegistrationUtil.registerService(context, service,
-                SchemaContextListener.class, BindingIndependentMappingService.class);
-    }
-
-    public CodecRegistry getCodecRegistry() {
-        return service.getCodecRegistry();
-    }
-
-    @Override
-    public void close() throws Exception {
-        registration.close();
-    }
-}
index bee14c837d1fec553b4e0e72bbfbdab057fe96b9..d4add505038eb3cdced6f55c77785ed478c663f3 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.config.manager.impl.osgi.mapping;
 
 import java.util.Hashtable;
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
@@ -22,15 +23,23 @@ import org.osgi.framework.ServiceRegistration;
 public class RefreshingSCPModuleInfoRegistry implements ModuleInfoRegistry, AutoCloseable {
 
     private final ModuleInfoRegistry moduleInfoRegistry;
+    private final SchemaContextProvider schemaContextProvider;
+    private final BindingContextProvider bindingContextProvider;
+    private final ClassLoadingStrategy classLoadingStrat;
+
     private final ServiceRegistration<SchemaContextProvider> osgiReg;
 
-    public RefreshingSCPModuleInfoRegistry(ModuleInfoRegistry moduleInfoRegistry,
-                                           SchemaContextProvider schemaContextProvider, BundleContext bundleContext) {
+    public RefreshingSCPModuleInfoRegistry(final ModuleInfoRegistry moduleInfoRegistry,
+                                           final SchemaContextProvider schemaContextProvider, final ClassLoadingStrategy classLoadingStrat, final BindingContextProvider bindingContextProvider, final BundleContext bundleContext) {
         this.moduleInfoRegistry = moduleInfoRegistry;
+        this.schemaContextProvider = schemaContextProvider;
+        this.classLoadingStrat = classLoadingStrat;
+        this.bindingContextProvider = bindingContextProvider;
         osgiReg = bundleContext.registerService(SchemaContextProvider.class, schemaContextProvider, new Hashtable<String, String>());
     }
 
     private void updateService() {
+        bindingContextProvider.update(classLoadingStrat, schemaContextProvider);
         osgiReg.setProperties(null); // send modifiedService event
     }
 
@@ -42,12 +51,12 @@ public class RefreshingSCPModuleInfoRegistry implements ModuleInfoRegistry, Auto
         return wrapper;
     }
 
-
     @Override
-    public void close() {
+    public void close() throws Exception {
         osgiReg.unregister();
     }
 
+
     private class ObjectRegistrationWrapper implements ObjectRegistration<YangModuleInfo> {
         private final ObjectRegistration<YangModuleInfo> inner;
 
index db1b794d300ef9552039e52591f3dd358a147971..30da27f1a1dee6951d05fe59b96b81e319d936c6 100644 (file)
@@ -39,12 +39,15 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleF
 import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
 import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolImpl;
 import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
@@ -121,8 +124,17 @@ public abstract class AbstractConfigTest extends
         internalJmxRegistrator = new InternalJMXRegistrator(platformMBeanServer);
         baseJmxRegistrator = new BaseJMXRegistrator(internalJmxRegistrator);
 
-        configRegistry = new ConfigRegistryImpl(resolver,
-                platformMBeanServer, baseJmxRegistrator, getCodecRegistry());
+        configRegistry = new ConfigRegistryImpl(resolver, platformMBeanServer, baseJmxRegistrator, new BindingContextProvider() {
+            @Override
+            public synchronized void update(final ClassLoadingStrategy classLoadingStrategy, final SchemaContextProvider ctxProvider) {
+                // NOOP
+            }
+
+            @Override
+            public synchronized BindingRuntimeContext getBindingContext() {
+                return getBindingRuntimeContext();
+            }
+        });
 
         try {
             configRegistryJMXRegistrator.registerToJMX(configRegistry);
@@ -192,8 +204,8 @@ public abstract class AbstractConfigTest extends
         return new ClassBasedModuleFactory(implementationName, configBeanClass);
     }
 
-    protected CodecRegistry getCodecRegistry() {
-        return mock(CodecRegistry.class);
+    protected BindingRuntimeContext getBindingRuntimeContext() {
+        return mock(BindingRuntimeContext.class);
     }
 
     public static interface BundleContextServiceRegistrationHandler {
index 9d799cb47d56169eaa987df7aa30f4350da4f4d8..bb2d9c7927286bbef4c6b71bed0e311073e9f11d 100644 (file)
@@ -3,12 +3,15 @@ package org.opendaylight.controller.config.manager.impl.osgi;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 
 import java.util.Dictionary;
 import org.junit.Test;
 import org.mockito.Mockito;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
 import org.opendaylight.controller.config.manager.impl.osgi.mapping.RefreshingSCPModuleInfoRegistry;
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
@@ -21,21 +24,29 @@ public class RefreshingSCPModuleInfoRegistryTest {
         ModuleInfoRegistry reg = mock(ModuleInfoRegistry.class);
         SchemaContextProvider prov = mock(SchemaContextProvider.class);
         doReturn("string").when(prov).toString();
-
         BundleContext ctxt = mock(BundleContext.class);
         ServiceRegistration<?> servReg = mock(ServiceRegistration.class);
         doReturn(servReg).when(ctxt).registerService(Mockito.any(Class.class), Mockito.any(SchemaContextProvider.class), Mockito.any(Dictionary.class));
         doReturn(servReg).when(ctxt).registerService(Mockito.anyString(), Mockito.any(Object.class), Mockito.any(Dictionary.class));
-        RefreshingSCPModuleInfoRegistry scpreg = new RefreshingSCPModuleInfoRegistry(reg, prov, ctxt);
 
-        YangModuleInfo modInfo = mock(YangModuleInfo.class);
+        final ClassLoadingStrategy classLoadingStrat = mock(ClassLoadingStrategy.class);
+        final BindingContextProvider codecRegistryProvider = mock(BindingContextProvider.class);
+        doNothing().when(codecRegistryProvider).update(classLoadingStrat, prov);
+
+        RefreshingSCPModuleInfoRegistry scpreg = new RefreshingSCPModuleInfoRegistry(reg, prov, classLoadingStrat, codecRegistryProvider, ctxt);
+
         doNothing().when(servReg).setProperties(null);
         doNothing().when(servReg).unregister();
+
+        YangModuleInfo modInfo = mock(YangModuleInfo.class);
         doReturn("").when(modInfo).toString();
         ObjectRegistration<YangModuleInfo> ymi = mock(ObjectRegistration.class);
         doReturn(ymi).when(reg).registerModuleInfo(modInfo);
 
         scpreg.registerModuleInfo(modInfo);
+
+        verify(codecRegistryProvider).update(classLoadingStrat, prov);
+
         scpreg.close();
 
         Mockito.verify(servReg, Mockito.times(1)).setProperties(null);
index 441de1f9f23c5b73f6fe924cbdcfc97e907b2cb6..680fe5048a8a23568a91df18571f7b84bada52cd 100644 (file)
@@ -12,7 +12,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 import com.google.common.collect.Lists;
 import java.util.ArrayList;
@@ -30,8 +29,7 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 
 public class NetconfTestImplModuleTest  extends AbstractConfigTest {
 
@@ -48,13 +46,10 @@ public class NetconfTestImplModuleTest  extends AbstractConfigTest {
     }
 
     @Override
-    protected CodecRegistry getCodecRegistry() {
-        final IdentityCodec<?> codec = mock(IdentityCodec.class);
-        doReturn(TestIdentity1.class).when(codec).deserialize(TestIdentity1.QNAME);
-        doReturn(TestIdentity2.class).when(codec).deserialize(TestIdentity2.QNAME);
-
-        final CodecRegistry ret = super.getCodecRegistry();
-        doReturn(codec).when(ret).getIdentityCodec();
+    protected BindingRuntimeContext getBindingRuntimeContext() {
+        final BindingRuntimeContext ret = super.getBindingRuntimeContext();
+        doReturn(TestIdentity1.class).when(ret).getIdentityClass(TestIdentity1.QNAME);
+        doReturn(TestIdentity2.class).when(ret).getIdentityClass(TestIdentity2.QNAME);
         return ret;
     }
 
index 8d5d5255f84232360b74fc1f4199e2135331bc34..5ef6a245ecf24ec5a673567f42a89329f50d8808 100644 (file)
                             <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
                         </instance>
                     </service>
+                    <service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-codec-tree-factory</type>
+                        <instance>
+                            <name>runtime-mapping-singleton</name>
+                            <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
+                        </instance>
+                    </service>
                     <service>
                         <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-new-notification-service</type>
                         <instance>
index 2503d3d24286b22d3b5bcd39efc36498f68331a9..6acf552638f3292872e0fbbaf28227ada4284d13 100644 (file)
@@ -1,7 +1,7 @@
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
-import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 
 public class BindingAsyncDataBrokerImplModule extends
@@ -29,7 +29,7 @@ public class BindingAsyncDataBrokerImplModule extends
     public java.lang.AutoCloseable createInstance() {
         final BindingToNormalizedNodeCodec mappingService = getBindingMappingServiceDependency();
         final DOMDataBroker domDataBroker = getDomAsyncBrokerDependency();
-        return new ForwardedBindingDataBroker(domDataBroker, mappingService);
+        return new BindingDOMDataBrokerAdapter(domDataBroker, mappingService);
     }
 
 }
index e7861512994c80e3d1a0326726ec7118e5d40e95..903cb27c92f52d8a6215ffd32c450f5c4039be28 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
-import org.opendaylight.controller.md.sal.binding.impl.ForwardedNotificationService;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationServiceAdapter;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
 import org.opendaylight.controller.sal.core.api.Broker;
@@ -34,7 +34,7 @@ public class BindingNotificationAdapterModule extends AbstractBindingNotificatio
         final BindingToNormalizedNodeCodec codec = getBindingMappingServiceDependency();
         final Broker.ProviderSession session = getDomAsyncBrokerDependency().registerProvider(new DummyDOMProvider());
         final DOMNotificationService notifService = session.getService(DOMNotificationService.class);
-        return new ForwardedNotificationService(codec.getCodecRegistry(), notifService, SingletonHolder.INVOKER_FACTORY);
+        return new BindingDOMNotificationServiceAdapter(codec.getCodecRegistry(), notifService, SingletonHolder.INVOKER_FACTORY);
     }
 
 }
index bdac710ecb1fd90634659dd701b6d9cc94fc3d22..de4a905931fe17478a53f2a287f086ab27b93066 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
-import org.opendaylight.controller.md.sal.binding.impl.ForwardedNotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
 import org.opendaylight.controller.sal.core.api.Broker;
 
@@ -33,7 +33,7 @@ public class BindingNotificationPublishAdapterModule extends AbstractBindingNoti
         final BindingToNormalizedNodeCodec codec = getBindingMappingServiceDependency();
         final Broker.ProviderSession session = getDomAsyncBrokerDependency().registerProvider(new DummyDOMProvider());
         final DOMNotificationPublishService publishService = session.getService(DOMNotificationPublishService.class);
-        return new ForwardedNotificationPublishService(codec.getCodecRegistry(), publishService);
+        return new BindingDOMNotificationPublishServiceAdapter(codec.getCodecRegistry(), publishService);
     }
 
 }
index 79c974959db6a8a293eaf4dc0a4ebd097a069062..175dbb6c99cb19fd2543e8b99cc12ec9d145d498 100644 (file)
@@ -24,9 +24,9 @@ public abstract class BindingDOMAdapterLoader extends AdapterLoader<BindingServi
 
 
     private static final Map<Class<?>,BindingDOMAdapterBuilder.Factory<?>> FACTORIES = ImmutableMap.<Class<?>,BindingDOMAdapterBuilder.Factory<?>>builder()
-            .put(NotificationService.class,ForwardedNotificationService.BUILDER_FACTORY)
-            .put(NotificationPublishService.class,ForwardedNotificationPublishService.BUILDER_FACTORY)
-            .put(DataBroker.class,ForwardedBindingDataBroker.BUILDER_FACTORY)
+            .put(NotificationService.class,BindingDOMNotificationServiceAdapter.BUILDER_FACTORY)
+            .put(NotificationPublishService.class,BindingDOMNotificationPublishServiceAdapter.BUILDER_FACTORY)
+            .put(DataBroker.class,BindingDOMDataBrokerAdapter.BUILDER_FACTORY)
             .put(RpcConsumerRegistry.class,BindingDOMRpcServiceAdapter.BUILDER_FACTORY)
             .build();
 
@@ -32,7 +32,7 @@ import org.opendaylight.controller.sal.core.api.model.SchemaService;
  *
 
  */
-public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker implements DataBroker {
+public class BindingDOMDataBrokerAdapter extends AbstractForwardedDataBroker implements DataBroker {
 
 
     static final Factory<DataBroker> BUILDER_FACTORY = new BindingDOMAdapterBuilder.Factory<DataBroker>() {
@@ -44,34 +44,34 @@ public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker impl
 
     };
 
-    public ForwardedBindingDataBroker(final DOMDataBroker domDataBroker, final BindingToNormalizedNodeCodec codec) {
+    public BindingDOMDataBrokerAdapter(final DOMDataBroker domDataBroker, final BindingToNormalizedNodeCodec codec) {
         super(domDataBroker, codec);
     }
 
     @Deprecated
-    public ForwardedBindingDataBroker(final DOMDataBroker domDataBroker, final BindingToNormalizedNodeCodec codec, final SchemaService schemaService) {
+    public BindingDOMDataBrokerAdapter(final DOMDataBroker domDataBroker, final BindingToNormalizedNodeCodec codec, final SchemaService schemaService) {
         super(domDataBroker, codec,schemaService);
     }
 
     @Override
 
     public ReadOnlyTransaction newReadOnlyTransaction() {
-        return new BindingDataReadTransactionImpl(getDelegate().newReadOnlyTransaction(),getCodec());
+        return new BindingDOMReadTransactionAdapter(getDelegate().newReadOnlyTransaction(),getCodec());
     }
 
     @Override
     public ReadWriteTransaction newReadWriteTransaction() {
-        return new BindingDataReadWriteTransactionImpl(getDelegate().newReadWriteTransaction(),getCodec());
+        return new BindingDOMReadWriteTransactionAdapter(getDelegate().newReadWriteTransaction(),getCodec());
     }
 
     @Override
     public WriteTransaction newWriteOnlyTransaction() {
-        return new BindingDataWriteTransactionImpl<>(getDelegate().newWriteOnlyTransaction(),getCodec());
+        return new BindingDOMWriteTransactionAdapter<>(getDelegate().newWriteOnlyTransaction(),getCodec());
     }
 
     @Override
     public BindingTransactionChain createTransactionChain(final TransactionChainListener listener) {
-        return new BindingTranslatedTransactionChain(getDelegate(), getCodec(), listener);
+        return new BindingDOMTransactionChainAdapter(getDelegate(), getCodec(), listener);
     }
 
     private static class Builder extends BindingDOMAdapterBuilder<DataBroker> {
@@ -85,7 +85,7 @@ public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker impl
         protected DataBroker createInstance(BindingToNormalizedNodeCodec codec,
                 ClassToInstanceMap<DOMService> delegates) {
             DOMDataBroker domDataBroker = delegates.getInstance(DOMDataBroker.class);
-            return new ForwardedBindingDataBroker(domDataBroker, codec);
+            return new BindingDOMDataBrokerAdapter(domDataBroker, codec);
         }
 
 
@@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.binding.Notification;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
-public class ForwardedNotificationPublishService implements NotificationPublishService, AutoCloseable {
+public class BindingDOMNotificationPublishServiceAdapter implements NotificationPublishService, AutoCloseable {
 
     static final Factory<NotificationPublishService> BUILDER_FACTORY = new BindingDOMAdapterBuilder.Factory<NotificationPublishService>() {
 
@@ -37,7 +37,7 @@ public class ForwardedNotificationPublishService implements NotificationPublishS
     private final BindingNormalizedNodeSerializer codecRegistry;
     private final DOMNotificationPublishService domPublishService;
 
-    public ForwardedNotificationPublishService(BindingNormalizedNodeSerializer codecRegistry, DOMNotificationPublishService domPublishService) {
+    public BindingDOMNotificationPublishServiceAdapter(BindingNormalizedNodeSerializer codecRegistry, DOMNotificationPublishService domPublishService) {
         this.codecRegistry = codecRegistry;
         this.domPublishService = domPublishService;
     }
@@ -105,7 +105,7 @@ public class ForwardedNotificationPublishService implements NotificationPublishS
                 ClassToInstanceMap<DOMService> delegates) {
             BindingNormalizedNodeSerializer codecReg = codec.getCodecRegistry();
             DOMNotificationPublishService domPublish = delegates.getInstance(DOMNotificationPublishService.class);
-            return new ForwardedNotificationPublishService(codecReg, domPublish);
+            return new BindingDOMNotificationPublishServiceAdapter(codecReg, domPublish);
         }
 
     }
@@ -30,7 +30,7 @@ import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
-public class ForwardedNotificationService implements NotificationService, AutoCloseable {
+public class BindingDOMNotificationServiceAdapter implements NotificationService, AutoCloseable {
 
     public static final Factory<NotificationService> BUILDER_FACTORY = new Factory<NotificationService>() {
 
@@ -44,7 +44,7 @@ public class ForwardedNotificationService implements NotificationService, AutoCl
     private final DOMNotificationService domNotifService;
     private final NotificationInvokerFactory notificationInvokerFactory;
 
-    public ForwardedNotificationService(BindingNormalizedNodeSerializer codec, DOMNotificationService domNotifService, NotificationInvokerFactory notificationInvokerFactory) {
+    public BindingDOMNotificationServiceAdapter(BindingNormalizedNodeSerializer codec, DOMNotificationService domNotifService, NotificationInvokerFactory notificationInvokerFactory) {
         this.codec = codec;
         this.domNotifService = domNotifService;
         this.notificationInvokerFactory = notificationInvokerFactory;
@@ -113,7 +113,7 @@ public class ForwardedNotificationService implements NotificationService, AutoCl
                 ClassToInstanceMap<DOMService> delegates) {
             DOMNotificationService domNotification = delegates.getInstance(DOMNotificationService.class);
             NotificationInvokerFactory invokerFactory = SingletonHolder.INVOKER_FACTORY;
-            return new ForwardedNotificationService(codec.getCodecFactory(), domNotification, invokerFactory);
+            return new BindingDOMNotificationServiceAdapter(codec.getCodecRegistry(), domNotification, invokerFactory);
         }
 
         @Override
@@ -17,10 +17,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 
-class BindingDataReadTransactionImpl extends AbstractForwardedTransaction<DOMDataReadOnlyTransaction> implements
+class BindingDOMReadTransactionAdapter extends AbstractForwardedTransaction<DOMDataReadOnlyTransaction> implements
         ReadOnlyTransaction {
 
-    protected BindingDataReadTransactionImpl(final DOMDataReadOnlyTransaction delegate,
+    protected BindingDOMReadTransactionAdapter(final DOMDataReadOnlyTransaction delegate,
             final BindingToNormalizedNodeCodec codec) {
         super(delegate, codec);
     }
@@ -17,10 +17,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 
-class BindingDataReadWriteTransactionImpl extends
-        BindingDataWriteTransactionImpl<DOMDataReadWriteTransaction> implements ReadWriteTransaction {
+class BindingDOMReadWriteTransactionAdapter extends
+        BindingDOMWriteTransactionAdapter<DOMDataReadWriteTransaction> implements ReadWriteTransaction {
 
-    protected BindingDataReadWriteTransactionImpl(final DOMDataReadWriteTransaction delegate,
+    protected BindingDOMReadWriteTransactionAdapter(final DOMDataReadWriteTransaction delegate,
             final BindingToNormalizedNodeCodec codec) {
         super(delegate, codec);
     }
index 46bd2f84d008885e55d6e989cd15b11336cbce8d..ba822989d81d8faa947db6885b9c002d46b3f054 100644 (file)
@@ -41,7 +41,7 @@ public class BindingDOMRpcProviderServiceAdapter {
     }
 
     private <S extends RpcService, T extends S> ObjectRegistration<T> register(final Class<S> type, final T implementation, final Set<DOMRpcIdentifier> domRpcs) {
-        final BindingRpcImplementationAdapter adapter = new BindingRpcImplementationAdapter(codec.getCodecFactory(), type, implementation);
+        final BindingRpcImplementationAdapter adapter = new BindingRpcImplementationAdapter(codec.getCodecRegistry(), type, implementation);
 
 
         final DOMRpcImplementationRegistration<?> domReg = domRpcRegistry.registerRpcImplementation(adapter, domRpcs);
index 9694bc99a61182c0f4de3348a6ca2337643fc781..6b64b7ea55473a98027b75a7a96cf9571acfa00e 100644 (file)
@@ -81,7 +81,7 @@ public class BindingDOMRpcServiceAdapter implements RpcConsumerRegistry, Invocat
     @Override
     public ListenableFuture<RpcResult<?>> invoke(final SchemaPath rpc, final DataObject input) {
         final CheckedFuture<DOMRpcResult, DOMRpcException> domFuture = domService.invokeRpc(rpc, serialize(rpc,input));
-        return transformFuture(rpc,domFuture,codec.getCodecFactory());
+        return transformFuture(rpc,domFuture,codec.getCodecRegistry());
     }
 
     private RpcServiceAdapter createProxy(final Class<? extends RpcService> key) {
@@ -96,7 +96,7 @@ public class BindingDOMRpcServiceAdapter implements RpcConsumerRegistry, Invocat
             return null;
         }
         final QName rpcInputIdentifier = QName.create(rpc.getLastComponent(),"input");
-        return new LazySerializedContainerNode(rpcInputIdentifier, input, codec.getCodecFactory());
+        return new LazySerializedContainerNode(rpcInputIdentifier, input, codec.getCodecRegistry());
     }
 
     private static ListenableFuture<RpcResult<?>> transformFuture(final SchemaPath rpc,final ListenableFuture<DOMRpcResult> domFuture, final BindingNormalizedNodeCodecRegistry codec) {
@@ -28,16 +28,16 @@ import org.opendaylight.yangtools.concepts.Delegator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class BindingTranslatedTransactionChain implements BindingTransactionChain, Delegator<DOMTransactionChain> {
+final class BindingDOMTransactionChainAdapter implements BindingTransactionChain, Delegator<DOMTransactionChain> {
 
-    private static final Logger LOG = LoggerFactory.getLogger(BindingTranslatedTransactionChain.class);
+    private static final Logger LOG = LoggerFactory.getLogger(BindingDOMTransactionChainAdapter.class);
 
     private final DOMTransactionChain delegate;
     private final BindingToNormalizedNodeCodec codec;
     private final DelegateChainListener domListener;
     private final TransactionChainListener bindingListener;
 
-    public BindingTranslatedTransactionChain(final DOMDataBroker chainFactory,
+    public BindingDOMTransactionChainAdapter(final DOMDataBroker chainFactory,
             final BindingToNormalizedNodeCodec codec, final TransactionChainListener listener) {
         Preconditions.checkNotNull(chainFactory, "DOM Transaction chain factory must not be null");
         this.domListener = new DelegateChainListener();
@@ -54,14 +54,14 @@ final class BindingTranslatedTransactionChain implements BindingTransactionChain
     @Override
     public ReadOnlyTransaction newReadOnlyTransaction() {
         DOMDataReadOnlyTransaction delegateTx = delegate.newReadOnlyTransaction();
-        ReadOnlyTransaction bindingTx = new BindingDataReadTransactionImpl(delegateTx, codec);
+        ReadOnlyTransaction bindingTx = new BindingDOMReadTransactionAdapter(delegateTx, codec);
         return bindingTx;
     }
 
     @Override
     public ReadWriteTransaction newReadWriteTransaction() {
         DOMDataReadWriteTransaction delegateTx = delegate.newReadWriteTransaction();
-        ReadWriteTransaction bindingTx = new BindingDataReadWriteTransactionImpl(delegateTx, codec) {
+        ReadWriteTransaction bindingTx = new BindingDOMReadWriteTransactionAdapter(delegateTx, codec) {
 
             @Override
             public CheckedFuture<Void, TransactionCommitFailedException> submit() {
@@ -75,7 +75,7 @@ final class BindingTranslatedTransactionChain implements BindingTransactionChain
     @Override
     public WriteTransaction newWriteOnlyTransaction() {
         final DOMDataWriteTransaction delegateTx = delegate.newWriteOnlyTransaction();
-        WriteTransaction bindingTx = new BindingDataWriteTransactionImpl<DOMDataWriteTransaction>(delegateTx, codec) {
+        WriteTransaction bindingTx = new BindingDOMWriteTransactionAdapter<DOMDataWriteTransaction>(delegateTx, codec) {
 
             @Override
             public CheckedFuture<Void,TransactionCommitFailedException> submit() {
@@ -141,7 +141,7 @@ final class BindingTranslatedTransactionChain implements BindingTransactionChain
         public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
             Preconditions.checkState(delegate.equals(chain),
                     "Illegal state - listener for %s was invoked for incorrect chain %s.", delegate, chain);
-            bindingListener.onTransactionChainSuccessful(BindingTranslatedTransactionChain.this);
+            bindingListener.onTransactionChainSuccessful(BindingDOMTransactionChainAdapter.this);
         }
     }
 
@@ -27,10 +27,10 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgum
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 
-class BindingDataWriteTransactionImpl<T extends DOMDataWriteTransaction> extends
+class BindingDOMWriteTransactionAdapter<T extends DOMDataWriteTransaction> extends
         AbstractWriteTransaction<T> implements WriteTransaction {
 
-    protected BindingDataWriteTransactionImpl(final T delegateTx, final BindingToNormalizedNodeCodec codec) {
+    protected BindingDOMWriteTransactionAdapter(final T delegateTx, final BindingToNormalizedNodeCodec codec) {
         super(delegateTx, codec);
     }
 
index d5b7d051b881c86db77a121546cceeec4072f627..bf3ac3d50d5bbebbf2d50681c513611fa674dd8a 100644 (file)
@@ -17,6 +17,8 @@ import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTree;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory;
 import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
@@ -37,7 +39,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
-public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoCloseable {
+public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, SchemaContextListener, AutoCloseable {
 
     private final BindingIndependentMappingService bindingToLegacy;
     private final BindingNormalizedNodeCodecRegistry codecRegistry;
@@ -45,8 +47,9 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoC
     private final GeneratedClassLoadingStrategy classLoadingStrategy;
     private BindingRuntimeContext runtimeContext;
 
-    public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy, final BindingIndependentMappingService mappingService, final BindingNormalizedNodeCodecRegistry codecRegistry) {
-        super();
+    public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy,
+            final BindingIndependentMappingService mappingService,
+            final BindingNormalizedNodeCodecRegistry codecRegistry) {
         this.bindingToLegacy = mappingService;
         this.classLoadingStrategy = classLoadingStrategy;
         this.codecRegistry = codecRegistry;
@@ -188,4 +191,15 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoC
         }
         return key.getMethod(methodName);
     }
+
+    @Override
+    public BindingCodecTree create(BindingRuntimeContext context) {
+        return codecRegistry.create(context);
+    }
+
+    @Override
+    public BindingCodecTree create(SchemaContext context, Class<?>... bindingClasses) {
+        return codecRegistry.create(context, bindingClasses);
+    }
+
 }
index b62f59699cb9af7122a6e82146b333bda4abf0d8..e15cb833855647231fc2fda8a6ef83535b76e436 100644 (file)
@@ -69,6 +69,7 @@ module opendaylight-sal-binding-broker-impl {
     identity runtime-generated-mapping {
         base config:module-type;
         config:provided-service binding-dom-mapping-service;
+        config:provided-service sal:binding-codec-tree-factory;
         config:java-name-prefix RuntimeMapping;
     }
 
index f8f45f25e004eea5cea925dbc3ec5ef93fda8d31..c5138040ecaf1fe0b3c3f18c35ba817cb83d40c6 100644 (file)
@@ -15,9 +15,9 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
-import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
-import org.opendaylight.controller.md.sal.binding.impl.ForwardedNotificationPublishService;
-import org.opendaylight.controller.md.sal.binding.impl.ForwardedNotificationService;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationServiceAdapter;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
@@ -80,12 +80,12 @@ public class DataBrokerTestCustomizer {
     }
 
     public NotificationService createNotificationService() {
-        return new ForwardedNotificationService(bindingToNormalized.getCodecRegistry(), domNotificationRouter,
+        return new BindingDOMNotificationServiceAdapter(bindingToNormalized.getCodecRegistry(), domNotificationRouter,
                 SingletonHolder.INVOKER_FACTORY);
     }
 
     public NotificationPublishService createNotificationPublishService() {
-        return new ForwardedNotificationPublishService(bindingToNormalized.getCodecRegistry(), domNotificationRouter);
+        return new BindingDOMNotificationPublishServiceAdapter(bindingToNormalized.getCodecRegistry(), domNotificationRouter);
     }
 
 
@@ -94,7 +94,7 @@ public class DataBrokerTestCustomizer {
     }
 
     public DataBroker createDataBroker() {
-        return new ForwardedBindingDataBroker(getDOMDataBroker(), bindingToNormalized);
+        return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), bindingToNormalized);
     }
 
     public BindingToNormalizedNodeCodec getBindingToNormalized() {
index 58d6a3de889b8759140b9ee7334719f3ab4780ca..262f5afca930023d494f5b9608ac458c8e6eb87d 100644 (file)
@@ -29,7 +29,7 @@ import org.opendaylight.controller.md.sal.binding.impl.BindingDOMMountPointServi
 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMRpcProviderServiceAdapter;
 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMRpcServiceAdapter;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
-import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
@@ -136,7 +136,7 @@ public class BindingTestContext implements AutoCloseable {
     public void startNewDataBroker() {
         checkState(executor != null, "Executor needs to be set");
         checkState(newDOMDataBroker != null, "DOM Data Broker must be set");
-        dataBroker = new ForwardedBindingDataBroker(newDOMDataBroker, codec);
+        dataBroker = new BindingDOMDataBrokerAdapter(newDOMDataBroker, codec);
     }
 
     public void startNewDomDataBroker() {
index 68af914f579e854014fbb60fe3b98db5f720582b..39aece42334aa2b431ef00e5ed686c1678083aba 100644 (file)
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>binding-data-codec</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
index fcfd6fa3cf0c163c84c4e091bce1479865c65f3d..81508d1b8fc93483277f31abf23cdaff50547397 100644 (file)
@@ -43,6 +43,11 @@ module opendaylight-md-sal-binding {
         config:java-class "org.opendaylight.controller.sal.binding.api.NotificationProviderService";
     }
 
+    identity binding-codec-tree-factory {
+        base "config:service-type";
+        config:java-class "org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory";
+    }
+
     identity binding-notification-subscription-service {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.sal.binding.api.NotificationService";
index 14d565c1d0b51253bad32a5182eb330ab860e94d..4e650842789b23504fec0801b85c71708617381e 100644 (file)
@@ -14,10 +14,10 @@ import com.google.common.collect.Multimap;
 import java.util.Collection;
 import java.util.Map.Entry;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.dom.spi.RegistrationTreeSnapshot;
 import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder;
 import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.SimpleEventFactory;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerWalker;
 import org.opendaylight.yangtools.util.concurrent.NotificationManager;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -51,7 +51,7 @@ final class ResolveDataChangeEventsTask {
      * Resolves and submits notification tasks to the specified manager.
      */
     public synchronized void resolve(final NotificationManager<DataChangeListenerRegistration<?>, DOMImmutableDataChangeEvent> manager) {
-        try (final ListenerWalker w = listenerRoot.getWalker()) {
+        try (final RegistrationTreeSnapshot<DataChangeListenerRegistration<?>> w = listenerRoot.takeSnapshot()) {
             // Defensive: reset internal state
             collectedEvents = ArrayListMultimap.create();
 
index 6bbed57f392db63c647f704ef71a5d223384d60a..e9b91e5a792ae831c152c8683a739f7780142720 100644 (file)
@@ -7,6 +7,9 @@
  */
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -14,10 +17,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.dom.spi.RegistrationTreeNode;
 import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
@@ -27,11 +29,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimap;
-
 /**
  * Recursion state used in {@link ResolveDataChangeEventsTask}. Instances of this
  * method track which listeners are affected by a particular change node. It takes
@@ -49,7 +46,7 @@ final class ResolveDataChangeState {
      */
     private final Collection<Builder> inheritedOne;
     private final YangInstanceIdentifier nodeId;
-    private final Collection<ListenerNode> nodes;
+    private final Collection<RegistrationTreeNode<DataChangeListenerRegistration<?>>> nodes;
 
     private final Map<DataChangeListenerRegistration<?>, Builder> subBuilders;
     private final Map<DataChangeListenerRegistration<?>, Builder> oneBuilders;
@@ -57,7 +54,7 @@ final class ResolveDataChangeState {
 
     private ResolveDataChangeState(final YangInstanceIdentifier nodeId,
             final Iterable<Builder> inheritedSub, final Collection<Builder> inheritedOne,
-            final Collection<ListenerNode> nodes) {
+            final Collection<RegistrationTreeNode<DataChangeListenerRegistration<?>>> nodes) {
         this.nodeId = Preconditions.checkNotNull(nodeId);
         this.nodes = Preconditions.checkNotNull(nodes);
         this.inheritedSub = Preconditions.checkNotNull(inheritedSub);
@@ -69,8 +66,8 @@ final class ResolveDataChangeState {
         final Map<DataChangeListenerRegistration<?>, Builder> sub = new HashMap<>();
         final Map<DataChangeListenerRegistration<?>, Builder> one = new HashMap<>();
         final Map<DataChangeListenerRegistration<?>, Builder> base = new HashMap<>();
-        for (ListenerNode n : nodes) {
-            for (DataChangeListenerRegistration<?> l : n.getListeners()) {
+        for (RegistrationTreeNode<DataChangeListenerRegistration<?>> n : nodes) {
+            for (DataChangeListenerRegistration<?> l : n.getRegistrations()) {
                 final Builder b = DOMImmutableDataChangeEvent.builder(DataChangeScope.BASE);
                 switch (l.getScope()) {
                 case BASE:
@@ -102,12 +99,12 @@ final class ResolveDataChangeState {
      * Create an initial state handle at a particular root node.
      *
      * @param rootId root instance identifier
-     * @param root root node
+     * @param registrationTreeNode root node
      * @return
      */
-    public static ResolveDataChangeState initial(final YangInstanceIdentifier rootId, final ListenerNode root) {
+    public static ResolveDataChangeState initial(final YangInstanceIdentifier rootId, final RegistrationTreeNode<DataChangeListenerRegistration<?>> registrationTreeNode) {
         return new ResolveDataChangeState(rootId, Collections.<Builder>emptyList(),
-            Collections.<Builder>emptyList(), Collections.singletonList(root));
+            Collections.<Builder>emptyList(), Collections.singletonList(registrationTreeNode));
     }
 
     /**
@@ -257,13 +254,13 @@ final class ResolveDataChangeState {
         LOG.trace("Collected events {}", map);
     }
 
-    private static Collection<ListenerNode> getListenerChildrenWildcarded(final Collection<ListenerNode> parentNodes,
+    private static Collection<RegistrationTreeNode<DataChangeListenerRegistration<?>>> getListenerChildrenWildcarded(final Collection<RegistrationTreeNode<DataChangeListenerRegistration<?>>> parentNodes,
             final PathArgument child) {
         if (parentNodes.isEmpty()) {
             return Collections.emptyList();
         }
 
-        final List<ListenerNode> result = new ArrayList<>();
+        final List<RegistrationTreeNode<DataChangeListenerRegistration<?>>> result = new ArrayList<>();
         if (child instanceof NodeWithValue || child instanceof NodeIdentifierWithPredicates) {
             NodeIdentifier wildcardedIdentifier = new NodeIdentifier(child.getNodeType());
             addChildNodes(result, parentNodes, wildcardedIdentifier);
@@ -272,11 +269,11 @@ final class ResolveDataChangeState {
         return result;
     }
 
-    private static void addChildNodes(final List<ListenerNode> result, final Collection<ListenerNode> parentNodes, final PathArgument childIdentifier) {
-        for (ListenerNode node : parentNodes) {
-            Optional<ListenerNode> child = node.getChild(childIdentifier);
-            if (child.isPresent()) {
-                result.add(child.get());
+    private static void addChildNodes(final List<RegistrationTreeNode<DataChangeListenerRegistration<?>>> result, final Collection<RegistrationTreeNode<DataChangeListenerRegistration<?>>> parentNodes, final PathArgument childIdentifier) {
+        for (RegistrationTreeNode<DataChangeListenerRegistration<?>> node : parentNodes) {
+            RegistrationTreeNode<DataChangeListenerRegistration<?>> child = node.getExactChild(childIdentifier);
+            if (child != null) {
+                result.add(child);
             }
         }
     }
index b8396c8a9552cb62d5c639fec702de0172a52241..578320ea9057988e58b97c85647964886d0b321f 100644 (file)
@@ -23,7 +23,10 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
  * unclosed.
  *
  * @author Robert Varga
+ *
+ * @deprecated Use {@link RegistrationTreeNode} instead.
  */
+@Deprecated
 public class ListenerNode implements StoreTreeNode<ListenerNode>, Identifiable<PathArgument> {
     final RegistrationTreeNode<DataChangeListenerRegistration<?>> delegate;
 
index 0909b9941d6287f26e9774716582e5395b3e1418..c0ad313291892b8873ee903b7de80def2f310bb5 100644 (file)
@@ -92,7 +92,10 @@ public final class ListenerTree extends AbstractRegistrationTree<DataChangeListe
      * the listener tree.
      *
      * @return A walker instance.
+     *
+     * @deprecated Use {@link #takeSnapshot()} instead.
      */
+    @Deprecated
     public ListenerWalker getWalker() {
         /*
          * TODO: The only current user of this method is local to the datastore.
index d1c4eacdf6e0fb29c25f63f380dad1de38fa8d10..f8169c4e48c0508228084ad414d7924fccd6abcc 100644 (file)
@@ -16,7 +16,10 @@ import org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegis
  * exposes the underlying tree structure.
  *
  * @author Robert Varga
+ *
+ * @deprecated Superseded by {@link RegistrationTreeSnapshot}.
  */
+@Deprecated
 public class ListenerWalker implements AutoCloseable {
     private final RegistrationTreeSnapshot<DataChangeListenerRegistration<?>> delegate;
 
index 4944d96b546933c49637fbb66b4b91ea8add05d1..5c17f2a14ab2558c4acd089e224828a9248530eb 100644 (file)
@@ -66,36 +66,54 @@ public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<Normalize
             return;
         }
 
+        @SuppressWarnings("unchecked")
         final InstanceIdentifierContext<SchemaNode> context = (InstanceIdentifierContext<SchemaNode>) t.getInstanceIdentifierContext();
 
         SchemaPath path = context.getSchemaNode().getPath();
-        boolean isDataRoot = false;
+        final JsonWriter jsonWriter = createJsonWriter(entityStream);
+        jsonWriter.beginObject();
+        writeNormalizedNode(jsonWriter,path,context,data);
+        jsonWriter.endObject();
+        jsonWriter.flush();
+    }
+
+    private void writeNormalizedNode(JsonWriter jsonWriter, SchemaPath path,
+            InstanceIdentifierContext<SchemaNode> context, NormalizedNode<?, ?> data) throws IOException {
+        final NormalizedNodeWriter nnWriter;
         if (SchemaPath.ROOT.equals(path)) {
-            isDataRoot = true;
+            /*
+             *  Creates writer without initialNs and we write children of root data container
+             *  which is not visible in restconf
+             */
+            nnWriter = createNormalizedNodeWriter(context,path,jsonWriter);
+            writeChildren(nnWriter,(ContainerNode) data);
         } else if (context.getSchemaNode() instanceof RpcDefinition) {
-            isDataRoot = true;
+            /*
+             *  RpcDefinition is not supported as initial codec in JSONStreamWriter,
+             *  so we need to emit initial output declaratation..
+             */
             path = ((RpcDefinition) context.getSchemaNode()).getOutput().getPath();
+            nnWriter = createNormalizedNodeWriter(context,path,jsonWriter);
+            jsonWriter.name("output");
+            jsonWriter.beginObject();
+            writeChildren(nnWriter, (ContainerNode) data);
+            jsonWriter.endObject();
         } else {
             path = path.getParent();
-            // FIXME: Add proper handling of reading root.
-        }
 
-        final JsonWriter jsonWriter = createJsonWriter(entityStream);
-        final NormalizedNodeWriter nnWriter = createNormalizedNodeWriter(context,path,jsonWriter);
-
-        jsonWriter.beginObject();
-        if(isDataRoot) {
-            writeDataRoot(nnWriter,(ContainerNode) data);
-        } else {
             if(data instanceof MapEntryNode) {
                 data = ImmutableNodes.mapNodeBuilder(data.getNodeType()).withChild(((MapEntryNode) data)).build();
             }
+            nnWriter = createNormalizedNodeWriter(context,path,jsonWriter);
             nnWriter.write(data);
         }
-
         nnWriter.flush();
-        jsonWriter.endObject();
-        jsonWriter.flush();
+    }
+
+    private void writeChildren(final NormalizedNodeWriter nnWriter, final ContainerNode data) throws IOException {
+        for(final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
+            nnWriter.write(child);
+        }
     }
 
     private NormalizedNodeWriter createNormalizedNodeWriter(final InstanceIdentifierContext<SchemaNode> context,
@@ -104,9 +122,15 @@ public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<Normalize
         final SchemaNode schema = context.getSchemaNode();
         final JSONCodecFactory codecs = getCodecFactory(context);
 
-        URI initialNs = null;
-        if ( ! (schema instanceof RpcDefinition) && (!((DataSchemaNode)schema).isAugmenting() && !(schema instanceof SchemaContext))) {
+        final URI initialNs;
+        if ((schema instanceof DataSchemaNode)
+                && !((DataSchemaNode)schema).isAugmenting()
+                && !(schema instanceof SchemaContext)) {
+            initialNs = schema.getQName().getNamespace();
+        } else if (schema instanceof RpcDefinition) {
             initialNs = schema.getQName().getNamespace();
+        } else {
+            initialNs = null;
         }
         final NormalizedNodeStreamWriter streamWriter = JSONNormalizedNodeStreamWriter.createNestedWriter(codecs,path,initialNs,jsonWriter);
         return NormalizedNodeWriter.forStreamWriter(streamWriter);
@@ -118,15 +142,9 @@ public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<Normalize
 
     }
 
-    private JSONCodecFactory getCodecFactory(final InstanceIdentifierContext context) {
+    private JSONCodecFactory getCodecFactory(final InstanceIdentifierContext<?> context) {
         // TODO: Performance: Cache JSON Codec factory and schema context
         return JSONCodecFactory.create(context.getSchemaContext());
     }
 
-    private void writeDataRoot(final NormalizedNodeWriter nnWriter, final ContainerNode data) throws IOException {
-        for(final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
-            nnWriter.write(child);
-        }
-    }
-
 }
index f61ec4e1c0941abef0fee706962b6a732af9c858..f6b7027b34a9994d43c2d731a40a11bcf7551bb6 100644 (file)
@@ -18,6 +18,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
+import javax.xml.XMLConstants;
 import javax.xml.stream.FactoryConfigurationError;
 import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
@@ -27,9 +28,7 @@ import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
 import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
@@ -85,38 +84,45 @@ public class NormalizedNodeXmlBodyWriter implements MessageBodyWriter<Normalized
         NormalizedNode<?, ?> data = t.getData();
         SchemaPath schemaPath = pathContext.getSchemaNode().getPath();
 
-        boolean isDataRoot = false;
+
+
+        writeNormalizedNode(xmlWriter,schemaPath,pathContext,data);
+    }
+
+    private void writeNormalizedNode(XMLStreamWriter xmlWriter, SchemaPath schemaPath,InstanceIdentifierContext<?> pathContext, NormalizedNode<?, ?> data) throws IOException {
+        final NormalizedNodeWriter nnWriter;
+        final SchemaContext schemaCtx = pathContext.getSchemaContext();
         if (SchemaPath.ROOT.equals(schemaPath)) {
-            isDataRoot = true;
+            nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, schemaPath);
+            writeElements(xmlWriter, nnWriter, (ContainerNode) data);
         }  else if (pathContext.getSchemaNode() instanceof RpcDefinition) {
-            isDataRoot = true;
-            schemaPath = ((RpcDefinition) pathContext.getSchemaNode()).getOutput().getPath();
-        } else {
-            schemaPath = schemaPath.getParent();
-        }
-
-        final NormalizedNodeStreamWriter jsonWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter,
-                pathContext.getSchemaContext(), schemaPath);
-        final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(jsonWriter);
-        if (isDataRoot) {
-            writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
+            nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, ((RpcDefinition) pathContext.getSchemaNode()).getOutput().getPath());
+            writeElements(xmlWriter, nnWriter, (ContainerNode) data);
         } else {
+            nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, schemaPath.getParent());
             if (data instanceof MapEntryNode) {
                 // Restconf allows returning one list item. We need to wrap it
                 // in map node in order to serialize it properly
                 data = ImmutableNodes.mapNodeBuilder(data.getNodeType()).addChild((MapEntryNode) data).build();
             }
             nnWriter.write(data);
-            nnWriter.flush();
         }
+        nnWriter.flush();
+    }
+
+    private NormalizedNodeWriter createNormalizedNodeWriter(XMLStreamWriter xmlWriter,
+            SchemaContext schemaContext, SchemaPath schemaPath) {
+        NormalizedNodeStreamWriter xmlStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter, schemaContext, schemaPath);
+        return NormalizedNodeWriter.forStreamWriter(xmlStreamWriter);
     }
 
-    private void writeRootElement(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter, final ContainerNode data)
+    private void writeElements(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter, final ContainerNode data)
             throws IOException {
         try {
-            final QName name = SchemaContext.NAME;
-            xmlWriter.writeStartElement(name.getNamespace().toString(), name.getLocalName());
-            for (final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
+            final QName name = data.getNodeType();
+            xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, name.getLocalName(), name.getNamespace().toString());
+            xmlWriter.writeDefaultNamespace(name.getNamespace().toString());
+            for(NormalizedNode<?,?> child : data.getValue()) {
                 nnWriter.write(child);
             }
             nnWriter.flush();
index 75c61d1c196d720401236dba043ec518d38b7fc4..814273ebc0dc6ba1205fa3a7c93dd97152e38034 100644 (file)
@@ -18,6 +18,7 @@ import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import java.math.BigInteger;
@@ -74,6 +75,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceI
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
@@ -168,8 +170,6 @@ public class RestconfImpl implements RestconfService {
 
     private static final URI NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT = URI.create("urn:sal:restconf:event:subscription");
 
-    private static final Date EVENT_SUBSCRIPTION_AUGMENT_REVISION;
-
     private static final String DATASTORE_PARAM_NAME = "datastore";
 
     private static final String SCOPE_PARAM_NAME = "scope";
@@ -180,10 +180,18 @@ public class RestconfImpl implements RestconfService {
 
     private static final QName NETCONF_BASE_QNAME;
 
+    private static final QNameModule SAL_REMOTE_AUGMENT;
+
+    private static final YangInstanceIdentifier.AugmentationIdentifier SAL_REMOTE_AUG_IDENTIFIER;
+
     static {
         try {
-            EVENT_SUBSCRIPTION_AUGMENT_REVISION = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-08");
+            final Date eventSubscriptionAugRevision = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-08");
             NETCONF_BASE_QNAME = QName.create(QNameModule.create(new URI(NETCONF_BASE), null), NETCONF_BASE_PAYLOAD_NAME );
+            SAL_REMOTE_AUGMENT = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT,
+                    eventSubscriptionAugRevision);
+            SAL_REMOTE_AUG_IDENTIFIER = new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(QName.create(SAL_REMOTE_AUGMENT, "scope"),
+                    QName.create(SAL_REMOTE_AUGMENT, "datastore")));
         } catch (final ParseException e) {
             throw new RestconfDocumentedException(
                     "It wasn't possible to convert revision date of sal-remote-augment to date", ErrorType.APPLICATION,
@@ -1325,10 +1333,12 @@ public class RestconfImpl implements RestconfService {
      */
     private <T> T parseEnumTypeParameter(final ContainerNode value, final Class<T> classDescriptor,
             final String paramName) {
-        final QNameModule salRemoteAugment = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT,
-                EVENT_SUBSCRIPTION_AUGMENT_REVISION);
-        final Optional<DataContainerChild<? extends PathArgument, ?>> enumNode = value.getChild(new NodeIdentifier(
-                QName.create(salRemoteAugment, paramName)));
+        final Optional<DataContainerChild<? extends PathArgument, ?>> augNode = value.getChild(SAL_REMOTE_AUG_IDENTIFIER);
+        if (!augNode.isPresent() && !(augNode instanceof AugmentationNode)) {
+            return null;
+        }
+        final Optional<DataContainerChild<? extends PathArgument, ?>> enumNode =
+                ((AugmentationNode) augNode.get()).getChild(new NodeIdentifier(QName.create(SAL_REMOTE_AUGMENT, paramName)));
         if (!enumNode.isPresent()) {
             return null;
         }
index d6b5e62b27b59eb60e023c64603e56474145592d..e1ffcdddffc679e33ccd823322ba2dce8cfdf199 100644 (file)
@@ -105,8 +105,7 @@ import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
@@ -200,14 +199,11 @@ public class NetconfMappingTest extends AbstractConfigTest {
     }
 
     @Override
-    protected CodecRegistry getCodecRegistry() {
-        IdentityCodec<?> idCodec = mock(IdentityCodec.class);
-        doReturn(TestIdentity1.class).when(idCodec).deserialize(TestIdentity1.QNAME);
-        doReturn(TestIdentity2.class).when(idCodec).deserialize(TestIdentity2.QNAME);
-
-        CodecRegistry codecReg = super.getCodecRegistry();
-        doReturn(idCodec).when(codecReg).getIdentityCodec();
-        return codecReg;
+    protected BindingRuntimeContext getBindingRuntimeContext() {
+        final BindingRuntimeContext ret = super.getBindingRuntimeContext();
+        doReturn(TestIdentity1.class).when(ret).getIdentityClass(TestIdentity1.QNAME);
+        doReturn(TestIdentity2.class).when(ret).getIdentityClass(TestIdentity2.QNAME);
+        return ret;
     }
 
     @Test
index 4c0730863fd0d0058281f468ec245c45c25e8fd6..70d7acf159052ac3c15c7d58f108e18c84f6942a 100644 (file)
@@ -14,7 +14,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 import com.google.common.base.Function;
 import com.google.common.base.Throwables;
@@ -47,8 +46,7 @@ import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
@@ -288,13 +286,10 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
     }
 
     @Override
-    protected CodecRegistry getCodecRegistry() {
-        final IdentityCodec<?> codec = mock(IdentityCodec.class);
-        doReturn(TestIdentity1.class).when(codec).deserialize(TestIdentity1.QNAME);
-        doReturn(TestIdentity2.class).when(codec).deserialize(TestIdentity2.QNAME);
-
-        final CodecRegistry ret = super.getCodecRegistry();
-        doReturn(codec).when(ret).getIdentityCodec();
+    protected BindingRuntimeContext getBindingRuntimeContext() {
+        final BindingRuntimeContext ret = super.getBindingRuntimeContext();
+        doReturn(TestIdentity1.class).when(ret).getIdentityClass(TestIdentity1.QNAME);
+        doReturn(TestIdentity2.class).when(ret).getIdentityClass(TestIdentity2.QNAME);
         return ret;
     }
 
index 6f38f24f10c02e3e6dac9c7147fb24104f2ba9db..05ed9bf006f79c2cc7937da1e7064f5d76364d6b 100644 (file)
@@ -8,14 +8,9 @@
 
 package org.opendaylight.controller.netconf.notifications.impl.ops;
 
-import static org.junit.Assert.assertTrue;
-
 import com.google.common.collect.Lists;
 import java.io.IOException;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.XMLUnit;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.notifications.impl.ops.Get;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
@@ -41,22 +36,20 @@ public class GetTest {
 
         final Document response = getBlankResponse();
         Get.serializeStreamsSubtree(response, streams);
-        final Diff diff = XMLUnit.compareXML(XmlUtil.toString(response),
+        NotificationsTransformUtilTest.compareXml(XmlUtil.toString(response),
                 "<rpc-reply message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
-                "<data>\n" +
-                "<netconf xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">\n" +
-                "<streams>\n" +
-                "<stream>\n" +
-                "<name>base</name>\n" +
-                "<description>description</description>\n" +
-                "<replaySupport>false</replaySupport>\n" +
-                "</stream>\n" +
-                "</streams>\n" +
-                "</netconf>\n" +
-                "</data>\n" +
-                "</rpc-reply>\n");
-
-        assertTrue(diff.toString(), diff.identical());
+                        "<data>\n" +
+                        "<netconf xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">\n" +
+                        "<streams>\n" +
+                        "<stream>\n" +
+                        "<name>base</name>\n" +
+                        "<description>description</description>\n" +
+                        "<replaySupport>false</replaySupport>\n" +
+                        "</stream>\n" +
+                        "</streams>\n" +
+                        "</netconf>\n" +
+                        "</data>\n" +
+                        "</rpc-reply>\n");
     }
 
     private Document getBlankResponse() throws IOException, SAXException {
index b63e0877b207ab66d55e5cbd92727f08ac73c762..7bb213ab46942578e4fdce191a5c7a3eb0436d79 100644 (file)
@@ -8,24 +8,30 @@
 
 package org.opendaylight.controller.netconf.notifications.impl.ops;
 
+import static org.junit.Assert.assertTrue;
+
 import com.google.common.collect.Lists;
+import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import org.custommonkey.xmlunit.DetailedDiff;
 import org.custommonkey.xmlunit.Diff;
 import org.custommonkey.xmlunit.XMLUnit;
+import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;
 import org.junit.Test;
 import org.opendaylight.controller.netconf.notifications.NetconfNotification;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
+import org.xml.sax.SAXException;
 
 public class NotificationsTransformUtilTest {
 
     private static final Date DATE = new Date();
     private static final String innerNotification = "<netconf-capability-change xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-notifications\">" +
-            "<deleted-capability>uri3</deleted-capability>" +
             "<deleted-capability>uri4</deleted-capability>" +
+            "<deleted-capability>uri3</deleted-capability>" +
             "<added-capability>uri1</added-capability>" +
             "</netconf-capability-change>";
 
@@ -39,17 +45,22 @@ public class NotificationsTransformUtilTest {
         final NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder();
 
         netconfCapabilityChangeBuilder.setAddedCapability(Lists.newArrayList(new Uri("uri1"), new Uri("uri1")));
-        netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(new Uri("uri3"), new Uri("uri4")));
+        netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(new Uri("uri4"), new Uri("uri3")));
 
         final NetconfCapabilityChange capabilityChange = netconfCapabilityChangeBuilder.build();
         final NetconfNotification transform = NotificationsTransformUtil.transform(capabilityChange, DATE);
 
         final String serialized = XmlUtil.toString(transform.getDocument());
 
+        compareXml(expectedNotification, serialized);
+    }
+
+    static void compareXml(final String expected, final String actual) throws SAXException, IOException {
         XMLUnit.setIgnoreWhitespace(true);
-        final Diff diff = XMLUnit.compareXML(expectedNotification, serialized);
-        // FIXME the diff is unreliable, provide a proper comparison of XML
-//        assertTrue(diff.toString(), diff.similar());
+        final Diff diff = new Diff(expected, actual);
+        final DetailedDiff detailedDiff = new DetailedDiff(diff);
+        detailedDiff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
+        assertTrue(detailedDiff.toString(), detailedDiff.similar());
     }
 
     @Test
@@ -57,9 +68,7 @@ public class NotificationsTransformUtilTest {
         final NetconfNotification netconfNotification = new NetconfNotification(XmlUtil.readXmlToDocument(innerNotification), DATE);
 
         XMLUnit.setIgnoreWhitespace(true);
-        final Diff diff = XMLUnit.compareXML(expectedNotification, netconfNotification.toString());
-        // FIXME the diff is unreliable, provide a proper comparison of XML
-//        assertTrue(diff.toString(), diff.similar());
+        compareXml(expectedNotification, netconfNotification.toString());
     }
 
 }
\ No newline at end of file