X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2Futils%2FPruningDataTreeModification.java;h=8ce7119651ddf743065600094cdcc572064d9484;hp=3c326dc2df9d8ae702caee2650191f2af53c5f4f;hb=d19cf96d390ffcdba8b1f64a6dd3f3749ecc5872;hpb=66e553f2098ea61426c4a441be57395673535c2f diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/PruningDataTreeModification.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/PruningDataTreeModification.java index 3c326dc2df..8ce7119651 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/PruningDataTreeModification.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/PruningDataTreeModification.java @@ -23,7 +23,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor; import org.opendaylight.yangtools.yang.data.impl.schema.tree.SchemaValidationFailedException; -import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +31,82 @@ import org.slf4j.LoggerFactory; * The PruningDataTreeModification first removes all entries from the data which do not belong in the schemaContext * before delegating it to the actual DataTreeModification. */ -public class PruningDataTreeModification extends ForwardingObject implements DataTreeModification { +public abstract class PruningDataTreeModification extends ForwardingObject implements DataTreeModification { + /** + * A PruningDataTreeModification which always performs pruning before attempting an operation. This sacrifices + * performance to ensure all data has passed through the pruner -- such that data adaptations are performed. + */ + public static final class Proactive extends PruningDataTreeModification { + public Proactive(final DataTreeModification delegate, final DataTree dataTree, + final ReusableNormalizedNodePruner pruner) { + super(delegate, dataTree, pruner); + } + + @Override + public void merge(final YangInstanceIdentifier path, final NormalizedNode data) { + pruneAndMergeNode(path, data); + } + + @Override + public void write(final YangInstanceIdentifier path, final NormalizedNode data) { + pruneAndWriteNode(path, data); + } + + @Override + PruningDataTreeModification createNew(final DataTreeModification delegate, final DataTree dataTree, + final ReusableNormalizedNodePruner pruner) { + return new Proactive(delegate, dataTree, pruner); + } + } + + /** + * A PruningDataTreeModification which performs pruning only when an operation results in an + * {@link SchemaValidationFailedException}. This offers superior performance in the normal case of not needing + * pruning. + */ + public static final class Reactive extends PruningDataTreeModification { + public Reactive(final DataTreeModification delegate, final DataTree dataTree, + final ReusableNormalizedNodePruner pruner) { + super(delegate, dataTree, pruner); + } + + @Override + public void merge(final YangInstanceIdentifier path, final NormalizedNode data) { + if (path.isEmpty()) { + pruneAndMergeNode(path, data); + return; + } + + try { + delegate().merge(path, data); + } catch (SchemaValidationFailedException e) { + LOG.warn("Node at path {} was pruned during merge due to validation error: {}", path, e.getMessage()); + pruneAndMergeNode(path, data); + } + } + + @Override + public void write(final YangInstanceIdentifier path, final NormalizedNode data) { + if (path.isEmpty()) { + pruneAndWriteNode(path, data); + return; + } + + try { + delegate().write(path, data); + } catch (SchemaValidationFailedException e) { + LOG.warn("Node at path : {} was pruned during write due to validation error: {}", path, e.getMessage()); + pruneAndWriteNode(path, data); + } + } + + @Override + PruningDataTreeModification createNew(final DataTreeModification delegate, final DataTree dataTree, + final ReusableNormalizedNodePruner pruner) { + return new Reactive(delegate, dataTree, pruner); + } + } + private static final Logger LOG = LoggerFactory.getLogger(PruningDataTreeModification.class); private final ReusableNormalizedNodePruner pruner; @@ -40,95 +114,48 @@ public class PruningDataTreeModification extends ForwardingObject implements Dat private DataTreeModification delegate; - private PruningDataTreeModification(final DataTreeModification delegate, final DataTree dataTree, + PruningDataTreeModification(final DataTreeModification delegate, final DataTree dataTree, final ReusableNormalizedNodePruner pruner) { this.delegate = requireNonNull(delegate); this.dataTree = requireNonNull(dataTree); this.pruner = requireNonNull(pruner); } - public PruningDataTreeModification(final DataTreeModification delegate, final DataTree dataTree, - final SchemaContext schemaContext) { - this(delegate, dataTree, ReusableNormalizedNodePruner.forSchemaContext(schemaContext)); - } - - public PruningDataTreeModification(final DataTreeModification delegate, final DataTree dataTree, - final DataSchemaContextTree dataSchemaContext) { - this(delegate, dataTree, ReusableNormalizedNodePruner.forDataSchemaContext(dataSchemaContext)); - } - @Override - public DataTreeModification delegate() { + protected final DataTreeModification delegate() { return delegate; } @Override - public SchemaContext getSchemaContext() { + public final SchemaContext getSchemaContext() { return delegate.getSchemaContext(); } @Override - public void delete(final YangInstanceIdentifier yangInstanceIdentifier) { + public final void delete(final YangInstanceIdentifier path) { try { - delegate.delete(yangInstanceIdentifier); + delegate.delete(path); } catch (SchemaValidationFailedException e) { - LOG.warn("Node at path : {} does not exist ignoring delete", yangInstanceIdentifier); + LOG.warn("Node at path : {} does not exist ignoring delete", path); } } - @Override - public void merge(final YangInstanceIdentifier yangInstanceIdentifier, final NormalizedNode normalizedNode) { - try { - if (YangInstanceIdentifier.empty().equals(yangInstanceIdentifier)) { - pruneAndMergeNode(yangInstanceIdentifier, normalizedNode); - } else { - delegate.merge(yangInstanceIdentifier, normalizedNode); - } - } catch (SchemaValidationFailedException e) { - LOG.warn("Node at path {} was pruned during merge due to validation error: {}", - yangInstanceIdentifier, e.getMessage()); - - pruneAndMergeNode(yangInstanceIdentifier, normalizedNode); - } - - } - - private void pruneAndMergeNode(final YangInstanceIdentifier yangInstanceIdentifier, - final NormalizedNode normalizedNode) { - NormalizedNode pruned = pruneNormalizedNode(yangInstanceIdentifier, normalizedNode); - + final void pruneAndMergeNode(final YangInstanceIdentifier path, final NormalizedNode data) { + final NormalizedNode pruned = pruneNormalizedNode(path, data); if (pruned != null) { - delegate.merge(yangInstanceIdentifier, pruned); - } - } - - @Override - public void write(final YangInstanceIdentifier yangInstanceIdentifier, final NormalizedNode normalizedNode) { - try { - if (YangInstanceIdentifier.empty().equals(yangInstanceIdentifier)) { - pruneAndWriteNode(yangInstanceIdentifier, normalizedNode); - } else { - delegate.write(yangInstanceIdentifier, normalizedNode); - } - } catch (SchemaValidationFailedException e) { - LOG.warn("Node at path : {} was pruned during write due to validation error: {}", - yangInstanceIdentifier, e.getMessage()); - - pruneAndWriteNode(yangInstanceIdentifier, normalizedNode); + delegate.merge(path, pruned); } } - private void pruneAndWriteNode(final YangInstanceIdentifier yangInstanceIdentifier, - final NormalizedNode normalizedNode) { - NormalizedNode pruned = pruneNormalizedNode(yangInstanceIdentifier, normalizedNode); - + final void pruneAndWriteNode(final YangInstanceIdentifier path, final NormalizedNode data) { + final NormalizedNode pruned = pruneNormalizedNode(path, data); if (pruned != null) { - delegate.write(yangInstanceIdentifier, pruned); + delegate.write(path, pruned); } } @Override - public void ready() { + public final void ready() { try { delegate.ready(); } catch (SchemaValidationFailedException e) { @@ -141,22 +168,23 @@ public class PruningDataTreeModification extends ForwardingObject implements Dat } @Override - public void applyToCursor(final DataTreeModificationCursor dataTreeModificationCursor) { + public final void applyToCursor(final DataTreeModificationCursor dataTreeModificationCursor) { delegate.applyToCursor(dataTreeModificationCursor); } @Override - public Optional> readNode(final YangInstanceIdentifier yangInstanceIdentifier) { + public final Optional> readNode(final YangInstanceIdentifier yangInstanceIdentifier) { return delegate.readNode(yangInstanceIdentifier); } @Override - public DataTreeModification newModification() { - return new PruningDataTreeModification(delegate.newModification(), dataTree, pruner.duplicate()); + public final DataTreeModification newModification() { + return createNew(delegate.newModification(), dataTree, pruner.duplicate()); } @VisibleForTesting - NormalizedNode pruneNormalizedNode(final YangInstanceIdentifier path, final NormalizedNode input) { + final NormalizedNode pruneNormalizedNode(final YangInstanceIdentifier path, + final NormalizedNode input) { pruner.initializeForPath(path); try { NormalizedNodeWriter.forStreamWriter(pruner).write(input); @@ -168,7 +196,10 @@ public class PruningDataTreeModification extends ForwardingObject implements Dat return pruner.getResult().orElse(null); } - private static class PruningDataTreeModificationCursor extends AbstractDataTreeModificationCursor { + abstract PruningDataTreeModification createNew(DataTreeModification delegate, DataTree dataTree, + ReusableNormalizedNodePruner pruner); + + private static final class PruningDataTreeModificationCursor extends AbstractDataTreeModificationCursor { private final DataTreeModification toModification; private final PruningDataTreeModification pruningModification; @@ -180,8 +211,8 @@ public class PruningDataTreeModification extends ForwardingObject implements Dat @Override public void write(final PathArgument child, final NormalizedNode data) { - YangInstanceIdentifier path = current().node(child); - NormalizedNode prunedNode = pruningModification.pruneNormalizedNode(path, data); + final YangInstanceIdentifier path = current().node(child); + final NormalizedNode prunedNode = pruningModification.pruneNormalizedNode(path, data); if (prunedNode != null) { toModification.write(path, prunedNode); } @@ -189,8 +220,8 @@ public class PruningDataTreeModification extends ForwardingObject implements Dat @Override public void merge(final PathArgument child, final NormalizedNode data) { - YangInstanceIdentifier path = current().node(child); - NormalizedNode prunedNode = pruningModification.pruneNormalizedNode(path, data); + final YangInstanceIdentifier path = current().node(child); + final NormalizedNode prunedNode = pruningModification.pruneNormalizedNode(path, data); if (prunedNode != null) { toModification.merge(path, prunedNode); }