X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2Futils%2FPruningDataTreeModification.java;h=0e97cd958804ce632d1b45af74f7f6b4192f36c7;hb=4e696d9795fe7eef40369c05c340d137394126f3;hp=cc976b381f98b7c76b9811f28aa6dbf5e1cfbe04;hpb=a54716c7a8c9a49a6b7b19eaedfbe522a2556b2b;p=controller.git 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 cc976b381f..0e97cd9588 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 @@ -10,39 +10,50 @@ package org.opendaylight.controller.cluster.datastore.utils; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.ForwardingObject; import java.io.IOException; -import java.net.URI; -import java.util.Set; import org.opendaylight.controller.cluster.datastore.node.utils.transformer.NormalizedNodePruner; +import org.opendaylight.controller.cluster.datastore.util.AbstractDataTreeModificationCursor; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter; +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.model.api.SchemaContext; import org.slf4j.Logger; 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 + * before delegating it to the actual DataTreeModification. */ -public class PruningDataTreeModification implements DataTreeModification { +public class PruningDataTreeModification extends ForwardingObject implements DataTreeModification { private static final Logger LOG = LoggerFactory.getLogger(PruningDataTreeModification.class); - private final DataTreeModification delegate; - private final Set validNamespaces; + private DataTreeModification delegate; + private final SchemaContext schemaContext; + private final DataTree dataTree; + + public PruningDataTreeModification(DataTreeModification delegate, DataTree dataTree, SchemaContext schemaContext) { + this.delegate = Preconditions.checkNotNull(delegate); + this.dataTree = Preconditions.checkNotNull(dataTree); + this.schemaContext = Preconditions.checkNotNull(schemaContext); + } - public PruningDataTreeModification(DataTreeModification delegate, Set validNamespaces) { - this.delegate = delegate; - this.validNamespaces = validNamespaces; + @Override + public DataTreeModification delegate() { + return delegate; } @Override public void delete(YangInstanceIdentifier yangInstanceIdentifier) { try { delegate.delete(yangInstanceIdentifier); - } catch(SchemaValidationFailedException e){ + } catch (SchemaValidationFailedException e) { LOG.warn("Node at path : {} does not exist ignoring delete", yangInstanceIdentifier); } } @@ -50,47 +61,63 @@ public class PruningDataTreeModification implements DataTreeModification { @Override public void merge(YangInstanceIdentifier yangInstanceIdentifier, NormalizedNode normalizedNode) { try { - delegate.merge(yangInstanceIdentifier, normalizedNode); - } catch (SchemaValidationFailedException e){ - if(!isValidYangInstanceIdentifier(yangInstanceIdentifier)){ - LOG.warn("Invalid node identifier {} ignoring merge", yangInstanceIdentifier); - return; + 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()); - LOG.warn("Node at path : {} was pruned during merge", yangInstanceIdentifier); + pruneAndMergeNode(yangInstanceIdentifier, normalizedNode); + } - NormalizedNode pruned = pruneNormalizedNode(normalizedNode); + } - if(pruned != null) { - delegate.merge(yangInstanceIdentifier, pruned); - } - } + private void pruneAndMergeNode(YangInstanceIdentifier yangInstanceIdentifier, NormalizedNode normalizedNode) { + NormalizedNode pruned = pruneNormalizedNode(yangInstanceIdentifier, normalizedNode); + if (pruned != null) { + delegate.merge(yangInstanceIdentifier, pruned); + } } @Override public void write(YangInstanceIdentifier yangInstanceIdentifier, NormalizedNode normalizedNode) { try { - delegate.write(yangInstanceIdentifier, normalizedNode); - } catch (SchemaValidationFailedException e){ - if(!isValidYangInstanceIdentifier(yangInstanceIdentifier)){ - LOG.warn("Invalid node identifier {} ignoring write", yangInstanceIdentifier); - return; + 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()); - LOG.warn("Node at path : {} was pruned during write", yangInstanceIdentifier); + pruneAndWriteNode(yangInstanceIdentifier, normalizedNode); + } + } - NormalizedNode pruned = pruneNormalizedNode(normalizedNode); + private void pruneAndWriteNode(YangInstanceIdentifier yangInstanceIdentifier, NormalizedNode normalizedNode) { + NormalizedNode pruned = pruneNormalizedNode(yangInstanceIdentifier, normalizedNode); - if(pruned != null) { - delegate.write(yangInstanceIdentifier, pruned); - } + if (pruned != null) { + delegate.write(yangInstanceIdentifier, pruned); } } @Override public void ready() { - delegate.ready(); + try { + delegate.ready(); + } catch (SchemaValidationFailedException e) { + DataTreeModification newModification = dataTree.takeSnapshot().newModification(); + delegate.applyToCursor(new PruningDataTreeModificationCursor(newModification, this)); + + delegate = newModification; + delegate.ready(); + } } @Override @@ -105,12 +132,12 @@ public class PruningDataTreeModification implements DataTreeModification { @Override public DataTreeModification newModification() { - return new PruningDataTreeModification(delegate.newModification(), validNamespaces); + return new PruningDataTreeModification(delegate.newModification(), dataTree, schemaContext); } @VisibleForTesting - NormalizedNode pruneNormalizedNode(NormalizedNode input){ - NormalizedNodePruner pruner = new NormalizedNodePruner(validNamespaces); + NormalizedNode pruneNormalizedNode(YangInstanceIdentifier path, NormalizedNode input) { + NormalizedNodePruner pruner = new NormalizedNodePruner(path, schemaContext); try { NormalizedNodeWriter.forStreamWriter(pruner).write(input); } catch (IOException ioe) { @@ -120,18 +147,41 @@ public class PruningDataTreeModification implements DataTreeModification { return pruner.normalizedNode(); } - public DataTreeModification getDelegate(){ - return delegate; - } + private static class PruningDataTreeModificationCursor extends AbstractDataTreeModificationCursor { + private final DataTreeModification toModification; + private final PruningDataTreeModification pruningModification; + + PruningDataTreeModificationCursor(DataTreeModification toModification, + PruningDataTreeModification pruningModification) { + this.toModification = toModification; + this.pruningModification = pruningModification; + } - private boolean isValidYangInstanceIdentifier(YangInstanceIdentifier instanceIdentifier){ - for(YangInstanceIdentifier.PathArgument pathArgument : instanceIdentifier.getPathArguments()){ - if(!validNamespaces.contains(pathArgument.getNodeType().getNamespace())){ - return false; + @Override + public void write(PathArgument child, NormalizedNode data) { + YangInstanceIdentifier path = current().node(child); + NormalizedNode prunedNode = pruningModification.pruneNormalizedNode(path, data); + if (prunedNode != null) { + toModification.write(path, prunedNode); } } - return true; - } + @Override + public void merge(PathArgument child, NormalizedNode data) { + YangInstanceIdentifier path = current().node(child); + NormalizedNode prunedNode = pruningModification.pruneNormalizedNode(path, data); + if (prunedNode != null) { + toModification.merge(path, prunedNode); + } + } + @Override + public void delete(PathArgument child) { + try { + toModification.delete(current().node(child)); + } catch (SchemaValidationFailedException e) { + // Ignoring since we would've already logged this in the call to the original modification. + } + } + } }