From 89f326c5d75fe39cc7ef7f646ccccb1e927c227c Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Tue, 29 Apr 2014 18:57:08 +0200 Subject: [PATCH] Bug 509: Fixed Backwards compatibility bugs with datastore. Fixed bug in write and merge of leaf set children, which prevented update of leaf sets. Change-Id: I61c130b9d40876ae50468ebfbd2cf15208f1249c Signed-off-by: Tony Tkacik --- .../impl/AbstractForwardedTransaction.java | 25 +++++++++-- ...orwardedBackwardsCompatibleDataBroker.java | 16 +++++-- .../impl/ResolveDataChangeEventsTask.java | 44 +++++++++++-------- .../store/impl/SchemaAwareApplyOperation.java | 42 ++++++++++++++++-- 4 files changed, 99 insertions(+), 28 deletions(-) diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java index 6bd6e6aaf5..cc9c6ebaa6 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java @@ -82,7 +82,7 @@ public class AbstractForwardedTransaction path, final DataObject data) { + invalidateCache(store, path); + final Entry> normalized = codec + .toNormalizedNode(path, data); + + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey(); + ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path); + LOG.debug("Tx: {} : Merge data {}",getDelegate().getIdentifier(),normalized.getKey()); + writeTransaction.merge(store, normalized.getKey(), normalized.getValue()); + } + + private void ensureParentsByMerge(final DOMDataReadWriteTransaction writeTransaction, + final LogicalDatastoreType store, + final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath, + final InstanceIdentifier path) { List currentArguments = new ArrayList<>(); DataNormalizationOperation currentOp = codec.getDataNormalizer().getRootOperation(); Iterator iterator = normalizedPath.getPath().iterator(); @@ -135,8 +156,6 @@ public class AbstractForwardedTransaction path, final DataObject data) { - posponedRemovedOperational.remove(path); - doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data); + boolean previouslyRemoved = posponedRemovedOperational.remove(path); + if(previouslyRemoved) { + doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data); + } else { + doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data); + } } @Override public void putConfigurationData(final InstanceIdentifier path, final DataObject data) { - posponedRemovedConfiguration.remove(path); + boolean previouslyRemoved = posponedRemovedConfiguration.remove(path); DataObject originalObj = readConfigurationData(path); if (originalObj != null) { original.put(path, originalObj); @@ -233,7 +237,11 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat created.put(path, data); } updated.put(path, data); - doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data); + if(previouslyRemoved) { + doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data); + } else { + doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data); + } } @Override diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java index c62c27dea8..e74ba95891 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java @@ -394,7 +394,8 @@ public class ResolveDataChangeEventsTask implements Callable listeners, final NormalizedNode node, final SimpleEventFactory eventFactory) { - DOMImmutableDataChangeEvent event = eventFactory.create(path, node); - - if (!listeners.isEmpty()) { + final DOMImmutableDataChangeEvent event = eventFactory.create(path, node); + DOMImmutableDataChangeEvent propagateEvent = event; // We have listeners for this node or it's children, so we will try // to do additional processing - if (node instanceof NormalizedNodeContainer) { - // Node has children, so we will try to resolve it's children - // changes. - @SuppressWarnings("unchecked") - NormalizedNodeContainer> container = (NormalizedNodeContainer>) node; - for (NormalizedNode child : container.getValue()) { - PathArgument childId = child.getIdentifier(); - Collection childListeners = getListenerChildrenWildcarded(listeners, childId); - if (!childListeners.isEmpty()) { - resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory); - } - } + if (node instanceof NormalizedNodeContainer) { + Builder eventBuilder = builder(DataChangeScope.BASE); + eventBuilder.merge(event); + eventBuilder.setBefore(event.getOriginalSubtree()); + eventBuilder.setAfter(event.getUpdatedSubtree()); + + // Node has children, so we will try to resolve it's children + // changes. + @SuppressWarnings("unchecked") + NormalizedNodeContainer> container = (NormalizedNodeContainer>) node; + for (NormalizedNode child : container.getValue()) { + PathArgument childId = child.getIdentifier(); + Collection childListeners = getListenerChildrenWildcarded(listeners, childId); + eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory)); } + propagateEvent = eventBuilder.build(); + } else { + // We do not dispatch leaf events since Binding Aware components do not support them. + propagateEvent = builder(DataChangeScope.BASE).build(); + } + if (!listeners.isEmpty()) { addPartialTask(listeners, event); } - return event; + return propagateEvent; } private DOMImmutableDataChangeEvent resolveSubtreeChangeEvent(final InstanceIdentifier path, @@ -476,7 +484,7 @@ public class ResolveDataChangeEventsTask implements Callable entryStrategy; @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafSetModificationStrategy(final LeafListSchemaNode schema) { + protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { super((Class) LeafSetNode.class); entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); } @@ -589,6 +599,32 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } + public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final Optional entryStrategy; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { + super((Class) LeafSetNode.class); + entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) { + return ImmutableOrderedLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier); + } + + @Override + public Optional getChild(final PathArgument identifier) { + if (identifier instanceof NodeWithValue) { + return entryStrategy; + } + return Optional.absent(); + } + + } + public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation { private final Optional entryStrategy; -- 2.36.6