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 2017/05/17 16:00:45 UTC

svn commit: r1795429 - in /jackrabbit/oak/branches/1.4: ./ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/ oak-core/src/test/java/org/apache/jackrabbit/oak/plugi...

Author: mreutegg
Date: Wed May 17 16:00:45 2017
New Revision: 1795429

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

Merge revision 1795330 from trunk

Added:
    jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java   (with props)
    jackrabbit/oak/branches/1.4/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.4/   (props changed)
    jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
    jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
    jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
    jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java
    jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java

Propchange: jackrabbit/oak/branches/1.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed May 17 16:00:45 2017
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1733615,1733875,1733913,1733929,1734230,1734254,1734279,1734941,1735052,1735081,1735109,1735141,1735267,1735405,1735484,1735549,1735564,1735588,1735622,1735638,1735919,1735983,1736176,1737309-1737310,1737334,1737349,1737998,1738004,1738136,1738138,1738207,1738234,1738252,1738775,1738795,1738833,1738950,1738957,1738963,1739712,1739760,1739867,1739894,1739959-1739960,1740114,1740116,1740250,1740333,1740349,1740360,1740625-1740626,1740774,1740837,1740879,1740971,1741016,1741032,1741339,1741343,1742077,1742117,1742125,1742363,1742520,1742888,1742916,1743097,1743172,1743343,1743674,1744265,1744292,1744589,1744670,1744672,1744959,1745038,1745127,1745197,1745336,1745368,1746086,1746117,1746342,1746345,1746408,1746634,1746696,1746981,1747198,1747200,1747341-1747342,1747380,1747387,1747406,1747492,1747512,1747654,1748505,1748553,1748722,1748870,1749275,1749350,1749424,1749443,1749464,1749475,1749645,1749662,1749815,1749872,1749875,1749899,1750052,1750076-1750077,1750287
 ,1750457,1750462,1750465,1750495,1750626,1750809,1750886-1750887,1751396,1751410,1751419,1751445-1751446,1751478,1751748,1751753,1751755,1751871,1752198,1752202,1752259,1752273-1752274,1752283,1752292,1752438,1752447-1752448,1752508,1752596,1752616,1752659,1752672,1753262,1753331-1753332,1753335-1753336,1753355,1753444,1754117,1754239,1755157,1755191,1756520,1756580,1757119,1757166,1758213,1758713,1759433,1759795,1759826,1760326,1760340,1760373,1760387,1760486,1760492,1760494,1760661-1760662,1760677,1760701,1760709,1760946,1761412,1761444,1761571,1761762,1761787,1761866,1761876,1762453,1762612,1762632,1762635,1763347,1763355-1763356,1763378,1763465,1763735,1764678,1764705,1764814,1764898,1765817,1765983,1766071,1766390,1766423,1766496,1766519,1766554,1766644,1767025,1767265,1767502,1767704,1768446,1768637,1769078,1769939-1769940,1770694,1770982,1771022,1771093,1771098,1771739,1771852,1771870,1771902,1772155,1772162,1772228,1772593,1772768,1773190,1774497,1774787,1775474,1775622,1775
 628,1775757,1778112,1778423,1778968,1779137,1779478,1780388,1780424,1780538,1780543,1781068,1781075,1781386,1781846,1781907,1782476,1782966,1783066,1783089,1783104-1783105,1783110,1783619,1783720,1783738,1783773,1783855,1784023,1784130,1784251,1784574,1784689,1785283,1785946,1787074,1787217,1787425,1789056,1792463,1792742,1793088,1793644,1795314
+/jackrabbit/oak/trunk:1733615,1733875,1733913,1733929,1734230,1734254,1734279,1734941,1735052,1735081,1735109,1735141,1735267,1735405,1735484,1735549,1735564,1735588,1735622,1735638,1735919,1735983,1736176,1737309-1737310,1737334,1737349,1737998,1738004,1738136,1738138,1738207,1738234,1738252,1738775,1738795,1738833,1738950,1738957,1738963,1739712,1739760,1739867,1739894,1739959-1739960,1740114,1740116,1740250,1740333,1740349,1740360,1740625-1740626,1740774,1740837,1740879,1740971,1741016,1741032,1741339,1741343,1742077,1742117,1742125,1742363,1742520,1742888,1742916,1743097,1743172,1743343,1743674,1744265,1744292,1744589,1744670,1744672,1744959,1745038,1745127,1745197,1745336,1745368,1746086,1746117,1746342,1746345,1746408,1746634,1746696,1746981,1747198,1747200,1747341-1747342,1747380,1747387,1747406,1747492,1747512,1747654,1748505,1748553,1748722,1748870,1749275,1749350,1749424,1749443,1749464,1749475,1749645,1749662,1749815,1749872,1749875,1749899,1750052,1750076-1750077,1750287
 ,1750457,1750462,1750465,1750495,1750626,1750809,1750886-1750887,1751396,1751410,1751419,1751445-1751446,1751478,1751748,1751753,1751755,1751871,1752198,1752202,1752259,1752273-1752274,1752283,1752292,1752438,1752447-1752448,1752508,1752596,1752616,1752659,1752672,1753262,1753331-1753332,1753335-1753336,1753355,1753444,1754117,1754239,1755157,1755191,1756520,1756580,1757119,1757166,1758213,1758713,1759433,1759795,1759826,1760326,1760340,1760373,1760387,1760486,1760492,1760494,1760661-1760662,1760677,1760701,1760709,1760946,1761412,1761444,1761571,1761762,1761787,1761866,1761876,1762453,1762612,1762632,1762635,1763347,1763355-1763356,1763378,1763465,1763735,1764678,1764705,1764814,1764898,1765817,1765983,1766071,1766390,1766423,1766496,1766519,1766554,1766644,1767025,1767265,1767502,1767704,1768446,1768637,1769078,1769939-1769940,1770694,1770982,1771022,1771093,1771098,1771739,1771852,1771870,1771902,1772155,1772162,1772228,1772593,1772768,1773190,1774497,1774787,1775474,1775622,1775
 628,1775757,1778112,1778423,1778968,1779137,1779478,1780388,1780424,1780538,1780543,1781068,1781075,1781386,1781846,1781907,1782476,1782966,1783066,1783089,1783104-1783105,1783110,1783619,1783720,1783738,1783773,1783855,1784023,1784130,1784251,1784574,1784689,1785283,1785946,1787074,1787217,1787425,1789056,1792463,1792742,1793088,1793644,1795314,1795330
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1795429&r1=1795428&r2=1795429&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java Wed May 17 16:00:45 2017
@@ -42,6 +42,8 @@ import com.google.common.cache.Weigher;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.MoreExecutors;
 import com.mongodb.DB;
+import com.mongodb.MongoClientOptions;
+
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.cache.CacheLIRS;
 import org.apache.jackrabbit.oak.cache.CacheLIRS.EvictionCallback;
@@ -498,6 +500,7 @@ public class DocumentMK {
         public static final int DEFAULT_CACHE_STACK_MOVE_DISTANCE = 16;
         private DocumentNodeStore nodeStore;
         private DocumentStore documentStore;
+        private boolean socketKeepAlive;
         private DiffCache diffCache;
         private BlobStore blobStore;
         private int clusterId  = Integer.getInteger("oak.documentMK.clusterId", 0);
@@ -552,7 +555,9 @@ public class DocumentMK {
                                   @Nonnull String name,
                                   int blobCacheSizeMB)
                 throws UnknownHostException {
-            DB db = new MongoConnection(uri).getDB(name);
+            MongoClientOptions.Builder options = MongoConnection.getDefaultBuilder();
+            options.socketKeepAlive(socketKeepAlive);
+            DB db = new MongoConnection(uri, options).getDB(name);
             if (!MongoConnection.hasWriteConcern(uri)) {
                 db.setWriteConcern(MongoConnection.getDefaultWriteConcern(db));
             }
@@ -588,6 +593,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;
+        }
+
         /**
          * Use the given MongoDB as backend storage for the DocumentNodeStore.
          *

Modified: jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java?rev=1795429&r1=1795428&r2=1795429&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java Wed May 17 16:00:45 2017
@@ -114,6 +114,7 @@ public class DocumentNodeStoreService {
     private static final int DEFAULT_CACHE = 256;
     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 = "";
     private static final int DEFAULT_CACHE_SEGMENT_COUNT = 16;
     private static final int DEFAULT_CACHE_STACK_MOVE_DISTANCE = 16;
@@ -131,6 +132,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 " +
@@ -146,6 +152,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"
@@ -378,6 +392,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);
@@ -463,6 +478,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.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java?rev=1795429&r1=1795428&r2=1795429&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java Wed May 17 16:00:45 2017
@@ -26,6 +26,7 @@ import com.mongodb.DB;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClientOptions;
 import com.mongodb.MongoClientURI;
+import com.mongodb.MongoException;
 import com.mongodb.WriteConcern;
 
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -45,12 +46,28 @@ public class MongoConnection {
      * 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 UnknownHostException  {
-        MongoClientOptions.Builder builder = MongoConnection.getDefaultBuilder();
+    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, MongoClientOptions.Builder builder)
+            throws MongoException {
         mongoURI = new MongoClientURI(uri, builder);
-        mongo = new MongoClient(mongoURI);
+        try {
+            mongo = new MongoClient(mongoURI);
+        } catch (UnknownHostException e) {
+            throw new MongoException(e.getMessage(), e);
+        }
     }
 
     /**
@@ -59,9 +76,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);
     }
 

Added: jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java?rev=1795429&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java (added)
+++ jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java Wed May 17 16:00:45 2017
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+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.jackrabbit.oak.plugins.document.mongo.MongoDocumentStore;
+import org.apache.jackrabbit.oak.plugins.document.mongo.MongoDocumentStoreHelper;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.sling.testing.mock.osgi.MockOsgi;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+public class DocumentNodeStoreServiceTest {
+
+    @Rule
+    public final OsgiContext context = new OsgiContext();
+
+    @Rule
+    public final TemporaryFolder target = new TemporaryFolder(new File("target"));
+
+    private final DocumentNodeStoreService service = new DocumentNodeStoreService();
+
+    private String repoHome;
+
+    @Before
+    public void setUp() throws  Exception {
+        assumeTrue(MongoUtils.isAvailable());
+        context.registerService(StatisticsProvider.class, StatisticsProvider.NOOP);
+        MockOsgi.injectServices(service, context.bundleContext());
+        repoHome = target.newFolder().getAbsolutePath();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        MockOsgi.deactivate(service);
+        MongoUtils.dropCollections(MongoUtils.DB);
+    }
+
+    @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 Map<String, Object> newConfig(String repoHome) {
+        Map<String, Object> config = Maps.newHashMap();
+        config.put("repository.home", repoHome);
+        config.put("db", MongoUtils.DB);
+        return config;
+    }
+}

Propchange: jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java?rev=1795429&r1=1795428&r2=1795429&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java Wed May 17 16:00:45 2017
@@ -36,6 +36,10 @@ public class MongoUtils {
     protected static final String DB =
             System.getProperty("mongo.db", "MongoMKDB");
 
+    public static final String URL =
+            System.getProperty("mongo.url", "mongodb://" + HOST + ":" + PORT + "/" + DB +
+                    "?connectTimeoutMS=3000&serverSelectionTimeoutMS=3000");
+
     protected static Exception exception;
 
     /**

Modified: jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java?rev=1795429&r1=1795428&r2=1795429&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoConnectionTest.java Wed May 17 16:00:45 2017
@@ -18,15 +18,18 @@ package org.apache.jackrabbit.oak.plugin
 
 import com.mongodb.DB;
 import com.mongodb.Mongo;
+import com.mongodb.MongoClientOptions;
 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;
 
@@ -65,6 +68,26 @@ public class MongoConnectionTest {
         sufficientWriteConcernSingleNode(WriteConcern.UNACKNOWLEDGED, false);
     }
 
+    @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);