X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-dom-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fdom%2Fstore%2Fimpl%2FResolveDataChangeEventsTask.java;h=5021d070e14a8ce7b45030e9a604092e3c5257eb;hb=18f8f0b852694daf18e8fd034ba576d78499e0ee;hp=db9bb0fef29fda971f08982d5d0f0e67353ec630;hpb=829938b736ecac866cf2ba9bc80451017b9395a9;p=controller.git 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 db9bb0fef2..5021d070e1 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 @@ -8,7 +8,6 @@ package org.opendaylight.controller.md.sal.dom.store.impl; import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder; -import static org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils.append; import java.util.Collection; import java.util.Collections; @@ -23,11 +22,11 @@ import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataCh import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder; import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.SimpleEventFactory; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidateNode; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Node; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Walker; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NodeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.StoreMetadataNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; @@ -46,23 +45,10 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; /** - * * Resolve Data Change Events based on modifications and listeners * * Computes data change events for all affected registered listeners in data * tree. - * - * Prerequisites for computation is to set all parameters properly: - * - * */ final class ResolveDataChangeEventsTask implements Callable> { private static final Logger LOG = LoggerFactory.getLogger(ResolveDataChangeEventsTask.class); @@ -72,10 +58,10 @@ final class ResolveDataChangeEventsTask implements Callable call() { try (final Walker w = listenerRoot.getWalker()) { - resolveAnyChangeEvent(candidate.getRootPath(), Collections.singleton(w.getRootNode()), - candidate.getModificationRoot(), Optional.fromNullable(candidate.getBeforeRoot()), - Optional.fromNullable(candidate.getAfterRoot())); + resolveAnyChangeEvent(candidate.getRootPath(), Collections.singleton(w.getRootNode()), candidate.getRootNode()); return createNotificationTasks(); } } @@ -256,29 +240,38 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final NodeModification modification, - final Optional before, final Optional after) { - // No listeners are present in listener registration subtree - // no before and after state is present - if (!before.isPresent() && !after.isPresent()) { + final Collection listeners, final DataTreeCandidateNode node) { + + if (node.getModificationType() != ModificationType.UNMODIFIED && + !node.getDataAfter().isPresent() && !node.getDataBefore().isPresent()) { + LOG.debug("Modification at {} has type {}, but no before- and after-data. Assuming unchanged.", + path, node.getModificationType()); return NO_CHANGE; } - switch (modification.getModificationType()) { + + // no before and after state is present + + switch (node.getModificationType()) { case SUBTREE_MODIFIED: - return resolveSubtreeChangeEvent(path, listeners, modification, before.get(), after.get()); + return resolveSubtreeChangeEvent(path, listeners, node); case MERGE: case WRITE: - if (before.isPresent()) { - return resolveReplacedEvent(path, listeners, before.get().getData(), after.get().getData()); + Preconditions.checkArgument(node.getDataAfter().isPresent(), + "Modification at {} has type {} but no after-data", path, node.getModificationType()); + if (node.getDataBefore().isPresent()) { + return resolveReplacedEvent(path, listeners, node.getDataBefore().get(), node.getDataAfter().get()); } else { - return resolveCreateEvent(path, listeners, after.get()); + return resolveCreateEvent(path, listeners, node.getDataAfter().get()); } case DELETE: - return resolveDeleteEvent(path, listeners, before.get()); - default: + Preconditions.checkArgument(node.getDataBefore().isPresent(), + "Modification at {} has type {} but no before-data", path, node.getModificationType()); + return resolveDeleteEvent(path, listeners, node.getDataBefore().get()); + case UNMODIFIED: return NO_CHANGE; } + throw new IllegalStateException(String.format("Unhandled node state %s at %s", node.getModificationType(), path)); } private DOMImmutableDataChangeEvent resolveReplacedEvent(final InstanceIdentifier path, @@ -297,9 +290,8 @@ final class ResolveDataChangeEventsTask implements Callable> afterCont = (NormalizedNodeContainer>) afterData; return resolveNodeContainerReplaced(path, listeners, beforeCont, afterCont); } else if (!beforeData.equals(afterData)) { - // Node is either of Leaf type (does not contain child nodes) - // or we do not have listeners, so normal equals method is - // sufficient for determining change. + // Node is Leaf type (does not contain child nodes) + // so normal equals method is sufficient for determining change. LOG.trace("Resolving leaf replace event for {} , before {}, after {}",path,beforeData,afterData); DOMImmutableDataChangeEvent event = builder(DataChangeScope.BASE).setBefore(beforeData).setAfter(afterData) .addUpdated(path, beforeData, afterData).build(); @@ -313,7 +305,7 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final NormalizedNodeContainer> beforeCont, - final NormalizedNodeContainer> afterCont) { + final NormalizedNodeContainer> afterCont) { final Set alreadyProcessed = new HashSet<>(); final List childChanges = new LinkedList<>(); @@ -322,7 +314,7 @@ final class ResolveDataChangeEventsTask implements Callable beforeChild : beforeCont.getValue()) { PathArgument childId = beforeChild.getIdentifier(); alreadyProcessed.add(childId); - InstanceIdentifier childPath = append(path, childId); + InstanceIdentifier childPath = path.node(childId); Collection childListeners = getListenerChildrenWildcarded(listeners, childId); Optional> afterChild = afterCont.getChild(childId); DOMImmutableDataChangeEvent childChange = resolveNodeContainerChildUpdated(childPath, childListeners, @@ -341,7 +333,7 @@ final class ResolveDataChangeEventsTask implements Callable childListeners = getListenerChildrenWildcarded(listeners, childId); - InstanceIdentifier childPath = append(path,childId); + InstanceIdentifier childPath = path.node(childId); childChanges.add(resolveSameEventRecursivelly(childPath , childListeners, afterChild, DOMImmutableDataChangeEvent.getCreateEventFactory())); } @@ -388,17 +380,17 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final StoreMetadataNode afterState) { + final Collection listeners, final NormalizedNode afterState) { @SuppressWarnings({ "unchecked", "rawtypes" }) - final NormalizedNode node = (NormalizedNode) afterState.getData(); + final NormalizedNode node = (NormalizedNode) afterState; return resolveSameEventRecursivelly(path, listeners, node, DOMImmutableDataChangeEvent.getCreateEventFactory()); } private DOMImmutableDataChangeEvent resolveDeleteEvent(final InstanceIdentifier path, - final Collection listeners, final StoreMetadataNode beforeState) { + final Collection listeners, final NormalizedNode beforeState) { @SuppressWarnings({ "unchecked", "rawtypes" }) - final NormalizedNode node = (NormalizedNode) beforeState.getData(); + final NormalizedNode node = (NormalizedNode) beforeState; return resolveSameEventRecursivelly(path, listeners, node, DOMImmutableDataChangeEvent.getRemoveEventFactory()); } @@ -408,7 +400,7 @@ final class ResolveDataChangeEventsTask implements Callable) { LOG.trace("Resolving subtree recursive event for {}, type {}", path, eventFactory); @@ -425,12 +417,9 @@ final class ResolveDataChangeEventsTask implements Callable childListeners = getListenerChildrenWildcarded(listeners, childId); - eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory)); + eventBuilder.merge(resolveSameEventRecursivelly(path.node(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, propagateEvent); @@ -439,30 +428,31 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final NodeModification modification, - final StoreMetadataNode before, final StoreMetadataNode after) { + final Collection listeners, final DataTreeCandidateNode modification) { - Builder one = builder(DataChangeScope.ONE).setBefore(before.getData()).setAfter(after.getData()); + Preconditions.checkArgument(modification.getDataBefore().isPresent(), "Subtree change with before-data not present at path %s", path); + Preconditions.checkArgument(modification.getDataAfter().isPresent(), "Subtree change with after-data not present at path %s", path); - Builder subtree = builder(DataChangeScope.SUBTREE).setBefore(before.getData()).setAfter(after.getData()); + Builder one = builder(DataChangeScope.ONE). + setBefore(modification.getDataBefore().get()). + setAfter(modification.getDataAfter().get()); + Builder subtree = builder(DataChangeScope.SUBTREE). + setBefore(modification.getDataBefore().get()). + setAfter(modification.getDataAfter().get()); - for (NodeModification childMod : modification.getModifications()) { + for (DataTreeCandidateNode childMod : modification.getChildNodes()) { PathArgument childId = childMod.getIdentifier(); - InstanceIdentifier childPath = append(path, childId); + InstanceIdentifier childPath = path.node(childId); Collection childListeners = getListenerChildrenWildcarded(listeners, childId); - Optional childBefore = before.getChild(childId); - Optional childAfter = after.getChild(childId); - switch (childMod.getModificationType()) { case WRITE: case MERGE: case DELETE: - one.merge(resolveAnyChangeEvent(childPath, childListeners, childMod, childBefore, childAfter)); + one.merge(resolveAnyChangeEvent(childPath, childListeners, childMod)); break; case SUBTREE_MODIFIED: - subtree.merge(resolveSubtreeChangeEvent(childPath, childListeners, childMod, childBefore.get(), - childAfter.get())); + subtree.merge(resolveSubtreeChangeEvent(childPath, childListeners, childMod)); break; case UNMODIFIED: // no-op @@ -514,7 +504,7 @@ final class ResolveDataChangeEventsTask implements Callable