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;
private final ModuleFactoriesResolver resolver;
private final MBeanServer configMBeanServer;
- private final CodecRegistry codecRegistry;
+ private final BindingContextProvider bindingContextProvider;
@GuardedBy("this")
private long version = 0;
// 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
readableSRRegistry, txLookupRegistry, allCurrentFactories);
ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
- txLookupRegistry, version, codecRegistry,
+ txLookupRegistry, version, bindingContextProvider,
versionCounter, allCurrentFactories, transactionsMBeanServer,
configMBeanServer, blankTransaction, writableRegistry);
try {
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;
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) {
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;
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;
@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;
@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;
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;
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;
/**
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;
}
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;
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;
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(
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);
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.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;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.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();
- }
-}
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;
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
}
return wrapper;
}
-
@Override
- public void close() {
+ public void close() throws Exception {
osgiReg.unregister();
}
+
private class ObjectRegistrationWrapper implements ObjectRegistration<YangModuleInfo> {
private final ObjectRegistration<YangModuleInfo> inner;
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;
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);
return new ClassBasedModuleFactory(implementationName, configBeanClass);
}
- protected CodecRegistry getCodecRegistry() {
- return mock(CodecRegistry.class);
+ protected BindingRuntimeContext getBindingRuntimeContext() {
+ return mock(BindingRuntimeContext.class);
}
public static interface BundleContextServiceRegistrationHandler {
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;
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);
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;
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 {
}
@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;
}
<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>
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
public java.lang.AutoCloseable createInstance() {
final BindingToNormalizedNodeCodec mappingService = getBindingMappingServiceDependency();
final DOMDataBroker domDataBroker = getDomAsyncBrokerDependency();
- return new ForwardedBindingDataBroker(domDataBroker, mappingService);
+ return new BindingDOMDataBrokerAdapter(domDataBroker, mappingService);
}
}
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;
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);
}
}
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;
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);
}
}
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();
*
*/
-public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker implements DataBroker {
+public class BindingDOMDataBrokerAdapter extends AbstractForwardedDataBroker implements DataBroker {
static final Factory<DataBroker> BUILDER_FACTORY = new BindingDOMAdapterBuilder.Factory<DataBroker>() {
};
- 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> {
protected DataBroker createInstance(BindingToNormalizedNodeCodec codec,
ClassToInstanceMap<DOMService> delegates) {
DOMDataBroker domDataBroker = delegates.getInstance(DOMDataBroker.class);
- return new ForwardedBindingDataBroker(domDataBroker, codec);
+ return new BindingDOMDataBrokerAdapter(domDataBroker, codec);
}
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>() {
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;
}
ClassToInstanceMap<DOMService> delegates) {
BindingNormalizedNodeSerializer codecReg = codec.getCodecRegistry();
DOMNotificationPublishService domPublish = delegates.getInstance(DOMNotificationPublishService.class);
- return new ForwardedNotificationPublishService(codecReg, domPublish);
+ return new BindingDOMNotificationPublishServiceAdapter(codecReg, domPublish);
}
}
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>() {
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;
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
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);
}
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);
}
}
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);
@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) {
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) {
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();
@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() {
@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() {
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);
}
}
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);
}
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;
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;
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;
}
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);
+ }
+
}
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;
}
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;
}
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);
}
}
public DataBroker createDataBroker() {
- return new ForwardedBindingDataBroker(getDOMDataBroker(), bindingToNormalized);
+ return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), bindingToNormalized);
}
public BindingToNormalizedNodeCodec getBindingToNormalized() {
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;
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() {
<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>
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";
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;
* 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();
*/
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;
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;
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
*/
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;
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);
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:
* 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));
}
/**
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);
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);
}
}
}
* unclosed.
*
* @author Robert Varga
+ *
+ * @deprecated Use {@link RegistrationTreeNode} instead.
*/
+@Deprecated
public class ListenerNode implements StoreTreeNode<ListenerNode>, Identifiable<PathArgument> {
final RegistrationTreeNode<DataChangeListenerRegistration<?>> delegate;
* 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.
* exposes the underlying tree structure.
*
* @author Robert Varga
+ *
+ * @deprecated Superseded by {@link RegistrationTreeSnapshot}.
*/
+@Deprecated
public class ListenerWalker implements AutoCloseable {
private final RegistrationTreeSnapshot<DataChangeListenerRegistration<?>> delegate;
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,
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);
}
- 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);
- }
- }
-
}
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;
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;
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();
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;
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;
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";
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,
*/
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;
}
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;
}
@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
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;
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;
}
@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;
}
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;
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 {
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>";
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
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