[LOG4J2-2205] New module log4j-mongodb3: Remove use of deprecated
MongoDB APIs and code to the Java driver version 3 API.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/e40e73e5
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/e40e73e5
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/e40e73e5

Branch: refs/heads/master
Commit: e40e73e5d753fafab5b516130dd317cd36ba23db
Parents: 67f2dd7
Author: Gary Gregory <[email protected]>
Authored: Thu Jan 25 08:47:05 2018 -0700
Committer: Gary Gregory <[email protected]>
Committed: Thu Jan 25 08:47:05 2018 -0700

----------------------------------------------------------------------
 log4j-mongodb2/pom.xml                          |   1 -
 .../mongodb2/MongoDbAuthFailureTestJava8.java   |   4 +-
 .../logging/log4j/mongodb2/MongoDbTestRule.java |   2 +
 .../mongodb2/MongoDbTestTestRuleTestJava8.java  |   2 +-
 log4j-mongodb3/pom.xml                          | 192 +++++++++++
 .../logging/log4j/mongodb3/LevelCodec.java      |  47 +++
 .../log4j/mongodb3/MongoDbConnection.java       | 113 +++++++
 .../log4j/mongodb3/MongoDbDocumentObject.java   |  58 ++++
 .../logging/log4j/mongodb3/MongoDbProvider.java | 326 +++++++++++++++++++
 .../logging/log4j/mongodb3/package-info.java    |  20 ++
 log4j-mongodb3/src/site/markdown/index.md.vm    |  48 +++
 log4j-mongodb3/src/site/site.xml                |  52 +++
 .../logging/log4j/mongodb3/Java8Test.java       |  48 +++
 .../mongodb3/MongoDbAuthFailureTestJava8.java   |  72 ++++
 .../log4j/mongodb3/MongoDbCappedTestJava8.java  |  69 ++++
 .../mongodb3/MongoDbMapMessageTestJava8.java    |  76 +++++
 .../log4j/mongodb3/MongoDbTestJava8.java        |  69 ++++
 .../logging/log4j/mongodb3/MongoDbTestRule.java | 192 +++++++++++
 .../mongodb3/MongoDbTestTestRuleTestJava8.java  |  71 ++++
 .../logging/log4j/mongodb3/TestConstants.java   |  24 ++
 .../resources/log4j2-mongodb-auth-failure.xml   |  31 ++
 .../test/resources/log4j2-mongodb-capped.xml    |  31 ++
 .../resources/log4j2-mongodb-map-message.xml    |  32 ++
 .../src/test/resources/log4j2-mongodb.xml       |  31 ++
 pom.xml                                         |   9 +-
 src/changes/changes.xml                         |   2 -
 src/site/site.xml                               |   2 +
 src/site/xdoc/manual/appenders.xml              | 143 ++++++++
 src/site/xdoc/manual/messages.xml               |   3 +-
 29 files changed, 1763 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb2/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb2/pom.xml b/log4j-mongodb2/pom.xml
index 1403350..9c7979e 100644
--- a/log4j-mongodb2/pom.xml
+++ b/log4j-mongodb2/pom.xml
@@ -73,7 +73,6 @@
     <dependency>
       <groupId>de.flapdoodle.embed</groupId>
       <artifactId>de.flapdoodle.embed.mongo</artifactId>
-      <version>2.0.1</version>
       <scope>test</scope>
     </dependency>
   </dependencies>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbAuthFailureTestJava8.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbAuthFailureTestJava8.java
 
b/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbAuthFailureTestJava8.java
index 903265c..0d970f7 100644
--- 
a/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbAuthFailureTestJava8.java
+++ 
b/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbAuthFailureTestJava8.java
@@ -25,6 +25,7 @@ import 
org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
 import org.junit.Assert;
 import org.junit.ClassRule;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.RuleChain;
@@ -36,8 +37,9 @@ import com.mongodb.MongoClient;
 /**
  * This class name does NOT end in "Test" in order to only be picked up by 
{@link Java8Test}.
  *
- * TODO set up the log4j user in MongoDB.
+ * TODO Set up the log4j user in MongoDB.
  */
+@Ignore("TODO Set up the log4j user in MongoDB")
 @Category(Appenders.MongoDb.class)
 public class MongoDbAuthFailureTestJava8 {
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestRule.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestRule.java
 
b/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestRule.java
index 248ccde..465fa3f 100644
--- 
a/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestRule.java
+++ 
b/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestRule.java
@@ -43,6 +43,8 @@ import de.flapdoodle.embed.process.runtime.Network;
 
 /**
  * A JUnit test rule to manage a MongoDB embedded instance.
+ * 
+ * TODO Move this class to Apache Commons Testing.
  */
 public class MongoDbTestRule implements TestRule {
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestTestRuleTestJava8.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestTestRuleTestJava8.java
 
b/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestTestRuleTestJava8.java
index 0230cc0..3d8b355 100644
--- 
a/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestTestRuleTestJava8.java
+++ 
b/log4j-mongodb2/src/test/java/org/apache/logging/log4j/mongodb2/MongoDbTestTestRuleTestJava8.java
@@ -32,7 +32,7 @@ import org.junit.Test;
 import org.junit.rules.RuleChain;
 
 /**
- * Tests MongoDbRule. This class name does NOT end in "Test" in order to only 
be picked up by {@link Java8Test}.
+ * Tests {@link MongoDbTestRule}. This class name does NOT end in "Test" in 
order to only be picked up by {@link Java8Test}.
  * <p>
  * The test framework {@code de.flapdoodle.embed.mongo} requires Java 8.
  * </p>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb3/pom.xml b/log4j-mongodb3/pom.xml
new file mode 100644
index 0000000..4d4a652
--- /dev/null
+++ b/log4j-mongodb3/pom.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+  <parent>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j</artifactId>
+    <version>2.10.1-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>log4j-mongodb3</artifactId>
+  <name>Apache Log4j MongoDB 3</name>
+  <description>
+    MongoDB appender for Log4j using the MongoDB 3 driver API.
+  </description>
+  <properties>
+    <log4jParentDir>${basedir}/..</log4jParentDir>
+    <docLabel>MongoDB 3 Documentation</docLabel>
+    <projectDir>/log4j-mongodb3</projectDir>
+    <module.name>org.apache.logging.log4j.mongodb3</module.name>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mongodb</groupId>
+      <artifactId>mongodb-driver</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mongodb</groupId>
+      <artifactId>bson</artifactId>
+    </dependency>
+    <!-- Test Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+      <type>test-jar</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <type>test-jar</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>de.flapdoodle.embed</groupId>
+      <artifactId>de.flapdoodle.embed.mongo</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Fragment-Host>org.apache.logging.log4j.core</Fragment-Host>
+            <Export-Package>*</Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-changes-plugin</artifactId>
+        <version>${changes.plugin.version}</version>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>changes-report</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+        <configuration>
+          <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
+          <useJql>true</useJql>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>${checkstyle.plugin.version}</version>
+        <configuration>
+          
<!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation>
 -->
+          <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
+          
<suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
+          <enableRulesSummary>false</enableRulesSummary>
+          <propertyExpansion>basedir=${basedir}</propertyExpansion>
+          
<propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>${javadoc.plugin.version}</version>
+        <configuration>
+          <bottom><![CDATA[<p align="center">Copyright &#169; 
{inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+            Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather 
logo, the Apache Logging project logo,
+            and the Apache Log4j logo are trademarks of The Apache Software 
Foundation.</p>]]></bottom>
+          <!-- module link generation is completely broken in the javadoc 
plugin for a multi-module non-aggregating
+               project -->
+          <detectOfflineLinks>false</detectOfflineLinks>
+          <linksource>true</linksource>
+        </configuration>
+        <reportSets>
+          <reportSet>
+            <id>non-aggregate</id>
+            <reports>
+              <report>javadoc</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>${findbugs.plugin.version}</version>
+        <configuration>
+          <fork>true</fork>
+          <jvmArgs>-Duser.language=en</jvmArgs>
+          <threshold>Normal</threshold>
+          <effort>Default</effort>
+          
<excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+        <version>${jxr.plugin.version}</version>
+        <reportSets>
+          <reportSet>
+            <id>non-aggregate</id>
+            <reports>
+              <report>jxr</report>
+            </reports>
+          </reportSet>
+          <reportSet>
+            <id>aggregate</id>
+            <reports>
+              <report>aggregate</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <version>${pmd.plugin.version}</version>
+        <configuration>
+          <targetJdk>${maven.compiler.target}</targetJdk>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/LevelCodec.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/LevelCodec.java
 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/LevelCodec.java
new file mode 100644
index 0000000..9bbc0b0
--- /dev/null
+++ 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/LevelCodec.java
@@ -0,0 +1,47 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import org.apache.logging.log4j.Level;
+import org.bson.BsonReader;
+import org.bson.BsonWriter;
+import org.bson.codecs.Codec;
+import org.bson.codecs.DecoderContext;
+import org.bson.codecs.EncoderContext;
+
+/**
+ * A BSON Codec for Log4j {@link Level}s.
+ */
+public class LevelCodec implements Codec<Level> {
+
+    @Override
+    public Level decode(final BsonReader reader, final DecoderContext 
decoderContext) {
+        return Level.getLevel(reader.readString());
+    }
+
+    @Override
+    public void encode(final BsonWriter writer, final Level level, final 
EncoderContext encoderContext) {
+        writer.writeString(level.name());
+    }
+
+    @Override
+    public Class<Level> getEncoderClass() {
+        return Level.class;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbConnection.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbConnection.java
 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbConnection.java
new file mode 100644
index 0000000..e25c366
--- /dev/null
+++ 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbConnection.java
@@ -0,0 +1,113 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.appender.AppenderLoggingException;
+import org.apache.logging.log4j.core.appender.nosql.AbstractNoSqlConnection;
+import org.apache.logging.log4j.core.appender.nosql.NoSqlConnection;
+import org.apache.logging.log4j.core.appender.nosql.NoSqlObject;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.bson.BSON;
+import org.bson.Document;
+import org.bson.Transformer;
+
+import com.mongodb.MongoClient;
+import com.mongodb.MongoException;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+import com.mongodb.client.model.CreateCollectionOptions;
+
+/**
+ * The MongoDB implementation of {@link NoSqlConnection}.
+ */
+public final class MongoDbConnection extends AbstractNoSqlConnection<Document, 
MongoDbDocumentObject> {
+
+    private static final Logger LOGGER = StatusLogger.getLogger();
+
+    static {
+        BSON.addEncodingHook(Level.class, new Transformer() {
+            @Override
+            public Object transform(final Object o) {
+                if (o instanceof Level) {
+                    return ((Level) o).name();
+                }
+                return o;
+            }
+        });
+    }
+
+    private static MongoCollection<Document> getOrCreateMongoCollection(final 
MongoDatabase database,
+            final String collectionName, final boolean isCapped, final Integer 
sizeInBytes) {
+        try {
+            LOGGER.debug("Gettting collection '{}'...", collectionName);
+            // throws IllegalArgumentException if collectionName is invalid
+            return database.getCollection(collectionName);
+        } catch (final IllegalStateException e) {
+            LOGGER.debug("Collection '{}' does not exist.", collectionName);
+            final CreateCollectionOptions options = new 
CreateCollectionOptions()
+            // @formatter:off
+                    .capped(isCapped)
+                    .sizeInBytes(sizeInBytes);
+            // @formatter:on
+            LOGGER.debug("Creating collection {} (capped = {}, sizeInBytes = 
{})", collectionName, isCapped,
+                    sizeInBytes);
+            database.createCollection(collectionName, options);
+            return database.getCollection(collectionName);
+        }
+
+    }
+
+    private final MongoCollection<Document> collection;
+    private final MongoClient mongoClient;
+
+    public MongoDbConnection(final MongoClient mongoClient, final 
MongoDatabase mongoDatabase,
+            final String collectionName, final boolean isCapped, final Integer 
sizeInBytes) {
+        this.mongoClient = mongoClient;
+        this.collection = getOrCreateMongoCollection(mongoDatabase, 
collectionName, isCapped, sizeInBytes);
+    }
+
+    @Override
+    public void closeImpl() {
+        // LOG4J2-1196
+        mongoClient.close();
+    }
+
+    @Override
+    public MongoDbDocumentObject[] createList(final int length) {
+        return new MongoDbDocumentObject[length];
+    }
+
+    @Override
+    public MongoDbDocumentObject createObject() {
+        return new MongoDbDocumentObject();
+    }
+
+    @Override
+    public void insertObject(final NoSqlObject<Document> object) {
+        try {
+            final Document unwrapped = object.unwrap();
+            LOGGER.debug("Inserting object {}", unwrapped);
+            this.collection.insertOne(unwrapped);
+        } catch (final MongoException e) {
+            throw new AppenderLoggingException("Failed to write log event to 
MongoDB due to error: " + e.getMessage(),
+                    e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbDocumentObject.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbDocumentObject.java
 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbDocumentObject.java
new file mode 100644
index 0000000..49bdc88
--- /dev/null
+++ 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbDocumentObject.java
@@ -0,0 +1,58 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import java.util.Arrays;
+
+import org.apache.logging.log4j.core.appender.nosql.NoSqlObject;
+import org.bson.Document;
+
+/**
+ * The MongoDB implementation of {@link NoSqlObject} typed to a BSON {@link 
Document}.
+ */
+public final class MongoDbDocumentObject implements NoSqlObject<Document> {
+    private final Document document;
+
+    public MongoDbDocumentObject() {
+        this.document = new Document();
+    }
+
+    @Override
+    public void set(final String field, final NoSqlObject<Document> value) {
+        this.document.append(field, value.unwrap());
+    }
+
+    @Override
+    public void set(final String field, final NoSqlObject<Document>[] values) {
+        this.document.append(field, Arrays.asList(values));
+    }
+
+    @Override
+    public void set(final String field, final Object value) {
+        this.document.append(field, value);
+    }
+
+    @Override
+    public void set(final String field, final Object[] values) {
+        this.document.append(field, Arrays.asList(values));
+    }
+
+    @Override
+    public Document unwrap() {
+        return this.document;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbProvider.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbProvider.java
 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbProvider.java
new file mode 100644
index 0000000..b5b437c
--- /dev/null
+++ 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/MongoDbProvider.java
@@ -0,0 +1,326 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Core;
+import org.apache.logging.log4j.core.appender.nosql.NoSqlProvider;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
+import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
+import 
org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
+import 
org.apache.logging.log4j.core.config.plugins.validation.constraints.ValidHost;
+import 
org.apache.logging.log4j.core.config.plugins.validation.constraints.ValidPort;
+import org.apache.logging.log4j.core.filter.AbstractFilterable;
+import org.apache.logging.log4j.core.util.NameUtil;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.LoaderUtil;
+import org.apache.logging.log4j.util.Strings;
+import org.bson.codecs.configuration.CodecRegistries;
+
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientOptions;
+import com.mongodb.MongoCredential;
+import com.mongodb.ServerAddress;
+import com.mongodb.WriteConcern;
+import com.mongodb.client.MongoDatabase;
+
+/**
+ * The MongoDB implementation of {@link NoSqlProvider}.
+ */
+@Plugin(name = "MongoDb3", category = Core.CATEGORY_NAME, printObject = true)
+public final class MongoDbProvider implements NoSqlProvider<MongoDbConnection> 
{
+
+    public static class Builder<B extends Builder<B>> extends 
AbstractFilterable.Builder<B>
+            implements 
org.apache.logging.log4j.core.util.Builder<MongoDbProvider> {
+
+        private static WriteConcern toWriteConcern(final String 
writeConcernConstant,
+                final String writeConcernConstantClassName) {
+            WriteConcern writeConcern;
+            if (Strings.isNotEmpty(writeConcernConstant)) {
+                if (Strings.isNotEmpty(writeConcernConstantClassName)) {
+                    try {
+                        final Class<?> writeConcernConstantClass = 
LoaderUtil.loadClass(writeConcernConstantClassName);
+                        final Field field = 
writeConcernConstantClass.getField(writeConcernConstant);
+                        writeConcern = (WriteConcern) field.get(null);
+                    } catch (final Exception e) {
+                        LOGGER.error("Write concern constant [{}.{}] not 
found, using default.",
+                                writeConcernConstantClassName, 
writeConcernConstant);
+                        writeConcern = DEFAULT_WRITE_CONCERN;
+                    }
+                } else {
+                    writeConcern = WriteConcern.valueOf(writeConcernConstant);
+                    if (writeConcern == null) {
+                        LOGGER.warn("Write concern constant [{}] not found, 
using default.", writeConcernConstant);
+                        writeConcern = DEFAULT_WRITE_CONCERN;
+                    }
+                }
+            } else {
+                writeConcern = DEFAULT_WRITE_CONCERN;
+            }
+            return writeConcern;
+        }
+
+        @PluginBuilderAttribute
+        @Required(message = "No collection name provided")
+        private String collectionName;
+
+        @PluginBuilderAttribute
+        private int collectionSize = DEFAULT_COLLECTION_SIZE;
+
+        @PluginBuilderAttribute
+        @Required(message = "No database name provided")
+        private String databaseName;
+
+        @PluginBuilderAttribute
+        private String factoryClassName;
+
+        @PluginBuilderAttribute
+        private String factoryMethodName;
+
+        @PluginBuilderAttribute("capped")
+        private boolean capped = false;
+
+        @PluginBuilderAttribute(sensitive = true)
+        private String password;
+
+        @PluginBuilderAttribute
+        @ValidPort
+        private String port = "" + DEFAULT_PORT;
+
+        @PluginBuilderAttribute
+        @ValidHost
+        private String server = "localhost";
+
+        @PluginBuilderAttribute
+        private String userName;
+
+        @PluginBuilderAttribute
+        private String writeConcernConstant;
+
+        @PluginBuilderAttribute
+        private String writeConcernConstantClassName;
+
+        @SuppressWarnings("resource")
+        @Override
+        public MongoDbProvider build() {
+            MongoDatabase database;
+            String description;
+            MongoClient mongoClient = null;
+
+            if (Strings.isNotEmpty(factoryClassName) && 
Strings.isNotEmpty(factoryMethodName)) {
+                try {
+                    final Class<?> factoryClass = 
LoaderUtil.loadClass(factoryClassName);
+                    final Method method = 
factoryClass.getMethod(factoryMethodName);
+                    final Object object = method.invoke(null);
+
+                    if (object instanceof MongoDatabase) {
+                        database = (MongoDatabase) object;
+                    } else if (object instanceof MongoClient) {
+                        if (Strings.isNotEmpty(databaseName)) {
+                            database = ((MongoClient) 
object).getDatabase(databaseName);
+                        } else {
+                            LOGGER.error("The factory method [{}.{}()] 
returned a MongoClient so the database name is "
+                                    + "required.", factoryClassName, 
factoryMethodName);
+                            return null;
+                        }
+                    } else if (object == null) {
+                        LOGGER.error("The factory method [{}.{}()] returned 
null.", factoryClassName,
+                                factoryMethodName);
+                        return null;
+                    } else {
+                        LOGGER.error("The factory method [{}.{}()] returned an 
unsupported type [{}].",
+                                factoryClassName, factoryMethodName, 
object.getClass().getName());
+                        return null;
+                    }
+
+                    final String databaseName = database.getName();
+                    description = "database=" + databaseName;
+                } catch (final ClassNotFoundException e) {
+                    LOGGER.error("The factory class [{}] could not be 
loaded.", factoryClassName, e);
+                    return null;
+                } catch (final NoSuchMethodException e) {
+                    LOGGER.error("The factory class [{}] does not have a 
no-arg method named [{}].", factoryClassName,
+                            factoryMethodName, e);
+                    return null;
+                } catch (final Exception e) {
+                    LOGGER.error("The factory method [{}.{}()] could not be 
invoked.", factoryClassName,
+                            factoryMethodName, e);
+                    return null;
+                }
+            } else if (Strings.isNotEmpty(databaseName)) {
+                MongoCredential mongoCredential = null;
+                description = "database=" + databaseName;
+                if (Strings.isNotEmpty(userName) && 
Strings.isNotEmpty(password)) {
+                    description += ", username=" + userName + ", passwordHash="
+                            + NameUtil.md5(password + 
MongoDbProvider.class.getName());
+                    mongoCredential = 
MongoCredential.createCredential(userName, databaseName, 
password.toCharArray());
+                }
+                try {
+                    final int portInt = TypeConverters.convert(port, 
int.class, DEFAULT_PORT);
+                    description += ", server=" + server + ", port=" + portInt;
+                    final WriteConcern writeConcern = 
toWriteConcern(writeConcernConstant, writeConcernConstantClassName);
+                    // @formatter:off
+                    final MongoClientOptions options = 
MongoClientOptions.builder()
+                            .codecRegistry(CodecRegistries.fromRegistries(
+                                            CodecRegistries.fromCodecs(new 
LevelCodec()),
+                                            
MongoClient.getDefaultCodecRegistry()))
+                            .writeConcern(writeConcern)
+                            .build();
+                    // @formatter:on
+                    final ServerAddress serverAddress = new 
ServerAddress(server, portInt);
+                    mongoClient = mongoCredential == null ?
+                    // @formatter:off
+                            new MongoClient(serverAddress, options) :
+                            new MongoClient(serverAddress, mongoCredential, 
options);
+                    // @formatter:on
+                    database = mongoClient.getDatabase(databaseName);
+                } catch (final Exception e) {
+                    LOGGER.error("Failed to obtain a database instance from 
the MongoClient at server [{}] and "
+                            + "port [{}].", server, port);
+                    close(mongoClient);
+                    return null;
+                }
+            } else {
+                LOGGER.error("No factory method was provided so the database 
name is required.");
+                close(mongoClient);
+                return null;
+            }
+
+            try {
+                database.listCollectionNames().first(); // Check if the 
database actually requires authentication
+            } catch (final Exception e) {
+                LOGGER.error(
+                        "The database is not up, or you are not authenticated, 
try supplying a username and password to the MongoDB provider.",
+                        e);
+                close(mongoClient);
+                return null;
+            }
+
+            return new MongoDbProvider(mongoClient, database, collectionName, 
capped, collectionSize, description);
+        }
+
+        private void close(final MongoClient mongoClient) {
+            if (mongoClient != null) {
+                mongoClient.close();
+            }
+        }
+
+        public B setCapped(final boolean isCapped) {
+            this.capped = isCapped;
+            return asBuilder();
+        }
+
+        public B setCollectionName(final String collectionName) {
+            this.collectionName = collectionName;
+            return asBuilder();
+        }
+
+        public B setCollectionSize(final int collectionSize) {
+            this.collectionSize = collectionSize;
+            return asBuilder();
+        }
+
+        public B setDatabaseName(final String databaseName) {
+            this.databaseName = databaseName;
+            return asBuilder();
+        }
+
+        public B setFactoryClassName(final String factoryClassName) {
+            this.factoryClassName = factoryClassName;
+            return asBuilder();
+        }
+
+        public B setFactoryMethodName(final String factoryMethodName) {
+            this.factoryMethodName = factoryMethodName;
+            return asBuilder();
+        }
+
+        public B setPassword(final String password) {
+            this.password = password;
+            return asBuilder();
+        }
+
+        public B setPort(final String port) {
+            this.port = port;
+            return asBuilder();
+        }
+
+        public B setServer(final String server) {
+            this.server = server;
+            return asBuilder();
+        }
+
+        public B setUserName(final String userName) {
+            this.userName = userName;
+            return asBuilder();
+        }
+
+        public B setWriteConcernConstant(final String writeConcernConstant) {
+            this.writeConcernConstant = writeConcernConstant;
+            return asBuilder();
+        }
+
+        public B setWriteConcernConstantClassName(final String 
writeConcernConstantClassName) {
+            this.writeConcernConstantClassName = writeConcernConstantClassName;
+            return asBuilder();
+        }
+    }
+
+    private static final int DEFAULT_COLLECTION_SIZE = 536870912;
+    private static final int DEFAULT_PORT = 27017;
+    private static final WriteConcern DEFAULT_WRITE_CONCERN = 
WriteConcern.ACKNOWLEDGED;
+
+    private static final Logger LOGGER = StatusLogger.getLogger();
+
+    @PluginBuilderFactory
+    public static <B extends Builder<B>> B newBuilder() {
+        return new Builder<B>().asBuilder();
+    }
+
+    private final String collectionName;
+    private final Integer collectionSize;
+    private final String description;
+    private final boolean isCapped;
+    private final MongoClient mongoClient;
+    private final MongoDatabase mongoDatabase;
+
+    private MongoDbProvider(final MongoClient mongoClient, final MongoDatabase 
mongoDatabase,
+            final String collectionName, final boolean isCapped, final Integer 
collectionSize,
+            final String description) {
+        this.mongoClient = mongoClient;
+        this.mongoDatabase = mongoDatabase;
+        this.collectionName = collectionName;
+        this.isCapped = isCapped;
+        this.collectionSize = collectionSize;
+        this.description = "mongoDb{ " + description + " }";
+    }
+
+    @Override
+    public MongoDbConnection getConnection() {
+        return new MongoDbConnection(mongoClient, mongoDatabase, 
collectionName, isCapped, collectionSize);
+    }
+
+    @Override
+    public String toString() {
+        return description;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/package-info.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/package-info.java
 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/package-info.java
new file mode 100644
index 0000000..0437d98
--- /dev/null
+++ 
b/log4j-mongodb3/src/main/java/org/apache/logging/log4j/mongodb3/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+/**
+ * The classes in this package contain the MongoDB provider for the NoSQL 
Appender.
+ */
+package org.apache.logging.log4j.mongodb3;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/site/markdown/index.md.vm
----------------------------------------------------------------------
diff --git a/log4j-mongodb3/src/site/markdown/index.md.vm 
b/log4j-mongodb3/src/site/markdown/index.md.vm
new file mode 100644
index 0000000..1bdd5a5
--- /dev/null
+++ b/log4j-mongodb3/src/site/markdown/index.md.vm
@@ -0,0 +1,48 @@
+<!-- vim: set syn=markdown : -->
+<!--
+    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.
+-->
+#set($h1='#')
+#set($h2='##')
+## TODO: use properties for dynamic dependency versions
+
+$h1 MongoDB appender
+
+[MongoDB](http://www.mongodb.org/) is supported through the
+[Java MongoDB Driver](http://docs.mongodb.org/ecosystem/drivers/java/).
+
+```
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.mongodb</groupId>
+        <artifactId>mongo-java-driver</artifactId>
+        <version>2.12.3</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.mongodb</groupId>
+      <artifactId>mongo-java-driver</artifactId>
+    </dependency>
+  </dependencies>
+```
+
+$h2 Requirements
+
+The MongoDB Appender is dependent on the Log4j 2 API and implementation.
+For more information, see [Runtime Dependencies](../runtime-dependencies.html).

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/site/site.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb3/src/site/site.xml b/log4j-mongodb3/src/site/site.xml
new file mode 100644
index 0000000..54ea9be
--- /dev/null
+++ b/log4j-mongodb3/src/site/site.xml
@@ -0,0 +1,52 @@
+<!--
+ 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.
+
+-->
+<project name="Log4j MongoDB Appender"
+         xmlns="http://maven.apache.org/DECORATION/1.4.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 
http://maven.apache.org/xsd/decoration-1.4.0.xsd";>
+  <body>
+    <links>
+      <item name="Apache" href="http://www.apache.org/"; />
+      <item name="Logging Services" href="http://logging.apache.org/"/>
+      <item name="Log4j" href="../index.html"/>
+    </links>
+
+    <!-- Component-specific reports -->
+    <menu ref="reports"/>
+
+       <!-- Overall Project Info -->
+    <menu name="Log4j Project Information" img="icon-info-sign">
+      <item name="Dependencies" href="../dependencies.html" />
+      <item name="Dependency Convergence" 
href="../dependency-convergence.html" />
+      <item name="Dependency Management" href="../dependency-management.html" 
/>
+      <item name="Project Team" href="../team-list.html" />
+      <item name="Mailing Lists" href="../mail-lists.html" />
+      <item name="Issue Tracking" href="../issue-tracking.html" />
+      <item name="Project License" href="../license.html" />
+      <item name="Source Repository" href="../source-repository.html" />
+      <item name="Project Summary" href="../project-summary.html" />
+    </menu>
+
+    <menu name="Log4j Project Reports" img="icon-cog">
+      <item name="Changes Report" href="../changes-report.html" />
+      <item name="JIRA Report" href="../jira-report.html" />
+      <item name="Surefire Report" href="../surefire-report.html" />
+      <item name="RAT Report" href="../rat-report.html" />
+    </menu>
+  </body>
+</project>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/Java8Test.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/Java8Test.java 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/Java8Test.java
new file mode 100644
index 0000000..71acc29
--- /dev/null
+++ 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/Java8Test.java
@@ -0,0 +1,48 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import org.apache.commons.lang3.JavaVersion;
+import org.apache.commons.lang3.SystemUtils;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Runs all MongoDB only on Java 8.
+ * <p>
+ * The test framework {@code de.flapdoodle.embed.mongo} requires Java 8.
+ * </p>
+ */
+@RunWith(Suite.class)
[email protected]({ MongoDbTestTestRuleTestJava8.class, 
MongoDbAuthFailureTestJava8.class, MongoDbCappedTestJava8.class,
+        MongoDbMapMessageTestJava8.class, MongoDbTestJava8.class })
+public class Java8Test {
+
+    @BeforeClass
+    public static void beforeClass() {
+        Assume.assumeTrue(SystemUtils.JAVA_VERSION, 
SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));
+    }
+
+    @Test
+    public void test() {
+        // noop
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbAuthFailureTestJava8.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbAuthFailureTestJava8.java
 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbAuthFailureTestJava8.java
new file mode 100644
index 0000000..6361a44
--- /dev/null
+++ 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbAuthFailureTestJava8.java
@@ -0,0 +1,72 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.mongodb3.MongoDbTestRule.LoggingTarget;
+import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
+import org.apache.logging.log4j.test.RuleChainFactory;
+import org.bson.Document;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.RuleChain;
+
+import com.mongodb.MongoClient;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+
+/**
+ * This class name does NOT end in "Test" in order to only be picked up by 
{@link Java8Test}.
+ *
+ * TODO Set up the log4j user in MongoDB.
+ */
+@Ignore("TODO Set up the log4j user in MongoDB")
+@Category(Appenders.MongoDb.class)
+public class MongoDbAuthFailureTestJava8 {
+
+    private static LoggerContextRule loggerContextTestRule = new 
LoggerContextRule("log4j2-mongodb-auth-failure.xml");
+
+    private static final AvailablePortSystemPropertyTestRule 
mongoDbPortTestRule = AvailablePortSystemPropertyTestRule
+            .create(TestConstants.SYS_PROP_NAME_PORT);
+
+    private static final MongoDbTestRule mongoDbTestRule = new 
MongoDbTestRule(mongoDbPortTestRule.getName(),
+            MongoDbAuthFailureTestJava8.class, LoggingTarget.NULL);
+
+    @ClassRule
+    public static RuleChain ruleChain = 
RuleChainFactory.create(mongoDbPortTestRule, mongoDbTestRule,
+            loggerContextTestRule);
+
+    @Test
+    public void test() {
+        final Logger logger = LogManager.getLogger();
+        logger.info("Hello log");
+        try (final MongoClient mongoClient = mongoDbTestRule.getMongoClient()) 
{
+            final MongoDatabase database = mongoClient.getDatabase("test");
+            Assert.assertNotNull(database);
+            final MongoCollection<Document> collection = 
database.getCollection("applog");
+            Assert.assertNotNull(collection);
+            final Document first = collection.find().first();
+            Assert.assertNull(first);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbCappedTestJava8.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbCappedTestJava8.java
 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbCappedTestJava8.java
new file mode 100644
index 0000000..06fb4f5
--- /dev/null
+++ 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbCappedTestJava8.java
@@ -0,0 +1,69 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.mongodb3.MongoDbTestRule.LoggingTarget;
+import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
+import org.apache.logging.log4j.test.RuleChainFactory;
+import org.bson.Document;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.RuleChain;
+
+import com.mongodb.MongoClient;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+
+/**
+ * This class name does NOT end in "Test" in order to only be picked up by 
{@link Java8Test}.
+ */
+@Category(Appenders.MongoDb.class)
+public class MongoDbCappedTestJava8 {
+
+    private static LoggerContextRule loggerContextTestRule = new 
LoggerContextRule("log4j2-mongodb-capped.xml");
+
+    private static final AvailablePortSystemPropertyTestRule 
mongoDbPortTestRule = AvailablePortSystemPropertyTestRule
+            .create(TestConstants.SYS_PROP_NAME_PORT);
+
+    private static final MongoDbTestRule mongoDbTestRule = new 
MongoDbTestRule(mongoDbPortTestRule.getName(),
+            MongoDbCappedTestJava8.class, LoggingTarget.NULL);
+
+    @ClassRule
+    public static RuleChain ruleChain = 
RuleChainFactory.create(mongoDbPortTestRule, mongoDbTestRule,
+            loggerContextTestRule);
+
+    @Test
+    public void test() {
+        final Logger logger = LogManager.getLogger();
+        logger.info("Hello log");
+        try (final MongoClient mongoClient = mongoDbTestRule.getMongoClient()) 
{
+            final MongoDatabase database = mongoClient.getDatabase("test");
+            Assert.assertNotNull(database);
+            final MongoCollection<Document> collection = 
database.getCollection("applog");
+            Assert.assertNotNull(collection);
+            final Document first = collection.find().first();
+            Assert.assertNotNull(first);
+            Assert.assertEquals(first.toJson(), "Hello log", 
first.getString("message"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbMapMessageTestJava8.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbMapMessageTestJava8.java
 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbMapMessageTestJava8.java
new file mode 100644
index 0000000..1c36e08
--- /dev/null
+++ 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbMapMessageTestJava8.java
@@ -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.logging.log4j.mongodb3;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.message.MapMessage;
+import org.apache.logging.log4j.mongodb3.MongoDbTestRule.LoggingTarget;
+import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
+import org.apache.logging.log4j.test.RuleChainFactory;
+import org.bson.Document;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.RuleChain;
+
+import com.mongodb.MongoClient;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+
+/**
+ * This class name does NOT end in "Test" in order to only be picked up by 
{@link Java8Test}.
+ */
+@Category(Appenders.MongoDb.class)
+public class MongoDbMapMessageTestJava8 {
+
+    private static LoggerContextRule loggerContextTestRule = new 
LoggerContextRule("log4j2-mongodb-map-message.xml");
+
+    private static final AvailablePortSystemPropertyTestRule 
mongoDbPortTestRule = AvailablePortSystemPropertyTestRule
+            .create(TestConstants.SYS_PROP_NAME_PORT);
+
+    private static final MongoDbTestRule mongoDbTestRule = new 
MongoDbTestRule(mongoDbPortTestRule.getName(),
+            MongoDbMapMessageTestJava8.class, LoggingTarget.NULL);
+
+    @ClassRule
+    public static RuleChain ruleChain = 
RuleChainFactory.create(mongoDbPortTestRule, mongoDbTestRule,
+            loggerContextTestRule);
+
+    @Test
+    public void test() {
+        final Logger logger = LogManager.getLogger();
+        final MapMessage mapMessage = new MapMessage();
+        mapMessage.with("SomeName", "SomeValue");
+        mapMessage.with("SomeInt", 1);
+        logger.info(mapMessage);
+        //
+        try (final MongoClient mongoClient = mongoDbTestRule.getMongoClient()) 
{
+            final MongoDatabase database = mongoClient.getDatabase("test");
+            Assert.assertNotNull(database);
+            final MongoCollection<Document> collection = 
database.getCollection("applog");
+            Assert.assertNotNull(collection);
+            final Document first = collection.find().first();
+            Assert.assertNotNull(first);
+            final String firstJson = first.toJson();
+            Assert.assertEquals(firstJson, "SomeValue", 
first.getString("SomeName"));
+            Assert.assertEquals(firstJson, Integer.valueOf(1), 
first.getInteger("SomeInt"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestJava8.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestJava8.java
 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestJava8.java
new file mode 100644
index 0000000..e1f283c
--- /dev/null
+++ 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestJava8.java
@@ -0,0 +1,69 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.mongodb3.MongoDbTestRule.LoggingTarget;
+import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
+import org.apache.logging.log4j.test.RuleChainFactory;
+import org.bson.Document;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.RuleChain;
+
+import com.mongodb.MongoClient;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+
+/**
+ * This class name does NOT end in "Test" in order to only be picked up by 
{@link Java8Test}.
+ */
+@Category(Appenders.MongoDb.class)
+public class MongoDbTestJava8 {
+
+    private static LoggerContextRule loggerContextTestRule = new 
LoggerContextRule("log4j2-mongodb.xml");
+
+    private static final AvailablePortSystemPropertyTestRule 
mongoDbPortTestRule = AvailablePortSystemPropertyTestRule
+            .create(TestConstants.SYS_PROP_NAME_PORT);
+
+    private static final MongoDbTestRule mongoDbTestRule = new 
MongoDbTestRule(mongoDbPortTestRule.getName(),
+            MongoDbTestJava8.class, LoggingTarget.NULL);
+
+    @ClassRule
+    public static RuleChain ruleChain = 
RuleChainFactory.create(mongoDbPortTestRule, mongoDbTestRule,
+            loggerContextTestRule);
+
+    @Test
+    public void test() {
+        final Logger logger = LogManager.getLogger();
+        logger.info("Hello log");
+        try (final MongoClient mongoClient = mongoDbTestRule.getMongoClient()) 
{
+            final MongoDatabase database = mongoClient.getDatabase("test");
+            Assert.assertNotNull(database);
+            final MongoCollection<Document> collection = 
database.getCollection("applog");
+            Assert.assertNotNull(collection);
+            final Document first = collection.find().first();
+            Assert.assertNotNull(first);
+            Assert.assertEquals(first.toJson(), "Hello log", 
first.getString("message"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestRule.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestRule.java
 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestRule.java
new file mode 100644
index 0000000..96a903b
--- /dev/null
+++ 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestRule.java
@@ -0,0 +1,192 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import java.util.Objects;
+
+import org.apache.commons.lang3.NotImplementedException;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mongodb.MongoClient;
+
+import de.flapdoodle.embed.mongo.Command;
+import de.flapdoodle.embed.mongo.MongodExecutable;
+import de.flapdoodle.embed.mongo.MongodProcess;
+import de.flapdoodle.embed.mongo.MongodStarter;
+import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
+import de.flapdoodle.embed.mongo.config.Net;
+import de.flapdoodle.embed.mongo.config.RuntimeConfigBuilder;
+import de.flapdoodle.embed.mongo.config.Timeout;
+import de.flapdoodle.embed.mongo.distribution.Version;
+import de.flapdoodle.embed.process.config.IRuntimeConfig;
+import de.flapdoodle.embed.process.config.io.ProcessOutput;
+import de.flapdoodle.embed.process.runtime.Network;
+
+/**
+ * A JUnit test rule to manage a MongoDB embedded instance.
+ * 
+ * TODO Move this class to Apache Commons Testing.
+ */
+public class MongoDbTestRule implements TestRule {
+
+    public enum LoggingTarget {
+        CONSOLE, NULL;
+
+        public static LoggingTarget getLoggingTarget(final String 
sysPropertyName, final LoggingTarget defaultValue) {
+            return LoggingTarget.valueOf(System.getProperty(sysPropertyName, 
defaultValue.name()));
+        }
+    }
+
+    private static final int BUILDER_TIMEOUT_MILLIS = 30000;
+
+    public static int getBuilderTimeoutMillis() {
+        return BUILDER_TIMEOUT_MILLIS;
+    }
+
+    private static MongodStarter getMongodStarter(final LoggingTarget 
loggingTarget) {
+        if (loggingTarget == null) {
+            return MongodStarter.getDefaultInstance();
+        }
+        switch (loggingTarget) {
+        case NULL:
+            final Logger logger = 
LoggerFactory.getLogger(MongoDbTestRule.class.getName());
+            final IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
+            // @formatter:off
+                .defaultsWithLogger(Command.MongoD, logger)
+                .processOutput(ProcessOutput.getDefaultInstanceSilent())
+                .build();
+            // @formatter:on
+
+            return MongodStarter.getInstance(runtimeConfig);
+        case CONSOLE:
+            return MongodStarter.getDefaultInstance();
+        default:
+            throw new NotImplementedException(loggingTarget.toString());
+        }
+    }
+
+    protected final LoggingTarget loggingTarget;
+
+    protected MongoClient mongoClient;
+    protected MongodExecutable mongodExecutable;
+    protected MongodProcess mongodProcess;
+    protected final String portSystemPropertyName;
+
+    /**
+     * Store {@link MongodStarter} (or RuntimeConfig) in a static final field 
if you want to use artifact store caching
+     * (or else disable caching).
+     * <p>
+     * The test framework {@code de.flapdoodle.embed.mongo} requires Java 8.
+     * </p>
+     */
+    protected final MongodStarter starter;
+
+    /**
+     * Constructs a new test rule.
+     *
+     * @param portSystemPropertyName
+     *            The system property name for the MongoDB port.
+     * @param clazz
+     *            The test case class.
+     * @param defaultLoggingTarget
+     *            The logging target.
+     */
+    public MongoDbTestRule(final String portSystemPropertyName, final Class<?> 
clazz,
+            final LoggingTarget defaultLoggingTarget) {
+        this.portSystemPropertyName = 
Objects.requireNonNull(portSystemPropertyName, "portSystemPropertyName");
+        this.loggingTarget = LoggingTarget.getLoggingTarget(clazz.getName() + 
"." + LoggingTarget.class.getSimpleName(),
+                defaultLoggingTarget);
+        this.starter = getMongodStarter(this.loggingTarget);
+    }
+
+    @Override
+    public Statement apply(final Statement base, final Description 
description) {
+        return new Statement() {
+
+            @Override
+            public void evaluate() throws Throwable {
+                final String value = 
Objects.requireNonNull(System.getProperty(portSystemPropertyName),
+                        "System property '" + portSystemPropertyName + "' is 
null");
+                final int port = Integer.parseInt(value);
+                mongodExecutable = starter.prepare(
+                // @formatter:off
+                        new MongodConfigBuilder()
+                            .version(Version.Main.PRODUCTION)
+                            .timeout(new Timeout(BUILDER_TIMEOUT_MILLIS))
+                            .net(
+                                    new Net("localhost", port, 
Network.localhostIsIPv6()))
+                            .build());
+                // @formatter:on
+                mongodProcess = mongodExecutable.start();
+                mongoClient = new MongoClient("localhost", port);
+                try {
+                    base.evaluate();
+                } finally {
+                    if (mongodProcess != null) {
+                        mongodProcess.stop();
+                        mongodProcess = null;
+                    }
+                    if (mongodExecutable != null) {
+                        mongodExecutable.stop();
+                        mongodExecutable = null;
+                    }
+                }
+            }
+        };
+    }
+
+    public MongoClient getMongoClient() {
+        return mongoClient;
+    }
+
+    public MongodExecutable getMongodExecutable() {
+        return mongodExecutable;
+    }
+
+    public MongodProcess getMongodProcess() {
+        return mongodProcess;
+    }
+
+    public MongodStarter getStarter() {
+        return starter;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("MongoDbTestRule [starter=");
+        builder.append(starter);
+        builder.append(", portSystemPropertyName=");
+        builder.append(portSystemPropertyName);
+        builder.append(", mongoClient=");
+        builder.append(mongoClient);
+        builder.append(", mongodExecutable=");
+        builder.append(mongodExecutable);
+        builder.append(", mongodProcess=");
+        builder.append(mongodProcess);
+        builder.append(", loggingTarget=");
+        builder.append(loggingTarget);
+        builder.append("]");
+        return builder.toString();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestTestRuleTestJava8.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestTestRuleTestJava8.java
 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestTestRuleTestJava8.java
new file mode 100644
index 0000000..21d62f9
--- /dev/null
+++ 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDbTestTestRuleTestJava8.java
@@ -0,0 +1,71 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+import org.apache.commons.lang3.JavaVersion;
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.logging.log4j.mongodb3.MongoDbTestRule.LoggingTarget;
+import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
+import org.apache.logging.log4j.test.RuleChainFactory;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+
+import com.mongodb.client.MongoIterable;
+
+/**
+ * Tests MongoDbRule. This class name does NOT end in "Test" in order to only 
be picked up by {@link Java8Test}.
+ * <p>
+ * The test framework {@code de.flapdoodle.embed.mongo} requires Java 8.
+ * </p>
+ */
+public class MongoDbTestTestRuleTestJava8 {
+
+    private static final AvailablePortSystemPropertyTestRule 
mongoDbPortTestRule = AvailablePortSystemPropertyTestRule
+            .create(TestConstants.SYS_PROP_NAME_PORT);
+
+    private static final MongoDbTestRule mongoDbTestRule = new 
MongoDbTestRule(mongoDbPortTestRule.getName(),
+            MongoDbTestTestRuleTestJava8.class, LoggingTarget.NULL);
+
+    @ClassRule
+    public static RuleChain mongoDbChain = 
RuleChainFactory.create(mongoDbPortTestRule, mongoDbTestRule);
+
+    @BeforeClass
+    public static void beforeClass() {
+        
Assume.assumeTrue(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));
+    }
+
+    @Test
+    public void testAccess() {
+        final MongoIterable<String> databaseNames = 
mongoDbTestRule.getMongoClient().listDatabaseNames();
+        Assert.assertNotNull(databaseNames);
+        Assert.assertNotNull(databaseNames.first());
+    }
+
+    @Test
+    public void testMongoDbTestRule() {
+        Assert.assertNotNull(mongoDbTestRule);
+        Assert.assertNotNull(mongoDbTestRule.getStarter());
+        Assert.assertNotNull(mongoDbTestRule.getMongoClient());
+        Assert.assertNotNull(mongoDbTestRule.getMongodExecutable());
+        Assert.assertNotNull(mongoDbTestRule.getMongodProcess());
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/TestConstants.java
----------------------------------------------------------------------
diff --git 
a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/TestConstants.java
 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/TestConstants.java
new file mode 100644
index 0000000..3e7e0f3
--- /dev/null
+++ 
b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/TestConstants.java
@@ -0,0 +1,24 @@
+/*
+ * 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.logging.log4j.mongodb3;
+
+public class TestConstants {
+
+    public static final String SYS_PROP_NAME_PORT = "MongoDBTestPort";
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/resources/log4j2-mongodb-auth-failure.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb3/src/test/resources/log4j2-mongodb-auth-failure.xml 
b/log4j-mongodb3/src/test/resources/log4j2-mongodb-auth-failure.xml
new file mode 100644
index 0000000..6603582
--- /dev/null
+++ b/log4j-mongodb3/src/test/resources/log4j2-mongodb-auth-failure.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <NoSql name="MongoDbAppender">
+      <MongoDb3 databaseName="test" collectionName="applog" server="localhost" 
userName="log4jUser" password="12345678"
+        port="${sys:MongoDBTestPort:-27017}" />
+    </NoSql>
+  </Appenders>
+  <Loggers>
+    <Root level="ALL">
+      <AppenderRef ref="MongoDbAppender" />
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/resources/log4j2-mongodb-capped.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb3/src/test/resources/log4j2-mongodb-capped.xml 
b/log4j-mongodb3/src/test/resources/log4j2-mongodb-capped.xml
new file mode 100644
index 0000000..9ff6dbc
--- /dev/null
+++ b/log4j-mongodb3/src/test/resources/log4j2-mongodb-capped.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <NoSql name="MongoDbAppender">
+      <MongoDb3 databaseName="test" collectionName="applog" server="localhost" 
capped="true" collectionSize="1073741824"
+        port="${sys:MongoDBTestPort:-27017}" />
+    </NoSql>
+  </Appenders>
+  <Loggers>
+    <Root level="ALL">
+      <AppenderRef ref="MongoDbAppender" />
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/resources/log4j2-mongodb-map-message.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb3/src/test/resources/log4j2-mongodb-map-message.xml 
b/log4j-mongodb3/src/test/resources/log4j2-mongodb-map-message.xml
new file mode 100644
index 0000000..eec81af
--- /dev/null
+++ b/log4j-mongodb3/src/test/resources/log4j2-mongodb-map-message.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <NoSql name="MongoDbAppender">
+      <MongoDb3 databaseName="test" collectionName="applog" server="localhost"
+        port="${sys:MongoDBTestPort:-27017}" />
+      <MessageLayout />
+    </NoSql>
+  </Appenders>
+  <Loggers>
+    <Root level="ALL">
+      <AppenderRef ref="MongoDbAppender" />
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/log4j-mongodb3/src/test/resources/log4j2-mongodb.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb3/src/test/resources/log4j2-mongodb.xml 
b/log4j-mongodb3/src/test/resources/log4j2-mongodb.xml
new file mode 100644
index 0000000..9819b64
--- /dev/null
+++ b/log4j-mongodb3/src/test/resources/log4j2-mongodb.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <NoSql name="MongoDbAppender">
+      <MongoDb3 databaseName="test" collectionName="applog" server="localhost"
+        port="${sys:MongoDBTestPort:-27017}" />
+    </NoSql>
+  </Appenders>
+  <Loggers>
+    <Root level="ALL">
+      <AppenderRef ref="MongoDbAppender" />
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a17e3a6..3f6286f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -829,6 +829,13 @@
         <artifactId>groovy-all</artifactId>
         <version>2.4.13</version>
       </dependency>
+      <dependency>
+        <!-- Testing MongoDB -->
+        <groupId>de.flapdoodle.embed</groupId>
+        <artifactId>de.flapdoodle.embed.mongo</artifactId>
+        <version>2.0.1</version>
+        <scope>test</scope>
+      </dependency>      
     </dependencies>
   </dependencyManagement>
   <build>
@@ -1329,7 +1336,7 @@
     <module>log4j-jdbc-dbcp2</module>
     <module>log4j-couchdb</module>
     <module>log4j-mongodb2</module>
-    <!-- <module>log4j-mongodb3</module> -->
+    <module>log4j-mongodb3</module>
     <module>log4j-cassandra</module>
     <module>log4j-web</module>
     <module>log4j-perf</module>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ed028c1..158c170 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -152,11 +152,9 @@
       <action issue="LOG4J2-2219" dev="ggregory" type="update" due-to="Kilian, 
Gary Gregory">
         Configuration builder classes should look for "onMismatch", not 
"onMisMatch".
       </action>
-      <!-- 
       <action issue="LOG4J2-2205" dev="ggregory" type="update" due-to="Björn 
Kautler">
         New module log4j-mongodb3: Remove use of deprecated MongoDB APIs and 
code to the Java driver version 3 API.
       </action>
-      -->
     </release>
     <release version="2.10.0" date="2017-11-18" description="GA Release 
2.10.0">
       <action issue="LOG4J2-2120" dev="mikes" type="add" due-to="Carter 
Douglas Kozak ">

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e40e73e5/src/site/site.xml
----------------------------------------------------------------------
diff --git a/src/site/site.xml b/src/site/site.xml
index d84b09e..6e0ac62 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -138,7 +138,9 @@
         <item name="Kafka" href="/manual/appenders.html#KafkaAppender"/>
         <item name="Memory Mapped File" 
href="/manual/appenders.html#MemoryMappedFileAppender"/>
         <item name="NoSQL" href="/manual/appenders.html#NoSQLAppender"/>
+        <item name="NoSQL for MongoDB" 
href="/manual/appenders.html#NoSQLAppenderMongoDB"/>
         <item name="NoSQL for MongoDB 2" 
href="/manual/appenders.html#NoSQLAppenderMongoDB2"/>
+        <item name="NoSQL for MongoDB 3" 
href="/manual/appenders.html#NoSQLAppenderMongoDB3"/>
         <item name="NoSQL for CouchDB" 
href="/manual/appenders.html#NoSQLAppenderCouchDB"/>
         <item name="Output Stream" 
href="/manual/appenders.html#OutputStreamAppender"/>
         <item name="Random Access File" 
href="/manual/appenders.html#RandomAccessFileAppender"/>

Reply via email to