Author: mreutegg
Date: Wed May 17 14:38:34 2017
New Revision: 1795418

URL: http://svn.apache.org/viewvc?rev=1795418&view=rev
Log:
OAK-6223: Expose socket keep-alive option

Merge revision 1795330 from trunk

Added:
    
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreHelper.java
      - copied unchanged from r1795330, 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreHelper.java
Modified:
    jackrabbit/oak/branches/1.6/   (props changed)
    
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
    
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
    
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
    
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
    
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java

Propchange: jackrabbit/oak/branches/1.6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed May 17 14:38:34 2017
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1781068,1781075,1781248,1781386,1781846,1781907,1782000,1782029,1782196,1782447,1782476,1782770,1782945,1782966,1782973,1782990,1783061,1783066,1783089,1783104-1783105,1783110,1783619,1783720,1783731,1783733,1783738,1783742,1783773,1783855,1783891,1784023,1784130,1784162,1784251,1784401,1784551,1784574,1784689,1785095,1785108,1785283,1785838,1785919,1785946,1787074,1787217,1787425,1788378,1788387-1788389,1789056,1790382,1792463,1792742,1792746,1793088,1793618,1793627,1793644,1795314
+/jackrabbit/oak/trunk:1781068,1781075,1781248,1781386,1781846,1781907,1782000,1782029,1782196,1782447,1782476,1782770,1782945,1782966,1782973,1782990,1783061,1783066,1783089,1783104-1783105,1783110,1783619,1783720,1783731,1783733,1783738,1783742,1783773,1783855,1783891,1784023,1784130,1784162,1784251,1784401,1784551,1784574,1784689,1785095,1785108,1785283,1785838,1785919,1785946,1787074,1787217,1787425,1788378,1788387-1788389,1789056,1790382,1792463,1792742,1792746,1793088,1793618,1793627,1793644,1795314,1795330
 /jackrabbit/trunk:1345480

Modified: 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1795418&r1=1795417&r2=1795418&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
 (original)
+++ 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
 Wed May 17 14:38:34 2017
@@ -46,6 +46,7 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.MoreExecutors;
 import com.mongodb.DB;
+import com.mongodb.MongoClientOptions;
 import com.mongodb.ReadConcernLevel;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
@@ -547,6 +548,7 @@ public class DocumentMK {
         private DocumentNodeStore nodeStore;
         private DocumentStore documentStore;
         private String mongoUri;
+        private boolean socketKeepAlive;
         private MongoStatus mongoStatus;
         private DiffCache diffCache;
         private BlobStore blobStore;
@@ -611,7 +613,9 @@ public class DocumentMK {
                 throws UnknownHostException {
             this.mongoUri = uri;
 
-            DB db = new MongoConnection(uri).getDB(name);
+            MongoClientOptions.Builder options = 
MongoConnection.getDefaultBuilder();
+            options.socketKeepAlive(socketKeepAlive);
+            DB db = new MongoConnection(uri, options).getDB(name);
             MongoStatus status = new MongoStatus(db);
             if (!MongoConnection.hasWriteConcern(uri)) {
                 db.setWriteConcern(MongoConnection.getDefaultWriteConcern(db));
@@ -665,6 +669,18 @@ public class DocumentMK {
             return this;
         }
 
+        /**
+         * Enables the socket keep-alive option for MongoDB. The default is
+         * disabled.
+         *
+         * @param enable whether to enable it.
+         * @return this
+         */
+        public Builder setSocketKeepAlive(boolean enable) {
+            this.socketKeepAlive = enable;
+            return this;
+        }
+
         private void setBlobStore(GarbageCollectableBlobStore s) {
             configureBlobStore(s);
             PersistentCache p = getPersistentCache();

Modified: 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java?rev=1795418&r1=1795417&r2=1795418&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
 (original)
+++ 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
 Wed May 17 14:38:34 2017
@@ -123,6 +123,7 @@ public class DocumentNodeStoreService {
     private static final int DEFAULT_CACHE = (int) (DEFAULT_MEMORY_CACHE_SIZE 
/ MB);
     private static final int DEFAULT_BLOB_CACHE_SIZE = 16;
     private static final String DEFAULT_DB = "oak";
+    private static final boolean DEFAULT_SO_KEEP_ALIVE = false;
     private static final String DEFAULT_PERSISTENT_CACHE = "cache,binary=0";
     private static final String DEFAULT_JOURNAL_CACHE = "diff-cache";
     private static final String PREFIX = "oak.documentstore.";
@@ -139,6 +140,11 @@ public class DocumentNodeStoreService {
      */
     private static final String FWK_PROP_DB = "oak.mongo.db";
 
+    /**
+     * Name of framework property to configure socket keep-alive for MongoDB
+     */
+    private static final String FWK_PROP_SO_KEEP_ALIVE = 
"oak.mongo.socketKeepAlive";
+
     @Property(value = DEFAULT_URI,
             label = "Mongo URI",
             description = "Mongo connection URI used to connect to Mongo. 
Refer to " +
@@ -154,6 +160,14 @@ public class DocumentNodeStoreService {
     )
     private static final String PROP_DB = "db";
 
+    @Property(boolValue = DEFAULT_SO_KEEP_ALIVE,
+            label = "MongoDB socket keep-alive option",
+            description = "Whether socket keep-alive should be enabled for " +
+                    "connections to MongoDB. Note that this value can be " +
+                    "overridden via framework property 
'oak.mongo.socketKeepAlive'"
+    )
+    static final String PROP_SO_KEEP_ALIVE = "socketKeepAlive";
+
     @Property(intValue = DEFAULT_CACHE,
             label = "Cache Size (in MB)",
             description = "Cache size in MB. This is distributed among various 
caches used in DocumentNodeStore"
@@ -420,6 +434,7 @@ public class DocumentNodeStoreService {
     private void registerNodeStore() throws IOException {
         String uri = PropertiesUtil.toString(prop(PROP_URI, FWK_PROP_URI), 
DEFAULT_URI);
         String db = PropertiesUtil.toString(prop(PROP_DB, FWK_PROP_DB), 
DEFAULT_DB);
+        boolean soKeepAlive = 
PropertiesUtil.toBoolean(prop(PROP_SO_KEEP_ALIVE, FWK_PROP_SO_KEEP_ALIVE), 
DEFAULT_SO_KEEP_ALIVE);
 
         int cacheSize = toInteger(prop(PROP_CACHE), DEFAULT_CACHE);
         int nodeCachePercentage = toInteger(prop(PROP_NODE_CACHE_PERCENTAGE), 
DEFAULT_NODE_CACHE_PERCENTAGE);
@@ -513,6 +528,7 @@ public class DocumentNodeStoreService {
             }
 
             mkBuilder.setMaxReplicationLag(maxReplicationLagInSecs, 
TimeUnit.SECONDS);
+            mkBuilder.setSocketKeepAlive(soKeepAlive);
             mkBuilder.setMongoDB(uri, db, blobCacheSize);
 
             log.info("Connected to database '{}'", db);

Modified: 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java?rev=1795418&r1=1795417&r2=1795418&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
 (original)
+++ 
jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
 Wed May 17 14:38:34 2017
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.oak.plugins.document.util;
 
-import java.net.UnknownHostException;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
@@ -28,6 +27,7 @@ import com.mongodb.DB;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClientOptions;
 import com.mongodb.MongoClientURI;
+import com.mongodb.MongoException;
 import com.mongodb.ReadConcern;
 import com.mongodb.ReadConcernLevel;
 import com.mongodb.WriteConcern;
@@ -45,15 +45,30 @@ public class MongoConnection {
     private final MongoClientURI mongoURI;
     private final MongoClient mongo;
 
+    private static boolean SO_KEEP_ALIVE =
+            Boolean.getBoolean("oak.mongo.socketKeepAlive");
+
     /**
      * Constructs a new connection using the specified MongoDB connection 
string.
      * See also http://docs.mongodb.org/manual/reference/connection-string/
      *
      * @param uri the MongoDB URI
-     * @throws UnknownHostException
+     * @throws MongoException if there are failures
+     */
+    public MongoConnection(String uri) throws MongoException {
+        this(uri, MongoConnection.getDefaultBuilder());
+    }
+
+    /**
+     * Constructs a new connection using the specified MongoDB connection
+     * String. The default client options are taken from the provided builder.
+     *
+     * @param uri the connection URI.
+     * @param builder the client option defaults.
+     * @throws MongoException if there are failures
      */
-    public MongoConnection(String uri) throws UnknownHostException  {
-        MongoClientOptions.Builder builder = 
MongoConnection.getDefaultBuilder();
+    public MongoConnection(String uri, MongoClientOptions.Builder builder)
+            throws MongoException {
         mongoURI = new MongoClientURI(uri, builder);
         mongo = new MongoClient(mongoURI);
     }
@@ -64,9 +79,10 @@ public class MongoConnection {
      * @param host The host address.
      * @param port The port.
      * @param database The database name.
-     * @throws Exception If an error occurred while trying to connect.
+     * @throws MongoException if there are failures
      */
-    public MongoConnection(String host, int port, String database) throws 
Exception {
+    public MongoConnection(String host, int port, String database)
+            throws MongoException {
         this("mongodb://" + host + ":" + port + "/" + database);
     }
 
@@ -106,6 +122,7 @@ public class MongoConnection {
         return new MongoClientOptions.Builder()
                 .description("MongoConnection for Oak DocumentMK")
                 .maxWaitTime(DEFAULT_MAX_WAIT_TIME)
+                .socketKeepAlive(SO_KEEP_ALIVE)
                 .threadsAllowedToBlockForConnectionMultiplier(100);
     }
 

Modified: 
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java?rev=1795418&r1=1795417&r2=1795418&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
 Wed May 17 14:38:34 2017
@@ -17,11 +17,15 @@
 package org.apache.jackrabbit.oak.plugins.document;
 
 import java.io.File;
+import java.lang.reflect.Field;
 import java.util.Map;
 
 import com.google.common.collect.Maps;
+import com.mongodb.DB;
 
 import org.apache.commons.io.FilenameUtils;
+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.spi.JournalPropertyService;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
@@ -37,6 +41,7 @@ import static org.junit.Assert.assertEqu
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.mock;
 
@@ -125,6 +130,28 @@ public class DocumentNodeStoreServiceTes
         assertEquals(1, 
store.getJournalPropertyHandlerFactory().getServiceCount());
     }
 
+    @Test
+    public void keepAlive() throws Exception {
+        Map<String, Object> config = newConfig(repoHome);
+        config.put(DocumentNodeStoreService.PROP_SO_KEEP_ALIVE, true);
+        MockOsgi.activate(service, context.bundleContext(), config);
+        DocumentNodeStore store = context.getService(DocumentNodeStore.class);
+        MongoDocumentStore mds = getMongoDocumentStore(store);
+        DB db = MongoDocumentStoreHelper.getDB(mds);
+        assertTrue(db.getMongo().getMongoOptions().isSocketKeepAlive());
+    }
+
+    private static MongoDocumentStore getMongoDocumentStore(DocumentNodeStore 
s) {
+        try {
+            Field f = s.getClass().getDeclaredField("nonLeaseCheckingStore");
+            f.setAccessible(true);
+            return (MongoDocumentStore) f.get(s);
+        } catch (Exception e) {
+            fail(e.getMessage());
+            return null;
+        }
+    }
+
     private void assertPersistentCachePath(String expectedPath,
                                            String persistentCache,
                                            String repoHome) {

Modified: 
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java?rev=1795418&r1=1795417&r2=1795418&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java
 Wed May 17 14:38:34 2017
@@ -18,16 +18,19 @@ package org.apache.jackrabbit.oak.plugin
 
 import com.mongodb.DB;
 import com.mongodb.Mongo;
+import com.mongodb.MongoClientOptions;
 import com.mongodb.ReadConcern;
 import com.mongodb.ReplicaSetStatus;
 import com.mongodb.WriteConcern;
 
+import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
 import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
 import org.junit.Test;
 
 import static junitx.framework.ComparableAssert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -83,6 +86,26 @@ public class MongoConnectionTest {
         sufficientReadConcernSingleNode(ReadConcern.MAJORITY, true);
     }
 
+    @Test
+    public void socketKeepAlive() throws Exception {
+        assumeTrue(MongoUtils.isAvailable());
+        MongoClientOptions.Builder options = 
MongoConnection.getDefaultBuilder();
+        options.socketKeepAlive(true);
+        MongoConnection c = new MongoConnection(MongoUtils.URL, options);
+        try {
+            
assertTrue(c.getDB().getMongo().getMongoOptions().isSocketKeepAlive());
+        } finally {
+            c.close();
+        }
+        // default is without keep-alive
+        c = new MongoConnection(MongoUtils.URL);
+        try {
+            
assertFalse(c.getDB().getMongo().getMongoOptions().isSocketKeepAlive());
+        } finally {
+            c.close();
+        }
+    }
+
     private void sufficientWriteConcernReplicaSet(WriteConcern w,
                                                   boolean sufficient) {
         sufficientWriteConcern(w, true, sufficient);


Reply via email to