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 2018/03/29 13:06:11 UTC

svn commit: r1827987 [1/4] - in /jackrabbit/oak/trunk: oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/ oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ oak-jcr/...

Author: mreutegg
Date: Thu Mar 29 13:06:10 2018
New Revision: 1827987

URL: http://svn.apache.org/viewvc?rev=1827987&view=rev
Log:
OAK-7360: Migrate to the MongoDB Java driver API 3.0

Added:
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterDescriptionProvider.java   (with props)
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobCodec.java   (with props)
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoClusterListener.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/DocumentToExternalMigrationTest.java
    jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoAzureDataStoreBlobGCTest.java
    jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoS3DataStoreBlobGCTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ObservationQueueTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/cluster/NonLocalObservationIT.java
    jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/directory/ActiveDeletedBlobCollectionIT.java
    jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java
    jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreHelper.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommand.java
    jackrabbit/oak/trunk/oak-run/src/test/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommandTest.java
    jackrabbit/oak/trunk/oak-store-document/pom.xml
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlob.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobReferenceIterator.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreMetrics.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoMissingLastRevSeeker.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoStatus.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoUtils.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoVersionGCSupport.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/replica/ReplicaSetInfo.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/CloseableIterable.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/com/mongodb/OakFongo.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/fixture/DocumentMongoFixture.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractMongoConnectionTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/BaseDocumentDiscoveryLiteServiceTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/BlobTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/CacheConsistencyTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/ClusterJoinTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/ClusterTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/CollisionWithSplitTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKBuilderTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreDiffTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoDocumentStoreTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/RandomizedClusterTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/SimpleTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/MongoBlobStoreTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/cloud/DocumentMKCloudGetLengthTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/cloud/DocumentMKCloudReadTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/cloud/DocumentMKCloudWriteTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/cloud/MongoCloudBlobGCTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/ds/DocumentMKDataStoreGetLengthTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/ds/DocumentMKDataStoreReadTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/ds/DocumentMKDataStoreWriteTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/blob/ds/MongoDataStoreBlobGCTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/impl/DocumentMKConcurrentAddTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/AcquireRecoveryLockTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/CacheInvalidationIT.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/CollisionMarkerTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/JournalIT.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoCacheConsistencyTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreMetricsTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTestHelper.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoMissingLastRevSeekerTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoStatusTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoUtilsTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/QueryHintTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ReadPreferenceIT.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/RetryReadIT.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/replica/ReplicaSetInfoMock.java
    jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java

Modified: jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/DocumentToExternalMigrationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/DocumentToExternalMigrationTest.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/DocumentToExternalMigrationTest.java (original)
+++ jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/DocumentToExternalMigrationTest.java Thu Mar 29 13:06:10 2018
@@ -68,7 +68,7 @@ public class DocumentToExternalMigration
         if (blobStore != null) {
             builder.setBlobStore(blobStore);
         }
-        builder.setMongoDB(connection.getDB());
+        builder.setMongoDB(connection.getMongoClient(), connection.getDBName());
         return nodeStore = builder.getNodeStore();
     }
 
@@ -88,7 +88,7 @@ public class DocumentToExternalMigration
     @Override
     protected BlobStore createOldBlobStore(File repository) {
         MongoConnection connection = connectionFactory.getConnection();
-        return new MongoBlobStore(connection.getDB());
+        return new MongoBlobStore(connection.getDatabase());
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoAzureDataStoreBlobGCTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoAzureDataStoreBlobGCTest.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoAzureDataStoreBlobGCTest.java (original)
+++ jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoAzureDataStoreBlobGCTest.java Thu Mar 29 13:06:10 2018
@@ -50,15 +50,16 @@ public class MongoAzureDataStoreBlobGCTe
         Properties props = AzureDataStoreUtils.getAzureConfig();
         startDate = new Date();
         mongoConnection = connectionFactory.getConnection();
-        MongoUtils.dropCollections(mongoConnection.getDB());
+        MongoUtils.dropCollections(mongoConnection.getDatabase());
         File root = folder.newFolder();
         bucket = root.getName();
         props.setProperty(AzureConstants.AZURE_BLOB_CONTAINER_NAME, bucket);
         props.setProperty("cacheSize", "0");
         blobStore = new DataStoreBlobStore(
             AzureDataStoreUtils.getAzureDataStore(props, root.getAbsolutePath()));
-        mk = new DocumentMK.Builder().clock(getTestClock()).setMongoDB(mongoConnection.getDB())
-            .setBlobStore(blobStore).open();
+        mk = new DocumentMK.Builder().clock(getTestClock())
+                .setMongoDB(mongoConnection.getMongoClient(), mongoConnection.getDBName())
+                .setBlobStore(blobStore).open();
     }
 
     @After

Modified: jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoS3DataStoreBlobGCTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoS3DataStoreBlobGCTest.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoS3DataStoreBlobGCTest.java (original)
+++ jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoS3DataStoreBlobGCTest.java Thu Mar 29 13:06:10 2018
@@ -62,7 +62,7 @@ public class MongoS3DataStoreBlobGCTest
         Properties props = S3DataStoreUtils.getS3Config();
         startDate = new Date();
         mongoConnection = connectionFactory.getConnection();
-        MongoUtils.dropCollections(mongoConnection.getDB());
+        MongoUtils.dropCollections(mongoConnection.getDatabase());
         File root = folder.newFolder();
         bucket = root.getName();
         props.setProperty(S3Constants.S3_BUCKET, bucket);
@@ -70,8 +70,9 @@ public class MongoS3DataStoreBlobGCTest
 
         blobStore = new DataStoreBlobStore(
             S3DataStoreUtils.getS3DataStore(s3Class, props, root.getAbsolutePath()));
-        mk = new DocumentMK.Builder().clock(getTestClock()).setMongoDB(mongoConnection.getDB())
-            .setBlobStore(blobStore).open();
+        mk = new DocumentMK.Builder().clock(getTestClock())
+                .setMongoDB(mongoConnection.getMongoClient(), mongoConnection.getDBName())
+                .setBlobStore(blobStore).open();
     }
 
     @After

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java Thu Mar 29 13:06:10 2018
@@ -92,8 +92,9 @@ public class ConcurrentAddNodesClusterIT
     @Test
     public void addNodesConcurrent() throws Exception {
         for (int i = 0; i < NUM_CLUSTER_NODES; i++) {
+            MongoConnection c = createConnection();
             DocumentMK mk = new DocumentMK.Builder()
-                    .setMongoDB(createConnection().getDB())
+                    .setMongoDB(c.getMongoClient(), c.getDBName())
                     .setClusterId(i + 1).open();
             mks.add(mk);
         }
@@ -122,8 +123,9 @@ public class ConcurrentAddNodesClusterIT
     public void addNodesConcurrent2() throws Exception {
         final Thread mainThread = Thread.currentThread();
         for (int i = 0; i < NUM_CLUSTER_NODES; i++) {
+            MongoConnection c = createConnection();
             DocumentMK mk = new DocumentMK.Builder()
-                    .setMongoDB(createConnection().getDB())
+                    .setMongoDB(c.getMongoClient(), c.getDBName())
                     .setClusterId(i + 1).open();
             mks.add(mk);
         }
@@ -208,8 +210,9 @@ public class ConcurrentAddNodesClusterIT
     @Test
     public void addNodes() throws Exception {
         for (int i = 0; i < 2; i++) {
+            MongoConnection c = createConnection();
             DocumentMK mk = new DocumentMK.Builder()
-                    .setMongoDB(createConnection().getDB())
+                    .setMongoDB(c.getMongoClient(), c.getDBName())
                     .setClusterId(i + 1).open();
             mks.add(mk);
         }
@@ -242,8 +245,9 @@ public class ConcurrentAddNodesClusterIT
     @Test
     public void addNodes2() throws Exception {
         for (int i = 0; i < 3; i++) {
+            MongoConnection c = createConnection();
             DocumentMK mk = new DocumentMK.Builder()
-                    .setMongoDB(createConnection().getDB())
+                    .setMongoDB(c.getMongoClient(), c.getDBName())
                     .setAsyncDelay(0)
                     .setClusterId(i + 1).open();
             mks.add(mk);
@@ -321,8 +325,9 @@ public class ConcurrentAddNodesClusterIT
     @Test
     public void rebaseVisibility() throws Exception {
         for (int i = 0; i < 2; i++) {
+            MongoConnection c = createConnection();
             DocumentMK mk = new DocumentMK.Builder()
-                    .setMongoDB(createConnection().getDB())
+                    .setMongoDB(c.getMongoClient(), c.getDBName())
                     .setAsyncDelay(0)
                     .setClusterId(i + 1).open();
             mks.add(mk);
@@ -380,7 +385,7 @@ public class ConcurrentAddNodesClusterIT
     private static void initRepository() throws Exception {
         MongoConnection con = createConnection();
         DocumentMK mk = new DocumentMK.Builder()
-                .setMongoDB(con.getDB())
+                .setMongoDB(con.getMongoClient(), con.getDBName())
                 .setClusterId(1).open();
         Repository repository = new Jcr(mk.getNodeStore()).createRepository();
         Session session = repository.login(

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ObservationQueueTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ObservationQueueTest.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ObservationQueueTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ObservationQueueTest.java Thu Mar 29 13:06:10 2018
@@ -57,6 +57,7 @@ import org.apache.jackrabbit.oak.fixture
 import org.apache.jackrabbit.oak.jcr.cluster.AbstractClusterTest;
 import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
 import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
+import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
 import org.apache.jackrabbit.oak.spi.commit.BackgroundObserverMBean;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
@@ -146,8 +147,9 @@ public class ObservationQueueTest extend
         return new DocumentMongoFixture() {
             @Override
             public NodeStore createNodeStore(int clusterNodeId) {
+                MongoConnection c = MongoUtils.getConnection("oak-test");
                 return new DocumentMK.Builder().setClusterId(clusterNodeId)
-                        .setMongoDB(MongoUtils.getConnection("oak-test").getDB())
+                        .setMongoDB(c.getMongoClient(), c.getDBName())
                         .setPersistentCache("target/persistentCache" + clusterNodeId + ",time,size=128")
                         .setJournalCache("target/journalCache" + clusterNodeId + ",time,size=128")
                         .memoryCacheSize(128 * MB)

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/cluster/NonLocalObservationIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/cluster/NonLocalObservationIT.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/cluster/NonLocalObservationIT.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/cluster/NonLocalObservationIT.java Thu Mar 29 13:06:10 2018
@@ -48,7 +48,7 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.mongodb.DB;
+import com.mongodb.MongoClient;
 
 /**
  * Test for external events from another cluster node.
@@ -73,10 +73,8 @@ public class NonLocalObservationIT exten
          */
         return new DocumentMongoFixture() {
             
-            private String clusterSuffix = System.currentTimeMillis() + "-NonLocalObservationIT";
+            private String dbName = System.currentTimeMillis() + "-NonLocalObservationIT";
 
-            private DB db;
-            
             /** keep a reference to the node stores so that the db only gets closed after the last nodeStore was closed */
             private Set<NodeStore> nodeStores = new HashSet<NodeStore>();
 
@@ -95,9 +93,7 @@ public class NonLocalObservationIT exten
                     DocumentMK.Builder builder = new DocumentMK.Builder();
                     builder.memoryCacheSize(32*1024*1024); // keep this one low to avoid OOME
                     builder.setPersistentCache(null);      // turn this one off to avoid OOME
-                    final String suffix = clusterSuffix;
-                    db = getDb(suffix); // db will be overwritten - but that's fine
-                    builder.setMongoDB(db);
+                    builder.setMongoDB(createClient(), dbName);
                     DocumentNodeStore ns = builder.getNodeStore();
                     nodeStores.add(ns);
                     return ns;
@@ -110,11 +106,9 @@ public class NonLocalObservationIT exten
             public void dispose(NodeStore nodeStore) {
                 super.dispose(nodeStore);
                 nodeStores.remove(nodeStore);
-                if (db != null && nodeStores.size() == 0) {
-                    try {
-                        db.dropDatabase();
-                        db.getMongo().close();
-                        db = null;
+                if (nodeStores.size() == 0) {
+                    try (MongoClient c = createClient()) {
+                        c.dropDatabase(dbName);
                     } catch (Exception e) {
                         log.error("dispose: Can't close Mongo", e);
                     }

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/directory/ActiveDeletedBlobCollectionIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/directory/ActiveDeletedBlobCollectionIT.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/directory/ActiveDeletedBlobCollectionIT.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/directory/ActiveDeletedBlobCollectionIT.java Thu Mar 29 13:06:10 2018
@@ -96,9 +96,9 @@ public class ActiveDeletedBlobCollection
                 null, Mounts.defaultMountInfoProvider(), adbc);
         provider = new LuceneIndexProvider(copier);
         mongoConnection = connectionFactory.getConnection();
-        MongoUtils.dropCollections(mongoConnection.getDB());
+        MongoUtils.dropCollections(mongoConnection.getDatabase());
         if (dataStoreType == DataStoreType.WITHOUT_FDS) {
-            MongoBlobStore blobStore = new MongoBlobStore(mongoConnection.getDB());
+            MongoBlobStore blobStore = new MongoBlobStore(mongoConnection.getDatabase());
             blobStore.setBlockSize(128);
             blobStore.setBlockSizeMin(48);
             this.blobStore = new CountingBlobStore(blobStore);
@@ -110,7 +110,7 @@ public class ActiveDeletedBlobCollection
             this.blobStore = new CountingBlobStore(dsbs);
         }
         nodeStore = new DocumentMK.Builder()
-                .setMongoDB(mongoConnection.getDB())
+                .setMongoDB(mongoConnection.getMongoClient(), mongoConnection.getDBName())
                 .setBlobStore(this.blobStore)
                 .getNodeStore();
         asyncIndexUpdate = new AsyncIndexUpdate("async", nodeStore, editorProvider);

Modified: jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java (original)
+++ jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java Thu Mar 29 13:06:10 2018
@@ -31,10 +31,12 @@ import com.google.common.cache.Cache;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.primitives.Longs;
-import com.mongodb.DBCollection;
-import com.mongodb.DBCursor;
+import com.mongodb.BasicDBObject;
 import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.Filters;
+
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.PropertyState;
@@ -44,6 +46,7 @@ import org.apache.jackrabbit.oak.commons
 import org.apache.jackrabbit.oak.plugins.document.mongo.MongoDocumentStore;
 import org.apache.jackrabbit.oak.plugins.document.mongo.MongoDocumentStoreHelper;
 import org.apache.jackrabbit.oak.plugins.document.util.Utils;
+import org.bson.conversions.Bson;
 
 /**
  * Helper class to access package private method of DocumentNodeStore and other
@@ -143,12 +146,10 @@ public class DocumentNodeStoreHelper {
         if (store instanceof MongoDocumentStore) {
             // optimized implementation for MongoDocumentStore
             final MongoDocumentStore mds = (MongoDocumentStore) store;
-            DBCollection dbCol = MongoDocumentStoreHelper.getDBCollection(
+            MongoCollection<BasicDBObject> dbCol = MongoDocumentStoreHelper.getDBCollection(
                     mds, Collection.NODES);
-            DBObject query = QueryBuilder.start(NodeDocument.HAS_BINARY_FLAG)
-                    .is(NodeDocument.HAS_BINARY_VAL)
-                    .get();
-            DBCursor cursor = dbCol.find(query);
+            Bson query = Filters.eq(NodeDocument.HAS_BINARY_FLAG, NodeDocument.HAS_BINARY_VAL);
+            FindIterable<BasicDBObject> cursor = dbCol.find(query);
             return Iterables.transform(cursor, new Function<DBObject, NodeDocument>() {
                 @Nullable
                 @Override

Modified: jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreHelper.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreHelper.java (original)
+++ jackrabbit/oak/trunk/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreHelper.java Thu Mar 29 13:06:10 2018
@@ -23,16 +23,18 @@ import java.util.SortedMap;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.mongodb.BasicDBObject;
-import com.mongodb.DBCollection;
 import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import com.mongodb.WriteResult;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.Filters;
+import com.mongodb.client.result.UpdateResult;
+
 import org.apache.jackrabbit.oak.plugins.document.Collection;
 import org.apache.jackrabbit.oak.plugins.document.Document;
 import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
 import org.apache.jackrabbit.oak.plugins.document.NodeDocumentHelper;
 import org.apache.jackrabbit.oak.plugins.document.Revision;
 import org.apache.jackrabbit.oak.plugins.document.util.Utils;
+import org.bson.conversions.Bson;
 
 import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
 
@@ -45,7 +47,7 @@ public class MongoDocumentStoreHelper {
     }
 
     public static void repair(MongoDocumentStore store, String path) {
-        DBCollection col = store.getDBCollection(NODES);
+        MongoCollection<BasicDBObject> col = store.getDBCollection(NODES);
         String id = Utils.getIdFromPath(path);
 
         NodeDocument doc = store.find(NODES, id);
@@ -73,19 +75,21 @@ public class MongoDocumentStoreHelper {
             System.err.println("Document does not have a modCount " + path);
             return;
         }
-        DBObject query = QueryBuilder.start(Document.ID).is(id)
-                .and(Document.MOD_COUNT).is(modCount).get();
+        Bson query = Filters.and(
+                Filters.eq(Document.ID, id),
+                Filters.eq(Document.MOD_COUNT, modCount)
+        );
         DBObject cr = new BasicDBObject();
         for (Map.Entry<Revision, String> entry : commitRoot.entrySet()) {
             cr.put(entry.getKey().toString(), entry.getValue());
         }
         
-        DBObject update = new BasicDBObject();
+        BasicDBObject update = new BasicDBObject();
         update.put("$set", new BasicDBObject(NodeDocumentHelper.commitRoot(), cr));
         update.put("$inc", new BasicDBObject(Document.MOD_COUNT, 1L));
                 
-        WriteResult result = col.update(query, update);
-        if (result.getN() == 1) {
+        UpdateResult result = col.updateOne(query, update);
+        if (result.getModifiedCount() == 1) {
             int num = NodeDocumentHelper.getLocalCommitRoot(doc).size() - commitRoot.size();
             System.out.println("Removed " + num + " _commitRoot entries on " + path);
         } else {
@@ -94,7 +98,7 @@ public class MongoDocumentStoreHelper {
         
     }
 
-    public static <T extends Document> DBCollection getDBCollection(
+    public static <T extends Document> MongoCollection<BasicDBObject> getDBCollection(
             MongoDocumentStore store, Collection<T> c) {
         return store.getDBCollection(c);
     }

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java Thu Mar 29 13:06:10 2018
@@ -22,9 +22,9 @@ package org.apache.jackrabbit.oak.plugin
 import java.util.function.Predicate;
 
 import com.google.common.collect.FluentIterable;
-import com.google.common.io.Closer;
-import com.mongodb.DBCollection;
-import com.mongodb.DBCursor;
+import com.mongodb.BasicDBObject;
+import com.mongodb.client.MongoCollection;
+
 import org.apache.jackrabbit.oak.plugins.document.Collection;
 import org.apache.jackrabbit.oak.plugins.document.Document;
 import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
@@ -46,19 +46,19 @@ public class MongoDocumentTraverser {
             checkState(mongoStore.isReadOnly(), "Traverser can only be used with readOnly store");
         }
 
-        DBCollection dbCollection = mongoStore.getDBCollection(collection);
-        Closer closer = Closer.create();
-
-
-        DBCursor cursor = dbCollection.find();
+        MongoCollection<BasicDBObject> dbCollection = mongoStore.getDBCollection(collection);
         //TODO This may lead to reads being routed to secondary depending on MongoURI
         //So caller must ensure that its safe to read from secondary
-        cursor.setReadPreference(mongoStore.getConfiguredReadPreference(collection));
-        closer.register(cursor);
+        Iterable<BasicDBObject> cursor = dbCollection
+                .withReadPreference(mongoStore.getConfiguredReadPreference(collection))
+                .find();
+
+        CloseableIterable<BasicDBObject> closeableCursor = CloseableIterable.wrap(cursor);
+        cursor = closeableCursor;
 
         @SuppressWarnings("Guava")
         Iterable<T> result = FluentIterable.from(cursor)
-                .filter(o -> filter.test((String) o.get("_id")))
+                .filter(o -> filter.test((String) o.get(Document.ID)))
                 .transform(o -> {
                     T doc = mongoStore.convertFromDBObject(collection, o);
                     //TODO Review the cache update approach where tracker has to track *all* docs
@@ -68,7 +68,7 @@ public class MongoDocumentTraverser {
                     }
                     return doc;
                 });
-        return CloseableIterable.wrap(result, closer);
+        return CloseableIterable.wrap(result, closeableCursor);
     }
 
     /**

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommand.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommand.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommand.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommand.java Thu Mar 29 13:06:10 2018
@@ -80,7 +80,9 @@ class UnlockUpgradeCommand implements Co
                     System.err.println("Database missing in MongoDB URI: " + clientURI.getURI());
                 } else {
                     MongoConnection mongo = new MongoConnection(clientURI.getURI());
-                    store = new MongoDocumentStore(mongo.getDB(), new MongoDocumentNodeStoreBuilder());
+                    store = new MongoDocumentStore(
+                            mongo.getMongoClient(), mongo.getDBName(),
+                            new MongoDocumentNodeStoreBuilder());
                 }
             } else if (uri.startsWith("jdbc")) {
                 DataSource ds = RDBDataSourceFactory.forJdbcUrl(uri,

Modified: jackrabbit/oak/trunk/oak-run/src/test/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommandTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/test/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommandTest.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/test/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommandTest.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/test/java/org/apache/jackrabbit/oak/run/UnlockUpgradeCommandTest.java Thu Mar 29 13:06:10 2018
@@ -74,13 +74,15 @@ public class UnlockUpgradeCommandTest {
 
     private DocumentNodeStore createDocumentNodeStore() {
         MongoConnection c = connectionFactory.getConnection();
-        MongoUtils.dropCollections(c.getDB().getName());
-        return builderProvider.newBuilder().setMongoDB(c.getDB()).getNodeStore();
+        MongoUtils.dropCollections(c.getDBName());
+        return builderProvider.newBuilder()
+                .setMongoDB(c.getMongoClient(), c.getDBName()).getNodeStore();
     }
 
     private void resetFormatVersion(FormatVersion v) {
         MongoConnection c = connectionFactory.getConnection();
-        DocumentStore s = new MongoDocumentStore(c.getDB(), newMongoDocumentNodeStoreBuilder());
+        DocumentStore s = new MongoDocumentStore(c.getMongoClient(),
+                c.getDBName(), newMongoDocumentNodeStoreBuilder());
         s.remove(Collection.SETTINGS, "version");
         assertTrue(v.writeTo(s));
         s.dispose();

Modified: jackrabbit/oak/trunk/oak-store-document/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/pom.xml?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-store-document/pom.xml Thu Mar 29 13:06:10 2018
@@ -39,7 +39,7 @@
         <configuration>
           <instructions>
             <Import-Package>
-              com.mongodb*;version="[2.14, 4)";resolution:=optional,
+              com.mongodb*;version="[3, 4)";resolution:=optional,
               *
             </Import-Package>
             <Export-Package>

Added: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterDescriptionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterDescriptionProvider.java?rev=1827987&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterDescriptionProvider.java (added)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterDescriptionProvider.java Thu Mar 29 13:06:10 2018
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.document.mongo;
+
+import javax.annotation.CheckForNull;
+
+import com.mongodb.connection.ClusterDescription;
+
+/**
+ * Provider of the current {@link ClusterDescription}.
+ */
+interface ClusterDescriptionProvider {
+
+    @CheckForNull
+    ClusterDescription getClusterDescription();
+}

Propchange: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterDescriptionProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlob.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlob.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlob.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlob.java Thu Mar 29 13:06:10 2018
@@ -16,19 +16,27 @@
  */
 package org.apache.jackrabbit.oak.plugins.document.mongo;
 
-import com.mongodb.BasicDBObject;
+import org.bson.BsonDocument;
+import org.bson.BsonDocumentWrapper;
+import org.bson.Document;
+import org.bson.codecs.configuration.CodecRegistry;
+import org.bson.conversions.Bson;
+import org.bson.types.Binary;
 
 /**
  * The {@code MongoDB} representation of a blob. Only used by MongoBlobStore
  */
-public class MongoBlob extends BasicDBObject {
+public class MongoBlob implements Bson {
 
     public static final String KEY_ID = "_id";
     public static final String KEY_DATA = "data";
     public static final String KEY_LAST_MOD = "lastMod";
     public static final String KEY_LEVEL = "level";
 
-    private static final long serialVersionUID = 5119970546251968672L;
+    private String id;
+    private byte[] data;
+    private int level;
+    private long lastMod;
 
     /**
      * Default constructor. Needed for MongoDB serialization.
@@ -36,35 +44,63 @@ public class MongoBlob extends BasicDBOb
     public MongoBlob() {
     }
 
+    static MongoBlob fromDocument(Document doc) {
+        MongoBlob blob = new MongoBlob();
+        blob.setId(doc.getString(KEY_ID));
+        blob.setLevel(doc.getInteger(KEY_LEVEL, 0));
+        if (doc.containsKey(KEY_LAST_MOD)) {
+            blob.setLastMod(doc.getLong(KEY_LAST_MOD));
+        }
+        if (doc.containsKey(KEY_DATA)) {
+            blob.setData(doc.get(KEY_DATA, Binary.class).getData());
+        }
+        return blob;
+    }
+
+    Document asDocument() {
+        Document doc = new Document();
+        doc.put(KEY_ID, id);
+        doc.put(KEY_LEVEL, level);
+        doc.put(KEY_LAST_MOD, lastMod);
+        doc.put(KEY_DATA, data);
+        return doc;
+    }
+
     public String getId() {
-        return getString(KEY_ID);
+        return id;
     }
 
     public void setId(String id) {
-        put(KEY_ID, id);
+        this.id = id;
     }
 
     public byte[] getData() {
-        return (byte[]) get(KEY_DATA);
+        return data;
     }
 
     public void setData(byte[] data) {
-        put(KEY_DATA, data);
+        this.data = data;
     }
 
     public int getLevel() {
-        return getInt(KEY_LEVEL);
+        return level;
     }
 
     public void setLevel(int level) {
-        put(KEY_LEVEL, level);
+        this.level = level;
     }
 
     public long getLastMod() {
-        return getLong(KEY_LAST_MOD);
+        return lastMod;
     }
 
     public void setLastMod(long lastMod) {
-        put(KEY_LAST_MOD, lastMod);
+        this.lastMod = lastMod;
+    }
+
+    @Override
+    public <TDocument> BsonDocument toBsonDocument(Class<TDocument> tDocumentClass,
+                                                   CodecRegistry codecRegistry) {
+        return new BsonDocumentWrapper<>(this, codecRegistry.get(MongoBlob.class));
     }
 }
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobCodec.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobCodec.java?rev=1827987&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobCodec.java (added)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobCodec.java Thu Mar 29 13:06:10 2018
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.document.mongo;
+
+import org.bson.BsonReader;
+import org.bson.BsonString;
+import org.bson.BsonValue;
+import org.bson.BsonWriter;
+import org.bson.Document;
+import org.bson.codecs.Codec;
+import org.bson.codecs.CollectibleCodec;
+import org.bson.codecs.DecoderContext;
+import org.bson.codecs.DocumentCodec;
+import org.bson.codecs.EncoderContext;
+
+class MongoBlobCodec implements CollectibleCodec<MongoBlob> {
+
+    private final Codec<Document> documentCodec = new DocumentCodec();
+
+    MongoBlobCodec() {
+    }
+
+    @Override
+    public MongoBlob generateIdIfAbsentFromDocument(MongoBlob document) {
+        if (!documentHasId(document)) {
+            throw new IllegalStateException("MongoBlob must not have generated id");
+        }
+        return document;
+    }
+
+    @Override
+    public boolean documentHasId(MongoBlob document) {
+        return document.getId() != null;
+    }
+
+    @Override
+    public BsonValue getDocumentId(MongoBlob document) {
+        if (!documentHasId(document)) {
+            throw new IllegalStateException("MongoBlob does not have an id");
+        }
+        return new BsonString(document.getId());
+    }
+
+    @Override
+    public MongoBlob decode(BsonReader reader, DecoderContext decoderContext) {
+        Document doc = documentCodec.decode(reader, decoderContext);
+        return MongoBlob.fromDocument(doc);
+    }
+
+    @Override
+    public void encode(BsonWriter writer,
+                       MongoBlob value,
+                       EncoderContext encoderContext) {
+        Document doc = value.asDocument();
+        documentCodec.encode(writer, doc, encoderContext);
+    }
+
+    @Override
+    public Class<MongoBlob> getEncoderClass() {
+        return MongoBlob.class;
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobCodec.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobReferenceIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobReferenceIterator.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobReferenceIterator.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobReferenceIterator.java Thu Mar 29 13:06:10 2018
@@ -19,20 +19,20 @@
 
 package org.apache.jackrabbit.oak.plugins.document.mongo;
 
-import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Iterators.transform;
+import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
 
 import java.util.Iterator;
 
 import org.apache.jackrabbit.oak.plugins.document.BlobReferenceIterator;
-import org.apache.jackrabbit.oak.plugins.document.Collection;
 import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
 import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
-import org.apache.jackrabbit.oak.plugins.document.util.CloseableIterable;
+import org.apache.jackrabbit.oak.plugins.document.util.CloseableIterator;
+import org.bson.conversions.Bson;
 
-import com.google.common.base.Function;
-import com.mongodb.DBCursor;
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
+import com.mongodb.BasicDBObject;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.model.Filters;
 
 public class MongoBlobReferenceIterator extends BlobReferenceIterator {
 
@@ -45,17 +45,14 @@ public class MongoBlobReferenceIterator
 
     @Override
     public Iterator<NodeDocument> getIteratorOverDocsWithBinaries() {
-        DBObject query = QueryBuilder.start(NodeDocument.HAS_BINARY_FLAG).is(NodeDocument.HAS_BINARY_VAL).get();
+        Bson query = Filters.eq(NodeDocument.HAS_BINARY_FLAG, NodeDocument.HAS_BINARY_VAL);
         // TODO It currently prefers secondary. Would that be Ok?
-        DBCursor cursor = documentStore.getDBCollection(Collection.NODES).find(query)
-                .setReadPreference(documentStore.getConfiguredReadPreference(Collection.NODES));
-
-        return CloseableIterable.wrap(transform(cursor, new Function<DBObject, NodeDocument>() {
-            @Override
-            public NodeDocument apply(DBObject input) {
-                return documentStore.convertFromDBObject(Collection.NODES, input);
-            }
-        }), cursor).iterator();
-
+        MongoCursor<BasicDBObject> cursor = documentStore.getDBCollection(NODES)
+                .withReadPreference(documentStore.getConfiguredReadPreference(NODES))
+                .find(query).iterator();
+
+        return CloseableIterator.wrap(transform(cursor,
+                input -> documentStore.convertFromDBObject(NODES, input)),
+                cursor);
     }
 }

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java Thu Mar 29 13:06:10 2018
@@ -17,30 +17,38 @@
 package org.apache.jackrabbit.oak.plugins.document.mongo;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.jackrabbit.oak.commons.StringUtils;
 import org.apache.jackrabbit.oak.plugins.blob.CachingBlobStore;
+import org.bson.Document;
+import org.bson.codecs.configuration.CodecRegistry;
+import org.bson.conversions.Bson;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.AbstractIterator;
 import com.mongodb.BasicDBObject;
-import com.mongodb.Bytes;
-import com.mongodb.DB;
-import com.mongodb.DBCollection;
-import com.mongodb.DBCursor;
-import com.mongodb.DBObject;
 import com.mongodb.DuplicateKeyException;
-import com.mongodb.QueryBuilder;
-import com.mongodb.ReadPreference;
-import com.mongodb.WriteResult;
+import com.mongodb.MongoClient;
+import com.mongodb.MongoException;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.MongoDatabase;
+import com.mongodb.client.model.Filters;
+
+import static com.mongodb.ReadPreference.primary;
+import static com.mongodb.ReadPreference.secondaryPreferred;
+import static java.util.stream.StreamSupport.stream;
+import static org.bson.codecs.configuration.CodecRegistries.fromCodecs;
+import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
 
 /**
  * Implementation of blob store for the MongoDB extending from
- * {@link org.apache.jackrabbit.oak.spi.blob.AbstractBlobStore}. It saves blobs into a separate collection in
+ * {@link CachingBlobStore}. It saves blobs into a separate collection in
  * MongoDB (not using GridFS) and it supports basic garbage collection.
  *
  * FIXME: -Do we need to create commands for retry etc.? -Not sure if this is
@@ -52,7 +60,14 @@ public class MongoBlobStore extends Cach
 
     private static final Logger LOG = LoggerFactory.getLogger(MongoBlobStore.class);
 
-    private final DB db;
+    private static final int DUPLICATE_KEY_ERROR_CODE = 11000;
+
+    private static final CodecRegistry CODEC_REGISTRY = fromRegistries(
+            MongoClient.getDefaultCodecRegistry(),
+            fromCodecs(new MongoBlobCodec())
+    );
+
+    private final MongoCollection<MongoBlob> blobCollection;
     private long minLastModified;
 
     /**
@@ -60,18 +75,17 @@ public class MongoBlobStore extends Cach
      *
      * @param db The DB.
      */
-    public MongoBlobStore(DB db) {
+    public MongoBlobStore(MongoDatabase db) {
         this(db, DEFAULT_CACHE_SIZE);
     }
 
-    public MongoBlobStore(DB db, long cacheSize) {
+    public MongoBlobStore(MongoDatabase db, long cacheSize) {
         super(cacheSize);
-        this.db = db;
         // use a block size of 2 MB - 1 KB, because MongoDB rounds up the
         // space allocated for a record to the next power of two
         // (there is an overhead per record, let's assume it is 1 KB at most)
         setBlockSize(2 * 1024 * 1024 - 1024);
-        initBlobCollection();
+        blobCollection = initBlobCollection(db);
     }
 
     @Override
@@ -87,9 +101,15 @@ public class MongoBlobStore extends Cach
         // TODO check the return value
         // TODO verify insert is fast if the entry already exists
         try {
-            getBlobCollection().insert(mongoBlob);
+            getBlobCollection().insertOne(mongoBlob);
         } catch (DuplicateKeyException e) {
             // the same block was already stored before: ignore
+        } catch (MongoException e) {
+            if (e.getCode() == DUPLICATE_KEY_ERROR_CODE) {
+                // the same block was already stored before: ignore
+            } else {
+                throw new IOException(e.getMessage(), e);
+            }
         }
     }
 
@@ -138,101 +158,101 @@ public class MongoBlobStore extends Cach
             return;
         }
         String id = StringUtils.convertBytesToHex(blockId.getDigest());
-        DBObject query = getBlobQuery(id, minLastModified);
-        DBObject update = new BasicDBObject("$set",
+        Bson query = getBlobQuery(id, minLastModified);
+        Bson update = new BasicDBObject("$set",
                 new BasicDBObject(MongoBlob.KEY_LAST_MOD, System.currentTimeMillis()));
-        getBlobCollection().update(query, update);
+        getBlobCollection().updateOne(query, update);
     }
 
     @Override
     public int sweep() throws IOException {
-        DBObject query = getBlobQuery(null, minLastModified);
-        long countBefore = getBlobCollection().count(query);
-        getBlobCollection().remove(query);
-
-        long countAfter = getBlobCollection().count(query);
+        Bson query = getBlobQuery(null, minLastModified);
+        long num = getBlobCollection().deleteMany(query).getDeletedCount();
         minLastModified = 0;
-        return (int) (countBefore - countAfter);
+        return (int) num;
     }
 
-    private DBCollection getBlobCollection() {
-        DBCollection collection = db.getCollection(COLLECTION_BLOBS);
-        collection.setObjectClass(MongoBlob.class);
-        return collection;
+    private MongoCollection<MongoBlob> initBlobCollection(MongoDatabase db) {
+        if (stream(db.listCollectionNames().spliterator(), false)
+                .noneMatch(COLLECTION_BLOBS::equals)) {
+            db.createCollection(COLLECTION_BLOBS);
+        }
+        return db.getCollection(COLLECTION_BLOBS, MongoBlob.class)
+                .withCodecRegistry(CODEC_REGISTRY);
     }
 
-    private void initBlobCollection() {
-        if (!db.collectionExists(COLLECTION_BLOBS)) {
-            db.createCollection(COLLECTION_BLOBS, new BasicDBObject());
-        }
+    private MongoCollection<MongoBlob> getBlobCollection() {
+        return this.blobCollection;
     }
 
     private MongoBlob getBlob(String id, long lastMod) {
-        DBObject query = getBlobQuery(id, lastMod);
+        Bson query = getBlobQuery(id, lastMod);
+        Bson fields = new BasicDBObject(MongoBlob.KEY_DATA, 1);
 
         // try the secondary first
         // TODO add a configuration option for whether to try reading from secondary
-        ReadPreference pref = ReadPreference.secondaryPreferred();
-        DBObject fields = new BasicDBObject();
-        fields.put(MongoBlob.KEY_DATA, 1);
-        MongoBlob blob = (MongoBlob) getBlobCollection().findOne(query, fields, pref);
-        if (blob == null) {
+        List<MongoBlob> result = new ArrayList<>(1);
+        getBlobCollection().withReadPreference(secondaryPreferred()).find(query)
+                .projection(fields).into(result);
+        if (result.isEmpty()) {
             // not found in the secondary: try the primary
-            pref = ReadPreference.primary();
-            blob = (MongoBlob) getBlobCollection().findOne(query, fields, pref);
+            getBlobCollection().withReadPreference(primary()).find(query)
+                    .projection(fields).into(result);
         }
-        return blob;
+        return result.isEmpty() ? null : result.get(0);
     }
 
-    private static DBObject getBlobQuery(String id, long lastMod) {
-        QueryBuilder queryBuilder = new QueryBuilder();
+    private static Bson getBlobQuery(String id, long lastMod) {
+        List<Bson> clauses = new ArrayList<>(2);
         if (id != null) {
-            queryBuilder = queryBuilder.and(MongoBlob.KEY_ID).is(id);
+            clauses.add(Filters.eq(MongoBlob.KEY_ID, id));
         }
         if (lastMod > 0) {
-            queryBuilder = queryBuilder.and(MongoBlob.KEY_LAST_MOD).lessThan(lastMod);
+            clauses.add(Filters.lt(MongoBlob.KEY_LAST_MOD, lastMod));
+        }
+
+        if (clauses.size() == 1) {
+            return clauses.get(0);
+        } else {
+            return Filters.and(clauses);
         }
-        return queryBuilder.get();
     }
 
     @Override
     public long countDeleteChunks(List<String> chunkIds, long maxLastModifiedTime) throws Exception {
-        DBCollection collection = getBlobCollection();
-        QueryBuilder queryBuilder = new QueryBuilder();
+        Bson query = new Document();
         if (chunkIds != null) {
-            queryBuilder = queryBuilder.and(MongoBlob.KEY_ID).in(chunkIds.toArray(new String[0]));
+            query = Filters.in(MongoBlob.KEY_ID, chunkIds);
             if (maxLastModifiedTime > 0) {
-                queryBuilder = queryBuilder.and(MongoBlob.KEY_LAST_MOD)
-                                    .lessThan(maxLastModifiedTime);
+                query = Filters.and(
+                        query,
+                        Filters.lt(MongoBlob.KEY_LAST_MOD, maxLastModifiedTime)
+                );
             }
         }
 
-        WriteResult result = collection.remove(queryBuilder.get());
-        return result.getN();
+        return getBlobCollection().deleteMany(query).getDeletedCount();
     }
 
     @Override
     public Iterator<String> getAllChunkIds(long maxLastModifiedTime) throws Exception {
-        DBCollection collection = getBlobCollection();
-
-        DBObject fields = new BasicDBObject();
-        fields.put(MongoBlob.KEY_ID, 1);
+        Bson fields = new BasicDBObject(MongoBlob.KEY_ID, 1);
+        Bson hint = new BasicDBObject("$hint", fields);
 
-        QueryBuilder builder = new QueryBuilder();
+        Bson query = new Document();
         if (maxLastModifiedTime != 0 && maxLastModifiedTime != -1) {
-            builder.and(MongoBlob.KEY_LAST_MOD).lessThanEquals(maxLastModifiedTime);
+            query = Filters.lte(MongoBlob.KEY_LAST_MOD, maxLastModifiedTime);
         }
 
-        final DBCursor cur =
-                collection.find(builder.get(), fields).hint(fields)
-                        .addOption(Bytes.QUERYOPTION_SLAVEOK);
+        final MongoCursor<MongoBlob> cur = getBlobCollection().find(query)
+                .projection(fields).modifiers(hint).iterator();
 
         //TODO The cursor needs to be closed
         return new AbstractIterator<String>() {
             @Override
             protected String computeNext() {
                 if (cur.hasNext()) {
-                    MongoBlob blob = (MongoBlob) cur.next();
+                    MongoBlob blob = cur.next();
                     if (blob != null) {
                         return blob.getId();
                     }

Added: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoClusterListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoClusterListener.java?rev=1827987&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoClusterListener.java (added)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoClusterListener.java Thu Mar 29 13:06:10 2018
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.document.mongo;
+
+import javax.annotation.CheckForNull;
+
+import com.mongodb.connection.ClusterDescription;
+import com.mongodb.event.ClusterDescriptionChangedEvent;
+import com.mongodb.event.ClusterListenerAdapter;
+
+/**
+ * Remembers the current {@link ClusterDescription} whenever it changes.
+ */
+class MongoClusterListener
+        extends ClusterListenerAdapter
+        implements ClusterDescriptionProvider {
+
+    private volatile ClusterDescription description;
+
+    @CheckForNull
+    public ClusterDescription getClusterDescription() {
+        return description;
+    }
+
+    @Override
+    public void clusterDescriptionChanged(ClusterDescriptionChangedEvent event) {
+        description = event.getNewDescription();
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoClusterListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java?rev=1827987&r1=1827986&r2=1827987&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java Thu Mar 29 13:06:10 2018
@@ -22,8 +22,12 @@ import java.util.concurrent.TimeUnit;
 import javax.annotation.Nonnull;
 
 import com.mongodb.DB;
+import com.mongodb.Mongo;
+import com.mongodb.MongoClient;
 import com.mongodb.MongoClientOptions;
+import com.mongodb.MongoClientURI;
 import com.mongodb.ReadConcernLevel;
+import com.mongodb.client.MongoDatabase;
 
 import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob;
 import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
@@ -75,17 +79,22 @@ public abstract class MongoDocumentNodeS
             throws UnknownHostException {
         this.mongoUri = uri;
 
+        MongoClusterListener listener = new MongoClusterListener();
         MongoClientOptions.Builder options = MongoConnection.getDefaultBuilder();
+        options.addClusterListener(listener);
         options.socketKeepAlive(socketKeepAlive);
-        DB db = new MongoConnection(uri, options).getDB(name);
-        MongoStatus status = new MongoStatus(db);
+        MongoClient client = new MongoClient(new MongoClientURI(uri, options));
+        MongoStatus status = new MongoStatus(client, name, listener);
+        MongoDatabase db = client.getDatabase(name);
         if (!MongoConnection.hasWriteConcern(uri)) {
-            db.setWriteConcern(MongoConnection.getDefaultWriteConcern(db));
+            db = db.withWriteConcern(MongoConnection.getDefaultWriteConcern(client));
         }
-        if (status.isMajorityReadConcernSupported() && status.isMajorityReadConcernEnabled() && !MongoConnection.hasReadConcern(uri)) {
-            db.setReadConcern(MongoConnection.getDefaultReadConcern(db));
+        if (status.isMajorityReadConcernSupported()
+                && status.isMajorityReadConcernEnabled()
+                && !MongoConnection.hasReadConcern(uri)) {
+            db = db.withReadConcern(MongoConnection.getDefaultReadConcern(client, db));
         }
-        setMongoDB(db, status, blobCacheSizeMB);
+        setMongoDB(client, db, status, blobCacheSizeMB);
         return thisBuilder();
     }
 
@@ -94,10 +103,26 @@ public abstract class MongoDocumentNodeS
      *
      * @param db the MongoDB connection
      * @return this
+     * @deprecated use {@link #setMongoDB(MongoClient, String, int)} instead.
      */
     public T setMongoDB(@Nonnull DB db,
                         int blobCacheSizeMB) {
-        return setMongoDB(db, new MongoStatus(db), blobCacheSizeMB);
+        return setMongoDB(mongoClientFrom(db), db.getName(), blobCacheSizeMB);
+    }
+
+    /**
+     * Use the given MongoDB as backend storage for the DocumentNodeStore.
+     *
+     * @param client the MongoDB connection
+     * @param dbName the database name
+     * @param blobCacheSizeMB the size of the blob cache in MB.
+     * @return this
+     */
+    public T setMongoDB(@Nonnull MongoClient client,
+                        @Nonnull String dbName,
+                        int blobCacheSizeMB) {
+        return setMongoDB(client, client.getDatabase(dbName),
+                new MongoStatus(client, dbName), blobCacheSizeMB);
     }
 
     /**
@@ -105,9 +130,22 @@ public abstract class MongoDocumentNodeS
      *
      * @param db the MongoDB connection
      * @return this
+     * @deprecated use {@link #setMongoDB(MongoClient, String)} instead.
      */
     public T setMongoDB(@Nonnull DB db) {
-        return setMongoDB(db, 16);
+        return setMongoDB(mongoClientFrom(db), db.getName());
+    }
+
+    /**
+     * Use the given MongoDB as backend storage for the DocumentNodeStore.
+     *
+     * @param client the MongoDB connection
+     * @param dbName the database name
+     * @return this
+     */
+    public T setMongoDB(@Nonnull MongoClient client,
+                        @Nonnull String dbName) {
+        return setMongoDB(client, dbName, 16);
     }
 
     /**
@@ -178,18 +216,19 @@ public abstract class MongoDocumentNodeS
         return maxReplicationLagMillis;
     }
 
-    private T setMongoDB(@Nonnull DB db,
+    private T setMongoDB(@Nonnull MongoClient client,
+                         @Nonnull MongoDatabase db,
                          MongoStatus status,
                          int blobCacheSizeMB) {
-        if (!MongoConnection.hasSufficientWriteConcern(db)) {
+        if (!MongoConnection.isSufficientWriteConcern(client, db.getWriteConcern())) {
             LOG.warn("Insufficient write concern: " + db.getWriteConcern()
-                    + " At least " + MongoConnection.getDefaultWriteConcern(db) + " is recommended.");
+                    + " At least " + MongoConnection.getDefaultWriteConcern(client) + " is recommended.");
         }
         if (status.isMajorityReadConcernSupported() && !status.isMajorityReadConcernEnabled()) {
             LOG.warn("The read concern should be enabled on mongod using --enableMajorityReadConcern");
-        } else if (status.isMajorityReadConcernSupported() && !MongoConnection.hasSufficientReadConcern(db)) {
+        } else if (status.isMajorityReadConcernSupported() && !MongoConnection.isSufficientReadConcern(client, db.getReadConcern())) {
             ReadConcernLevel currentLevel = readConcernLevel(db.getReadConcern());
-            ReadConcernLevel recommendedLevel = readConcernLevel(MongoConnection.getDefaultReadConcern(db));
+            ReadConcernLevel recommendedLevel = readConcernLevel(MongoConnection.getDefaultReadConcern(client, db));
             if (currentLevel == null) {
                 LOG.warn("Read concern hasn't been set. At least " + recommendedLevel + " is recommended.");
             } else {
@@ -199,7 +238,7 @@ public abstract class MongoDocumentNodeS
 
         this.mongoStatus = status;
         this.documentStoreSupplier = memoize(() -> new MongoDocumentStore(
-                db, MongoDocumentNodeStoreBuilderBase.this));
+                client, db.getName(), MongoDocumentNodeStoreBuilderBase.this));
 
         if (this.blobStore == null) {
             GarbageCollectableBlobStore s = new MongoBlobStore(db, blobCacheSizeMB * 1024 * 1024L);
@@ -207,4 +246,12 @@ public abstract class MongoDocumentNodeS
         }
         return thisBuilder();
     }
+
+    private static MongoClient mongoClientFrom(DB db) {
+        Mongo mongo = db.getMongo();
+        if (mongo instanceof MongoClient) {
+            return (MongoClient) mongo;
+        }
+        throw new UnsupportedOperationException("DB must be constructed from MongoClient");
+    }
 }