org.opendaylight.controller.sal.binding.impl.*,
org.opendaylight.controller.sal.binding.codegen,
org.opendaylight.controller.sal.binding.codegen.*,
+ org.opendaylight.controller.md.sal.binding.impl,
<!--org.opendaylight.controller.sal.binding.dom.*,-->
org.opendaylight.controller.sal.binding.osgi.*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.binding.impl.rev131028
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.osgi.framework.BundleContext;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+/**
+*
+*/
+public final class ForwardedCompatibleDataBrokerImplModule extends
+ org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractForwardedCompatibleDataBrokerImplModule
+ implements Provider {
+
+ private BundleContext bundleContext;
+
+ public ForwardedCompatibleDataBrokerImplModule(
+ final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public ForwardedCompatibleDataBrokerImplModule(
+ final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ final ForwardedCompatibleDataBrokerImplModule oldModule, final java.lang.AutoCloseable oldInstance) {
+
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ protected void customValidation() {
+ // Add custom validation for module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ ListeningExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();
+ BindingIndependentMappingService mappingService = getBindingMappingServiceDependency();
+
+ Broker domBroker = getDomAsyncBrokerDependency();
+ ProviderSession session = domBroker.registerProvider(this, getBundleContext());
+ DOMDataBroker domDataBroker = session.getService(DOMDataBroker.class);
+ ForwardedBackwardsCompatibleDataBroker dataBroker = new ForwardedBackwardsCompatibleDataBroker(domDataBroker,
+ mappingService, listeningExecutor);
+
+ session.getService(SchemaService.class).registerSchemaServiceListener(dataBroker);
+
+ dataBroker.setConnector(BindingDomConnectorDeployer.createConnector(getBindingMappingServiceDependency()));
+ dataBroker.setDomProviderContext(session);
+ return dataBroker;
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setBundleContext(final BundleContext bundleContext2) {
+ this.bundleContext = bundleContext2;
+ }
+
+ @Override
+ public void onSessionInitiated(final ProviderSession session) {
+
+ }
+
+ @Override
+ public Collection<ProviderFunctionality> getProviderFunctionality() {
+ return Collections.emptySet();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+
+/**
+*
+*/
+public class ForwardedCompatibleDataBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractForwardedCompatibleDataBrokerImplModuleFactory
+{
+
+
+ @Override
+ public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
+ ForwardedCompatibleDataBrokerImplModule module = (ForwardedCompatibleDataBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+ @Override
+ public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
+ final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
+ ForwardedCompatibleDataBrokerImplModule module = (ForwardedCompatibleDataBrokerImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.opendaylight.controller.md.sal.binding.api.BindingDataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+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.DOMDataChangeListener;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBroker;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBroker>, DomForwardedBroker, SchemaContextListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedDataBroker.class);
+ // The Broker to whom we do all forwarding
+ private final DOMDataBroker domDataBroker;
+
+ // Mapper to convert from Binding Independent objects to Binding Aware
+ // objects
+ private final BindingIndependentMappingService mappingService;
+
+ private final BindingToNormalizedNodeCodec codec;
+ private BindingIndependentConnector connector;
+ private ProviderSession context;
+
+ protected AbstractForwardedDataBroker(final DOMDataBroker domDataBroker,
+ final BindingIndependentMappingService mappingService) {
+ this.domDataBroker = domDataBroker;
+ this.mappingService = mappingService;
+ this.codec = new BindingToNormalizedNodeCodec(mappingService);
+ }
+
+ protected BindingToNormalizedNodeCodec getCodec() {
+ return codec;
+ }
+
+ protected BindingIndependentMappingService getMappingService() {
+ return mappingService;
+ }
+
+ @Override
+ public DOMDataBroker getDelegate() {
+ return domDataBroker;
+ }
+
+ @Override
+ public void onGlobalContextUpdated(final SchemaContext ctx) {
+ codec.onGlobalContextUpdated(ctx);
+ }
+
+ public ListenerRegistration<BindingDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
+ final InstanceIdentifier<?> path, final BindingDataChangeListener listener,
+ final DataChangeScope triggeringScope) {
+ DOMDataChangeListener domDataChangeListener = new TranslatingDataChangeInvoker(store, path, listener,
+ triggeringScope);
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = codec.toNormalized(path);
+ ListenerRegistration<DOMDataChangeListener> domRegistration = domDataBroker.registerDataChangeListener(store, domPath, domDataChangeListener, triggeringScope);
+ return new ListenerRegistrationImpl(listener, domRegistration);
+ }
+
+ protected Map<InstanceIdentifier<?>, DataObject> fromDOMToData(
+ final Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized) {
+ Map<InstanceIdentifier<?>, DataObject> newMap = new HashMap<>();
+ for (Map.Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : normalized
+ .entrySet()) {
+ try {
+ Entry<InstanceIdentifier<? extends DataObject>, DataObject> binding = getCodec().toBinding(entry);
+ newMap.put(binding.getKey(), binding.getValue());
+ } catch (DeserializationException e) {
+ LOG.debug("Ommiting {}",entry,e);
+ }
+ }
+ return newMap;
+ }
+
+ private class TranslatingDataChangeInvoker implements DOMDataChangeListener {
+ private final BindingDataChangeListener bindingDataChangeListener;
+ private final LogicalDatastoreType store;
+ private final InstanceIdentifier<?> path;
+ private final DataChangeScope triggeringScope;
+
+ public TranslatingDataChangeInvoker(final LogicalDatastoreType store, final InstanceIdentifier<?> path,
+ final BindingDataChangeListener bindingDataChangeListener, final DataChangeScope triggeringScope) {
+ this.store = store;
+ this.path = path;
+ this.bindingDataChangeListener = bindingDataChangeListener;
+ this.triggeringScope = triggeringScope;
+ }
+
+ @Override
+ public void onDataChanged(
+ final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> change) {
+ bindingDataChangeListener.onDataChanged(new TranslatedDataChangeEvent(change,path));
+ }
+ }
+
+ private class TranslatedDataChangeEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {
+ private final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> domEvent;
+ private InstanceIdentifier<?> path;
+
+ public TranslatedDataChangeEvent(
+ final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> change) {
+ this.domEvent = change;
+ }
+
+ public TranslatedDataChangeEvent(
+ final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> change,
+ final InstanceIdentifier<?> path) {
+ this.domEvent = change;
+ this.path = path;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
+ return fromDOMToData(domEvent.getCreatedData());
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
+ return fromDOMToData(domEvent.getUpdatedData());
+
+ }
+
+ @Override
+ public Set<InstanceIdentifier<?>> getRemovedPaths() {
+ final Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> removedPaths = domEvent
+ .getRemovedPaths();
+ final Set<InstanceIdentifier<?>> output = new HashSet<>();
+ for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier instanceIdentifier : removedPaths) {
+ try {
+ output.add(mappingService.fromDataDom(instanceIdentifier));
+ } catch (DeserializationException e) {
+ Exceptions.sneakyThrow(e);
+ }
+ }
+
+ return output;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, ? extends DataObject> getOriginalData() {
+ return fromDOMToData(domEvent.getOriginalData());
+
+ }
+
+ @Override
+ public DataObject getOriginalSubtree() {
+
+ return toBindingData(path,domEvent.getOriginalSubtree());
+ }
+
+ @Override
+ public DataObject getUpdatedSubtree() {
+
+ return toBindingData(path,domEvent.getUpdatedSubtree());
+ }
+
+ @Override
+ public String toString() {
+ return "TranslatedDataChangeEvent [domEvent=" + domEvent + "]";
+ }
+ }
+
+ private static class ListenerRegistrationImpl extends AbstractListenerRegistration<BindingDataChangeListener> {
+ private final ListenerRegistration<DOMDataChangeListener> registration;
+
+ public ListenerRegistrationImpl(final BindingDataChangeListener listener,
+ final ListenerRegistration<DOMDataChangeListener> registration) {
+ super(listener);
+ this.registration = registration;
+ }
+
+ @Override
+ protected void removeRegistration() {
+ registration.close();
+ }
+ }
+
+ protected DataObject toBindingData(final InstanceIdentifier<?> path, final NormalizedNode<?, ?> data) {
+ try {
+ return getCodec().toBinding(path, data);
+ } catch (DeserializationException e) {
+ return null;
+ }
+ }
+
+
+ @Override
+ public BindingIndependentConnector getConnector() {
+ return this.connector;
+ }
+
+ @Override
+ public ProviderSession getDomProviderContext() {
+ return this.context;
+ }
+
+ @Override
+ public void setConnector(final BindingIndependentConnector connector) {
+ this.connector = connector;
+ }
+
+ @Override
+ public void setDomProviderContext(final ProviderSession domProviderContext) {
+ this.context = domProviderContext;
+ }
+
+ @Override
+ public void startForwarding() {
+ // NOOP
+ }
+
+
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nullable;
+
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class AbstractForwardedTransaction<T extends AsyncTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>>>
+ implements Delegator<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedTransaction.class);
+ private final T delegate;
+ private final static CacheBuilder<Object, Object> CACHE_BUILDER = CacheBuilder.newBuilder()
+ .expireAfterWrite(10, TimeUnit.MILLISECONDS).maximumSize(100);
+ private final BindingToNormalizedNodeCodec codec;
+ private final EnumMap<LogicalDatastoreType, Cache<InstanceIdentifier<?>, DataObject>> cacheMap;
+
+ protected AbstractForwardedTransaction(final T delegate, final BindingToNormalizedNodeCodec codec) {
+ super();
+ this.delegate = delegate;
+ this.codec = codec;
+
+ this.cacheMap = new EnumMap<>(LogicalDatastoreType.class);
+ cacheMap.put(LogicalDatastoreType.OPERATIONAL, CACHE_BUILDER.<InstanceIdentifier<?>, DataObject> build());
+ cacheMap.put(LogicalDatastoreType.CONFIGURATION, CACHE_BUILDER.<InstanceIdentifier<?>, DataObject> build());
+
+ }
+
+ @Override
+ public T getDelegate() {
+ return delegate;
+ }
+
+ protected final BindingToNormalizedNodeCodec getCodec() {
+ return codec;
+ }
+
+ protected ListenableFuture<Optional<DataObject>> transformFuture(final LogicalDatastoreType store,
+ final InstanceIdentifier<?> path, final ListenableFuture<Optional<NormalizedNode<?, ?>>> future) {
+ return Futures.transform(future, new Function<Optional<NormalizedNode<?, ?>>, Optional<DataObject>>() {
+ @Nullable
+ @Override
+ public Optional<DataObject> apply(@Nullable final Optional<NormalizedNode<?, ?>> normalizedNode) {
+ try {
+ final DataObject dataObject = normalizedNode.isPresent() ? codec.toBinding(path,
+ normalizedNode.get()) : null;
+ if(dataObject != null) {
+ updateCache(store, path, dataObject);
+ }
+ return Optional.fromNullable(dataObject);
+ } catch (DeserializationException e) {
+ Exceptions.sneakyThrow(e);
+ }
+ return null;
+ }
+ });
+ }
+
+ protected void doPut(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
+ final InstanceIdentifier<?> path, final DataObject data) {
+ invalidateCache(store, path);
+ final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
+ .toNormalizedNode(path, data);
+ writeTransaction.put(store, normalized.getKey(), normalized.getValue());
+ }
+
+ protected void doPutWithEnsureParents(final DOMDataReadWriteTransaction writeTransaction,
+ final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
+ invalidateCache(store, path);
+ final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
+ .toNormalizedNode(path, data);
+
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+ try {
+ List<PathArgument> currentArguments = new ArrayList<>();
+ DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
+ Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
+ while (iterator.hasNext()) {
+ PathArgument currentArg = iterator.next();
+ currentOp = currentOp.getChild(currentArg);
+ currentArguments.add(currentArg);
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier currentPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
+ currentArguments);
+ boolean isPresent = writeTransaction.read(store, currentPath).get().isPresent();
+ if (isPresent == false && iterator.hasNext()) {
+ writeTransaction.put(store, currentPath, currentOp.createDefault(currentArg));
+ }
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ //LOG .info("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
+ writeTransaction.put(store, normalized.getKey(), normalized.getValue());
+
+ }
+
+ protected void doMerge(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
+ final InstanceIdentifier<?> path, final DataObject data) {
+ invalidateCache(store, path);
+ final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
+ .toNormalizedNode(path, data);
+ writeTransaction.merge(store, normalized.getKey(), normalized.getValue());
+ }
+
+ protected void doDelete(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
+ final InstanceIdentifier<?> path) {
+ invalidateCache(store, path);
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized = codec.toNormalized(path);
+ writeTransaction.delete(store, normalized);
+ }
+
+ protected ListenableFuture<RpcResult<TransactionStatus>> doCommit(final DOMDataWriteTransaction writeTransaction) {
+ return writeTransaction.commit();
+ }
+
+ protected void doCancel(final DOMDataWriteTransaction writeTransaction) {
+ writeTransaction.cancel();
+ }
+
+ protected ListenableFuture<Optional<DataObject>> doRead(final DOMDataReadTransaction readTransaction,
+ final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
+ final DataObject dataObject = getFromCache(store, path);
+ if (dataObject == null) {
+ final ListenableFuture<Optional<NormalizedNode<?, ?>>> future = readTransaction.read(store,
+ codec.toNormalized(path));
+ return transformFuture(store, path, future);
+ } else {
+ return Futures.immediateFuture(Optional.of(dataObject));
+ }
+ }
+
+ private DataObject getFromCache(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
+ Cache<InstanceIdentifier<?>, DataObject> cache = cacheMap.get(store);
+ if (cache != null) {
+ return cache.getIfPresent(path);
+ }
+ return null;
+ }
+
+ private void updateCache(final LogicalDatastoreType store, final InstanceIdentifier<?> path,
+ final DataObject dataObject) {
+ // Check if cache exists. If not create one.
+ Cache<InstanceIdentifier<?>, DataObject> cache = cacheMap.get(store);
+ if (cache == null) {
+ cache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(1, TimeUnit.MINUTES).build();
+
+ }
+
+ cache.put(path, dataObject);
+ }
+
+ private void invalidateCache(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
+ // FIXME: Optimization: invalidate only parents and children of path
+ Cache<InstanceIdentifier<?>, DataObject> cache = cacheMap.get(store);
+ cache.invalidateAll();
+ LOG.trace("Cache invalidated");
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+public class BindingToNormalizedNodeCodec implements SchemaContextListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BindingToNormalizedNodeCodec.class);
+
+ private final BindingIndependentMappingService bindingToLegacy;
+ private DataNormalizer legacyToNormalized;
+
+ public BindingToNormalizedNodeCodec(final BindingIndependentMappingService mappingService) {
+ super();
+ this.bindingToLegacy = mappingService;
+ }
+
+ public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toNormalized(
+ final InstanceIdentifier<? extends DataObject> binding) {
+ return legacyToNormalized.toNormalized(bindingToLegacy.toDataDom(binding));
+ }
+
+ public Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
+ final InstanceIdentifier<? extends DataObject> bindingPath, final DataObject bindingObject) {
+ return toNormalizedNode(toEntry(bindingPath, bindingObject));
+
+ }
+
+ public Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
+ final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> binding) {
+ Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalizedEntry = legacyToNormalized.toNormalized(bindingToLegacy.toDataDom(binding));
+ if(Augmentation.class.isAssignableFrom(binding.getKey().getTargetType())) {
+
+ for(DataContainerChild<? extends PathArgument, ?> child : ((DataContainerNode<?>) normalizedEntry.getValue()).getValue()) {
+ if(child instanceof AugmentationNode) {
+ ImmutableList<PathArgument> childArgs = ImmutableList.<PathArgument>builder()
+ .addAll(normalizedEntry.getKey().getPath())
+ .add(child.getIdentifier())
+ .build();
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(childArgs);
+ return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>>(childPath,child);
+ }
+ }
+
+ }
+ return normalizedEntry;
+
+
+ }
+
+ public InstanceIdentifier<? extends DataObject> toBinding(
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
+ throws DeserializationException {
+
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier legacyPath = legacyToNormalized
+ .toLegacy(normalized);
+ return bindingToLegacy.fromDataDom(legacyPath);
+ }
+
+ private static final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toEntry(
+ final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> key,
+ final DataObject value) {
+ return new SimpleEntry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>(
+ key, value);
+ }
+
+ public DataObject toBinding(final InstanceIdentifier<?> path, final NormalizedNode<?, ?> normalizedNode)
+ throws DeserializationException {
+ return bindingToLegacy.dataObjectFromDataDom(path, (CompositeNode) DataNormalizer.toLegacy(normalizedNode));
+ }
+
+ public DataNormalizer getDataNormalizer() {
+ return legacyToNormalized;
+ }
+
+ public Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toBinding(
+ final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized)
+ throws DeserializationException {
+ InstanceIdentifier<? extends DataObject> bindingPath = toBinding(normalized.getKey());
+ DataObject bindingData = toBinding(bindingPath, normalized.getValue());
+ return toEntry(bindingPath, bindingData);
+ }
+
+ @Override
+ public void onGlobalContextUpdated(final SchemaContext arg0) {
+ legacyToNormalized = new DataNormalizer(arg0);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.BindingDataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+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.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDataBroker implements DataProviderService, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ForwardedBackwardsCompatibleDataBroker.class);
+
+ private final ConcurrentHashMap<InstanceIdentifier<?>, CommitHandlerRegistrationImpl> commitHandlers = new ConcurrentHashMap<>();
+ private final ListenerRegistry<DataChangeListener> fakeRegistry = ListenerRegistry.create();
+ private final ListeningExecutorService executorService;
+
+ public ForwardedBackwardsCompatibleDataBroker(final DOMDataBroker domDataBroker,
+ final BindingIndependentMappingService mappingService, final ListeningExecutorService executor) {
+ super(domDataBroker, mappingService);
+ executorService = executor;
+ LOG.info("ForwardedBackwardsCompatibleBroker started.");
+ }
+
+ @Override
+ public DataModificationTransaction beginTransaction() {
+ return new ForwardedBackwardsCompatibleTransacion(getDelegate().newReadWriteTransaction(), getCodec());
+ }
+
+ @Override
+ public DataObject readConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
+ DataModificationTransaction tx = beginTransaction();
+ return tx.readConfigurationData(path);
+ }
+
+ @Override
+ public DataObject readOperationalData(final InstanceIdentifier<? extends DataObject> path) {
+ DataModificationTransaction tx = beginTransaction();
+ return tx.readOperationalData(path);
+ }
+
+ @Override
+ public Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> registerCommitHandler(
+ final InstanceIdentifier<? extends DataObject> path,
+ final DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
+
+
+ //transformingCommitHandler = new TransformingDataChangeListener
+ //fakeCommitHandler = registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, listener, DataChangeScope.SUBTREE);
+
+ CommitHandlerRegistrationImpl reg = new CommitHandlerRegistrationImpl(path, commitHandler);
+ commitHandlers.put(path, reg);
+ return reg;
+ }
+
+ @Override
+ @Deprecated
+ public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>>> registerCommitHandlerListener(
+ final RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>> commitHandlerListener) {
+ throw new UnsupportedOperationException("Not supported contract.");
+ }
+
+ @Override
+ public ListenerRegistration<DataChangeListener> registerDataChangeListener(
+ final InstanceIdentifier<? extends DataObject> path, final DataChangeListener listener) {
+
+
+ BindingDataChangeListener asyncOperListener = new BackwardsCompatibleOperationalDataChangeInvoker(listener);
+ BindingDataChangeListener asyncCfgListener = new BackwardsCompatibleConfigurationDataChangeInvoker(listener);
+
+ ListenerRegistration<BindingDataChangeListener> cfgReg = registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, asyncCfgListener, DataChangeScope.SUBTREE);
+ ListenerRegistration<BindingDataChangeListener> operReg = registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, path, asyncOperListener, DataChangeScope.SUBTREE);
+
+ return new LegacyListenerRegistration(listener,cfgReg,operReg);
+ }
+
+ @Override
+ public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerDataReader(
+ final InstanceIdentifier<? extends DataObject> path,
+ final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
+ throw new UnsupportedOperationException("Data reader contract is not supported.");
+ }
+
+ @Override
+ public void close() throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+
+ public ListenableFuture<RpcResult<TransactionStatus>> commit(final ForwardedBackwardsCompatibleTransacion tx) {
+
+ final List<DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject>> subTrans = new ArrayList<>();
+ LOG.debug("Tx: {} Submitted.",tx.getIdentifier());
+ ListenableFuture<Boolean> requestCommit = executorService.submit(new Callable<Boolean>() {
+
+ @Override
+ public Boolean call() throws Exception {
+ try {
+ for (CommitHandlerRegistrationImpl handler : commitHandlers.values()) {
+
+ DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> subTx = handler
+ .getInstance().requestCommit(tx);
+ subTrans.add(subTx);
+ }
+ } catch (Exception e) {
+ LOG.error("Tx: {} Rollback.",tx.getIdentifier(),e);
+ for (DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> subTx : subTrans) {
+ subTx.rollback();
+ }
+ return false;
+ }
+ LOG.debug("Tx: {} Can Commit True.",tx.getIdentifier());
+ return true;
+ }
+
+ });
+
+ ListenableFuture<RpcResult<TransactionStatus>> dataStoreCommit = Futures.transform(requestCommit, new AsyncFunction<Boolean, RpcResult<TransactionStatus>>() {
+
+ @Override
+ public ListenableFuture<RpcResult<TransactionStatus>> apply(final Boolean requestCommitSuccess) throws Exception {
+ if(requestCommitSuccess) {
+ return tx.getDelegate().commit();
+ }
+ return Futures.immediateFuture(Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.<RpcError>emptySet()));
+ }
+ });
+
+ return Futures.transform(dataStoreCommit, new Function<RpcResult<TransactionStatus>,RpcResult<TransactionStatus>>() {
+ @Override
+ public RpcResult<TransactionStatus> apply(final RpcResult<TransactionStatus> input) {
+ if(input.isSuccessful()) {
+ for(DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> subTx : subTrans ) {
+ subTx.finish();
+ }
+ } else {
+ LOG.error("Tx: {} Rollback - Datastore commit failed.",tx.getIdentifier());
+ for(DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> subTx : subTrans ) {
+ subTx.rollback();
+ }
+ }
+ return input;
+ }
+ });
+ }
+
+ private class ForwardedBackwardsCompatibleTransacion extends
+ AbstractForwardedTransaction<DOMDataReadWriteTransaction> implements DataModificationTransaction {
+
+ private final Map<InstanceIdentifier<? extends DataObject>, DataObject> updated = new HashMap<>();
+ private final Map<InstanceIdentifier<? extends DataObject>, DataObject> created = new HashMap<>();
+ private final Set<InstanceIdentifier<? extends DataObject>> removed = new HashSet<>();
+ private final Map<InstanceIdentifier<? extends DataObject>, DataObject> original = new HashMap<>();
+ private TransactionStatus status = TransactionStatus.NEW;
+
+ @Override
+ public final TransactionStatus getStatus() {
+ return status;
+ }
+
+ protected ForwardedBackwardsCompatibleTransacion(final DOMDataReadWriteTransaction delegate,
+ final BindingToNormalizedNodeCodec codec) {
+ super(delegate, codec);
+ LOG.debug("Tx {} allocated.",getIdentifier());
+ }
+
+ @Override
+ public void putOperationalData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
+
+ doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+ }
+
+ @Override
+ public void putConfigurationData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
+ DataObject originalObj = readConfigurationData(path);
+ if (originalObj != null) {
+ original.put(path, originalObj);
+
+ } else {
+ created.put(path, data);
+ }
+ updated.put(path, data);
+ doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+ }
+
+ @Override
+ public void removeOperationalData(final InstanceIdentifier<? extends DataObject> path) {
+ doDelete(getDelegate(), LogicalDatastoreType.OPERATIONAL, path);
+
+ }
+
+ @Override
+ public void removeConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
+ doDelete(getDelegate(), LogicalDatastoreType.CONFIGURATION, path);
+ }
+
+ @Override
+ public Map<InstanceIdentifier<? extends DataObject>, DataObject> getCreatedOperationalData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<? extends DataObject>, DataObject> getCreatedConfigurationData() {
+ return created;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<? extends DataObject>, DataObject> getUpdatedOperationalData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<? extends DataObject>, DataObject> getUpdatedConfigurationData() {
+ return updated;
+ }
+
+ @Override
+ public Set<InstanceIdentifier<? extends DataObject>> getRemovedConfigurationData() {
+ return removed;
+ }
+
+ @Override
+ public Set<InstanceIdentifier<? extends DataObject>> getRemovedOperationalData() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<? extends DataObject>, DataObject> getOriginalConfigurationData() {
+ return original;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<? extends DataObject>, DataObject> getOriginalOperationalData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public DataObject readOperationalData(final InstanceIdentifier<? extends DataObject> path) {
+ try {
+ return doRead(getDelegate(), LogicalDatastoreType.OPERATIONAL, path).get().orNull();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Read of {} failed.", path,e);
+ return null;
+ }
+ }
+
+ @Override
+ public DataObject readConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
+ try {
+ return doRead(getDelegate(), LogicalDatastoreType.CONFIGURATION, path).get().orNull();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Read of {} failed.", path,e);
+ return null;
+ }
+ }
+
+ @Override
+ public Object getIdentifier() {
+ return getDelegate().getIdentifier();
+ }
+
+ private void changeStatus(TransactionStatus status) {
+ LOG.trace("Transaction {} changed status to {}", getIdentifier(), status);
+ this.status = status;
+ }
+
+ @Override
+ public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+ final ListenableFuture<RpcResult<TransactionStatus>> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this);
+
+ changeStatus(TransactionStatus.SUBMITED);
+
+ Futures.addCallback(f, new FutureCallback<RpcResult<TransactionStatus>>() {
+ @Override
+ public void onSuccess(RpcResult<TransactionStatus> result) {
+ changeStatus(result.getResult());
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ LOG.error("Transaction {} failed to complete", getIdentifier(), t);
+ changeStatus(TransactionStatus.FAILED);
+ }
+ });
+
+ return f;
+ }
+
+ @Override
+ public ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+ private class CommitHandlerRegistrationImpl extends
+ AbstractObjectRegistration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> {
+
+ private final InstanceIdentifier<? extends DataObject> path;
+
+ public CommitHandlerRegistrationImpl(final InstanceIdentifier<? extends DataObject> path,
+ final DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
+ super(commitHandler);
+ this.path = path;
+ }
+
+ @Override
+ protected void removeRegistration() {
+ commitHandlers.remove(path, this);
+ }
+
+ }
+
+
+ private static final class LegacyListenerRegistration implements ListenerRegistration<DataChangeListener> {
+
+ private final DataChangeListener instance;
+ private final ListenerRegistration<BindingDataChangeListener> cfgReg;
+ private final ListenerRegistration<BindingDataChangeListener> operReg;
+
+ public LegacyListenerRegistration(final DataChangeListener listener,
+ final ListenerRegistration<BindingDataChangeListener> cfgReg,
+ final ListenerRegistration<BindingDataChangeListener> operReg) {
+ this.instance = listener;
+ this.cfgReg = cfgReg;
+ this.operReg = operReg;
+ }
+
+ @Override
+ public DataChangeListener getInstance() {
+ return instance;
+ }
+
+ @Override
+ public void close() {
+ cfgReg.close();
+ operReg.close();
+ }
+
+ }
+
+ private static class BackwardsCompatibleOperationalDataChangeInvoker implements BindingDataChangeListener, Delegator<DataChangeListener> {
+
+ private final org.opendaylight.controller.md.sal.common.api.data.DataChangeListener<?,?> delegate;
+
+
+ public BackwardsCompatibleOperationalDataChangeInvoker(final DataChangeListener listener) {
+ this.delegate = listener;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+
+ DataChangeEvent legacyChange = LegacyDataChangeEvent.createOperational(change);
+ delegate.onDataChanged(legacyChange);
+
+ }
+
+ @Override
+ public DataChangeListener getDelegate() {
+ return (DataChangeListener) delegate;
+ }
+
+ }
+
+ private static class BackwardsCompatibleConfigurationDataChangeInvoker implements BindingDataChangeListener, Delegator<DataChangeListener> {
+
+
+ @SuppressWarnings("rawtypes")
+ private final org.opendaylight.controller.md.sal.common.api.data.DataChangeListener<?,?> delegate;
+
+ public BackwardsCompatibleConfigurationDataChangeInvoker(final DataChangeListener listener) {
+ this.delegate = listener;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+
+ DataChangeEvent legacyChange = LegacyDataChangeEvent.createConfiguration(change);
+
+ delegate.onDataChanged(legacyChange);
+
+ }
+
+ @Override
+ public DataChangeListener getDelegate() {
+ return (DataChangeListener) delegate;
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import org.opendaylight.controller.md.sal.binding.api.BindingDataBroker;
+import org.opendaylight.controller.md.sal.binding.api.BindingDataReadTransaction;
+import org.opendaylight.controller.md.sal.binding.api.BindingDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.BindingDataWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
+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.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * The DataBrokerImpl simply defers to the DOMDataBroker for all its operations.
+ * All transactions and listener registrations are wrapped by the DataBrokerImpl
+ * to allow binding aware components to use the DataBroker transparently.
+ *
+ * Besides this the DataBrokerImpl and it's collaborators also cache data that
+ * is already transformed from the binding independent to binding aware format
+ *
+ * TODO : All references in this class to CompositeNode should be switched to
+ * NormalizedNode once the MappingService is updated
+ *
+ */
+public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker implements BindingDataBroker {
+
+ public ForwardedBindingDataBroker(final DOMDataBroker domDataBroker, final BindingIndependentMappingService mappingService) {
+ super(domDataBroker, mappingService);
+ }
+
+ @Override
+ public BindingDataReadTransaction newReadOnlyTransaction() {
+ return new BindingDataReadTransactionImpl(getDelegate().newReadOnlyTransaction(),getCodec());
+ }
+
+ @Override
+ public BindingDataReadWriteTransaction newReadWriteTransaction() {
+ return new BindingDataReadWriteTransactionImpl(getDelegate().newReadWriteTransaction(),getCodec());
+ }
+
+ @Override
+ public BindingDataWriteTransaction newWriteOnlyTransaction() {
+ return new BindingDataWriteTransactionImpl<DOMDataWriteTransaction>(getDelegate().newWriteOnlyTransaction(),getCodec());
+ }
+
+ private abstract class AbstractBindingTransaction<T extends AsyncTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>>>
+ extends AbstractForwardedTransaction<T> implements AsyncTransaction<InstanceIdentifier<?>, DataObject> {
+
+ protected AbstractBindingTransaction(final T delegate, final BindingToNormalizedNodeCodec codec) {
+ super(delegate, codec);
+ }
+
+ @Override
+ public Object getIdentifier() {
+ return getDelegate().getIdentifier();
+ }
+
+ @Override
+ public void close() {
+ getDelegate().close();
+ }
+
+ }
+
+ private class BindingDataReadTransactionImpl extends AbstractBindingTransaction<DOMDataReadTransaction> implements
+ BindingDataReadTransaction {
+
+ protected BindingDataReadTransactionImpl(final DOMDataReadTransaction delegate,
+ final BindingToNormalizedNodeCodec codec) {
+ super(delegate, codec);
+ }
+
+ @Override
+ public ListenableFuture<Optional<DataObject>> read(final LogicalDatastoreType store,
+ final InstanceIdentifier<?> path) {
+ return doRead(getDelegate(), store, path);
+ }
+ }
+
+ private class BindingDataWriteTransactionImpl<T extends DOMDataWriteTransaction> extends
+ AbstractBindingTransaction<T> implements BindingDataWriteTransaction {
+
+ protected BindingDataWriteTransactionImpl(final T delegate, final BindingToNormalizedNodeCodec codec) {
+ super(delegate, codec);
+
+ }
+
+ @Override
+ public void cancel() {
+ doCancel(getDelegate());
+ }
+
+ @Override
+ public void put(final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
+ doPut(getDelegate(), store, path, data);
+ }
+
+ @Override
+ public void merge(final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
+ doMerge(getDelegate(), store, path, data);
+ }
+
+ @Override
+ public void delete(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
+ doDelete(getDelegate(), store, path);
+ }
+
+ @Override
+ public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+ return doCommit(getDelegate());
+ }
+ }
+
+ private class BindingDataReadWriteTransactionImpl extends
+ BindingDataWriteTransactionImpl<DOMDataReadWriteTransaction> implements BindingDataReadWriteTransaction {
+
+ protected BindingDataReadWriteTransactionImpl(final DOMDataReadWriteTransaction delegate,
+ final BindingToNormalizedNodeCodec codec) {
+ super(delegate, codec);
+ }
+
+ @Override
+ public ListenableFuture<Optional<DataObject>> read(final LogicalDatastoreType store,
+ final InstanceIdentifier<?> path) {
+ return doRead(getDelegate(), store, path);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public abstract class LegacyDataChangeEvent implements
+ DataChangeEvent<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+ private LegacyDataChangeEvent() {
+ }
+
+ public static final DataChangeEvent<InstanceIdentifier<?>, DataObject> createOperational(
+ final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ return new OperationalChangeEvent(change);
+ }
+
+ public static final DataChangeEvent<InstanceIdentifier<?>, DataObject> createConfiguration(
+ final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ return new ConfigurationChangeEvent(change);
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getCreatedOperationalData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getCreatedConfigurationData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getUpdatedOperationalData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getUpdatedConfigurationData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Set<InstanceIdentifier<?>> getRemovedConfigurationData() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<InstanceIdentifier<?>> getRemovedOperationalData() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getOriginalConfigurationData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getOriginalOperationalData() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public DataObject getOriginalConfigurationSubtree() {
+ return null;
+ }
+
+ @Override
+ public DataObject getOriginalOperationalSubtree() {
+ return null;
+ }
+
+ @Override
+ public DataObject getUpdatedConfigurationSubtree() {
+ return null;
+ }
+
+ @Override
+ public DataObject getUpdatedOperationalSubtree() {
+ return null;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private final static class OperationalChangeEvent extends LegacyDataChangeEvent {
+
+ private final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> delegate;
+
+ public OperationalChangeEvent(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ this.delegate = change;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getCreatedOperationalData() {
+ return delegate.getCreatedData();
+ }
+
+ @Override
+ public Set<InstanceIdentifier<?>> getRemovedOperationalData() {
+ return delegate.getRemovedPaths();
+ }
+
+ @Override
+ public DataObject getOriginalOperationalSubtree() {
+ return delegate.getOriginalSubtree();
+ }
+
+ @Override
+ public DataObject getUpdatedOperationalSubtree() {
+ return delegate.getUpdatedSubtree();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getOriginalOperationalData() {
+ return (Map) delegate.getOriginalData();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getUpdatedOperationalData() {
+ return delegate.getUpdatedData();
+ }
+
+ @Override
+ public String toString() {
+ return "OperationalChangeEvent [delegate=" + delegate + "]";
+ }
+
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private final static class ConfigurationChangeEvent extends LegacyDataChangeEvent {
+
+ private final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> delegate;
+
+ public ConfigurationChangeEvent(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ this.delegate = change;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getCreatedConfigurationData() {
+ return delegate.getCreatedData();
+ }
+
+ @Override
+ public Set<InstanceIdentifier<?>> getRemovedConfigurationData() {
+ return delegate.getRemovedPaths();
+ }
+
+ @Override
+ public DataObject getOriginalConfigurationSubtree() {
+ return delegate.getOriginalSubtree();
+ }
+
+ @Override
+ public DataObject getUpdatedConfigurationSubtree() {
+ return delegate.getUpdatedSubtree();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getOriginalConfigurationData() {
+ return (Map) delegate.getOriginalData();
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getUpdatedConfigurationData() {
+ return delegate.getUpdatedData();
+ }
+
+ @Override
+ public String toString() {
+ return "ConfigurationChangeEvent [delegate=" + delegate + "]";
+ }
+
+ }
+
+}
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
+import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker;
import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
private final Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> toDOMInstanceIdentifier = new Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier>() {
@Override
- public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier apply(InstanceIdentifier<?> input) {
+ public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier apply(final InstanceIdentifier<?> input) {
return mappingService.toDataDom(input);
}
}
@Override
- public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+ public DataObject readOperationalData(final InstanceIdentifier<? extends DataObject> path) {
try {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
CompositeNode result = biDataService.readOperationalData(biPath);
}
private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path,
- org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result)
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, final CompositeNode result)
throws DeserializationException {
Class<? extends DataObject> targetType = path.getTargetType();
if (Augmentation.class.isAssignableFrom(targetType)) {
}
@Override
- public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+ public DataObject readConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
try {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
CompositeNode result = biDataService.readConfigurationData(biPath);
}
private DataModificationTransaction createBindingToDomTransaction(
- DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
+ final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
DataModificationTransaction target = biDataService.beginTransaction();
LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(),source.getIdentifier());
for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
}
private org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction createDomToBindingTransaction(
- DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> source) {
+ final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> source) {
org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService
.beginTransaction();
for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
return biDataService;
}
- protected void setDomDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
+ protected void setDomDataService(final org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
this.biDataService = biDataService;
}
return baDataService;
}
- protected void setBindingDataService(DataProviderService baDataService) {
+ protected void setBindingDataService(final DataProviderService baDataService) {
this.baDataService = baDataService;
}
return baRpcRegistry;
}
- protected void setBindingRpcRegistry(RpcProviderRegistry rpcRegistry) {
+ protected void setBindingRpcRegistry(final RpcProviderRegistry rpcRegistry) {
this.baRpcRegistry = rpcRegistry;
}
public void startDataForwarding() {
+ if(baDataService instanceof AbstractForwardedDataBroker) {
+ dataForwarding = true;
+ return;
+ }
checkState(!dataForwarding, "Connector is already forwarding data.");
baDataReaderRegistration = baDataService.registerDataReader(ROOT, this);
baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler);
}
}
- protected void setMappingService(BindingIndependentMappingService mappingService) {
+ protected void setMappingService(final BindingIndependentMappingService mappingService) {
this.mappingService = mappingService;
}
}
@Override
- public void onSessionInitiated(ProviderSession session) {
+ public void onSessionInitiated(final ProviderSession session) {
setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
setDomRpcRegistry(session.getService(RpcProvisionRegistry.class));
}
- public <T extends RpcService> void onRpcRouterCreated(Class<T> serviceType, RpcRouter<T> router) {
+ public <T extends RpcService> void onRpcRouterCreated(final Class<T> serviceType, final RpcRouter<T> router) {
}
- public void setDomRpcRegistry(RpcProvisionRegistry registry) {
+ public void setDomRpcRegistry(final RpcProvisionRegistry registry) {
biRpcRegistry = registry;
}
private final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification;
public DomToBindingTransaction(
- org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing,
- DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification) {
+ final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing,
+ final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification) {
super();
this.backing = backing;
this.modification = modification;
private final DataModificationTransaction backing;
private final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
- public BindingToDomTransaction(DataModificationTransaction backing,
- DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+ public BindingToDomTransaction(final DataModificationTransaction backing,
+ final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
this.backing = backing;
this.modification = modification;
domOpenedTransactions.put(backing.getIdentifier(), this);
@Override
public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
- DataModification<InstanceIdentifier<? extends DataObject>, DataObject> bindingTransaction) {
+ final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> bindingTransaction) {
/**
* Transaction was created as DOM transaction, in that case we do
DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
@Override
- public void onRegister(DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
+ public void onRegister(final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration
.getPath());
}
@Override
- public void onUnregister(DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
+ public void onUnregister(final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
// NOOP for now
// FIXME: do registration based on only active commit handlers.
}
@Override
public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> requestCommit(
- DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> domTransaction) {
+ final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> domTransaction) {
Object identifier = domTransaction.getIdentifier();
/**
return registryImpl;
}
- public void setRegistryImpl(RpcProviderRegistryImpl registryImpl) {
+ public void setRegistryImpl(final RpcProviderRegistryImpl registryImpl) {
this.registryImpl = registryImpl;
}
@Override
- public void onGlobalRpcRegistered(Class<? extends RpcService> cls) {
+ public void onGlobalRpcRegistered(final Class<? extends RpcService> cls) {
getRpcForwarder(cls, null);
}
@Override
- public void onGlobalRpcUnregistered(Class<? extends RpcService> cls) {
+ public void onGlobalRpcUnregistered(final Class<? extends RpcService> cls) {
// NOOP
}
@Override
- public void onRpcRouterCreated(RpcRouter<?> router) {
+ public void onRpcRouterCreated(final RpcRouter<?> router) {
Class<? extends BaseIdentity> ctx = router.getContexts().iterator().next();
getRpcForwarder(router.getServiceType(), ctx);
}
@Override
- public void onRouteChange(RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
+ public void onRouteChange(final RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
for (Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry : change.getAnnouncements().entrySet()) {
bindingRoutesAdded(entry);
}
}
- private void bindingRoutesAdded(Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry) {
+ private void bindingRoutesAdded(final Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry) {
Class<? extends BaseIdentity> context = entry.getKey().getRoutingContext();
Class<? extends RpcService> service = entry.getKey().getRpcService();
if (context != null) {
}
}
- private DomToBindingRpcForwarder getRpcForwarder(Class<? extends RpcService> service,
- Class<? extends BaseIdentity> context) {
+ private DomToBindingRpcForwarder getRpcForwarder(final Class<? extends RpcService> service,
+ final Class<? extends BaseIdentity> context) {
DomToBindingRpcForwarder potential = forwarders.get(service);
if (potential != null) {
return potential;
private final Map<QName, RpcInvocationStrategy> strategiesByQName = new HashMap<>();
private final WeakHashMap<Method, RpcInvocationStrategy> strategiesByMethod = new WeakHashMap<>();
- public DomToBindingRpcForwarder(Class<? extends RpcService> service) {
+ public DomToBindingRpcForwarder(final Class<? extends RpcService> service) {
this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
this.supportedRpcs = mappingService.getRpcQNamesFor(service);
try {
* @param service
* @param context
*/
- public DomToBindingRpcForwarder(Class<? extends RpcService> service, Class<? extends BaseIdentity> context) {
+ public DomToBindingRpcForwarder(final Class<? extends RpcService> service, final Class<? extends BaseIdentity> context) {
this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
this.supportedRpcs = mappingService.getRpcQNamesFor(service);
Builder<RoutedRpcRegistration> registrationsBuilder = ImmutableSet
registrations = registrationsBuilder.build();
}
- public void registerPaths(Class<? extends BaseIdentity> context, Class<? extends RpcService> service,
- Set<InstanceIdentifier<?>> set) {
+ public void registerPaths(final Class<? extends BaseIdentity> context, final Class<? extends RpcService> service,
+ final Set<InstanceIdentifier<?>> set) {
QName ctx = BindingReflections.findQName(context);
for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform(
toDOMInstanceIdentifier)) {
@Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if (EQUALS_METHOD.equals(method)) {
return false;
}
return strategy.forwardToDomBroker(null);
}
- public void removePaths(Class<? extends BaseIdentity> context, Class<? extends RpcService> service,
- Set<InstanceIdentifier<?>> set) {
+ public void removePaths(final Class<? extends BaseIdentity> context, final Class<? extends RpcService> service,
+ final Set<InstanceIdentifier<?>> set) {
QName ctx = BindingReflections.findQName(context);
for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform(
toDOMInstanceIdentifier)) {
}
@Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode domInput) {
+ public RpcResult<CompositeNode> invokeRpc(final QName rpc, final CompositeNode domInput) {
checkArgument(rpc != null);
checkArgument(domInput != null);
}
}
- private RpcInvocationStrategy resolveInvocationStrategy(QName rpc) {
+ private RpcInvocationStrategy resolveInvocationStrategy(final QName rpc) {
return strategiesByQName.get(rpc);
}
protected final Method targetMethod;
protected final QName rpc;
- public RpcInvocationStrategy(QName rpc, Method targetMethod) {
+ public RpcInvocationStrategy(final QName rpc, final Method targetMethod) {
this.targetMethod = targetMethod;
this.rpc = rpc;
}
public abstract RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput)
throws Exception;
- public RpcResult<CompositeNode> invokeOn(RpcService rpcService, CompositeNode domInput) throws Exception {
+ public RpcResult<CompositeNode> invokeOn(final RpcService rpcService, final CompositeNode domInput) throws Exception {
return uncheckedInvoke(rpcService, domInput);
}
}
private final WeakReference<Class> outputClass;
@SuppressWarnings({ "rawtypes", "unchecked" })
- public DefaultInvocationStrategy(QName rpc, Method targetMethod, Class<?> outputClass,
- Class<? extends DataContainer> inputClass) {
+ public DefaultInvocationStrategy(final QName rpc, final Method targetMethod, final Class<?> outputClass,
+ final Class<? extends DataContainer> inputClass) {
super(rpc, targetMethod);
this.outputClass = new WeakReference(outputClass);
this.inputClass = new WeakReference(inputClass);
@SuppressWarnings("unchecked")
@Override
- public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
+ public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception {
DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
Future<RpcResult<?>> futureResult = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
if (futureResult == null) {
}
@Override
- public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
+ public Future<RpcResult<?>> forwardToDomBroker(final DataObject input) {
if(biRpcRegistry != null) {
CompositeNode xml = mappingService.toDataDom(input);
CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy {
- public NoInputNoOutputInvocationStrategy(QName rpc, Method targetMethod) {
+ public NoInputNoOutputInvocationStrategy(final QName rpc, final Method targetMethod) {
super(rpc, targetMethod);
}
@Override
- public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
+ public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception {
@SuppressWarnings("unchecked")
Future<RpcResult<Void>> result = (Future<RpcResult<Void>>) targetMethod.invoke(rpcService);
RpcResult<Void> bindingResult = result.get();
}
@Override
- public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
+ public Future<RpcResult<?>> forwardToDomBroker(final DataObject input) {
return Futures.immediateFuture(null);
}
}
private final WeakReference<Class> inputClass;
@SuppressWarnings({ "rawtypes", "unchecked" })
- public NoOutputInvocationStrategy(QName rpc, Method targetMethod,
- Class<? extends DataContainer> inputClass) {
+ public NoOutputInvocationStrategy(final QName rpc, final Method targetMethod,
+ final Class<? extends DataContainer> inputClass) {
super(rpc,targetMethod);
this.inputClass = new WeakReference(inputClass);
}
@Override
- public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
+ public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception {
DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
Future<RpcResult<?>> result = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
if (result == null) {
}
@Override
- public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
+ public Future<RpcResult<?>> forwardToDomBroker(final DataObject input) {
if(biRpcRegistry != null) {
CompositeNode xml = mappingService.toDataDom(input);
CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
return mappingService;
}
- public void setBindingNotificationService(NotificationProviderService baService) {
+ public void setBindingNotificationService(final NotificationProviderService baService) {
this.baNotifyService = baService;
}
- public void setDomNotificationService(NotificationPublishService domService) {
+ public void setDomNotificationService(final NotificationPublishService domService) {
this.domNotificationService = domService;
}
}
@Override
- public void onNotification(CompositeNode notification) {
+ public void onNotification(final CompositeNode notification) {
QName qname = notification.getNodeType();
WeakReference<Class<? extends Notification>> potential = notifications.get(qname);
if (potential != null) {
}
@Override
- public void onNotificationSubscribtion(Class<? extends Notification> notificationType) {
+ public void onNotificationSubscribtion(final Class<? extends Notification> notificationType) {
QName qname = BindingReflections.findQName(notificationType);
if (qname != null) {
WeakReference<Class<? extends Notification>> already = notifications.putIfAbsent(qname,
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-interface DomForwardedBroker {
+public interface DomForwardedBroker {
public BindingIndependentConnector getConnector();
-
+
public void setConnector(BindingIndependentConnector connector);
-
+
public void setDomProviderContext(ProviderSession domProviderContext);
public ProviderSession getDomProviderContext();
module opendaylight-sal-binding-broker-impl {
- yang-version 1;
+ yang-version 1;
namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl";
prefix "binding-impl";
description
"Service definition for Binding Aware MD-SAL.";
-
+
revision "2013-10-28" {
description
"Initial revision";
config:provided-service sal:binding-rpc-registry;
config:java-name-prefix BindingBrokerImpl;
}
-
+
identity binding-data-broker {
base config:module-type;
config:provided-service sal:binding-data-broker;
config:provided-service sal:binding-data-consumer-broker;
config:java-name-prefix DataBrokerImpl;
}
-
+
+ identity binding-data-compatible-broker {
+ base config:module-type;
+ config:provided-service sal:binding-data-broker;
+ config:provided-service sal:binding-data-consumer-broker;
+ config:java-name-prefix ForwardedCompatibleDataBrokerImpl;
+ }
+
identity binding-rpc-broker {
base config:module-type;
config:provided-service sal:binding-rpc-registry;
config:java-name-prefix RpcBrokerImpl;
}
-
+
identity binding-notification-broker {
base config:module-type;
config:provided-service sal:binding-notification-service;
augment "/config:modules/config:module/config:configuration" {
case binding-broker-impl {
when "/config:modules/config:module/config:type = 'binding-broker-impl'";
-
+
/*
container rpc-registry {
uses config:service-ref {
}
}
}*/
-
+
container data-broker {
uses config:service-ref {
refine type {
}
}
}
-
+
container notification-service {
uses config:service-ref {
refine type {
config:required-identity binding-dom-mapping-service;
}
}
- }
+ }
+ }
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case binding-data-compatible-broker {
+ when "/config:modules/config:module/config:type = 'binding-data-compatible-broker'";
+
+ container dom-async-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity dom:dom-broker-osgi-registry;
+ }
+ }
+ }
+
+ container binding-mapping-service {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity binding-dom-mapping-service;
+ }
+ }
+ }
}
}
-
+
augment "/config:modules/config:module/config:state" {
case runtime-generated-mapping {
uses common:notification-state;
}
}
-}
\ No newline at end of file
+}
import javassist.ClassPool;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
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.DOMDataBrokerImpl;
import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker;
import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
private final List<SchemaContextListener> schemaListeners = new ArrayList<>();
+ private DataProviderService baData;
+
+ private DOMDataBroker newDOMDataBroker;
+
@Override
public SchemaContext getSchemaContext() {
return schemaContext;
.put(LogicalDatastoreType.CONFIGURATION, configStore)
.build();
- DOMDataBrokerImpl newBiDataImpl = new DOMDataBrokerImpl(newDatastores, executor);
+ newDOMDataBroker = new DOMDataBrokerImpl(newDatastores, executor);
- biCompatibleBroker = new BackwardsCompatibleDataBroker(newBiDataImpl);
+ biCompatibleBroker = new BackwardsCompatibleDataBroker(newDOMDataBroker);
schemaListeners.add(configStore);
schemaListeners.add(operStore);
checkState(executor != null, "Executor needs to be set");
baDataImpl = new DataBrokerImpl();
baDataImpl.setExecutor(executor);
+ baData = baDataImpl;
}
public void startBindingBroker() {
checkState(executor != null, "Executor needs to be set");
- checkState(baDataImpl != null, "Binding Data Broker must be started");
+ checkState(baData != null, "Binding Data Broker must be started");
checkState(baNotifyImpl != null, "Notification Service must be started");
baBrokerImpl = new DomForwardedBindingBrokerImpl("test");
baBrokerImpl.getMountManager().setDataCommitExecutor(executor);
baBrokerImpl.getMountManager().setNotificationExecutor(executor);
baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test"));
- baBrokerImpl.setDataBroker(baDataImpl);
+ baBrokerImpl.setDataBroker(baData);
baBrokerImpl.setNotificationBroker(baNotifyImpl);
baBrokerImpl.start();
}
public void startForwarding() {
- checkState(baDataImpl != null, "Binding Data Broker needs to be started");
+ checkState(baData != null, "Binding Data Broker needs to be started");
checkState(biDataLegacyBroker != null, "DOM Data Broker needs to be started.");
checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started.");
}
public void start() {
- startBindingDataBroker();
- startBindingNotificationBroker();
- startBindingBroker();
startNewDomDataBroker();
startDomBroker();
startDomMountPoint();
startBindingToDomMappingService();
+ startNewBindingDataBroker();
+
+ startBindingNotificationBroker();
+ startBindingBroker();
+
startForwarding();
if (startWithSchema) {
loadYangSchemaFromClasspath();
}
}
+ public void startNewBindingDataBroker() {
+ ForwardedBackwardsCompatibleDataBroker forwarded = new ForwardedBackwardsCompatibleDataBroker(newDOMDataBroker, mappingServiceImpl, executor);
+ schemaListeners.add(forwarded);
+ baData = forwarded;
+ }
+
private void startDomMountPoint() {
biMountImpl = new MountPointManagerImpl();
biMountImpl.setDataBroker(getDomDataBroker());
}
public DataProviderService getBindingDataBroker() {
- return baDataImpl;
+ return baData;
}
public org.opendaylight.controller.sal.core.api.data.DataProviderService getDomDataBroker() {
*/
package org.opendaylight.controller.sal.binding.test.bugfix;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Callable;
import javassist.ClassPool;
-import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
-import static org.junit.Assert.*;
-
public class DOMCodecBug02Test extends AbstractDataServiceTest {
private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
/**
- * This test is ignored, till found out better way to test generation
- * of classes without leaking of instances from previous run
- *
+ * This test is ignored, till found out better way to test generation of
+ * classes without leaking of instances from previous run
+ *
* @throws Exception
*/
-
+
+ @Override
public void setUp() {
ListeningExecutorService executor = MoreExecutors.sameThreadExecutor();
BindingBrokerTestFactory factory = new BindingBrokerTestFactory();
factory.setStartWithParsedSchema(getStartWithSchema());
testContext = factory.getTestContext();
testContext.start();
-
+
baDataService = testContext.getBindingDataBroker();
biDataService = testContext.getDomDataBroker();
dataStore = testContext.getDomDataStore();
mappingService = testContext.getBindingToDomMappingService();
};
-
+
@Test
public void testSchemaContextNotAvailable() throws Exception {
ExecutorService testExecutor = Executors.newFixedThreadPool(1);
testContext.loadYangSchemaFromClasspath();
- Future<Future<RpcResult<TransactionStatus>>> future = testExecutor.submit(new Callable<Future<RpcResult<TransactionStatus>>>() {
- @Override
- public Future<RpcResult<TransactionStatus>> call() throws Exception {
- NodesBuilder nodesBuilder = new NodesBuilder();
- nodesBuilder.setNode(Collections.<Node> emptyList());
- DataModificationTransaction transaction = baDataService.beginTransaction();
- transaction.putOperationalData(NODES_INSTANCE_ID_BA, nodesBuilder.build());
- return transaction.commit();
- }
- });
-
-
+ Future<Future<RpcResult<TransactionStatus>>> future = testExecutor
+ .submit(new Callable<Future<RpcResult<TransactionStatus>>>() {
+ @Override
+ public Future<RpcResult<TransactionStatus>> call() throws Exception {
+ NodesBuilder nodesBuilder = new NodesBuilder();
+ nodesBuilder.setNode(Collections.<Node> emptyList());
+ DataModificationTransaction transaction = baDataService.beginTransaction();
+ transaction.putOperationalData(NODES_INSTANCE_ID_BA, nodesBuilder.build());
+ return transaction.commit();
+ }
+ });
+
RpcResult<TransactionStatus> result = future.get().get();
assertEquals(TransactionStatus.COMMITED, result.getResult());
-
+
Nodes nodes = checkForNodes();
assertNotNull(nodes);
return (Nodes) baDataService.readOperationalData(NODES_INSTANCE_ID_BA);
}
-
+
@Override
protected boolean getStartWithSchema() {
return false;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import com.google.common.util.concurrent.SettableFuture;
+
public class DOMCodecBug03Test extends AbstractDataServiceTest implements DataChangeListener {
private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
.node(SUPPORTED_ACTIONS_QNAME) //
.toInstance();
- private DataChangeEvent<InstanceIdentifier<?>, DataObject> receivedChangeEvent;
+ private final SettableFuture<DataChangeEvent<InstanceIdentifier<?>, DataObject>> receivedChangeEvent = SettableFuture.create();
RpcResult<TransactionStatus> result = transaction.commit().get();
assertEquals(TransactionStatus.COMMITED, result.getResult());
- assertNotNull(receivedChangeEvent);
+ DataChangeEvent<InstanceIdentifier<?>, DataObject> potential = receivedChangeEvent.get(1000,TimeUnit.MILLISECONDS);
+ assertNotNull(potential);
- verifyNodes((Nodes) receivedChangeEvent.getUpdatedOperationalSubtree(),original);
+ verifyNodes((Nodes) potential.getUpdatedOperationalSubtree(),original);
assertBindingIndependentVersion(NODE_INSTANCE_ID_BI);
Nodes nodes = checkForNodes();
verifyNodes(nodes,original);
assertNull(node);
}
- private void verifyNodes(Nodes nodes,Node original) {
+ private void verifyNodes(final Nodes nodes,final Node original) {
assertNotNull(nodes);
assertNotNull(nodes.getNode());
assertEquals(1, nodes.getNode().size());
}
private void assertBindingIndependentVersion(
- org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
CompositeNode node = biDataService.readOperationalData(nodeId);
assertNotNull(node);
}
}
@Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- receivedChangeEvent = change;
+ public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ receivedChangeEvent.set(change);
}
}
import java.util.Collections;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import com.google.common.util.concurrent.SettableFuture;
+
public class PutAugmentationTest extends AbstractDataServiceTest implements DataChangeListener {
private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
.augmentation(FlowCapableNode.class) //
.build();
- private DataChangeEvent<InstanceIdentifier<?>, DataObject> lastReceivedChangeEvent;
+ private SettableFuture<DataChangeEvent<InstanceIdentifier<?>, DataObject>> lastReceivedChangeEvent;
/**
* Test for Bug 148
* @throws Exception
*/
@Test
+ @Ignore
public void putNodeAndAugmentation() throws Exception {
-
+ lastReceivedChangeEvent = SettableFuture.create();
baDataService.registerDataChangeListener(ALL_FLOW_CAPABLE_NODES, this);
DataModificationTransaction augmentedTransaction = baDataService.beginTransaction();
augmentedTransaction.putOperationalData(augmentIdentifier, fnu);
+
+ lastReceivedChangeEvent = SettableFuture.create();
result = augmentedTransaction.commit().get();
assertEquals(TransactionStatus.COMMITED, result.getResult());
- assertNotNull(lastReceivedChangeEvent);
- assertTrue(lastReceivedChangeEvent.getCreatedOperationalData().containsKey(FLOW_AUGMENTATION_PATH));
+ DataChangeEvent<InstanceIdentifier<?>, DataObject> potential = lastReceivedChangeEvent.get(1000,TimeUnit.MILLISECONDS);
+ assertNotNull(potential);
+ assertTrue(potential.getCreatedOperationalData().containsKey(FLOW_AUGMENTATION_PATH));
+
+ lastReceivedChangeEvent = SettableFuture.create();
Node augmentedNode = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
assertNotNull(node);
assertEquals(fnu.getDescription(), readedAugmentation.getDescription());
assertBindingIndependentVersion(NODE_INSTANCE_ID_BI);
testNodeRemove();
- assertTrue(lastReceivedChangeEvent.getRemovedOperationalData().contains(FLOW_AUGMENTATION_PATH));
+ assertTrue(lastReceivedChangeEvent.get(1000,TimeUnit.MILLISECONDS).getRemovedOperationalData().contains(FLOW_AUGMENTATION_PATH));
}
@Test
+ @Ignore
public void putNodeWithAugmentation() throws Exception {
-
+ lastReceivedChangeEvent = SettableFuture.create();
baDataService.registerDataChangeListener(ALL_FLOW_CAPABLE_NODES, this);
NodeBuilder nodeBuilder = new NodeBuilder();
baseTransaction.putOperationalData(NODE_INSTANCE_ID_BA, nodeBuilder.build());
RpcResult<TransactionStatus> result = baseTransaction.commit().get();
- assertNotNull(lastReceivedChangeEvent);
- assertTrue(lastReceivedChangeEvent.getCreatedOperationalData().containsKey(FLOW_AUGMENTATION_PATH));
- lastReceivedChangeEvent = null;
+
+ DataChangeEvent<InstanceIdentifier<?>, DataObject> potential = lastReceivedChangeEvent.get(1000,TimeUnit.MILLISECONDS);
+ assertNotNull(potential);
+ assertTrue(potential.getCreatedOperationalData().containsKey(FLOW_AUGMENTATION_PATH));
+ lastReceivedChangeEvent = SettableFuture.create();
assertEquals(TransactionStatus.COMMITED, result.getResult());
FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(InstanceIdentifier
assertEquals(fnu.getHardware(), readedAugmentation.getHardware());
testPutNodeConnectorWithAugmentation();
- lastReceivedChangeEvent = null;
+ lastReceivedChangeEvent = SettableFuture.create();
testNodeRemove();
- assertTrue(lastReceivedChangeEvent.getRemovedOperationalData().contains(FLOW_AUGMENTATION_PATH));
+ assertTrue(lastReceivedChangeEvent.get(1000,TimeUnit.MILLISECONDS).getRemovedOperationalData().contains(FLOW_AUGMENTATION_PATH));
}
private void testPutNodeConnectorWithAugmentation() throws Exception {
assertNull(node);
}
- private void verifyNodes(Nodes nodes, Node original) {
+ private void verifyNodes(final Nodes nodes, final Node original) {
assertNotNull(nodes);
assertNotNull(nodes.getNode());
assertEquals(1, nodes.getNode().size());
}
- private void assertBindingIndependentVersion(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
+ private void assertBindingIndependentVersion(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
CompositeNode node = biDataService.readOperationalData(nodeId);
assertNotNull(node);
}
}
@Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- lastReceivedChangeEvent = change;
+ public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ lastReceivedChangeEvent.set(change);
}
}
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
-import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
-import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
-import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.SettableFuture;
public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
+ private static final Logger LOG = LoggerFactory.getLogger(ChangeOriginatedInDomBrokerTest.class);
+
private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
private static final FlowKey FLOW_KEY = new FlowKey(FLOW_ID);
- private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modificationCapture;
+ private final SettableFuture<DataChangeEvent<InstanceIdentifier<?>, DataObject>> modificationCapture = SettableFuture.create();
private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
NODE_ID);
.toInstance();
@Test
- @Ignore
public void simpleModifyOperation() throws Exception {
assertNull(biDataService.readConfigurationData(FLOW_INSTANCE_ID_BI));
- registerCommitHandler();
+ registerChangeListener();
CompositeNode domflow = createTestFlow();
DataModificationTransaction biTransaction = biDataService.beginTransaction();
biTransaction.putConfigurationData(FLOW_INSTANCE_ID_BI, domflow);
RpcResult<TransactionStatus> biResult = biTransaction.commit().get();
assertEquals(TransactionStatus.COMMITED, biResult.getResult());
- assertNotNull(modificationCapture);
- Flow flow = (Flow) modificationCapture.getCreatedConfigurationData().get(FLOW_INSTANCE_ID_BA);
+ DataChangeEvent<InstanceIdentifier<?>, DataObject> event = modificationCapture.get(1000,TimeUnit.MILLISECONDS);
+ assertNotNull(event);
+ LOG.info("Created Configuration :{}",event.getCreatedConfigurationData());
+ Flow flow = (Flow) event.getCreatedConfigurationData().get(FLOW_INSTANCE_ID_BA);
assertNotNull(flow);
assertNotNull(flow.getMatch());
assertEquals(TransactionStatus.COMMITED, biResult.getResult());
}
- private void registerCommitHandler() {
- DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> flowTestCommitHandler = new DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>() {
+ private void registerChangeListener() {
+ baDataService.registerDataChangeListener(FLOWS_PATH_BA, new DataChangeListener() {
@Override
- public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
- final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
- modificationCapture = modification;
- return CommitHandlerTransactions.allwaysSuccessfulTransaction(modification);
+ public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ LOG.info("Data Change listener invoked.");
+ modificationCapture.set(change);
}
-
- };
- Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> registration = baDataService
- .registerCommitHandler(FLOWS_PATH_BA, flowTestCommitHandler);
- assertNotNull(registration);
+ });
}
private CompositeNode createTestFlow() {
// Wrap our Apply Action in an Instruction
InstructionBuilder ib = new InstructionBuilder();
+ ib.setOrder(0);
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
// Put our Instruction in a list of Instructions