X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fbinding%2Fimpl%2FAbstractForwardedDataBroker.java;h=e632e6336aaf959808a28f9ecc209432c504b4eb;hp=2a866a94b358ebcc031c5965e16305dcc5930b0f;hb=be2b35105f8e10ada7d73f4523a5a931c57323b3;hpb=9bcddde7fb7e277d315499bcbda79484c3e49f2e diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java index 2a866a94b3..e632e6336a 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java @@ -7,14 +7,20 @@ */ package org.opendaylight.controller.md.sal.binding.impl; +import com.google.common.base.Objects; +import com.google.common.base.Optional; + +import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import org.opendaylight.controller.md.sal.binding.api.BindingDataChangeListener; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; 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; @@ -23,11 +29,13 @@ 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.controller.sal.core.api.model.SchemaService; 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.YangInstanceIdentifier; 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; @@ -36,11 +44,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Objects; -import com.google.common.base.Optional; - -public abstract class AbstractForwardedDataBroker implements Delegator, DomForwardedBroker, - SchemaContextListener { +public abstract class AbstractForwardedDataBroker implements Delegator, DomForwardedBroker, SchemaContextListener, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedDataBroker.class); // The Broker to whom we do all forwarding @@ -53,12 +57,14 @@ public abstract class AbstractForwardedDataBroker implements Delegator schemaListenerRegistration; protected AbstractForwardedDataBroker(final DOMDataBroker domDataBroker, - final BindingIndependentMappingService mappingService) { + final BindingIndependentMappingService mappingService,final SchemaService schemaService) { this.domDataBroker = domDataBroker; this.mappingService = mappingService; this.codec = new BindingToNormalizedNodeCodec(mappingService); + this.schemaListenerRegistration = schemaService.registerSchemaContextListener(this); } protected BindingToNormalizedNodeCodec getCodec() { @@ -79,28 +85,34 @@ public abstract class AbstractForwardedDataBroker implements Delegator registerDataChangeListener(final LogicalDatastoreType store, - final InstanceIdentifier path, final BindingDataChangeListener listener, + public ListenerRegistration registerDataChangeListener(final LogicalDatastoreType store, + final InstanceIdentifier path, final DataChangeListener listener, final DataChangeScope triggeringScope) { DOMDataChangeListener domDataChangeListener = new TranslatingDataChangeInvoker(store, path, listener, triggeringScope); - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = codec.toNormalized(path); + YangInstanceIdentifier domPath = codec.toNormalized(path); ListenerRegistration domRegistration = domDataBroker.registerDataChangeListener(store, domPath, domDataChangeListener, triggeringScope); return new ListenerRegistrationImpl(listener, domRegistration); } protected Map, DataObject> toBinding( - final Map> normalized) { + InstanceIdentifier path, + final Map> normalized) { Map, DataObject> newMap = new HashMap<>(); - for (Map.Entry> entry : normalized - .entrySet()) { + + for (Map.Entry> entry : sortedEntries(normalized)) { try { Optional, DataObject>> potential = getCodec().toBinding( entry); if (potential.isPresent()) { Entry, DataObject> binding = potential.get(); newMap.put(binding.getKey(), binding.getValue()); + } else if (entry.getKey().getLastPathArgument() instanceof YangInstanceIdentifier.AugmentationIdentifier) { + DataObject bindingDataObject = getCodec().toBinding(path, entry.getValue()); + if (bindingDataObject != null) { + newMap.put(path, bindingDataObject); + } } } catch (DeserializationException e) { LOG.warn("Failed to transform {}, omitting it", entry, e); @@ -109,15 +121,50 @@ public abstract class AbstractForwardedDataBroker implements Delegator> toBinding( - final Set normalized) { + private static final Comparator> MAP_ENTRY_COMPARATOR = new Comparator>() { + @Override + public int compare(final Entry left, + final Entry right) { + final Iterator li = left.getKey().getPathArguments().iterator(); + final Iterator ri = right.getKey().getPathArguments().iterator(); + + // Iterate until left is exhausted... + while (li.hasNext()) { + if (!ri.hasNext()) { + // Left is deeper + return 1; + } + + li.next(); + ri.next(); + } + + // Check if right is exhausted + return ri.hasNext() ? -1 : 0; + } + }; + + private static Iterable> sortedEntries(final Map map) { + if (!map.isEmpty()) { + ArrayList> entries = new ArrayList<>(map.entrySet()); + Collections.sort(entries, MAP_ENTRY_COMPARATOR); + return entries; + } else { + return Collections.emptySet(); + } + } + + protected Set> toBinding(InstanceIdentifier path, + final Set normalized) { Set> hashSet = new HashSet<>(); - for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath : normalized) { + for (YangInstanceIdentifier normalizedPath : normalized) { try { Optional> potential = getCodec().toBinding(normalizedPath); if (potential.isPresent()) { InstanceIdentifier binding = potential.get(); hashSet.add(binding); + } else if (normalizedPath.getLastPathArgument() instanceof YangInstanceIdentifier.AugmentationIdentifier) { + hashSet.add(path); } } catch (DeserializationException e) { LOG.warn("Failed to transform {}, omitting it", normalizedPath, e); @@ -139,13 +186,13 @@ public abstract class AbstractForwardedDataBroker implements Delegator path; private final DataChangeScope triggeringScope; public TranslatingDataChangeInvoker(final LogicalDatastoreType store, final InstanceIdentifier path, - final BindingDataChangeListener bindingDataChangeListener, final DataChangeScope triggeringScope) { + final DataChangeListener bindingDataChangeListener, final DataChangeScope triggeringScope) { this.store = store; this.path = path; this.bindingDataChangeListener = bindingDataChangeListener; @@ -154,24 +201,24 @@ public abstract class AbstractForwardedDataBroker implements Delegator> change) { + final AsyncDataChangeEvent> change) { bindingDataChangeListener.onDataChanged(new TranslatedDataChangeEvent(change, path)); } } private class TranslatedDataChangeEvent implements AsyncDataChangeEvent, DataObject> { - private final AsyncDataChangeEvent> domEvent; + private final AsyncDataChangeEvent> domEvent; private final InstanceIdentifier path; private Map, DataObject> createdCache; private Map, DataObject> updatedCache; - private Map, ? extends DataObject> originalCache; + private Map, DataObject> originalCache; private Set> removedCache; private Optional originalDataCache; private Optional updatedDataCache; public TranslatedDataChangeEvent( - final AsyncDataChangeEvent> change, + final AsyncDataChangeEvent> change, final InstanceIdentifier path) { this.domEvent = change; this.path = path; @@ -180,7 +227,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator, DataObject> getCreatedData() { if (createdCache == null) { - createdCache = Collections.unmodifiableMap(toBinding(domEvent.getCreatedData())); + createdCache = Collections.unmodifiableMap(toBinding(path, domEvent.getCreatedData())); } return createdCache; } @@ -188,7 +235,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator, DataObject> getUpdatedData() { if (updatedCache == null) { - updatedCache = Collections.unmodifiableMap(toBinding(domEvent.getUpdatedData())); + updatedCache = Collections.unmodifiableMap(toBinding(path, domEvent.getUpdatedData())); } return updatedCache; @@ -197,15 +244,15 @@ public abstract class AbstractForwardedDataBroker implements Delegator> getRemovedPaths() { if (removedCache == null) { - removedCache = Collections.unmodifiableSet(toBinding(domEvent.getRemovedPaths())); + removedCache = Collections.unmodifiableSet(toBinding(path, domEvent.getRemovedPaths())); } return removedCache; } @Override - public Map, ? extends DataObject> getOriginalData() { + public Map, DataObject> getOriginalData() { if (originalCache == null) { - originalCache = Collections.unmodifiableMap(toBinding(domEvent.getOriginalData())); + originalCache = Collections.unmodifiableMap(toBinding(path, domEvent.getOriginalData())); } return originalCache; @@ -246,10 +293,10 @@ public abstract class AbstractForwardedDataBroker implements Delegator { + private static class ListenerRegistrationImpl extends AbstractListenerRegistration { private final ListenerRegistration registration; - public ListenerRegistrationImpl(final BindingDataChangeListener listener, + public ListenerRegistrationImpl(final DataChangeListener listener, final ListenerRegistration registration) { super(listener); this.registration = registration; @@ -286,4 +333,9 @@ public abstract class AbstractForwardedDataBroker implements Delegator