You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2013/11/05 10:05:39 UTC

svn commit: r1538908 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/mongomk/ test/java/org/apache/jackrabbit/oak/ test/java/org/apache/jackrabbit/oak/kernel/ test/java/org/apache/jackrabbit/oak/plugins/mongomk/

Author: mreutegg
Date: Tue Nov  5 09:05:39 2013
New Revision: 1538908

URL: http://svn.apache.org/r1538908
Log:
OAK-1131: Provide a way to inject Observer instances into NodeStore implementations
- inject Observer into MongoNodeStore
- enable test

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/NodeStoreFixture.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java?rev=1538908&r1=1538907&r2=1538908&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java Tue Nov  5 09:05:39 2013
@@ -41,12 +41,16 @@ import org.apache.jackrabbit.oak.commons
 import org.apache.jackrabbit.oak.plugins.mongomk.Node.Children;
 import org.apache.jackrabbit.oak.plugins.mongomk.blob.MongoBlobStore;
 import org.apache.jackrabbit.oak.plugins.mongomk.util.Utils;
+import org.apache.jackrabbit.oak.spi.commit.EmptyObserver;
+import org.apache.jackrabbit.oak.spi.commit.Observer;
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.Weigher;
 import com.mongodb.DB;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * A MicroKernel implementation that stores the data in a MongoDB.
  */
@@ -618,6 +622,7 @@ public class MongoMK implements MicroKer
         private MongoNodeStore nodeStore;
         private DocumentStore documentStore;
         private BlobStore blobStore;
+        private Observer observer = EmptyObserver.INSTANCE;
         private int clusterId  = Integer.getInteger("oak.mongoMK.clusterId", 0);
         private int asyncDelay = 1000;
         private boolean timing;
@@ -804,6 +809,16 @@ public class MongoMK implements MicroKer
             return splitDocumentAgeMillis;
         }
 
+        public Builder setObserver(@Nonnull Observer observer) {
+            this.observer = checkNotNull(observer);
+            return this;
+        }
+
+        @Nonnull
+        public Observer getObserver() {
+            return observer;
+        }
+
         /**
          * Open the MongoMK instance using the configured options.
          * 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java?rev=1538908&r1=1538907&r2=1538908&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java Tue Nov  5 09:05:39 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.mongomk;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
@@ -61,6 +62,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.observation.Observable;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.Observer;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -163,14 +165,6 @@ public final class MongoNodeStore
     private final Map<String, String> splitCandidates = Maps.newConcurrentMap();
 
     /**
-     * The splitting point in milliseconds. If a document is split, revisions
-     * older than this number of milliseconds are moved to a different document.
-     * The default is 0, meaning documents are never split. Revisions that are
-     * newer than this are kept in the newest document.
-     */
-    private final long splitDocumentAgeMillis;
-
-    /**
      * The last known revision for each cluster instance.
      *
      * Key: the machine id, value: revision.
@@ -197,8 +191,6 @@ public final class MongoNodeStore
      */
     private AtomicInteger simpleRevisionCounter;
 
-    private boolean stopBackground;
-
     /**
      * The node cache.
      *
@@ -226,8 +218,14 @@ public final class MongoNodeStore
      */
     private final BlobStore blobStore;
 
+    /**
+     * The node store observer.
+     */
+    private final Observer observer;
+
     public MongoNodeStore(MongoMK.Builder builder) {
         this.blobStore = builder.getBlobStore();
+        this.observer = builder.getObserver();
         if (builder.isUseSimpleRevision()) {
             this.simpleRevisionCounter = new AtomicInteger(0);
         }
@@ -253,7 +251,6 @@ public final class MongoNodeStore
         this.clusterId = cid;
         this.revisionComparator = new Revision.RevisionComparator(clusterId);
         this.branches = new UnmergedBranches(getRevisionComparator());
-        this.splitDocumentAgeMillis = builder.getSplitDocumentAgeMillis();
         this.asyncDelay = builder.getAsyncDelay();
 
         //TODO Make stats collection configurable as it add slight overhead
@@ -270,38 +267,39 @@ public final class MongoNodeStore
         docChildrenCacheStats = new CacheStats(docChildrenCache, "MongoMk-DocChildren",
                 builder.getWeigher(), builder.getDocChildrenCacheSize());
 
-        init();
-        // initial reading of the revisions of other cluster nodes
-        backgroundRead();
-        getRevisionComparator().add(headRevision, Revision.newRevision(0));
-        headRevision = newRevision();
-        dispatcher = new ChangeDispatcher(this);
-        commitQueue = new CommitQueue(this, dispatcher);
-
-        LOG.info("Initialized MongoNodeStore with clusterNodeId: {}", clusterId);
-    }
-
-    void init() {
-        headRevision = newRevision();
-        Node n = readNode("/", headRevision);
+        // check if root node exists
+        Revision head = newRevision();
+        Node n = readNode("/", head);
         if (n == null) {
             // root node is missing: repository is not initialized
-            Commit commit = new Commit(this, null, headRevision);
-            n = new Node("/", headRevision);
+            Commit commit = new Commit(this, null, head);
+            n = new Node("/", head);
             commit.addNode(n);
             commit.applyToDocumentStore();
             commit.applyToCache(false);
+            setHeadRevision(commit.getRevision());
             // make sure _lastRev is written back to store
             backgroundWrite();
         } else {
             // initialize branchCommits
             branches.init(store, this);
+            // initial reading of the revisions of other cluster nodes
+            backgroundRead();
+            if (headRevision == null) {
+                // no revision read from other cluster nodes
+                setHeadRevision(newRevision());
+            }
+            getRevisionComparator().add(headRevision, Revision.newRevision(0));
         }
+        dispatcher = new ChangeDispatcher(this);
+        commitQueue = new CommitQueue(this, dispatcher);
         backgroundThread = new Thread(
                 new BackgroundOperation(this, isDisposed),
                 "MongoNodeStore background thread");
         backgroundThread.setDaemon(true);
         backgroundThread.start();
+
+        LOG.info("Initialized MongoNodeStore with clusterNodeId: {}", clusterId);
     }
 
     public void dispose() {
@@ -328,9 +326,17 @@ public final class MongoNodeStore
         return headRevision;
     }
 
-    Revision setHeadRevision(Revision newHead) {
+    Revision setHeadRevision(@Nonnull Revision newHead) {
+        checkArgument(!newHead.isBranch());
         Revision previous = headRevision;
+        if (checkNotNull(newHead).equals(previous)) {
+            return previous;
+        }
+        // head changed
         headRevision = newHead;
+        if (previous != null) {
+            observer.contentChanged(getRoot(previous), getRoot(newHead));
+        }
         return previous;
     }
 
@@ -610,8 +616,7 @@ public final class MongoNodeStore
             docChildrenCache.put(path, clone);
             c = clone;
         }
-        Iterable<NodeDocument> it = Iterables.transform(c.childNames,
-                new Function<String, NodeDocument>() {
+        Iterable<NodeDocument> it = Iterables.transform(c.childNames, new Function<String, NodeDocument>() {
             @Override
             public NodeDocument apply(String name) {
                 String p = PathUtils.concat(path, name);
@@ -963,7 +968,7 @@ public final class MongoNodeStore
         revisionComparator.add(headRevision, headSeen);
         revisionComparator.add(changeRevision, changeSeen);
         // the head revision is after other revisions
-        headRevision = Revision.newRevision(clusterId);
+        setHeadRevision(Revision.newRevision(clusterId));
     }
 
     @Override
@@ -982,7 +987,7 @@ public final class MongoNodeStore
             // only when using timestamp
             return;
         }
-        if (!ENABLE_BACKGROUND_OPS || stopBackground) {
+        if (!ENABLE_BACKGROUND_OPS) {
             return;
         }
         try {
@@ -1058,7 +1063,7 @@ public final class MongoNodeStore
             // happened before the latest revisions of other cluster nodes
             revisionComparator.add(r, headSeen);
             // the head revision is after other revisions
-            headRevision = Revision.newRevision(clusterId);
+            setHeadRevision(Revision.newRevision(clusterId));
         }
         revisionComparator.purge(Revision.getCurrentTimestamp() - REMEMBER_REVISION_ORDER_MILLIS);
     }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/NodeStoreFixture.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/NodeStoreFixture.java?rev=1538908&r1=1538907&r2=1538908&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/NodeStoreFixture.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/NodeStoreFixture.java Tue Nov  5 09:05:39 2013
@@ -101,7 +101,7 @@ public abstract class NodeStoreFixture {
 
         @Override
         public NodeStore createNodeStore() {
-            return new MongoMK.Builder().getNodeStore();
+            return new MongoMK.Builder().setObserver(observer).getNodeStore();
         }
 
         @Override

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java?rev=1538908&r1=1538907&r2=1538908&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java Tue Nov  5 09:05:39 2013
@@ -137,9 +137,6 @@ public class NodeStoreTest {
 
     @Test
     public void afterCommitHook() throws CommitFailedException {
-        // FIXME OAK-1131
-        assumeTrue(fixture != NodeStoreFixture.MONGO_NS);
-
         final NodeState[] states = new NodeState[2]; // { before, after }
         fixture.setObserver(new Observer() {
             @Override

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java?rev=1538908&r1=1538907&r2=1538908&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java Tue Nov  5 09:05:39 2013
@@ -98,23 +98,23 @@ public class SimpleTest {
         String r0 = mk.getNodes("/", rev0, 0, 0, Integer.MAX_VALUE, ":id");
         assertEquals("{\":id\":\"/@r0-0-1\",\":childNodeCount\":0}", r0);
         String r1 = mk.getNodes("/", rev1, 0, 0, Integer.MAX_VALUE, ":id");
-        assertEquals("{\":id\":\"/@r2-0-1\",\"test\":{},\":childNodeCount\":1}", r1);
+        assertEquals("{\":id\":\"/@r1-0-1\",\"test\":{},\":childNodeCount\":1}", r1);
         String r2 = mk.getNodes("/", rev2, 0, 0, Integer.MAX_VALUE, ":id");
-        assertEquals("{\":id\":\"/@r3-0-1\",\"test\":{},\":childNodeCount\":1}", r2);
+        assertEquals("{\":id\":\"/@r2-0-1\",\"test\":{},\":childNodeCount\":1}", r2);
         String r3;
         r3 = mk.getNodes("/", rev3, 0, 0, Integer.MAX_VALUE, ":id");
-        assertEquals("{\":id\":\"/@r4-0-1\",\"test\":{},\":childNodeCount\":1}", r3);
+        assertEquals("{\":id\":\"/@r3-0-1\",\"test\":{},\":childNodeCount\":1}", r3);
         r3 = mk.getNodes("/test", rev3, 0, 0, Integer.MAX_VALUE, ":id");
-        assertEquals("{\":id\":\"/test@r4-0-1\",\"a\":{},\"b\":{},\":childNodeCount\":2}", r3);
+        assertEquals("{\":id\":\"/test@r3-0-1\",\"a\":{},\"b\":{},\":childNodeCount\":2}", r3);
         String r4;
         r4 = mk.getNodes("/", rev4, 0, 0, Integer.MAX_VALUE, ":id");
-        assertEquals("{\":id\":\"/@r5-0-1\",\"test\":{},\":childNodeCount\":1}", r4);
+        assertEquals("{\":id\":\"/@r4-0-1\",\"test\":{},\":childNodeCount\":1}", r4);
         r4 = mk.getNodes("/test", rev4, 0, 0, Integer.MAX_VALUE, ":id");
-        assertEquals("{\":id\":\"/test@r5-0-1\",\"a\":{},\"b\":{},\":childNodeCount\":2}", r4);
+        assertEquals("{\":id\":\"/test@r4-0-1\",\"a\":{},\"b\":{},\":childNodeCount\":2}", r4);
         r4 = mk.getNodes("/test/a", rev4, 0, 0, Integer.MAX_VALUE, ":id");
-        assertEquals("{\":id\":\"/test/a@r5-0-1\",\"x\":1,\":childNodeCount\":0}", r4);
+        assertEquals("{\":id\":\"/test/a@r4-0-1\",\"x\":1,\":childNodeCount\":0}", r4);
         r4 = mk.getNodes("/test/b", rev4, 0, 0, Integer.MAX_VALUE, ":id");
-        assertEquals("{\":id\":\"/test/b@r4-0-1\",\":childNodeCount\":0}", r4);
+        assertEquals("{\":id\":\"/test/b@r3-0-1\",\":childNodeCount\":0}", r4);
         
         mk.dispose();        
     }