BUG-509: migrate to TreeNodes
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / store / impl / tree / data / InMemoryDataTree.java
index 1f2a775cdc71115b92b015180b9a95149b8204ba..ae71ed9adfdb43ac3d53f92313cf3747c2f4c11b 100644 (file)
@@ -14,7 +14,9 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFa
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
@@ -31,16 +33,21 @@ final class InMemoryDataTree implements DataTree {
     private static final InstanceIdentifier PUBLIC_ROOT_PATH = InstanceIdentifier.builder().build();
 
     private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
-    private StoreMetadataNode rootNode;
+    private ModificationApplyOperation applyOper = new AlwaysFailOperation();
     private SchemaContext currentSchemaContext;
+    private TreeNode rootNode;
 
-    public InMemoryDataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) {
+    public InMemoryDataTree(final TreeNode rootNode, final SchemaContext schemaContext) {
         this.rootNode = Preconditions.checkNotNull(rootNode);
-        this.currentSchemaContext = schemaContext;
+
+        if (schemaContext != null) {
+            // Also sets applyOper
+            setSchemaContext(schemaContext);
+        }
     }
 
     @Override
-       public synchronized void setSchemaContext(final SchemaContext newSchemaContext) {
+    public synchronized void setSchemaContext(final SchemaContext newSchemaContext) {
         Preconditions.checkNotNull(newSchemaContext);
 
         LOG.info("Attepting to install schema context {}", newSchemaContext);
@@ -50,9 +57,13 @@ final class InMemoryDataTree implements DataTree {
          *        whether they are compatible here. Reject incompatible changes.
          */
 
+        // Instantiate new apply operation, this still may fail
+        final ModificationApplyOperation newApplyOper = SchemaAwareApplyOperation.from(newSchemaContext);
+
         // Ready to change the context now, make sure no operations are running
         rwLock.writeLock().lock();
         try {
+            this.applyOper = newApplyOper;
             this.currentSchemaContext = newSchemaContext;
         } finally {
             rwLock.writeLock().unlock();
@@ -60,55 +71,54 @@ final class InMemoryDataTree implements DataTree {
     }
 
     @Override
-       public InMemoryDataTreeSnapshot takeSnapshot() {
+    public InMemoryDataTreeSnapshot takeSnapshot() {
         rwLock.readLock().lock();
         try {
-            return new InMemoryDataTreeSnapshot(currentSchemaContext, rootNode);
+            return new InMemoryDataTreeSnapshot(currentSchemaContext, rootNode, applyOper);
         } finally {
             rwLock.readLock().unlock();
         }
     }
 
-       @Override
-       public void validate(DataTreeModification modification) throws DataPreconditionFailedException {
-               Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
+    @Override
+    public void validate(final DataTreeModification modification) throws DataPreconditionFailedException {
+        Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
 
-               final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
-               m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.of(rootNode));
-       }
+        final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
+        m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.<TreeNode>of(rootNode));
+    }
 
-       @Override
-       public synchronized DataTreeCandidate prepare(DataTreeModification modification) {
-               Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
+    @Override
+    public synchronized DataTreeCandidate prepare(final DataTreeModification modification) {
+        Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
 
-               final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
-               final NodeModification root = m.getRootModification();
+        final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
+        final ModifiedNode root = m.getRootModification();
 
-        if (root.getModificationType() == ModificationType.UNMODIFIED) {
-               return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root);
+        if (root.getType() == ModificationType.UNMODIFIED) {
+            return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root);
         }
 
         rwLock.writeLock().lock();
         try {
-               // FIXME: rootNode needs to be a read-write snapshot here...
-               final Optional<StoreMetadataNode> newRoot = m.getStrategy().apply(m.getRootModification(), Optional.of(rootNode), StoreUtils.increase(rootNode.getSubtreeVersion()));
-               Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node");
-               return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, rootNode, newRoot.get());
+            final Optional<TreeNode> newRoot = m.getStrategy().apply(m.getRootModification(), Optional.<TreeNode>of(rootNode), StoreUtils.increase(rootNode.getSubtreeVersion()));
+            Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node");
+            return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, rootNode, newRoot.get());
         } finally {
-               rwLock.writeLock().unlock();
+            rwLock.writeLock().unlock();
         }
-       }
+    }
 
-       @Override
-       public synchronized void commit(DataTreeCandidate candidate) {
-               if (candidate instanceof NoopDataTreeCandidate) {
-                       return;
-               }
+    @Override
+    public synchronized void commit(final DataTreeCandidate candidate) {
+        if (candidate instanceof NoopDataTreeCandidate) {
+            return;
+        }
 
-               Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass());
-               final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate;
+        Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass());
+        final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate;
 
-        LOG.debug("Updating Store snapshot version: {} with version:{}", rootNode.getSubtreeVersion(), c.getAfterRoot().getSubtreeVersion());
+        LOG.debug("Updating datastore from {} to {}", rootNode, c.getAfterRoot());
 
         if (LOG.isTraceEnabled()) {
             LOG.trace("Data Tree is {}", StoreUtils.toStringTree(c.getAfterRoot().getData()));
@@ -118,10 +128,10 @@ final class InMemoryDataTree implements DataTree {
         rwLock.writeLock().lock();
         try {
             Preconditions.checkState(c.getBeforeRoot() == rootNode,
-                    String.format("Store snapshot %s and transaction snapshot %s differ.", rootNode, c.getBeforeRoot()));
+                    String.format("Store tree %s and candidate base %s differ.", rootNode, c.getBeforeRoot()));
             this.rootNode = c.getAfterRoot();
         } finally {
             rwLock.writeLock().unlock();
         }
-       }
+    }
 }