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/09/11 11:53:44 UTC
svn commit: r1840545 - in /jackrabbit/oak/trunk/oak-store-document: ./
src/test/java/org/apache/jackrabbit/oak/plugins/document/
src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/
Author: mreutegg
Date: Tue Sep 11 11:53:44 2018
New Revision: 1840545
URL: http://svn.apache.org/viewvc?rev=1840545&view=rev
Log:
OAK-7732: Use docker for MongoDB based tests when available
Try fallback to local docker if configured MongoDB is not available
Added:
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDockerRule.java (with props)
Modified:
jackrabbit/oak/trunk/oak-store-document/pom.xml
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoConnectionFactory.java
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java
Modified: jackrabbit/oak/trunk/oak-store-document/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/pom.xml?rev=1840545&r1=1840544&r2=1840545&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-store-document/pom.xml Tue Sep 11 11:53:44 2018
@@ -327,5 +327,10 @@
<artifactId>metrics-core</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.arakelian</groupId>
+ <artifactId>docker-junit-rule</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
Modified: jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoConnectionFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoConnectionFactory.java?rev=1840545&r1=1840544&r2=1840545&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoConnectionFactory.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoConnectionFactory.java Tue Sep 11 11:53:44 2018
@@ -20,26 +20,44 @@ import java.util.List;
import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.plugins.document.mongo.MongoDockerRule;
import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
import org.jetbrains.annotations.Nullable;
import org.junit.rules.ExternalResource;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import static org.junit.Assume.assumeNotNull;
public class MongoConnectionFactory extends ExternalResource {
+ private final MongoDockerRule mongo = new MongoDockerRule();
+
private final List<MongoConnection> connections = Lists.newArrayList();
+ @Override
+ public Statement apply(Statement base, Description description) {
+ Statement s = super.apply(base, description);
+ if (mongo.isDockerAvailable()) {
+ s = mongo.apply(s, description);
+ }
+ return s;
+ }
+
@Nullable
public MongoConnection getConnection() {
- MongoConnection c = MongoUtils.getConnection();
- if (c != null) {
- connections.add(c);
- }
- return c;
+ return getConnection(MongoUtils.DB);
}
@Nullable
public MongoConnection getConnection(String dbName) {
+ // first try MongoDB running on configured host and port
MongoConnection c = MongoUtils.getConnection(dbName);
+ if (c == null && mongo.isDockerAvailable()) {
+ // fall back to docker if available
+ c = new MongoConnection("localhost", mongo.getPort(), dbName);
+ }
+ assumeNotNull(c);
if (c != null) {
connections.add(c);
}
Modified: jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java?rev=1840545&r1=1840544&r2=1840545&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoUtils.java Tue Sep 11 11:53:44 2018
@@ -16,10 +16,20 @@
*/
package org.apache.jackrabbit.oak.plugins.document;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.jackrabbit.oak.plugins.document.mongo.MongoDockerRule;
import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
+import com.mongodb.MongoClientURI;
import com.mongodb.client.MongoDatabase;
/**
@@ -28,6 +38,10 @@ import com.mongodb.client.MongoDatabase;
*/
public class MongoUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(MongoUtils.class);
+
+ protected static Map<String, Exception> exceptions = new ConcurrentHashMap<>();
+
protected static final String HOST =
System.getProperty("mongo.host", "127.0.0.1");
@@ -37,19 +51,44 @@ public class MongoUtils {
public static final String DB =
System.getProperty("mongo.db", "MongoMKDB");
+ public static final String VERSION =
+ System.getProperty("mongo.version", "3.6");
+
+ private static final String OPTIONS = "connectTimeoutMS=3000&serverSelectionTimeoutMS=3000";
+
public static final String URL = createMongoURL();
private static String createMongoURL() {
+ // first try configured URL
String mongoUrl = System.getProperty("mongo.url");
if (mongoUrl == null || mongoUrl.isEmpty()) {
- mongoUrl = "mongodb://" + HOST + ":" + PORT + "/" + DB +
- "?connectTimeoutMS=3000&serverSelectionTimeoutMS=3000";
+ mongoUrl = "mongodb://" + HOST + ":" + PORT + "/" + DB + "?" + OPTIONS;
+ }
+ // check if we can connect
+ MongoConnection c = getConnectionByURL(mongoUrl);
+ if (c != null) {
+ c.close();
+ return mongoUrl;
+ }
+ // fallback to docker based MongoDB if available
+ MongoDockerRule dockerRule = new MongoDockerRule();
+ if (dockerRule.isDockerAvailable()) {
+ AtomicInteger port = new AtomicInteger();
+ try {
+ dockerRule.apply(new Statement() {
+ @Override
+ public void evaluate() {
+ port.set(dockerRule.getPort());
+ }
+ }, Description.EMPTY).evaluate();
+ mongoUrl = "mongodb://localhost:" + port.get() + "/" + DB + "?" + OPTIONS;
+ } catch (Throwable t) {
+ LOG.warn("Unable to get MongoDB port from Docker", t);
+ }
}
return mongoUrl;
}
- protected static Exception exception;
-
/**
* Get a connection if available. If not available, null is returned.
*
@@ -66,7 +105,22 @@ public class MongoUtils {
* @return the connection or null
*/
public static MongoConnection getConnection(String dbName) {
- return getConnectionByURL("mongodb://" + HOST + ":" + PORT + "/" + dbName);
+ MongoClientURI clientURI;
+ try {
+ clientURI = new MongoClientURI(URL);
+ } catch (IllegalArgumentException e) {
+ // configured URL is invalid
+ return null;
+ }
+ StringBuilder uri = new StringBuilder("mongodb://");
+ String separator = "";
+ for (String host : clientURI.getHosts()) {
+ uri.append(separator);
+ separator = ",";
+ uri.append(host);
+ }
+ uri.append("/").append(dbName).append("?").append(OPTIONS);
+ return getConnectionByURL(uri.toString());
}
/**
@@ -156,7 +210,7 @@ public class MongoUtils {
* @return the connection or null
*/
private static MongoConnection getConnectionByURL(String url) {
- if (exception != null) {
+ if (exceptions.get(url) != null) {
return null;
}
MongoConnection mongoConnection;
@@ -165,7 +219,7 @@ public class MongoUtils {
mongoConnection.getDatabase().runCommand(new BasicDBObject("ping", 1));
// dropCollections(mongoConnection.getDB());
} catch (Exception e) {
- exception = e;
+ exceptions.put(url, e);
mongoConnection = null;
}
return mongoConnection;
Added: jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDockerRule.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDockerRule.java?rev=1840545&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDockerRule.java (added)
+++ jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDockerRule.java Tue Sep 11 11:53:44 2018
@@ -0,0 +1,68 @@
+/*
+ * 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 com.arakelian.docker.junit.DockerRule;
+import com.arakelian.docker.junit.model.ImmutableDockerConfig;
+import com.spotify.docker.client.DefaultDockerClient;
+
+import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A MongoDB {@link DockerRule}.
+ */
+public class MongoDockerRule extends DockerRule {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MongoDockerRule.class);
+
+ private static final String CONFIG_NAME = "MongoDB";
+
+ private static final boolean DOCKER_AVAILABLE;
+
+ static {
+ boolean available = false;
+ try (DefaultDockerClient client = DefaultDockerClient.fromEnv()
+ .connectTimeoutMillis(5000L).readTimeoutMillis(20000L).build()) {
+ client.ping();
+ available = true;
+ } catch (Exception e) {
+ LOG.info("Cannot connect to docker", e);
+ }
+ DOCKER_AVAILABLE = available;
+ }
+
+ public MongoDockerRule() {
+ super(ImmutableDockerConfig.builder()
+ .name(CONFIG_NAME)
+ .image("mongo:" + MongoUtils.VERSION)
+ .ports("27017")
+ .allowRunningBetweenUnitTests(true)
+ .alwaysRemoveContainer(true)
+ .addStartedListener(container -> container.waitForPort("27017/tcp"))
+ .build());
+ }
+
+ public int getPort() {
+ return getContainer().getPortBinding("27017/tcp").getPort();
+ }
+
+ public boolean isDockerAvailable() {
+ return DOCKER_AVAILABLE;
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDockerRule.java
------------------------------------------------------------------------------
svn:eol-style = native