You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by mi...@apache.org on 2017/10/17 20:25:21 UTC

[1/4] logging-log4j2 git commit: LOG4J2-2076 CouchDB and MongoDB appenders in own modules, remove log4j-nosql module

Repository: logging-log4j2
Updated Branches:
  refs/heads/LOG4J2-2076 d3f9719f9 -> ebec215eb


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/test/resources/log4j2-mongodb.xml
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/test/resources/log4j2-mongodb.xml b/log4j-nosql/src/test/resources/log4j2-mongodb.xml
deleted file mode 100644
index c759054..0000000
--- a/log4j-nosql/src/test/resources/log4j2-mongodb.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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="error">
-  <Appenders>
-    <NoSql name="MongoDbAppender">
-      <MongoDb databaseName="test" collectionName="applog" server="localhost" />
-    </NoSql>
-  </Appenders>
-  <Loggers>
-    <Root level="ALL">
-      <AppenderRef ref="MongoDbAppender" />
-    </Root>
-  </Loggers>
-</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 739c090..3b96fdc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1290,7 +1290,8 @@
     <module>log4j-samples</module>
     <module>log4j-osgi</module>
     <module>log4j-bom</module>
-    <module>log4j-nosql</module>
+    <module>log4j-couchdb</module>
+    <module>log4j-mongodb</module>
     <module>log4j-cassandra</module>
     <module>log4j-web</module>
     <module>log4j-perf</module>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/src/site/markdown/javadoc.md
----------------------------------------------------------------------
diff --git a/src/site/markdown/javadoc.md b/src/site/markdown/javadoc.md
index b2e435f..00cd556 100644
--- a/src/site/markdown/javadoc.md
+++ b/src/site/markdown/javadoc.md
@@ -44,4 +44,6 @@ Component | Description
 [Apache Flume Appender](log4j-flume-ng/apidocs/index.html) | An Appender that allows applications to send logging events to Apache Flume Agents.
 [Log4j JMX GUI](log4j-jmx-gui/apidocs/index.html) | A Java Swing-based client for remotely viewing the status logger and editing the Log4j configuration.
 [Log4j Web Application Support](log4j-web/apidocs/index.html) | Additional classes that enable multiple configurations within a Servlet Container.
-[Log4j NoSQL Support](log4j-nosql/apidocs/index.html) | Additional Appenders for NoSQL databases such as MongoDB and CouchDB.
+[Log4j CouchDB Support](log4j-couchdb/apidocs/index.html) | Additional Appender for CouchDB.
+[Log4j MongoDB Support](log4j-mongodb/apidocs/index.html) | Additional Appender for MongoDB.
+[Log4j Cassandra Support](log4j-cassandra/apidocs/index.html) | Additional Appender for Cassandra.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/src/site/markdown/maven-artifacts.md.vm
----------------------------------------------------------------------
diff --git a/src/site/markdown/maven-artifacts.md.vm b/src/site/markdown/maven-artifacts.md.vm
index 272cf2e..175fb2f 100644
--- a/src/site/markdown/maven-artifacts.md.vm
+++ b/src/site/markdown/maven-artifacts.md.vm
@@ -224,11 +224,23 @@ to SLF4J. The SLF4J Bridge must NOT be on the class path when this is in use.
 
 #dependencies(['log4j-to-slf4j'])
 
-$h3 NoSQL Appenders
+$h3 CouchDB
 
-If your configuration uses one of the NoSQL Appenders, then add the following.
+If your configuration uses the NoSQL CouchDB appender, then add the following.
 
-#dependencies(['log4j-nosql'])
+#dependencies(['log4j-couchdb'])
+
+$h3 MongoDB
+
+If your configuration uses the NoSQL MongoDB appender, then add the following.
+
+#dependencies(['log4j-mongodb'])
+
+$h3 Cassandra
+
+If your configuration uses the Cassandra appender, then add the following.
+
+#dependencies(['log4j-cassandra'])
 
 $h3 IO Streams
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/src/site/site.xml
----------------------------------------------------------------------
diff --git a/src/site/site.xml b/src/site/site.xml
index 6de65be..d323cd2 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -272,7 +272,9 @@
       <item name="Log4j JMX GUI" href="log4j-jmx-gui/index.html"/>
       <item name="Log4j Web Application Support" href="log4j-web/index.html"/>
       <item name="Log4j Application Server Integration" href="log4j-appserver/index.html"/>
-      <item name="Log4j NoSQL support" href="log4j-nosql/index.html"/>
+      <item name="Log4j CouchDB appender" href="log4j-couchdb/index.html"/>
+      <item name="Log4j MongoDB appender" href="log4j-mongodb/index.html"/>
+      <item name="Log4j Cassandra appender" href="log4j-cassandra/index.html"/>
       <item name="Log4j IO Streams" href="log4j-iostreams/index.html"/>
       <item name="Log4j Liquibase Binding" href="log4j-liquibase/index.html"/>
     </menu>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/src/site/xdoc/runtime-dependencies.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/runtime-dependencies.xml b/src/site/xdoc/runtime-dependencies.xml
index e319c34..1f66725 100644
--- a/src/site/xdoc/runtime-dependencies.xml
+++ b/src/site/xdoc/runtime-dependencies.xml
@@ -121,8 +121,13 @@
             <td>Automatic Module</td>
           </tr>
           <tr>
-            <td>log4j-nosql</td>
-            <td>org.apache.logging.log4j.nosql</td>
+            <td>log4j-couchdb</td>
+            <td>org.apache.logging.log4j.couchdb</td>
+            <td>Automatic Module</td>
+          </tr>
+          <tr>
+            <td>log4j-mongodb</td>
+            <td>org.apache.logging.log4j.mongodb</td>
             <td>Automatic Module</td>
           </tr>
           <tr>
@@ -255,11 +260,11 @@
         </tr>
         <tr>
           <td>NoSQL Appender with MongoDB provider</td>
-          <td>MongoDB Java Client driver and Log4j NoSQL library</td>
+          <td>MongoDB Java Client driver and Log4j MongoDB library</td>
         </tr>
         <tr>
           <td>NoSQL Appender with Apache CouchDB provider</td>
-          <td>LightCouch CouchDB client library and Log4j NoSQL library</td>
+          <td>LightCouch CouchDB client library and Log4j CouchDB library</td>
         </tr>
         <tr>
           <td>Cassandra Appender</td>
@@ -368,34 +373,24 @@
         Note that this works with the Servlet 2.5 API as well as the Servlet 3.x API.
       </p>
 
-      <a name="log4j-nosql" />
-      <h4>log4j-nosql</h4>
+      <a name="log4j-couchdb" />
+      <h4>log4j-couchdb</h4>
       <p>
-        The Log4J <a href="log4j-nosql/index.html">NoSQL Appenders</a> module has several optional
-        <a href="log4j-nosql/dependencies.html">dependencies</a>.
-        See the <a href="log4j-nosql/dependencies.html#Dependency_Tree">Dependency Tree</a> for the
-        exact list of JAR files needed for these features.
+        The Log4J <a href="log4j-couchdb/index.html">CouchDB</a> module depends on
+        the <a href="http://www.lightcouch.org/">LightCouch</a> CouchDB client library.
+      </p>
+
+      <a name="log4j-mongodb" />
+      <h4>log4j-mongodb</h4>
+      <p>
+        The Log4J <a href="log4j-mongodb/index.html">MongoDB</a> module depends on
+        the <a href="http://docs.mongodb.org/ecosystem/drivers/java/">MongoDB Java Client driver</a>.
       </p>
-      <table>
-        <caption align="top">Optional Dependencies per Feature in Log4J NoSQL Appenders</caption>
-        <tr>
-          <td>NoSQL Appender with <a href="http://www.mongodb.org/">MongoDB</a> provider</td>
-          <td>the <a href="http://docs.mongodb.org/ecosystem/drivers/java/">MongoDB Java Client driver</a></td>
-        </tr>
-        <tr>
-          <td>NoSQL Appender with <a href="https://couchdb.apache.org/">Apache CouchDB</a> provider</td>
-          <td>the <a href="http://www.lightcouch.org/">LightCouch</a> CouchDB client library</td>
-        </tr>
-        <tr>
-          <td>Cassandra Appender</td>
-          <td>the <a href="http://docs.datastax.com/en/developer/driver-matrix/doc/javaDrivers.html">Datastax Cassandra driver</a></td>
-        </tr>
-      </table>
 
       <a name="log4j-cassandra" />
       <h4>log4j-cassandra</h4>
       <p>
-        The Log4J <a href="log4j-cassandra/index.html">Cassandra</a> module has depends on
+        The Log4J <a href="log4j-cassandra/index.html">Cassandra</a> module depends on
         the <a href="http://docs.datastax.com/en/developer/driver-matrix/doc/javaDrivers.html">Datastax Cassandra driver</a>.
       </p>
 


[4/4] logging-log4j2 git commit: LOG4J2-2076 CouchDB and MongoDB appenders in own modules, remove log4j-nosql module

Posted by mi...@apache.org.
LOG4J2-2076 CouchDB and MongoDB appenders in own modules, remove log4j-nosql module


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

Branch: refs/heads/LOG4J2-2076
Commit: ebec215eb9604963ff9930252f3013121b4be751
Parents: d3f9719
Author: Mikael Ståldal <mi...@staldal.nu>
Authored: Tue Oct 17 22:23:50 2017 +0200
Committer: Mikael Ståldal <mi...@staldal.nu>
Committed: Tue Oct 17 22:23:50 2017 +0200

----------------------------------------------------------------------
 log4j-bom/pom.xml                               |  16 +-
 .../appender/db/AbstractDatabaseAppender.java   |   2 +-
 .../appender/nosql/AbstractNoSqlConnection.java |  48 +++
 .../core/appender/nosql/DefaultNoSqlObject.java |  66 +++
 .../core/appender/nosql/NoSqlAppender.java      |  96 +++++
 .../core/appender/nosql/NoSqlConnection.java    |  76 ++++
 .../appender/nosql/NoSqlDatabaseManager.java    | 224 ++++++++++
 .../log4j/core/appender/nosql/NoSqlObject.java  |  63 +++
 .../core/appender/nosql/NoSqlProvider.java      |  49 +++
 .../log4j/core/appender/nosql/package-info.java |  24 ++
 .../core/appender/nosql/NoSqlAppenderTest.java  |  62 +++
 .../nosql/NoSqlDatabaseManagerTest.java         | 427 +++++++++++++++++++
 log4j-couchdb/pom.xml                           | 183 ++++++++
 .../appender/couchdb/CouchDbConnection.java     |  69 +++
 .../nosql/appender/couchdb/CouchDbProvider.java | 161 +++++++
 .../nosql/appender/couchdb/package-info.java    |  20 +
 log4j-couchdb/src/site/markdown/index.md.vm     |  48 +++
 log4j-couchdb/src/site/site.xml                 |  52 +++
 log4j-distribution/pom.xml                      |  40 +-
 log4j-mongodb/pom.xml                           | 183 ++++++++
 .../appender/mongodb/MongoDbConnection.java     |  96 +++++
 .../nosql/appender/mongodb/MongoDbObject.java   |  66 +++
 .../nosql/appender/mongodb/MongoDbProvider.java | 351 +++++++++++++++
 .../nosql/appender/mongodb/package-info.java    |  20 +
 log4j-mongodb/src/site/markdown/index.md.vm     |  48 +++
 log4j-mongodb/src/site/site.xml                 |  52 +++
 .../nosql/appender/mongodb/MongoDbAuthTest.java |  40 ++
 .../appender/mongodb/MongoDbCappedTest.java     |  40 ++
 .../nosql/appender/mongodb/MongoDbTest.java     |  40 ++
 .../src/test/resources/log4j2-mongodb-auth.xml  |  30 ++
 .../test/resources/log4j2-mongodb-capped.xml    |  30 ++
 .../src/test/resources/log4j2-mongodb.xml       |  30 ++
 log4j-nosql/pom.xml                             | 194 ---------
 .../nosql/appender/AbstractNoSqlConnection.java |  48 ---
 .../nosql/appender/DefaultNoSqlObject.java      |  66 ---
 .../log4j/nosql/appender/NoSqlAppender.java     | 106 -----
 .../log4j/nosql/appender/NoSqlConnection.java   |  76 ----
 .../nosql/appender/NoSqlDatabaseManager.java    | 224 ----------
 .../log4j/nosql/appender/NoSqlObject.java       |  63 ---
 .../log4j/nosql/appender/NoSqlProvider.java     |  49 ---
 .../appender/couchdb/CouchDbConnection.java     |  69 ---
 .../nosql/appender/couchdb/CouchDbProvider.java | 161 -------
 .../nosql/appender/couchdb/package-info.java    |  20 -
 .../appender/mongodb/MongoDbConnection.java     |  96 -----
 .../nosql/appender/mongodb/MongoDbObject.java   |  66 ---
 .../nosql/appender/mongodb/MongoDbProvider.java | 351 ---------------
 .../nosql/appender/mongodb/package-info.java    |  20 -
 .../log4j/nosql/appender/package-info.java      |  34 --
 log4j-nosql/src/site/markdown/index.md.vm       |  77 ----
 log4j-nosql/src/site/site.xml                   |  52 ---
 .../log4j/nosql/appender/MongoDbAuthTest.java   |  40 --
 .../log4j/nosql/appender/MongoDbCappedTest.java |  40 --
 .../log4j/nosql/appender/MongoDbTest.java       |  40 --
 .../log4j/nosql/appender/NoSqlAppenderTest.java |  62 ---
 .../appender/NoSqlDatabaseManagerTest.java      | 427 -------------------
 .../src/test/resources/log4j2-mongodb-auth.xml  |  30 --
 .../test/resources/log4j2-mongodb-capped.xml    |  30 --
 .../src/test/resources/log4j2-mongodb.xml       |  30 --
 pom.xml                                         |   3 +-
 src/site/markdown/javadoc.md                    |   4 +-
 src/site/markdown/maven-artifacts.md.vm         |  18 +-
 src/site/site.xml                               |   4 +-
 src/site/xdoc/runtime-dependencies.xml          |  47 +-
 63 files changed, 2790 insertions(+), 2509 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-bom/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-bom/pom.xml b/log4j-bom/pom.xml
index 129aa91..96bf601 100644
--- a/log4j-bom/pom.xml
+++ b/log4j-bom/pom.xml
@@ -84,10 +84,22 @@
         <artifactId>log4j-web</artifactId>
         <version>${project.version}</version>
       </dependency>
-      <!-- NoSQL Appender Plugins -->
+      <!-- CouchDB Appender Plugin -->
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>
-        <artifactId>log4j-nosql</artifactId>
+        <artifactId>log4j-couchdb</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <!-- MongoDB Appender Plugin -->
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-mongodb</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <!-- Cassandra Appender Plugin -->
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-cassandra</artifactId>
         <version>${project.version}</version>
       </dependency>
       <!-- Streaming API -->

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java
index 538b644..38f412c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java
@@ -32,7 +32,7 @@ import org.apache.logging.log4j.core.appender.AppenderLoggingException;
  * An abstract Appender for writing events to a database of some type, be it relational or NoSQL. All database appenders
  * should inherit from this base appender. Three implementations are currently provided:
  * {@link org.apache.logging.log4j.core.appender.db.jdbc JDBC}, {@link org.apache.logging.log4j.core.appender.db.jpa
- * JPA}, and <a href="/log4j/2.x/log4j-nosql/apidocs/">NoSQL</a>.
+ * JPA}, and {@link org.apache.logging.log4j.core.appender.nosql NoSQL}.
  *
  * @param <T> Specifies which type of {@link AbstractDatabaseManager} this Appender requires.
  */

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/AbstractNoSqlConnection.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/AbstractNoSqlConnection.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/AbstractNoSqlConnection.java
new file mode 100644
index 0000000..965dc1e
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/AbstractNoSqlConnection.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.core.appender.nosql;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Facilitates implementations of {@link NoSqlConnection}.
+ *
+ * @param <W>
+ *            See {@link NoSqlConnection}.
+ * @param <T>See
+ *            {@link NoSqlConnection}.
+ */
+public abstract class AbstractNoSqlConnection<W, T extends NoSqlObject<W>> implements NoSqlConnection<W, T> {
+
+    private final AtomicBoolean closed = new AtomicBoolean(false);
+
+    @Override
+    public void close() {
+        if (this.closed.compareAndSet(false, true)) {
+            closeImpl();
+        }
+    }
+
+    protected abstract void closeImpl();
+
+    @Override
+    public boolean isClosed() {
+        return this.closed.get();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/DefaultNoSqlObject.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/DefaultNoSqlObject.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/DefaultNoSqlObject.java
new file mode 100644
index 0000000..7600e1a
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/DefaultNoSqlObject.java
@@ -0,0 +1,66 @@
+/*
+ * 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.core.appender.nosql;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Default implementation of {@link NoSqlObject}. Most NoSQL Java APIs tend
+ * to re-use the Map interface for storage and retrieval of the underlying JSON documents. Therefore, this
+ * implementation is provided for convenience.
+ */
+public class DefaultNoSqlObject implements NoSqlObject<Map<String, Object>> {
+
+    private final Map<String, Object> map;
+
+    public DefaultNoSqlObject() {
+        this.map = new HashMap<>();
+    }
+
+    @Override
+    public void set(final String field, final Object value) {
+        this.map.put(field, value);
+    }
+
+    @Override
+    public void set(final String field, final NoSqlObject<Map<String, Object>> value) {
+        this.map.put(field, value.unwrap());
+    }
+
+    @Override
+    public void set(final String field, final Object[] values) {
+        this.map.put(field, Arrays.asList(values));
+    }
+
+    @Override
+    public void set(final String field, final NoSqlObject<Map<String, Object>>[] values) {
+        final List<Map<String, Object>> list = new ArrayList<>(values.length);
+        for (final NoSqlObject<Map<String, Object>> value : values) {
+            list.add(value.unwrap());
+        }
+        this.map.put(field, list);
+    }
+
+    @Override
+    public Map<String, Object> unwrap() {
+        return this.map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlAppender.java
new file mode 100644
index 0000000..3200b3e
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlAppender.java
@@ -0,0 +1,96 @@
+/*
+ * 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.core.appender.nosql;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.util.Booleans;
+
+/**
+ * This Appender writes logging events to a NoSQL database using a configured NoSQL provider. It requires
+ * implementations of {@link NoSqlObject}, {@link NoSqlConnection}, and {@link NoSqlProvider} to "know" how to write
+ * events to the chosen NoSQL database.
+ * 
+ * For examples on how to write your own NoSQL provider, see the simple source code for the MongoDB and CouchDB
+ * providers.
+ * </p>
+ * 
+ * @see NoSqlObject
+ * @see NoSqlConnection
+ * @see NoSqlProvider
+ */
+@Plugin(name = "NoSql", category = "Core", elementType = Appender.ELEMENT_TYPE, printObject = true)
+public final class NoSqlAppender extends AbstractDatabaseAppender<NoSqlDatabaseManager<?>> {
+    private final String description;
+
+    private NoSqlAppender(final String name, final Filter filter, final boolean ignoreExceptions,
+                          final NoSqlDatabaseManager<?> manager) {
+        super(name, filter, ignoreExceptions, manager);
+        this.description = this.getName() + "{ manager=" + this.getManager() + " }";
+    }
+
+    @Override
+    public String toString() {
+        return this.description;
+    }
+
+    /**
+     * Factory method for creating a NoSQL appender within the plugin manager.
+     *
+     * @param name The name of the appender.
+     * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise
+     *               they are propagated to the caller.
+     * @param filter The filter, if any, to use.
+     * @param bufferSize If an integer greater than 0, this causes the appender to buffer log events and flush whenever
+     *                   the buffer reaches this size.
+     * @param provider The NoSQL provider that provides connections to the chosen NoSQL database.
+     * @return a new NoSQL appender.
+     */
+    @PluginFactory
+    public static NoSqlAppender createAppender(
+            @PluginAttribute("name") final String name,
+            @PluginAttribute("ignoreExceptions") final String ignore,
+            @PluginElement("Filter") final Filter filter,
+            @PluginAttribute("bufferSize") final String bufferSize,
+            @PluginElement("NoSqlProvider") final NoSqlProvider<?> provider) {
+        if (provider == null) {
+            LOGGER.error("NoSQL provider not specified for appender [{}].", name);
+            return null;
+        }
+
+        final int bufferSizeInt = AbstractAppender.parseInt(bufferSize, 0);
+        final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
+
+        final String managerName = "noSqlManager{ description=" + name + ", bufferSize=" + bufferSizeInt
+                + ", provider=" + provider + " }";
+
+        final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager(
+                managerName, bufferSizeInt, provider
+        );
+        if (manager == null) {
+            return null;
+        }
+
+        return new NoSqlAppender(name, filter, ignoreExceptions, manager);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlConnection.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlConnection.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlConnection.java
new file mode 100644
index 0000000..4ca024e
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlConnection.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.core.appender.nosql;
+
+import java.io.Closeable;
+
+/**
+ * Represents a connection to the NoSQL database. Serves as a factory for new (empty) objects and an endpoint for
+ * inserted objects.
+ *
+ * @param <T> Specifies which implementation of {@link NoSqlObject} this connection provides.
+ * @param <W> Specifies which type of database object is wrapped by the {@link NoSqlObject} implementation provided.
+ */
+public interface NoSqlConnection<W, T extends NoSqlObject<W>> extends Closeable {
+    /**
+     * Instantiates and returns a {@link NoSqlObject} instance whose properties can be configured before ultimate
+     * insertion via {@link #insertObject(NoSqlObject)}.
+     *
+     * @return a new object.
+     * @see NoSqlObject
+     */
+    T createObject();
+
+    /**
+     * Creates an array of the specified length typed to match the {@link NoSqlObject} implementation appropriate for
+     * this provider.
+     *
+     * @param length the length of the array to create.
+     * @return a new array.
+     * @see NoSqlObject
+     */
+    T[] createList(int length);
+
+    /**
+     * Inserts the given object into the underlying NoSQL database.
+     *
+     * @param object The object to insert.
+     */
+    void insertObject(NoSqlObject<W> object);
+
+    /**
+     * Closes the underlying connection. This method call should be idempotent. Only the first call should have any
+     * effect; all further calls should be ignored. It's possible the underlying connection is stateless (such as an
+     * HTTP web service), in which case this method would be a no-op. This method should also commit any open
+     * transactions, if applicable and if not already committed.
+     * <p>
+     * If this connection is part of a connection pool, executing this method should commit the transaction and return
+     * the connection to the pool, but it should not actually close the underlying connection.
+     * </p>
+     */
+    @Override
+    void close();
+
+    /**
+     * Indicates whether the underlying connection is closed. If the underlying connection is stateless (such as an
+     * HTTP web service), this method would likely always return true. Essentially, this method should only return
+     * {@code true} if a call to {@link #insertObject(NoSqlObject)} <b>will</b> fail due to the state of this object.
+     *
+     * @return {@code true} if this object is considered closed.
+     */
+    boolean isClosed();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManager.java
new file mode 100644
index 0000000..a0a29ce
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManager.java
@@ -0,0 +1,224 @@
+/*
+ * 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.core.appender.nosql;
+
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AppenderLoggingException;
+import org.apache.logging.log4j.core.appender.ManagerFactory;
+import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager;
+import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.util.BiConsumer;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+
+/**
+ * An {@link AbstractDatabaseManager} implementation for all NoSQL databases.
+ *
+ * @param <W> A type parameter for reassuring the compiler that all operations are using the same {@link NoSqlObject}.
+ */
+public final class NoSqlDatabaseManager<W> extends AbstractDatabaseManager {
+    private static final NoSQLDatabaseManagerFactory FACTORY = new NoSQLDatabaseManagerFactory();
+
+    private final NoSqlProvider<NoSqlConnection<W, ? extends NoSqlObject<W>>> provider;
+
+    private NoSqlConnection<W, ? extends NoSqlObject<W>> connection;
+
+    private NoSqlDatabaseManager(final String name, final int bufferSize,
+            final NoSqlProvider<NoSqlConnection<W, ? extends NoSqlObject<W>>> provider) {
+        super(name, bufferSize);
+        this.provider = provider;
+    }
+
+    @Override
+    protected void startupInternal() {
+        // nothing to see here
+    }
+
+    @Override
+    protected boolean shutdownInternal() {
+        // NoSQL doesn't use transactions, so all we need to do here is simply close the client
+        return Closer.closeSilently(this.connection);
+    }
+
+    @Override
+    protected void connectAndStart() {
+        try {
+            this.connection = this.provider.getConnection();
+        } catch (final Exception e) {
+            throw new AppenderLoggingException("Failed to get connection from NoSQL connection provider.", e);
+        }
+    }
+
+    @Override
+    protected void writeInternal(final LogEvent event) {
+        if (!this.isRunning() || this.connection == null || this.connection.isClosed()) {
+            throw new AppenderLoggingException(
+                    "Cannot write logging event; NoSQL manager not connected to the database.");
+        }
+
+        final NoSqlObject<W> entity = this.connection.createObject();
+        entity.set("level", event.getLevel());
+        entity.set("loggerName", event.getLoggerName());
+        entity.set("message", event.getMessage() == null ? null : event.getMessage().getFormattedMessage());
+
+        final StackTraceElement source = event.getSource();
+        if (source == null) {
+            entity.set("source", (Object) null);
+        } else {
+            entity.set("source", this.convertStackTraceElement(source));
+        }
+
+        final Marker marker = event.getMarker();
+        if (marker == null) {
+            entity.set("marker", (Object) null);
+        } else {
+            entity.set("marker", buildMarkerEntity(marker));
+        }
+
+        entity.set("threadId", event.getThreadId());
+        entity.set("threadName", event.getThreadName());
+        entity.set("threadPriority", event.getThreadPriority());
+        entity.set("millis", event.getTimeMillis());
+        entity.set("date", new java.util.Date(event.getTimeMillis()));
+
+        @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+        Throwable thrown = event.getThrown();
+        if (thrown == null) {
+            entity.set("thrown", (Object) null);
+        } else {
+            final NoSqlObject<W> originalExceptionEntity = this.connection.createObject();
+            NoSqlObject<W> exceptionEntity = originalExceptionEntity;
+            exceptionEntity.set("type", thrown.getClass().getName());
+            exceptionEntity.set("message", thrown.getMessage());
+            exceptionEntity.set("stackTrace", this.convertStackTrace(thrown.getStackTrace()));
+            while (thrown.getCause() != null) {
+                thrown = thrown.getCause();
+                final NoSqlObject<W> causingExceptionEntity = this.connection.createObject();
+                causingExceptionEntity.set("type", thrown.getClass().getName());
+                causingExceptionEntity.set("message", thrown.getMessage());
+                causingExceptionEntity.set("stackTrace", this.convertStackTrace(thrown.getStackTrace()));
+                exceptionEntity.set("cause", causingExceptionEntity);
+                exceptionEntity = causingExceptionEntity;
+            }
+
+            entity.set("thrown", originalExceptionEntity);
+        }
+
+        final ReadOnlyStringMap contextMap = event.getContextData();
+        if (contextMap == null) {
+            entity.set("contextMap", (Object) null);
+        } else {
+            final NoSqlObject<W> contextMapEntity = this.connection.createObject();
+            contextMap.forEach(new BiConsumer<String, String>() {
+                @Override
+                public void accept(final String key, final String val) {
+                    contextMapEntity.set(key, val);
+                }
+            });
+            entity.set("contextMap", contextMapEntity);
+        }
+
+        final ThreadContext.ContextStack contextStack = event.getContextStack();
+        if (contextStack == null) {
+            entity.set("contextStack", (Object) null);
+        } else {
+            entity.set("contextStack", contextStack.asList().toArray());
+        }
+
+        this.connection.insertObject(entity);
+    }
+
+    private NoSqlObject<W> buildMarkerEntity(final Marker marker) {
+        final NoSqlObject<W> entity = this.connection.createObject();
+        entity.set("name", marker.getName());
+
+        final Marker[] parents = marker.getParents();
+        if (parents != null) {
+            @SuppressWarnings("unchecked")
+            final NoSqlObject<W>[] parentEntities = new NoSqlObject[parents.length];
+            for (int i = 0; i < parents.length; i++) {
+                parentEntities[i] = buildMarkerEntity(parents[i]);
+            }
+            entity.set("parents", parentEntities);
+        }
+        return entity;
+    }
+
+    @Override
+    protected boolean commitAndClose() {
+        // all NoSQL drivers auto-commit (since NoSQL doesn't generally use the concept of transactions).
+        // also, all our NoSQL drivers use internal connection pooling and provide clients, not connections.
+        // thus, we should not be closing the client until shutdown as NoSQL is very different from SQL.
+        // see LOG4J2-591 and LOG4J2-676
+    	return true;
+    }
+
+    private NoSqlObject<W>[] convertStackTrace(final StackTraceElement[] stackTrace) {
+        final NoSqlObject<W>[] stackTraceEntities = this.connection.createList(stackTrace.length);
+        for (int i = 0; i < stackTrace.length; i++) {
+            stackTraceEntities[i] = this.convertStackTraceElement(stackTrace[i]);
+        }
+        return stackTraceEntities;
+    }
+
+    private NoSqlObject<W> convertStackTraceElement(final StackTraceElement element) {
+        final NoSqlObject<W> elementEntity = this.connection.createObject();
+        elementEntity.set("className", element.getClassName());
+        elementEntity.set("methodName", element.getMethodName());
+        elementEntity.set("fileName", element.getFileName());
+        elementEntity.set("lineNumber", element.getLineNumber());
+        return elementEntity;
+    }
+
+    /**
+     * Creates a NoSQL manager for use within the {@link NoSqlAppender}, or returns a suitable one if it already exists.
+     *
+     * @param name The name of the manager, which should include connection details and hashed passwords where possible.
+     * @param bufferSize The size of the log event buffer.
+     * @param provider A provider instance which will be used to obtain connections to the chosen NoSQL database.
+     * @return a new or existing NoSQL manager as applicable.
+     */
+    public static NoSqlDatabaseManager<?> getNoSqlDatabaseManager(final String name, final int bufferSize,
+                                                                  final NoSqlProvider<?> provider) {
+        return AbstractDatabaseManager.getManager(name, new FactoryData(bufferSize, provider), FACTORY);
+    }
+
+    /**
+     * Encapsulates data that {@link NoSQLDatabaseManagerFactory} uses to create managers.
+     */
+    private static final class FactoryData extends AbstractDatabaseManager.AbstractFactoryData {
+        private final NoSqlProvider<?> provider;
+
+        protected FactoryData(final int bufferSize, final NoSqlProvider<?> provider) {
+            super(bufferSize);
+            this.provider = provider;
+        }
+    }
+
+    /**
+     * Creates managers.
+     */
+    private static final class NoSQLDatabaseManagerFactory implements
+            ManagerFactory<NoSqlDatabaseManager<?>, FactoryData> {
+        @Override
+        @SuppressWarnings("unchecked")
+        public NoSqlDatabaseManager<?> createManager(final String name, final FactoryData data) {
+            return new NoSqlDatabaseManager(name, data.getBufferSize(), data.provider);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlObject.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlObject.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlObject.java
new file mode 100644
index 0000000..41bc7f9
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlObject.java
@@ -0,0 +1,63 @@
+/*
+ * 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.core.appender.nosql;
+
+/**
+ * Represents a simple POJO object inserted into a NoSQL object.
+ *
+ * @param <W> Specifies what type of underlying object (such as a MongoDB BasicDBObject) this NoSqlObject wraps.
+ */
+public interface NoSqlObject<W> {
+    /**
+     * Sets the value of a property on this object to a String or primitive.
+     *
+     * @param field The name of the property
+     * @param value The value of the property
+     */
+    void set(String field, Object value);
+
+    /**
+     * Sets the value of a property on this object to a nested complex object.
+     *
+     * @param field The name of the property
+     * @param value The value of the property
+     */
+    void set(String field, NoSqlObject<W> value);
+
+    /**
+     * Sets the value of a property on this object to an array of Strings or primitives.
+     *
+     * @param field The name of the property
+     * @param values The values for the property
+     */
+    void set(String field, Object[] values);
+
+    /**
+     * Sets the value of a property on this object to an array of nested complex objects.
+     *
+     * @param field The name of the property
+     * @param values The values for the property
+     */
+    void set(String field, NoSqlObject<W>[] values);
+
+    /**
+     * Obtains the underlying NoSQL library-specific object that this object wraps.
+     *
+     * @return the wrapped object.
+     */
+    W unwrap();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlProvider.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlProvider.java
new file mode 100644
index 0000000..39c4d60
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/NoSqlProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.core.appender.nosql;
+
+/**
+ * Implementations of this class are plugins for configuring the {@link NoSqlAppender} with the proper provider
+ * (MongoDB, etc.).
+ *
+ * @param <C> Specifies which implementation of {@link NoSqlConnection} this provider provides.
+ */
+public interface NoSqlProvider<C extends NoSqlConnection<?, ? extends NoSqlObject<?>>> {
+    
+    /**
+     * Obtains a connection from this provider. The concept of a connection in this case is not strictly an active
+     * duplex UDP or TCP connection to the underlying database. It can be thought of more as a gateway, a path for
+     * inserting objects that may use a persistent connection or may use HTTP web service calls, etc.
+     * <p>
+     * Where applicable, this method should return a connection from the connection pool as opposed to opening a
+     * brand new connection every time.
+     * </p>
+     * 
+     * @return a connection that can be used to create and persist objects to this database.
+     * @see NoSqlConnection
+     */
+    C getConnection();
+
+    /**
+     * All implementations must override {@link Object#toString()} to provide information about the provider
+     * configuration (obscuring passwords with one-way hashes).
+     *
+     * @return the string representation of this NoSQL provider.
+     */
+    @Override
+    String toString();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/package-info.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/package-info.java
new file mode 100644
index 0000000..641762f
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/nosql/package-info.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.
+ */
+/**
+ * The NoSQL Appender supports writing log events to NoSQL databases. You can also easily
+ * extend this to support various NoSQL databases by implementing just three interfaces:
+ * {@link org.apache.logging.log4j.core.appender.nosql.NoSqlObject NoSqlObject},
+ * {@link org.apache.logging.log4j.core.appender.nosql.NoSqlConnection NoSqlConnection}, and
+ * {@link org.apache.logging.log4j.core.appender.nosql.NoSqlProvider NoSqlProvider}.
+ */
+package org.apache.logging.log4j.core.appender.nosql;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlAppenderTest.java
new file mode 100644
index 0000000..6ab9419
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlAppenderTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.core.appender.nosql;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class NoSqlAppenderTest {
+
+    @Mock
+    private NoSqlProvider<?> provider;
+
+    @Test
+    public void testNoProvider() {
+        final NoSqlAppender appender = NoSqlAppender.createAppender("myName01", null, null, null, null);
+
+        assertNull("The appender should be null.", appender);
+    }
+
+    @Test
+    public void testProvider() {
+        final NoSqlAppender appender = NoSqlAppender.createAppender("myName01", null, null, null, provider);
+
+        assertNotNull("The appender should not be null.", appender);
+        assertEquals("The toString value is not correct.",
+                "myName01{ manager=noSqlManager{ description=myName01, bufferSize=0, provider=" + provider + " } }",
+                appender.toString());
+
+        appender.stop();
+    }
+
+    @Test
+    public void testProviderBuffer() {
+        final NoSqlAppender appender = NoSqlAppender.createAppender("anotherName02", null, null, "25", provider);
+
+        assertNotNull("The appender should not be null.", appender);
+        assertEquals("The toString value is not correct.",
+                "anotherName02{ manager=noSqlManager{ description=anotherName02, bufferSize=25, provider=" + provider
+                        + " } }", appender.toString());
+
+        appender.stop();
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManagerTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManagerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManagerTest.java
new file mode 100644
index 0000000..c203e90
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManagerTest.java
@@ -0,0 +1,427 @@
+/*
+ * 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.core.appender.nosql;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AppenderLoggingException;
+import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.junit.ThreadContextStackRule;
+import org.apache.logging.log4j.message.Message;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Mockito.mock;
+
+@RunWith(MockitoJUnitRunner.class)
+public class NoSqlDatabaseManagerTest {
+    @Mock
+    private NoSqlConnection<Map<String, Object>, DefaultNoSqlObject> connection;
+    @Mock
+    private NoSqlProvider<NoSqlConnection<Map<String, Object>, DefaultNoSqlObject>> provider;
+    @Mock
+    private Message message;
+    @Captor
+    private ArgumentCaptor<NoSqlObject<Map<String, Object>>> captor;
+
+    @Rule
+    public final ThreadContextStackRule threadContextRule = new ThreadContextStackRule();
+    @Rule
+    public final ExpectedException expectedException = ExpectedException.none();
+
+    @Before
+    public void setUp() {
+        given(provider.getConnection()).willReturn(connection);
+        given(connection.createObject()).willAnswer(new Answer<DefaultNoSqlObject>() {
+            @Override
+            public DefaultNoSqlObject answer(final InvocationOnMock invocation) throws Throwable {
+                return new DefaultNoSqlObject();
+            }
+        });
+        given(connection.createList(anyInt())).willAnswer(new Answer<DefaultNoSqlObject[]>() {
+            @Override
+            public DefaultNoSqlObject[] answer(final InvocationOnMock invocation) throws Throwable {
+                return new DefaultNoSqlObject[invocation.<Integer>getArgument(0)];
+            }
+        });
+    }
+
+    @Test
+    public void testConnection() {
+        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
+            provider)) {
+
+            assertNotNull("The manager should not be null.", manager);
+
+            manager.connectAndStart();
+            then(provider).should().getConnection();
+            manager.commitAndClose();
+        }
+    }
+
+    @Test
+    public void testWriteInternalNotConnected01() {
+        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
+            provider)) {
+            expectedException.expect(AppenderLoggingException.class);
+            manager.writeInternal(mock(LogEvent.class));
+        }
+    }
+
+    @Test
+    public void testWriteInternalNotConnected02() {
+        given(connection.isClosed()).willReturn(true);
+
+        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
+            provider)) {
+
+            manager.startup();
+            manager.connectAndStart();
+            then(provider).should().getConnection();
+
+            expectedException.expect(AppenderLoggingException.class);
+            manager.writeInternal(mock(LogEvent.class));
+        }
+    }
+
+    @Test
+    public void testWriteInternal01() {
+        given(connection.isClosed()).willReturn(false);
+        given(message.getFormattedMessage()).willReturn("My formatted message 01.");
+
+        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
+            provider)) {
+
+            manager.startup();
+            manager.connectAndStart();
+            then(provider).should().getConnection();
+
+            final LogEvent event = Log4jLogEvent.newBuilder()
+                .setLevel(Level.WARN)
+                .setLoggerName("com.foo.NoSQLDbTest.testWriteInternal01")
+                .setMessage(message)
+                .setSource(new StackTraceElement("com.foo.Bar", "testMethod01", "Bar.java", 15))
+                .setThreadId(1L)
+                .setThreadName("MyThread-A")
+                .setThreadPriority(1)
+                .setTimeMillis(1234567890123L)
+                .build();
+
+            manager.writeInternal(event);
+            then(connection).should().insertObject(captor.capture());
+
+            final NoSqlObject<Map<String, Object>> inserted = captor.getValue();
+            assertNotNull("The inserted value should not be null.", inserted);
+            final Map<String, Object> object = inserted.unwrap();
+            assertNotNull("The unwrapped object should not be null.", object);
+
+            assertEquals("The level is not correct.", Level.WARN, object.get("level"));
+            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal01",
+                object.get("loggerName"));
+            assertEquals("The message is not correct.", "My formatted message 01.", object.get("message"));
+            assertEquals("The thread is not correct.", "MyThread-A", object.get("threadName"));
+            assertEquals("The millis is not correct.", 1234567890123L, object.get("millis"));
+            assertEquals("The date is not correct.", 1234567890123L, ((Date) object.get("date")).getTime());
+
+            assertTrue("The source should be a map.", object.get("source") instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> source = (Map<String, Object>) object.get("source");
+            assertEquals("The class is not correct.", "com.foo.Bar", source.get("className"));
+            assertEquals("The method is not correct.", "testMethod01", source.get("methodName"));
+            assertEquals("The file name is not correct.", "Bar.java", source.get("fileName"));
+            assertEquals("The line number is not correct.", 15, source.get("lineNumber"));
+
+            assertNull("The marker should be null.", object.get("marker"));
+
+            assertNull("The thrown should be null.", object.get("thrown"));
+
+            assertTrue("The context map should be empty.", ((Map) object.get("contextMap")).isEmpty());
+
+            assertTrue("The context stack should be null.", ((Collection) object.get("contextStack")).isEmpty());
+
+        }
+    }
+
+    @Test
+    public void testWriteInternal02() {
+        given(connection.isClosed()).willReturn(false);
+        given(message.getFormattedMessage()).willReturn("Another cool message 02.");
+
+        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
+            provider)) {
+            manager.startup();
+
+            manager.connectAndStart();
+            then(provider).should().getConnection();
+
+            final RuntimeException exception = new RuntimeException("This is something cool!");
+            final Map<String, String> context = new HashMap<>();
+            context.put("hello", "world");
+            context.put("user", "pass");
+
+            ThreadContext.push("message1");
+            ThreadContext.push("stack2");
+            final ThreadContext.ContextStack stack = ThreadContext.getImmutableStack();
+            ThreadContext.clearStack();
+
+            final LogEvent event = Log4jLogEvent.newBuilder()
+                .setLevel(Level.DEBUG)
+                .setLoggerName("com.foo.NoSQLDbTest.testWriteInternal02")
+                .setMessage(message)
+                .setSource(new StackTraceElement("com.bar.Foo", "anotherMethod03", "Foo.java", 9))
+                .setMarker(MarkerManager.getMarker("LoneMarker"))
+                .setThreadId(1L)
+                .setThreadName("AnotherThread-B")
+                .setThreadPriority(1)
+                .setTimeMillis(987654321564L)
+                .setThrown(exception)
+                .setContextMap(context)
+                .setContextStack(stack)
+                .build();
+
+            manager.writeInternal(event);
+            then(connection).should().insertObject(captor.capture());
+
+            final NoSqlObject<Map<String, Object>> inserted = captor.getValue();
+            assertNotNull("The inserted value should not be null.", inserted);
+            final Map<String, Object> object = inserted.unwrap();
+            assertNotNull("The unwrapped object should not be null.", object);
+
+            assertEquals("The level is not correct.", Level.DEBUG, object.get("level"));
+            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal02",
+                object.get("loggerName"));
+            assertEquals("The message is not correct.", "Another cool message 02.", object.get("message"));
+            assertEquals("The thread is not correct.", "AnotherThread-B", object.get("threadName"));
+            assertEquals("The millis is not correct.", 987654321564L, object.get("millis"));
+            assertEquals("The date is not correct.", 987654321564L, ((Date) object.get("date")).getTime());
+
+            assertTrue("The source should be a map.", object.get("source") instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> source = (Map<String, Object>) object.get("source");
+            assertEquals("The class is not correct.", "com.bar.Foo", source.get("className"));
+            assertEquals("The method is not correct.", "anotherMethod03", source.get("methodName"));
+            assertEquals("The file name is not correct.", "Foo.java", source.get("fileName"));
+            assertEquals("The line number is not correct.", 9, source.get("lineNumber"));
+
+            assertTrue("The marker should be a map.", object.get("marker") instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> marker = (Map<String, Object>) object.get("marker");
+            assertEquals("The marker name is not correct.", "LoneMarker", marker.get("name"));
+            assertNull("The marker parent should be null.", marker.get("parent"));
+
+            assertTrue("The thrown should be a map.", object.get("thrown") instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> thrown = (Map<String, Object>) object.get("thrown");
+            assertEquals("The thrown type is not correct.", "java.lang.RuntimeException", thrown.get("type"));
+            assertEquals("The thrown message is not correct.", "This is something cool!", thrown.get("message"));
+            assertTrue("The thrown stack trace should be a list.", thrown.get("stackTrace") instanceof List);
+            @SuppressWarnings("unchecked")
+            final List<Map<String, Object>> stackTrace = (List<Map<String, Object>>) thrown.get("stackTrace");
+            assertEquals("The thrown stack trace length is not correct.", exception.getStackTrace().length,
+                stackTrace.size());
+            for (int i = 0; i < exception.getStackTrace().length; i++) {
+                final StackTraceElement e1 = exception.getStackTrace()[i];
+                final Map<String, Object> e2 = stackTrace.get(i);
+
+                assertEquals("Element class name [" + i + "] is not correct.", e1.getClassName(), e2.get("className"));
+                assertEquals("Element method name [" + i + "] is not correct.", e1.getMethodName(),
+                    e2.get("methodName"));
+                assertEquals("Element file name [" + i + "] is not correct.", e1.getFileName(), e2.get("fileName"));
+                assertEquals("Element line number [" + i + "] is not correct.", e1.getLineNumber(),
+                    e2.get("lineNumber"));
+            }
+            assertNull("The thrown should have no cause.", thrown.get("cause"));
+
+            assertTrue("The context map should be a map.", object.get("contextMap") instanceof Map);
+            assertEquals("The context map is not correct.", context, object.get("contextMap"));
+
+            assertTrue("The context stack should be list.", object.get("contextStack") instanceof List);
+            assertEquals("The context stack is not correct.", stack.asList(), object.get("contextStack"));
+        }
+    }
+
+    @Test
+    public void testWriteInternal03() {
+        given(connection.isClosed()).willReturn(false);
+        given(message.getFormattedMessage()).willReturn("Another cool message 02.");
+
+        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
+            provider)) {
+            manager.startup();
+
+            manager.connectAndStart();
+            then(provider).should().getConnection();
+
+            final IOException exception1 = new IOException("This is the cause.");
+            final SQLException exception2 = new SQLException("This is the result.", exception1);
+            final Map<String, String> context = new HashMap<>();
+            context.put("hello", "world");
+            context.put("user", "pass");
+
+            ThreadContext.push("message1");
+            ThreadContext.push("stack2");
+            final ThreadContext.ContextStack stack = ThreadContext.getImmutableStack();
+            ThreadContext.clearStack();
+
+            final LogEvent event = Log4jLogEvent.newBuilder()
+                .setLevel(Level.DEBUG)
+                .setLoggerName("com.foo.NoSQLDbTest.testWriteInternal02")
+                .setMessage(message)
+                .setSource(new StackTraceElement("com.bar.Foo", "anotherMethod03", "Foo.java", 9))
+                .setMarker(MarkerManager.getMarker("AnotherMarker").addParents(
+                    MarkerManager.getMarker("Parent1").addParents(MarkerManager.getMarker("GrandParent1")),
+                    MarkerManager.getMarker("Parent2")))
+                .setThreadId(1L)
+                .setThreadName("AnotherThread-B")
+                .setThreadPriority(1)
+                .setTimeMillis(987654321564L)
+                .setThrown(exception2)
+                .setContextMap(context)
+                .setContextStack(stack)
+                .build();
+
+            manager.writeInternal(event);
+            then(connection).should().insertObject(captor.capture());
+
+            final NoSqlObject<Map<String, Object>> inserted = captor.getValue();
+            assertNotNull("The inserted value should not be null.", inserted);
+            final Map<String, Object> object = inserted.unwrap();
+            assertNotNull("The unwrapped object should not be null.", object);
+
+            assertEquals("The level is not correct.", Level.DEBUG, object.get("level"));
+            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal02",
+                object.get("loggerName"));
+            assertEquals("The message is not correct.", "Another cool message 02.", object.get("message"));
+            assertEquals("The thread is not correct.", "AnotherThread-B", object.get("threadName"));
+            assertEquals("The millis is not correct.", 987654321564L, object.get("millis"));
+            assertEquals("The date is not correct.", 987654321564L, ((Date) object.get("date")).getTime());
+
+            assertTrue("The source should be a map.", object.get("source") instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> source = (Map<String, Object>) object.get("source");
+            assertEquals("The class is not correct.", "com.bar.Foo", source.get("className"));
+            assertEquals("The method is not correct.", "anotherMethod03", source.get("methodName"));
+            assertEquals("The file name is not correct.", "Foo.java", source.get("fileName"));
+            assertEquals("The line number is not correct.", 9, source.get("lineNumber"));
+
+            assertTrue("The marker should be a map.", object.get("marker") instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> marker = (Map<String, Object>) object.get("marker");
+            assertEquals("The marker name is not correct.", "AnotherMarker", marker.get("name"));
+
+            assertTrue("The marker parents should be a list.", marker.get("parents") instanceof List);
+            @SuppressWarnings("unchecked")
+            final List<Object> markerParents = (List<Object>) marker.get("parents");
+            assertEquals("The marker parents should contain two parents", 2, markerParents.size());
+
+            assertTrue("The marker parents[0] should be a map.", markerParents.get(0) instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> parent1 = (Map<String, Object>) markerParents.get(0);
+            assertEquals("The first marker parent name is not correct.", "Parent1", parent1.get("name"));
+
+            assertTrue("The marker parents[1] should be a map.", markerParents.get(1) instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> parent2 = (Map<String, Object>) markerParents.get(1);
+            assertEquals("The second marker parent name is not correct.", "Parent2", parent2.get("name"));
+            assertNull("The second marker should have no parent.", parent2.get("parent"));
+
+            assertTrue("The parent1 parents should be a list.", parent1.get("parents") instanceof List);
+            @SuppressWarnings("unchecked")
+            final List<Object> parent1Parents = (List<Object>) parent1.get("parents");
+            assertEquals("The parent1 parents should have only one parent", 1, parent1Parents.size());
+
+            assertTrue("The parent1Parents[0] should be a map.", parent1Parents.get(0) instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> parent1parent = (Map<String, Object>) parent1Parents.get(0);
+            assertEquals("The first parent1 parent name is not correct.", "GrandParent1", parent1parent.get("name"));
+            assertNull("The parent1parent marker should have no parent.", parent1parent.get("parent"));
+
+            assertTrue("The thrown should be a map.", object.get("thrown") instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> thrown = (Map<String, Object>) object.get("thrown");
+            assertEquals("The thrown type is not correct.", "java.sql.SQLException", thrown.get("type"));
+            assertEquals("The thrown message is not correct.", "This is the result.", thrown.get("message"));
+            assertTrue("The thrown stack trace should be a list.", thrown.get("stackTrace") instanceof List);
+            @SuppressWarnings("unchecked")
+            final List<Map<String, Object>> stackTrace = (List<Map<String, Object>>) thrown.get("stackTrace");
+            assertEquals("The thrown stack trace length is not correct.", exception2.getStackTrace().length,
+                stackTrace.size());
+            for (int i = 0; i < exception2.getStackTrace().length; i++) {
+                final StackTraceElement e1 = exception2.getStackTrace()[i];
+                final Map<String, Object> e2 = stackTrace.get(i);
+
+                assertEquals("Element class name [" + i + "] is not correct.", e1.getClassName(), e2.get("className"));
+                assertEquals("Element method name [" + i + "] is not correct.", e1.getMethodName(),
+                    e2.get("methodName"));
+                assertEquals("Element file name [" + i + "] is not correct.", e1.getFileName(), e2.get("fileName"));
+                assertEquals("Element line number [" + i + "] is not correct.", e1.getLineNumber(),
+                    e2.get("lineNumber"));
+            }
+            assertTrue("The thrown cause should be a map.", thrown.get("cause") instanceof Map);
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> cause = (Map<String, Object>) thrown.get("cause");
+            assertEquals("The cause type is not correct.", "java.io.IOException", cause.get("type"));
+            assertEquals("The cause message is not correct.", "This is the cause.", cause.get("message"));
+            assertTrue("The cause stack trace should be a list.", cause.get("stackTrace") instanceof List);
+            @SuppressWarnings("unchecked")
+            final List<Map<String, Object>> causeStackTrace = (List<Map<String, Object>>) cause.get("stackTrace");
+            assertEquals("The cause stack trace length is not correct.", exception1.getStackTrace().length,
+                causeStackTrace.size());
+            for (int i = 0; i < exception1.getStackTrace().length; i++) {
+                final StackTraceElement e1 = exception1.getStackTrace()[i];
+                final Map<String, Object> e2 = causeStackTrace.get(i);
+
+                assertEquals("Element class name [" + i + "] is not correct.", e1.getClassName(), e2.get("className"));
+                assertEquals("Element method name [" + i + "] is not correct.", e1.getMethodName(),
+                    e2.get("methodName"));
+                assertEquals("Element file name [" + i + "] is not correct.", e1.getFileName(), e2.get("fileName"));
+                assertEquals("Element line number [" + i + "] is not correct.", e1.getLineNumber(),
+                    e2.get("lineNumber"));
+            }
+            assertNull("The cause should have no cause.", cause.get("cause"));
+
+            assertTrue("The context map should be a map.", object.get("contextMap") instanceof Map);
+            assertEquals("The context map is not correct.", context, object.get("contextMap"));
+
+            assertTrue("The context stack should be list.", object.get("contextStack") instanceof List);
+            assertEquals("The context stack is not correct.", stack.asList(), object.get("contextStack"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-couchdb/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-couchdb/pom.xml b/log4j-couchdb/pom.xml
new file mode 100644
index 0000000..2e3e539
--- /dev/null
+++ b/log4j-couchdb/pom.xml
@@ -0,0 +1,183 @@
+<?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.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>log4j-couchdb</artifactId>
+  <name>Apache Log4j CouchDB</name>
+  <description>
+    CouchDB appender for Log4j.
+  </description>
+  <properties>
+    <log4jParentDir>${basedir}/..</log4jParentDir>
+    <docLabel>CouchDB Documentation</docLabel>
+    <projectDir>/log4j-couchdb</projectDir>
+    <module.name>org.apache.logging.log4j.couchdb</module.name>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.lightcouch</groupId>
+      <artifactId>lightcouch</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>
+  </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/ebec215e/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java
new file mode 100644
index 0000000..2c3248d
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.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.nosql.appender.couchdb;
+
+import java.util.Map;
+
+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.DefaultNoSqlObject;
+import org.apache.logging.log4j.core.appender.nosql.NoSqlConnection;
+import org.apache.logging.log4j.core.appender.nosql.NoSqlObject;
+import org.apache.logging.log4j.util.Strings;
+import org.lightcouch.CouchDbClient;
+import org.lightcouch.Response;
+
+/**
+ * The Apache CouchDB implementation of {@link NoSqlConnection}.
+ */
+public final class CouchDbConnection extends AbstractNoSqlConnection<Map<String, Object>, DefaultNoSqlObject> {
+    private final CouchDbClient client;
+
+    public CouchDbConnection(final CouchDbClient client) {
+        this.client = client;
+    }
+
+    @Override
+    public DefaultNoSqlObject createObject() {
+        return new DefaultNoSqlObject();
+    }
+
+    @Override
+    public DefaultNoSqlObject[] createList(final int length) {
+        return new DefaultNoSqlObject[length];
+    }
+
+    @Override
+    public void insertObject(final NoSqlObject<Map<String, Object>> object) {
+        try {
+            final Response response = this.client.save(object.unwrap());
+            if (Strings.isNotEmpty(response.getError())) {
+                throw new AppenderLoggingException(
+                        "Failed to write log event to CouchDB due to error: " + response.getError() + '.');
+            }
+        } catch (final Exception e) {
+            throw new AppenderLoggingException("Failed to write log event to CouchDB due to error: " + e.getMessage(),
+                    e);
+        }
+    }
+
+    @Override
+    protected void closeImpl() {
+        this.client.shutdown();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
new file mode 100644
index 0000000..cdae592
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
@@ -0,0 +1,161 @@
+/*
+ * 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.nosql.appender.couchdb;
+
+import java.lang.reflect.Method;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
+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.util.NameUtil;
+import org.apache.logging.log4j.core.appender.nosql.NoSqlProvider;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.LoaderUtil;
+import org.apache.logging.log4j.util.Strings;
+import org.lightcouch.CouchDbClient;
+import org.lightcouch.CouchDbProperties;
+
+/**
+ * The Apache CouchDB implementation of {@link NoSqlProvider}.
+ */
+@Plugin(name = "CouchDB", category = "Core", printObject = true)
+public final class CouchDbProvider implements NoSqlProvider<CouchDbConnection> {
+    private static final int HTTP = 80;
+    private static final int HTTPS = 443;
+    private static final Logger LOGGER = StatusLogger.getLogger();
+
+    private final CouchDbClient client;
+    private final String description;
+
+    private CouchDbProvider(final CouchDbClient client, final String description) {
+        this.client = client;
+        this.description = "couchDb{ " + description + " }";
+    }
+
+    @Override
+    public CouchDbConnection getConnection() {
+        return new CouchDbConnection(this.client);
+    }
+
+    @Override
+    public String toString() {
+        return this.description;
+    }
+
+    /**
+     * Factory method for creating an Apache CouchDB provider within the plugin manager.
+     *
+     * @param databaseName The name of the database to which log event documents will be written.
+     * @param protocol Either "http" or "https," defaults to "http" and mutually exclusive with
+     *                 {@code factoryClassName&factoryMethodName!=null}.
+     * @param server The host name of the CouchDB server, defaults to localhost and mutually exclusive with
+     *               {@code factoryClassName&factoryMethodName!=null}.
+     * @param port The port that CouchDB is listening on, defaults to 80 if {@code protocol} is "http" and 443 if
+     *             {@code protocol} is "https," and mutually exclusive with
+     *             {@code factoryClassName&factoryMethodName!=null}.
+     * @param username The username to authenticate against the MongoDB server with, mutually exclusive with
+     *                 {@code factoryClassName&factoryMethodName!=null}.
+     * @param password The password to authenticate against the MongoDB server with, mutually exclusive with
+     *                 {@code factoryClassName&factoryMethodName!=null}.
+     * @param factoryClassName A fully qualified class name containing a static factory method capable of returning a
+     *                         {@link CouchDbClient} or {@link CouchDbProperties}.
+     * @param factoryMethodName The name of the public static factory method belonging to the aforementioned factory
+     *                          class.
+     * @return a new Apache CouchDB provider.
+     */
+    @PluginFactory
+    public static CouchDbProvider createNoSqlProvider(
+            @PluginAttribute("databaseName") final String databaseName,
+            @PluginAttribute("protocol") String protocol,
+            @PluginAttribute(value = "server", defaultString = "localhost") @ValidHost final String server,
+            @PluginAttribute(value = "port", defaultString = "0") @ValidPort final String port,
+            @PluginAttribute("username") final String username,
+            @PluginAttribute(value = "password", sensitive = true) final String password,
+            @PluginAttribute("factoryClassName") final String factoryClassName,
+            @PluginAttribute("factoryMethodName") final String factoryMethodName) {
+        CouchDbClient client;
+        String description;
+        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 CouchDbClient) {
+                    client = (CouchDbClient) object;
+                    description = "uri=" + client.getDBUri();
+                } else if (object instanceof CouchDbProperties) {
+                    final CouchDbProperties properties = (CouchDbProperties) object;
+                    client = new CouchDbClient(properties);
+                    description = "uri=" + client.getDBUri() + ", username=" + properties.getUsername()
+                            + ", passwordHash=" + NameUtil.md5(password + CouchDbProvider.class.getName())
+                            + ", maxConnections=" + properties.getMaxConnections() + ", connectionTimeout="
+                            + properties.getConnectionTimeout() + ", socketTimeout=" + properties.getSocketTimeout();
+                } 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;
+                }
+            } 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)) {
+            if (protocol != null && protocol.length() > 0) {
+                protocol = protocol.toLowerCase();
+                if (!protocol.equals("http") && !protocol.equals("https")) {
+                    LOGGER.error("Only protocols [http] and [https] are supported, [{}] specified.", protocol);
+                    return null;
+                }
+            } else {
+                protocol = "http";
+                LOGGER.warn("No protocol specified, using default port [http].");
+            }
+
+            final int portInt = TypeConverters.convert(port, int.class, protocol.equals("https") ? HTTPS : HTTP);
+
+            if (Strings.isEmpty(username) || Strings.isEmpty(password)) {
+                LOGGER.error("You must provide a username and password for the CouchDB provider.");
+                return null;
+            }
+
+            client = new CouchDbClient(databaseName, false, protocol, server, portInt, username, password);
+            description = "uri=" + client.getDBUri() + ", username=" + username + ", passwordHash="
+                    + NameUtil.md5(password + CouchDbProvider.class.getName());
+        } else {
+            LOGGER.error("No factory method was provided so the database name is required.");
+            return null;
+        }
+
+        return new CouchDbProvider(client, description);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java
new file mode 100644
index 0000000..b783f87
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/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 Apache CouchDB provider for the NoSQL Appender.
+ */
+package org.apache.logging.log4j.nosql.appender.couchdb;


[2/4] logging-log4j2 git commit: LOG4J2-2076 CouchDB and MongoDB appenders in own modules, remove log4j-nosql module

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlObject.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlObject.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlObject.java
deleted file mode 100644
index 191d1a8..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlObject.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.nosql.appender;
-
-/**
- * Represents a simple POJO object inserted into a NoSQL object.
- *
- * @param <W> Specifies what type of underlying object (such as a MongoDB BasicDBObject) this NoSqlObject wraps.
- */
-public interface NoSqlObject<W> {
-    /**
-     * Sets the value of a property on this object to a String or primitive.
-     *
-     * @param field The name of the property
-     * @param value The value of the property
-     */
-    void set(String field, Object value);
-
-    /**
-     * Sets the value of a property on this object to a nested complex object.
-     *
-     * @param field The name of the property
-     * @param value The value of the property
-     */
-    void set(String field, NoSqlObject<W> value);
-
-    /**
-     * Sets the value of a property on this object to an array of Strings or primitives.
-     *
-     * @param field The name of the property
-     * @param values The values for the property
-     */
-    void set(String field, Object[] values);
-
-    /**
-     * Sets the value of a property on this object to an array of nested complex objects.
-     *
-     * @param field The name of the property
-     * @param values The values for the property
-     */
-    void set(String field, NoSqlObject<W>[] values);
-
-    /**
-     * Obtains the underlying NoSQL library-specific object that this object wraps.
-     *
-     * @return the wrapped object.
-     */
-    W unwrap();
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlProvider.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlProvider.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlProvider.java
deleted file mode 100644
index 75692bd..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlProvider.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.nosql.appender;
-
-/**
- * Implementations of this class are plugins for configuring the {@link NoSqlAppender} with the proper provider
- * (MongoDB, etc.).
- *
- * @param <C> Specifies which implementation of {@link NoSqlConnection} this provider provides.
- */
-public interface NoSqlProvider<C extends NoSqlConnection<?, ? extends NoSqlObject<?>>> {
-    
-    /**
-     * Obtains a connection from this provider. The concept of a connection in this case is not strictly an active
-     * duplex UDP or TCP connection to the underlying database. It can be thought of more as a gateway, a path for
-     * inserting objects that may use a persistent connection or may use HTTP web service calls, etc.
-     * <p>
-     * Where applicable, this method should return a connection from the connection pool as opposed to opening a
-     * brand new connection every time.
-     * </p>
-     * 
-     * @return a connection that can be used to create and persist objects to this database.
-     * @see NoSqlConnection
-     */
-    C getConnection();
-
-    /**
-     * All implementations must override {@link Object#toString()} to provide information about the provider
-     * configuration (obscuring passwords with one-way hashes).
-     *
-     * @return the string representation of this NoSQL provider.
-     */
-    @Override
-    String toString();
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java
deleted file mode 100644
index 2494a5c..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.nosql.appender.couchdb;
-
-import java.util.Map;
-
-import org.apache.logging.log4j.core.appender.AppenderLoggingException;
-import org.apache.logging.log4j.nosql.appender.AbstractNoSqlConnection;
-import org.apache.logging.log4j.nosql.appender.DefaultNoSqlObject;
-import org.apache.logging.log4j.nosql.appender.NoSqlConnection;
-import org.apache.logging.log4j.nosql.appender.NoSqlObject;
-import org.apache.logging.log4j.util.Strings;
-import org.lightcouch.CouchDbClient;
-import org.lightcouch.Response;
-
-/**
- * The Apache CouchDB implementation of {@link NoSqlConnection}.
- */
-public final class CouchDbConnection extends AbstractNoSqlConnection<Map<String, Object>, DefaultNoSqlObject> {
-    private final CouchDbClient client;
-
-    public CouchDbConnection(final CouchDbClient client) {
-        this.client = client;
-    }
-
-    @Override
-    public DefaultNoSqlObject createObject() {
-        return new DefaultNoSqlObject();
-    }
-
-    @Override
-    public DefaultNoSqlObject[] createList(final int length) {
-        return new DefaultNoSqlObject[length];
-    }
-
-    @Override
-    public void insertObject(final NoSqlObject<Map<String, Object>> object) {
-        try {
-            final Response response = this.client.save(object.unwrap());
-            if (Strings.isNotEmpty(response.getError())) {
-                throw new AppenderLoggingException(
-                        "Failed to write log event to CouchDB due to error: " + response.getError() + '.');
-            }
-        } catch (final Exception e) {
-            throw new AppenderLoggingException("Failed to write log event to CouchDB due to error: " + e.getMessage(),
-                    e);
-        }
-    }
-
-    @Override
-    protected void closeImpl() {
-        this.client.shutdown();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
deleted file mode 100644
index cafe644..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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.nosql.appender.couchdb;
-
-import java.lang.reflect.Method;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
-import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
-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.util.NameUtil;
-import org.apache.logging.log4j.nosql.appender.NoSqlProvider;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.LoaderUtil;
-import org.apache.logging.log4j.util.Strings;
-import org.lightcouch.CouchDbClient;
-import org.lightcouch.CouchDbProperties;
-
-/**
- * The Apache CouchDB implementation of {@link NoSqlProvider}.
- */
-@Plugin(name = "CouchDB", category = "Core", printObject = true)
-public final class CouchDbProvider implements NoSqlProvider<CouchDbConnection> {
-    private static final int HTTP = 80;
-    private static final int HTTPS = 443;
-    private static final Logger LOGGER = StatusLogger.getLogger();
-
-    private final CouchDbClient client;
-    private final String description;
-
-    private CouchDbProvider(final CouchDbClient client, final String description) {
-        this.client = client;
-        this.description = "couchDb{ " + description + " }";
-    }
-
-    @Override
-    public CouchDbConnection getConnection() {
-        return new CouchDbConnection(this.client);
-    }
-
-    @Override
-    public String toString() {
-        return this.description;
-    }
-
-    /**
-     * Factory method for creating an Apache CouchDB provider within the plugin manager.
-     *
-     * @param databaseName The name of the database to which log event documents will be written.
-     * @param protocol Either "http" or "https," defaults to "http" and mutually exclusive with
-     *                 {@code factoryClassName&factoryMethodName!=null}.
-     * @param server The host name of the CouchDB server, defaults to localhost and mutually exclusive with
-     *               {@code factoryClassName&factoryMethodName!=null}.
-     * @param port The port that CouchDB is listening on, defaults to 80 if {@code protocol} is "http" and 443 if
-     *             {@code protocol} is "https," and mutually exclusive with
-     *             {@code factoryClassName&factoryMethodName!=null}.
-     * @param username The username to authenticate against the MongoDB server with, mutually exclusive with
-     *                 {@code factoryClassName&factoryMethodName!=null}.
-     * @param password The password to authenticate against the MongoDB server with, mutually exclusive with
-     *                 {@code factoryClassName&factoryMethodName!=null}.
-     * @param factoryClassName A fully qualified class name containing a static factory method capable of returning a
-     *                         {@link CouchDbClient} or {@link CouchDbProperties}.
-     * @param factoryMethodName The name of the public static factory method belonging to the aforementioned factory
-     *                          class.
-     * @return a new Apache CouchDB provider.
-     */
-    @PluginFactory
-    public static CouchDbProvider createNoSqlProvider(
-            @PluginAttribute("databaseName") final String databaseName,
-            @PluginAttribute("protocol") String protocol,
-            @PluginAttribute(value = "server", defaultString = "localhost") @ValidHost final String server,
-            @PluginAttribute(value = "port", defaultString = "0") @ValidPort final String port,
-            @PluginAttribute("username") final String username,
-            @PluginAttribute(value = "password", sensitive = true) final String password,
-            @PluginAttribute("factoryClassName") final String factoryClassName,
-            @PluginAttribute("factoryMethodName") final String factoryMethodName) {
-        CouchDbClient client;
-        String description;
-        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 CouchDbClient) {
-                    client = (CouchDbClient) object;
-                    description = "uri=" + client.getDBUri();
-                } else if (object instanceof CouchDbProperties) {
-                    final CouchDbProperties properties = (CouchDbProperties) object;
-                    client = new CouchDbClient(properties);
-                    description = "uri=" + client.getDBUri() + ", username=" + properties.getUsername()
-                            + ", passwordHash=" + NameUtil.md5(password + CouchDbProvider.class.getName())
-                            + ", maxConnections=" + properties.getMaxConnections() + ", connectionTimeout="
-                            + properties.getConnectionTimeout() + ", socketTimeout=" + properties.getSocketTimeout();
-                } 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;
-                }
-            } 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)) {
-            if (protocol != null && protocol.length() > 0) {
-                protocol = protocol.toLowerCase();
-                if (!protocol.equals("http") && !protocol.equals("https")) {
-                    LOGGER.error("Only protocols [http] and [https] are supported, [{}] specified.", protocol);
-                    return null;
-                }
-            } else {
-                protocol = "http";
-                LOGGER.warn("No protocol specified, using default port [http].");
-            }
-
-            final int portInt = TypeConverters.convert(port, int.class, protocol.equals("https") ? HTTPS : HTTP);
-
-            if (Strings.isEmpty(username) || Strings.isEmpty(password)) {
-                LOGGER.error("You must provide a username and password for the CouchDB provider.");
-                return null;
-            }
-
-            client = new CouchDbClient(databaseName, false, protocol, server, portInt, username, password);
-            description = "uri=" + client.getDBUri() + ", username=" + username + ", passwordHash="
-                    + NameUtil.md5(password + CouchDbProvider.class.getName());
-        } else {
-            LOGGER.error("No factory method was provided so the database name is required.");
-            return null;
-        }
-
-        return new CouchDbProvider(client, description);
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java
deleted file mode 100644
index b783f87..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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 Apache CouchDB provider for the NoSQL Appender.
- */
-package org.apache.logging.log4j.nosql.appender.couchdb;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java
deleted file mode 100644
index 0edbb66..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.nosql.appender.mongodb;
-
-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.nosql.appender.AbstractNoSqlConnection;
-import org.apache.logging.log4j.nosql.appender.NoSqlConnection;
-import org.apache.logging.log4j.nosql.appender.NoSqlObject;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.bson.BSON;
-import org.bson.Transformer;
-
-import com.mongodb.BasicDBObject;
-import com.mongodb.DB;
-import com.mongodb.DBCollection;
-import com.mongodb.MongoException;
-import com.mongodb.WriteConcern;
-
-/**
- * The MongoDB implementation of {@link NoSqlConnection}.
- */
-public final class MongoDbConnection extends AbstractNoSqlConnection<BasicDBObject, MongoDbObject> {
-
-    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 final DBCollection collection;
-    private final WriteConcern writeConcern;
-
-    public MongoDbConnection(final DB database, final WriteConcern writeConcern, final String collectionName,
-            final Boolean isCapped, final Integer collectionSize) {
-        if (database.collectionExists(collectionName)) {
-            collection = database.getCollection(collectionName);
-        } else {
-            final BasicDBObject options = new BasicDBObject();
-            options.put("capped", isCapped);
-            options.put("size", collectionSize);
-            this.collection = database.createCollection(collectionName, options);
-        }
-        this.writeConcern = writeConcern;
-    }
-
-    @Override
-    public MongoDbObject createObject() {
-        return new MongoDbObject();
-    }
-
-    @Override
-    public MongoDbObject[] createList(final int length) {
-        return new MongoDbObject[length];
-    }
-
-    @Override
-    public void insertObject(final NoSqlObject<BasicDBObject> object) {
-        try {
-            this.collection.insert(object.unwrap(), this.writeConcern);
-        } catch (final MongoException e) {
-            throw new AppenderLoggingException("Failed to write log event to MongoDB due to error: " + e.getMessage(),
-                    e);
-        }
-    }
-
-    @Override
-    public void closeImpl() {
-        // LOG4J2-1196
-        this.collection.getDB().getMongo().close();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java
deleted file mode 100644
index 9c39cc3..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.nosql.appender.mongodb;
-
-import java.util.Collections;
-
-import org.apache.logging.log4j.nosql.appender.NoSqlObject;
-
-import com.mongodb.BasicDBList;
-import com.mongodb.BasicDBObject;
-
-/**
- * The MongoDB implementation of {@link NoSqlObject}.
- */
-public final class MongoDbObject implements NoSqlObject<BasicDBObject> {
-    private final BasicDBObject mongoObject;
-
-    public MongoDbObject() {
-        this.mongoObject = new BasicDBObject();
-    }
-
-    @Override
-    public void set(final String field, final Object value) {
-        this.mongoObject.append(field, value);
-    }
-
-    @Override
-    public void set(final String field, final NoSqlObject<BasicDBObject> value) {
-        this.mongoObject.append(field, value.unwrap());
-    }
-
-    @Override
-    public void set(final String field, final Object[] values) {
-        final BasicDBList list = new BasicDBList();
-        Collections.addAll(list, values);
-        this.mongoObject.append(field, list);
-    }
-
-    @Override
-    public void set(final String field, final NoSqlObject<BasicDBObject>[] values) {
-        final BasicDBList list = new BasicDBList();
-        for (final NoSqlObject<BasicDBObject> value : values) {
-            list.add(value.unwrap());
-        }
-        this.mongoObject.append(field, list);
-    }
-
-    @Override
-    public BasicDBObject unwrap() {
-        return this.mongoObject;
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java
deleted file mode 100644
index 69a1f00..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * 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.nosql.appender.mongodb;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Core;
-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.PluginFactory;
-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.nosql.appender.NoSqlProvider;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.LoaderUtil;
-import org.apache.logging.log4j.util.Strings;
-
-import com.mongodb.DB;
-import com.mongodb.MongoClient;
-import com.mongodb.MongoCredential;
-import com.mongodb.ServerAddress;
-import com.mongodb.WriteConcern;
-
-/**
- * The MongoDB implementation of {@link NoSqlProvider}.
- */
-@Plugin(name = "MongoDb", category = Core.CATEGORY_NAME, printObject = true)
-public final class MongoDbProvider implements NoSqlProvider<MongoDbConnection> {
-
-    private static final WriteConcern DEFAULT_WRITE_CONCERN = WriteConcern.ACKNOWLEDGED;
-    private static final Logger LOGGER = StatusLogger.getLogger();
-    private static final int DEFAULT_PORT = 27017;
-    private static final int DEFAULT_COLLECTION_SIZE = 536870912;
-
-    private final String collectionName;
-    private final DB database;
-    private final String description;
-    private final WriteConcern writeConcern;
-    private final boolean isCapped;
-    private final Integer collectionSize;
-
-    private MongoDbProvider(final DB database, final WriteConcern writeConcern, final String collectionName,
-            final boolean isCapped, final Integer collectionSize, final String description) {
-        this.database = database;
-        this.writeConcern = writeConcern;
-        this.collectionName = collectionName;
-        this.isCapped = isCapped;
-        this.collectionSize = collectionSize;
-        this.description = "mongoDb{ " + description + " }";
-    }
-
-    @Override
-    public MongoDbConnection getConnection() {
-        return new MongoDbConnection(this.database, this.writeConcern, this.collectionName, this.isCapped, this.collectionSize);
-    }
-
-    @Override
-    public String toString() {
-        return this.description;
-    }
-
-    /**
-     * Factory method for creating a MongoDB provider within the plugin manager.
-     *
-     * @param collectionName The name of the MongoDB collection to which log events should be written.
-     * @param writeConcernConstant The {@link WriteConcern} constant to control writing details, defaults to
-     *                             {@link WriteConcern#ACKNOWLEDGED}.
-     * @param writeConcernConstantClassName The name of a class containing the aforementioned static WriteConcern
-     *                                      constant. Defaults to {@link WriteConcern}.
-     * @param databaseName The name of the MongoDB database containing the collection to which log events should be
-     *                     written. Mutually exclusive with {@code factoryClassName&factoryMethodName!=null}.
-     * @param server The host name of the MongoDB server, defaults to localhost and mutually exclusive with
-     *               {@code factoryClassName&factoryMethodName!=null}.
-     * @param port The port the MongoDB server is listening on, defaults to the default MongoDB port and mutually
-     *             exclusive with {@code factoryClassName&factoryMethodName!=null}.
-     * @param userName The username to authenticate against the MongoDB server with.
-     * @param password The password to authenticate against the MongoDB server with.
-     * @param factoryClassName A fully qualified class name containing a static factory method capable of returning a
-     *                         {@link DB} or a {@link MongoClient}.
-     * @param factoryMethodName The name of the public static factory method belonging to the aforementioned factory
-     *                          class.
-     * @return a new MongoDB provider.
-     * @deprecated in 2.8; use {@link #newBuilder()} instead.
-     */
-    @PluginFactory
-    public static MongoDbProvider createNoSqlProvider(
-            final String collectionName,
-            final String writeConcernConstant,
-            final String writeConcernConstantClassName,
-            final String databaseName,
-            final String server,
-            final String port,
-            final String userName,
-            final String password,
-            final String factoryClassName,
-			final String factoryMethodName) {
-    	LOGGER.info("createNoSqlProvider");
-		return newBuilder().setCollectionName(collectionName).setWriteConcernConstant(writeConcernConstantClassName)
-				.setWriteConcernConstant(writeConcernConstant).setDatabaseName(databaseName).setServer(server)
-				.setPort(port).setUserName(userName).setPassword(password).setFactoryClassName(factoryClassName)
-				.setFactoryMethodName(factoryMethodName).build();
-	}
-
-	@PluginBuilderFactory
-	public static <B extends Builder<B>> B newBuilder() {
-		return new Builder<B>().asBuilder();
-	}
-
-	public static class Builder<B extends Builder<B>> extends AbstractFilterable.Builder<B>
-			implements org.apache.logging.log4j.core.util.Builder<MongoDbProvider> {
-
-		@PluginBuilderAttribute
-		@ValidHost
-		private String server = "localhost";
-
-		@PluginBuilderAttribute
-		@ValidPort
-		private String port = "" + DEFAULT_PORT;
-
-		@PluginBuilderAttribute
-		@Required(message = "No database name provided")
-		private String databaseName;
-
-		@PluginBuilderAttribute
-		@Required(message = "No collection name provided")
-		private String collectionName;
-
-		@PluginBuilderAttribute
-		private String userName;
-
-		@PluginBuilderAttribute(sensitive = true)
-		private String password;
-
-		@PluginBuilderAttribute("capped")
-		private boolean isCapped = false;
-
-		@PluginBuilderAttribute
-		private int collectionSize = DEFAULT_COLLECTION_SIZE;
-
-		@PluginBuilderAttribute
-		private String factoryClassName;
-
-		@PluginBuilderAttribute
-		private String factoryMethodName;
-
-		@PluginBuilderAttribute
-		private String writeConcernConstantClassName;
-
-		@PluginBuilderAttribute
-		private String writeConcernConstant;
-
-		public B setServer(final String server) {
-			this.server = server;
-			return asBuilder();
-		}
-
-		public B setPort(final String port) {
-			this.port = port;
-			return asBuilder();
-		}
-
-		public B setDatabaseName(final String databaseName) {
-			this.databaseName = databaseName;
-			return asBuilder();
-		}
-
-		public B setCollectionName(final String collectionName) {
-			this.collectionName = collectionName;
-			return asBuilder();
-		}
-
-		public B setUserName(final String userName) {
-			this.userName = userName;
-			return asBuilder();
-		}
-
-		public B setPassword(final String password) {
-			this.password = password;
-			return asBuilder();
-		}
-
-		public B setCapped(final boolean isCapped) {
-			this.isCapped = isCapped;
-			return asBuilder();
-		}
-
-		public B setCollectionSize(final int collectionSize) {
-			this.collectionSize = collectionSize;
-			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 setWriteConcernConstantClassName(final String writeConcernConstantClassName) {
-			this.writeConcernConstantClassName = writeConcernConstantClassName;
-			return asBuilder();
-		}
-
-		public B setWriteConcernConstant(final String writeConcernConstant) {
-			this.writeConcernConstant = writeConcernConstant;
-			return asBuilder();
-		}
-        
-		@Override
-		public MongoDbProvider build() {
-	        DB database;
-	        String description;
-	        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 DB) {
-	                    database = (DB) object;
-	                } else if (object instanceof MongoClient) {
-	                    if (Strings.isNotEmpty(databaseName)) {
-	                        database = ((MongoClient) object).getDB(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;
-	                }
-
-	                description = "database=" + database.getName();
-	                final List<ServerAddress> addresses = database.getMongo().getAllAddress();
-	                if (addresses.size() == 1) {
-	                    description += ", server=" + addresses.get(0).getHost() + ", port=" + addresses.get(0).getPort();
-	                } else {
-	                    description += ", servers=[";
-	                    for (final ServerAddress address : addresses) {
-	                        description += " { " + address.getHost() + ", " + address.getPort() + " } ";
-	                    }
-	                    description += "]";
-	                }
-	            } 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)) {
-	            final List<MongoCredential> credentials = new ArrayList<>();
-	            description = "database=" + databaseName;
-	            if (Strings.isNotEmpty(userName) && Strings.isNotEmpty(password)) {
-	                description += ", username=" + userName + ", passwordHash="
-	                        + NameUtil.md5(password + MongoDbProvider.class.getName());
-	                credentials.add(MongoCredential.createCredential(userName, databaseName, password.toCharArray()));
-	            }
-	            try {
-	                final int portInt = TypeConverters.convert(port, int.class, DEFAULT_PORT);
-	                description += ", server=" + server + ", port=" + portInt;
-	                database = new MongoClient(new ServerAddress(server, portInt), credentials).getDB(databaseName);
-	            } catch (final Exception e) {
-	                LOGGER.error(
-	                        "Failed to obtain a database instance from the MongoClient at server [{}] and " + "port [{}].",
-	                        server, port);
-	                return null;
-	            }
-	        } else {
-	            LOGGER.error("No factory method was provided so the database name is required.");
-	            return null;
-	        }
-
-	        try {
-	            database.getCollectionNames(); // 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);
-	            return null;
-	        }
-
-	        final WriteConcern writeConcern = toWriteConcern(writeConcernConstant, writeConcernConstantClassName);
-
-	        return new MongoDbProvider(database, writeConcern, collectionName, isCapped, collectionSize, description);
-		}
-
-	    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;
-	    }
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java
deleted file mode 100644
index 54a2878..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.nosql.appender.mongodb;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/package-info.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/package-info.java
deleted file mode 100644
index 9560e9d..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/package-info.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 NoSQL Appender supports writing log events to NoSQL databases. The following NoSQL databases are currently
- * supported. You can also easily extend this to support other NoSQL databases by implementing just three interfaces:
- * {@link org.apache.logging.log4j.nosql.appender.NoSqlObject NoSqlObject},
- * {@link org.apache.logging.log4j.nosql.appender.NoSqlConnection NoSqlConnection}, and
- * {@link org.apache.logging.log4j.nosql.appender.NoSqlProvider NoSqlProvider}. You will need the client library for your
- * NoSQL database of choice on the classpath to use this appender; these Maven dependencies are optional and will not
- * automatically be added to your classpath.<br>
- * <br>
- * <ul>
- *     <li><a href="http://www.mongodb.org/" target="_blank">MongoDB</a>: org.mongodb:mongo-java-driver:3.0.4 or newer
- *     must be on the classpath.</li>
- *     <li><a href="http://couchdb.apache.org/" target="_blank">Apache CouchDB</a>: org.lightcouch:lightcouch:0.0.6 or
- *     newer must be on the classpath.</li>
- * </ul>
- */
-package org.apache.logging.log4j.nosql.appender;
-

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/site/markdown/index.md.vm
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/site/markdown/index.md.vm b/log4j-nosql/src/site/markdown/index.md.vm
deleted file mode 100644
index 48c80c4..0000000
--- a/log4j-nosql/src/site/markdown/index.md.vm
+++ /dev/null
@@ -1,77 +0,0 @@
-<!-- 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 NoSQL Appenders
-
-The NoSQL Appenders allow applications to send events to NoSQL repositories.
-To use it, you need both the `log4j-nosql` as well as the appropriate
-driver for your NoSQL database type.
-
-$h2 CouchDB
-
-[Apache CouchDB](https://couchdb.apache.org/) is supported through the
-[LightCouch](http://www.lightcouch.org/) driver.
-
-```
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.lightcouch</groupId>
-        <artifactId>lightcouch</artifactId>
-        <version>0.0.6</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-  <dependencies>
-    <dependency>
-      <groupId>org.lightcouch</groupId>
-      <artifactId>lightcouch</artifactId>
-    </dependency>
-  </dependencies>
-```
-
-$h2 MongoDB
-
-[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 NoSQL Appenders 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/ebec215e/log4j-nosql/src/site/site.xml
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/site/site.xml b/log4j-nosql/src/site/site.xml
deleted file mode 100644
index bc6efc3..0000000
--- a/log4j-nosql/src/site/site.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<!--
- 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 NoSQL Appenders"
-         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/ebec215e/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbAuthTest.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbAuthTest.java b/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbAuthTest.java
deleted file mode 100644
index f87d91d..0000000
--- a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbAuthTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.nosql.appender;
-
-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.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-@Ignore("Requires a running MongoDB server")
-@Category(Appenders.MongoDb.class)
-public class MongoDbAuthTest {
-
-    @ClassRule
-    public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb-auth.xml");
-
-    @Test
-    public void test() {
-        final Logger logger = LogManager.getLogger();
-        logger.info("Hello log");
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbCappedTest.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbCappedTest.java b/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbCappedTest.java
deleted file mode 100644
index a622716..0000000
--- a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbCappedTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.nosql.appender;
-
-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.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-@Ignore("Requires a running MongoDB server")
-@Category(Appenders.MongoDb.class)
-public class MongoDbCappedTest {
-
-    @ClassRule
-    public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb-capped.xml");
-
-    @Test
-    public void test() {
-        final Logger logger = LogManager.getLogger();
-        logger.info("Hello log");
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbTest.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbTest.java b/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbTest.java
deleted file mode 100644
index b480798..0000000
--- a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/MongoDbTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.nosql.appender;
-
-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.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-@Ignore("Requires a running MongoDB server")
-@Category(Appenders.MongoDb.class)
-public class MongoDbTest {
-
-    @ClassRule
-    public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb.xml");
-
-    @Test
-    public void test() {
-        final Logger logger = LogManager.getLogger();
-        logger.info("Hello log");
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/NoSqlAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/NoSqlAppenderTest.java b/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/NoSqlAppenderTest.java
deleted file mode 100644
index 236218c..0000000
--- a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/NoSqlAppenderTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.nosql.appender;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import static org.junit.Assert.*;
-
-@RunWith(MockitoJUnitRunner.class)
-public class NoSqlAppenderTest {
-
-    @Mock
-    private NoSqlProvider<?> provider;
-
-    @Test
-    public void testNoProvider() {
-        final NoSqlAppender appender = NoSqlAppender.createAppender("myName01", null, null, null, null);
-
-        assertNull("The appender should be null.", appender);
-    }
-
-    @Test
-    public void testProvider() {
-        final NoSqlAppender appender = NoSqlAppender.createAppender("myName01", null, null, null, provider);
-
-        assertNotNull("The appender should not be null.", appender);
-        assertEquals("The toString value is not correct.",
-                "myName01{ manager=noSqlManager{ description=myName01, bufferSize=0, provider=" + provider + " } }",
-                appender.toString());
-
-        appender.stop();
-    }
-
-    @Test
-    public void testProviderBuffer() {
-        final NoSqlAppender appender = NoSqlAppender.createAppender("anotherName02", null, null, "25", provider);
-
-        assertNotNull("The appender should not be null.", appender);
-        assertEquals("The toString value is not correct.",
-                "anotherName02{ manager=noSqlManager{ description=anotherName02, bufferSize=25, provider=" + provider
-                        + " } }", appender.toString());
-
-        appender.stop();
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManagerTest.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManagerTest.java b/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManagerTest.java
deleted file mode 100644
index af55e2c..0000000
--- a/log4j-nosql/src/test/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManagerTest.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * 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.nosql.appender;
-
-import java.io.IOException;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.appender.AppenderLoggingException;
-import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.junit.ThreadContextStackRule;
-import org.apache.logging.log4j.message.Message;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.mockito.stubbing.Answer;
-
-import static org.junit.Assert.*;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.BDDMockito.then;
-import static org.mockito.Mockito.mock;
-
-@RunWith(MockitoJUnitRunner.class)
-public class NoSqlDatabaseManagerTest {
-    @Mock
-    private NoSqlConnection<Map<String, Object>, DefaultNoSqlObject> connection;
-    @Mock
-    private NoSqlProvider<NoSqlConnection<Map<String, Object>, DefaultNoSqlObject>> provider;
-    @Mock
-    private Message message;
-    @Captor
-    private ArgumentCaptor<NoSqlObject<Map<String, Object>>> captor;
-
-    @Rule
-    public final ThreadContextStackRule threadContextRule = new ThreadContextStackRule();
-    @Rule
-    public final ExpectedException expectedException = ExpectedException.none();
-
-    @Before
-    public void setUp() {
-        given(provider.getConnection()).willReturn(connection);
-        given(connection.createObject()).willAnswer(new Answer<DefaultNoSqlObject>() {
-            @Override
-            public DefaultNoSqlObject answer(final InvocationOnMock invocation) throws Throwable {
-                return new DefaultNoSqlObject();
-            }
-        });
-        given(connection.createList(anyInt())).willAnswer(new Answer<DefaultNoSqlObject[]>() {
-            @Override
-            public DefaultNoSqlObject[] answer(final InvocationOnMock invocation) throws Throwable {
-                return new DefaultNoSqlObject[invocation.<Integer>getArgument(0)];
-            }
-        });
-    }
-
-    @Test
-    public void testConnection() {
-        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
-            provider)) {
-
-            assertNotNull("The manager should not be null.", manager);
-
-            manager.connectAndStart();
-            then(provider).should().getConnection();
-            manager.commitAndClose();
-        }
-    }
-
-    @Test
-    public void testWriteInternalNotConnected01() {
-        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
-            provider)) {
-            expectedException.expect(AppenderLoggingException.class);
-            manager.writeInternal(mock(LogEvent.class));
-        }
-    }
-
-    @Test
-    public void testWriteInternalNotConnected02() {
-        given(connection.isClosed()).willReturn(true);
-
-        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
-            provider)) {
-
-            manager.startup();
-            manager.connectAndStart();
-            then(provider).should().getConnection();
-
-            expectedException.expect(AppenderLoggingException.class);
-            manager.writeInternal(mock(LogEvent.class));
-        }
-    }
-
-    @Test
-    public void testWriteInternal01() {
-        given(connection.isClosed()).willReturn(false);
-        given(message.getFormattedMessage()).willReturn("My formatted message 01.");
-
-        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
-            provider)) {
-
-            manager.startup();
-            manager.connectAndStart();
-            then(provider).should().getConnection();
-
-            final LogEvent event = Log4jLogEvent.newBuilder()
-                .setLevel(Level.WARN)
-                .setLoggerName("com.foo.NoSQLDbTest.testWriteInternal01")
-                .setMessage(message)
-                .setSource(new StackTraceElement("com.foo.Bar", "testMethod01", "Bar.java", 15))
-                .setThreadId(1L)
-                .setThreadName("MyThread-A")
-                .setThreadPriority(1)
-                .setTimeMillis(1234567890123L)
-                .build();
-
-            manager.writeInternal(event);
-            then(connection).should().insertObject(captor.capture());
-
-            final NoSqlObject<Map<String, Object>> inserted = captor.getValue();
-            assertNotNull("The inserted value should not be null.", inserted);
-            final Map<String, Object> object = inserted.unwrap();
-            assertNotNull("The unwrapped object should not be null.", object);
-
-            assertEquals("The level is not correct.", Level.WARN, object.get("level"));
-            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal01",
-                object.get("loggerName"));
-            assertEquals("The message is not correct.", "My formatted message 01.", object.get("message"));
-            assertEquals("The thread is not correct.", "MyThread-A", object.get("threadName"));
-            assertEquals("The millis is not correct.", 1234567890123L, object.get("millis"));
-            assertEquals("The date is not correct.", 1234567890123L, ((Date) object.get("date")).getTime());
-
-            assertTrue("The source should be a map.", object.get("source") instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> source = (Map<String, Object>) object.get("source");
-            assertEquals("The class is not correct.", "com.foo.Bar", source.get("className"));
-            assertEquals("The method is not correct.", "testMethod01", source.get("methodName"));
-            assertEquals("The file name is not correct.", "Bar.java", source.get("fileName"));
-            assertEquals("The line number is not correct.", 15, source.get("lineNumber"));
-
-            assertNull("The marker should be null.", object.get("marker"));
-
-            assertNull("The thrown should be null.", object.get("thrown"));
-
-            assertTrue("The context map should be empty.", ((Map) object.get("contextMap")).isEmpty());
-
-            assertTrue("The context stack should be null.", ((Collection) object.get("contextStack")).isEmpty());
-
-        }
-    }
-
-    @Test
-    public void testWriteInternal02() {
-        given(connection.isClosed()).willReturn(false);
-        given(message.getFormattedMessage()).willReturn("Another cool message 02.");
-
-        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
-            provider)) {
-            manager.startup();
-
-            manager.connectAndStart();
-            then(provider).should().getConnection();
-
-            final RuntimeException exception = new RuntimeException("This is something cool!");
-            final Map<String, String> context = new HashMap<>();
-            context.put("hello", "world");
-            context.put("user", "pass");
-
-            ThreadContext.push("message1");
-            ThreadContext.push("stack2");
-            final ThreadContext.ContextStack stack = ThreadContext.getImmutableStack();
-            ThreadContext.clearStack();
-
-            final LogEvent event = Log4jLogEvent.newBuilder()
-                .setLevel(Level.DEBUG)
-                .setLoggerName("com.foo.NoSQLDbTest.testWriteInternal02")
-                .setMessage(message)
-                .setSource(new StackTraceElement("com.bar.Foo", "anotherMethod03", "Foo.java", 9))
-                .setMarker(MarkerManager.getMarker("LoneMarker"))
-                .setThreadId(1L)
-                .setThreadName("AnotherThread-B")
-                .setThreadPriority(1)
-                .setTimeMillis(987654321564L)
-                .setThrown(exception)
-                .setContextMap(context)
-                .setContextStack(stack)
-                .build();
-
-            manager.writeInternal(event);
-            then(connection).should().insertObject(captor.capture());
-
-            final NoSqlObject<Map<String, Object>> inserted = captor.getValue();
-            assertNotNull("The inserted value should not be null.", inserted);
-            final Map<String, Object> object = inserted.unwrap();
-            assertNotNull("The unwrapped object should not be null.", object);
-
-            assertEquals("The level is not correct.", Level.DEBUG, object.get("level"));
-            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal02",
-                object.get("loggerName"));
-            assertEquals("The message is not correct.", "Another cool message 02.", object.get("message"));
-            assertEquals("The thread is not correct.", "AnotherThread-B", object.get("threadName"));
-            assertEquals("The millis is not correct.", 987654321564L, object.get("millis"));
-            assertEquals("The date is not correct.", 987654321564L, ((Date) object.get("date")).getTime());
-
-            assertTrue("The source should be a map.", object.get("source") instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> source = (Map<String, Object>) object.get("source");
-            assertEquals("The class is not correct.", "com.bar.Foo", source.get("className"));
-            assertEquals("The method is not correct.", "anotherMethod03", source.get("methodName"));
-            assertEquals("The file name is not correct.", "Foo.java", source.get("fileName"));
-            assertEquals("The line number is not correct.", 9, source.get("lineNumber"));
-
-            assertTrue("The marker should be a map.", object.get("marker") instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> marker = (Map<String, Object>) object.get("marker");
-            assertEquals("The marker name is not correct.", "LoneMarker", marker.get("name"));
-            assertNull("The marker parent should be null.", marker.get("parent"));
-
-            assertTrue("The thrown should be a map.", object.get("thrown") instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> thrown = (Map<String, Object>) object.get("thrown");
-            assertEquals("The thrown type is not correct.", "java.lang.RuntimeException", thrown.get("type"));
-            assertEquals("The thrown message is not correct.", "This is something cool!", thrown.get("message"));
-            assertTrue("The thrown stack trace should be a list.", thrown.get("stackTrace") instanceof List);
-            @SuppressWarnings("unchecked")
-            final List<Map<String, Object>> stackTrace = (List<Map<String, Object>>) thrown.get("stackTrace");
-            assertEquals("The thrown stack trace length is not correct.", exception.getStackTrace().length,
-                stackTrace.size());
-            for (int i = 0; i < exception.getStackTrace().length; i++) {
-                final StackTraceElement e1 = exception.getStackTrace()[i];
-                final Map<String, Object> e2 = stackTrace.get(i);
-
-                assertEquals("Element class name [" + i + "] is not correct.", e1.getClassName(), e2.get("className"));
-                assertEquals("Element method name [" + i + "] is not correct.", e1.getMethodName(),
-                    e2.get("methodName"));
-                assertEquals("Element file name [" + i + "] is not correct.", e1.getFileName(), e2.get("fileName"));
-                assertEquals("Element line number [" + i + "] is not correct.", e1.getLineNumber(),
-                    e2.get("lineNumber"));
-            }
-            assertNull("The thrown should have no cause.", thrown.get("cause"));
-
-            assertTrue("The context map should be a map.", object.get("contextMap") instanceof Map);
-            assertEquals("The context map is not correct.", context, object.get("contextMap"));
-
-            assertTrue("The context stack should be list.", object.get("contextStack") instanceof List);
-            assertEquals("The context stack is not correct.", stack.asList(), object.get("contextStack"));
-        }
-    }
-
-    @Test
-    public void testWriteInternal03() {
-        given(connection.isClosed()).willReturn(false);
-        given(message.getFormattedMessage()).willReturn("Another cool message 02.");
-
-        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
-            provider)) {
-            manager.startup();
-
-            manager.connectAndStart();
-            then(provider).should().getConnection();
-
-            final IOException exception1 = new IOException("This is the cause.");
-            final SQLException exception2 = new SQLException("This is the result.", exception1);
-            final Map<String, String> context = new HashMap<>();
-            context.put("hello", "world");
-            context.put("user", "pass");
-
-            ThreadContext.push("message1");
-            ThreadContext.push("stack2");
-            final ThreadContext.ContextStack stack = ThreadContext.getImmutableStack();
-            ThreadContext.clearStack();
-
-            final LogEvent event = Log4jLogEvent.newBuilder()
-                .setLevel(Level.DEBUG)
-                .setLoggerName("com.foo.NoSQLDbTest.testWriteInternal02")
-                .setMessage(message)
-                .setSource(new StackTraceElement("com.bar.Foo", "anotherMethod03", "Foo.java", 9))
-                .setMarker(MarkerManager.getMarker("AnotherMarker").addParents(
-                    MarkerManager.getMarker("Parent1").addParents(MarkerManager.getMarker("GrandParent1")),
-                    MarkerManager.getMarker("Parent2")))
-                .setThreadId(1L)
-                .setThreadName("AnotherThread-B")
-                .setThreadPriority(1)
-                .setTimeMillis(987654321564L)
-                .setThrown(exception2)
-                .setContextMap(context)
-                .setContextStack(stack)
-                .build();
-
-            manager.writeInternal(event);
-            then(connection).should().insertObject(captor.capture());
-
-            final NoSqlObject<Map<String, Object>> inserted = captor.getValue();
-            assertNotNull("The inserted value should not be null.", inserted);
-            final Map<String, Object> object = inserted.unwrap();
-            assertNotNull("The unwrapped object should not be null.", object);
-
-            assertEquals("The level is not correct.", Level.DEBUG, object.get("level"));
-            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal02",
-                object.get("loggerName"));
-            assertEquals("The message is not correct.", "Another cool message 02.", object.get("message"));
-            assertEquals("The thread is not correct.", "AnotherThread-B", object.get("threadName"));
-            assertEquals("The millis is not correct.", 987654321564L, object.get("millis"));
-            assertEquals("The date is not correct.", 987654321564L, ((Date) object.get("date")).getTime());
-
-            assertTrue("The source should be a map.", object.get("source") instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> source = (Map<String, Object>) object.get("source");
-            assertEquals("The class is not correct.", "com.bar.Foo", source.get("className"));
-            assertEquals("The method is not correct.", "anotherMethod03", source.get("methodName"));
-            assertEquals("The file name is not correct.", "Foo.java", source.get("fileName"));
-            assertEquals("The line number is not correct.", 9, source.get("lineNumber"));
-
-            assertTrue("The marker should be a map.", object.get("marker") instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> marker = (Map<String, Object>) object.get("marker");
-            assertEquals("The marker name is not correct.", "AnotherMarker", marker.get("name"));
-
-            assertTrue("The marker parents should be a list.", marker.get("parents") instanceof List);
-            @SuppressWarnings("unchecked")
-            final List<Object> markerParents = (List<Object>) marker.get("parents");
-            assertEquals("The marker parents should contain two parents", 2, markerParents.size());
-
-            assertTrue("The marker parents[0] should be a map.", markerParents.get(0) instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> parent1 = (Map<String, Object>) markerParents.get(0);
-            assertEquals("The first marker parent name is not correct.", "Parent1", parent1.get("name"));
-
-            assertTrue("The marker parents[1] should be a map.", markerParents.get(1) instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> parent2 = (Map<String, Object>) markerParents.get(1);
-            assertEquals("The second marker parent name is not correct.", "Parent2", parent2.get("name"));
-            assertNull("The second marker should have no parent.", parent2.get("parent"));
-
-            assertTrue("The parent1 parents should be a list.", parent1.get("parents") instanceof List);
-            @SuppressWarnings("unchecked")
-            final List<Object> parent1Parents = (List<Object>) parent1.get("parents");
-            assertEquals("The parent1 parents should have only one parent", 1, parent1Parents.size());
-
-            assertTrue("The parent1Parents[0] should be a map.", parent1Parents.get(0) instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> parent1parent = (Map<String, Object>) parent1Parents.get(0);
-            assertEquals("The first parent1 parent name is not correct.", "GrandParent1", parent1parent.get("name"));
-            assertNull("The parent1parent marker should have no parent.", parent1parent.get("parent"));
-
-            assertTrue("The thrown should be a map.", object.get("thrown") instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> thrown = (Map<String, Object>) object.get("thrown");
-            assertEquals("The thrown type is not correct.", "java.sql.SQLException", thrown.get("type"));
-            assertEquals("The thrown message is not correct.", "This is the result.", thrown.get("message"));
-            assertTrue("The thrown stack trace should be a list.", thrown.get("stackTrace") instanceof List);
-            @SuppressWarnings("unchecked")
-            final List<Map<String, Object>> stackTrace = (List<Map<String, Object>>) thrown.get("stackTrace");
-            assertEquals("The thrown stack trace length is not correct.", exception2.getStackTrace().length,
-                stackTrace.size());
-            for (int i = 0; i < exception2.getStackTrace().length; i++) {
-                final StackTraceElement e1 = exception2.getStackTrace()[i];
-                final Map<String, Object> e2 = stackTrace.get(i);
-
-                assertEquals("Element class name [" + i + "] is not correct.", e1.getClassName(), e2.get("className"));
-                assertEquals("Element method name [" + i + "] is not correct.", e1.getMethodName(),
-                    e2.get("methodName"));
-                assertEquals("Element file name [" + i + "] is not correct.", e1.getFileName(), e2.get("fileName"));
-                assertEquals("Element line number [" + i + "] is not correct.", e1.getLineNumber(),
-                    e2.get("lineNumber"));
-            }
-            assertTrue("The thrown cause should be a map.", thrown.get("cause") instanceof Map);
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> cause = (Map<String, Object>) thrown.get("cause");
-            assertEquals("The cause type is not correct.", "java.io.IOException", cause.get("type"));
-            assertEquals("The cause message is not correct.", "This is the cause.", cause.get("message"));
-            assertTrue("The cause stack trace should be a list.", cause.get("stackTrace") instanceof List);
-            @SuppressWarnings("unchecked")
-            final List<Map<String, Object>> causeStackTrace = (List<Map<String, Object>>) cause.get("stackTrace");
-            assertEquals("The cause stack trace length is not correct.", exception1.getStackTrace().length,
-                causeStackTrace.size());
-            for (int i = 0; i < exception1.getStackTrace().length; i++) {
-                final StackTraceElement e1 = exception1.getStackTrace()[i];
-                final Map<String, Object> e2 = causeStackTrace.get(i);
-
-                assertEquals("Element class name [" + i + "] is not correct.", e1.getClassName(), e2.get("className"));
-                assertEquals("Element method name [" + i + "] is not correct.", e1.getMethodName(),
-                    e2.get("methodName"));
-                assertEquals("Element file name [" + i + "] is not correct.", e1.getFileName(), e2.get("fileName"));
-                assertEquals("Element line number [" + i + "] is not correct.", e1.getLineNumber(),
-                    e2.get("lineNumber"));
-            }
-            assertNull("The cause should have no cause.", cause.get("cause"));
-
-            assertTrue("The context map should be a map.", object.get("contextMap") instanceof Map);
-            assertEquals("The context map is not correct.", context, object.get("contextMap"));
-
-            assertTrue("The context stack should be list.", object.get("contextStack") instanceof List);
-            assertEquals("The context stack is not correct.", stack.asList(), object.get("contextStack"));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/test/resources/log4j2-mongodb-auth.xml
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/test/resources/log4j2-mongodb-auth.xml b/log4j-nosql/src/test/resources/log4j2-mongodb-auth.xml
deleted file mode 100644
index 2eec2b6..0000000
--- a/log4j-nosql/src/test/resources/log4j2-mongodb-auth.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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="error">
-  <Appenders>
-    <NoSql name="MongoDbAppender">
-      <MongoDb databaseName="test" collectionName="applog" server="localhost" userName="log4jUser" password="12345678"/>
-    </NoSql>
-  </Appenders>
-  <Loggers>
-    <Root level="ALL">
-      <AppenderRef ref="MongoDbAppender" />
-    </Root>
-  </Loggers>
-</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/test/resources/log4j2-mongodb-capped.xml
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/test/resources/log4j2-mongodb-capped.xml b/log4j-nosql/src/test/resources/log4j2-mongodb-capped.xml
deleted file mode 100644
index 24d964b..0000000
--- a/log4j-nosql/src/test/resources/log4j2-mongodb-capped.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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="error">
-  <Appenders>
-    <NoSql name="MongoDbAppender">
-      <MongoDb databaseName="test" collectionName="applog" server="localhost" capped="true" collectionSize="1073741824" />
-    </NoSql>
-  </Appenders>
-  <Loggers>
-    <Root level="ALL">
-      <AppenderRef ref="MongoDbAppender" />
-    </Root>
-  </Loggers>
-</Configuration>


[3/4] logging-log4j2 git commit: LOG4J2-2076 CouchDB and MongoDB appenders in own modules, remove log4j-nosql module

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-couchdb/src/site/markdown/index.md.vm
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/site/markdown/index.md.vm b/log4j-couchdb/src/site/markdown/index.md.vm
new file mode 100644
index 0000000..a6b9639
--- /dev/null
+++ b/log4j-couchdb/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 CouchDB Appender
+
+[Apache CouchDB](https://couchdb.apache.org/) is supported through the
+[LightCouch](http://www.lightcouch.org/) driver.
+
+```
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.lightcouch</groupId>
+        <artifactId>lightcouch</artifactId>
+        <version>0.0.6</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.lightcouch</groupId>
+      <artifactId>lightcouch</artifactId>
+    </dependency>
+  </dependencies>
+```
+
+$h2 Requirements
+
+The CouchDB 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/ebec215e/log4j-couchdb/src/site/site.xml
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/site/site.xml b/log4j-couchdb/src/site/site.xml
new file mode 100644
index 0000000..affd43f
--- /dev/null
+++ b/log4j-couchdb/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 CouchDB 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/ebec215e/log4j-distribution/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-distribution/pom.xml b/log4j-distribution/pom.xml
index 651717a..fa46876 100644
--- a/log4j-distribution/pom.xml
+++ b/log4j-distribution/pom.xml
@@ -240,18 +240,52 @@
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-nosql</artifactId>
+      <artifactId>log4j-couchdb</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-nosql</artifactId>
+      <artifactId>log4j-couchdb</artifactId>
       <version>${project.version}</version>
       <classifier>sources</classifier>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-nosql</artifactId>
+      <artifactId>log4j-couchdb</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-mongodb</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-mongodb</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-mongodb</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-cassandra</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-cassandra</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-cassandra</artifactId>
       <version>${project.version}</version>
       <classifier>javadoc</classifier>
     </dependency>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb/pom.xml b/log4j-mongodb/pom.xml
new file mode 100644
index 0000000..29c511c
--- /dev/null
+++ b/log4j-mongodb/pom.xml
@@ -0,0 +1,183 @@
+<?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.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>log4j-mongodb</artifactId>
+  <name>Apache Log4j MongoDB</name>
+  <description>
+    MongoDB appender for Log4j.
+  </description>
+  <properties>
+    <log4jParentDir>${basedir}/..</log4jParentDir>
+    <docLabel>MongoDB Documentation</docLabel>
+    <projectDir>/log4j-mongodb</projectDir>
+    <module.name>org.apache.logging.log4j.mongodb</module.name>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mongodb</groupId>
+      <artifactId>mongo-java-driver</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>
+  </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/ebec215e/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java
new file mode 100644
index 0000000..66e205d
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java
@@ -0,0 +1,96 @@
+/*
+ * 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.nosql.appender.mongodb;
+
+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.Transformer;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.MongoException;
+import com.mongodb.WriteConcern;
+
+/**
+ * The MongoDB implementation of {@link NoSqlConnection}.
+ */
+public final class MongoDbConnection extends AbstractNoSqlConnection<BasicDBObject, MongoDbObject> {
+
+    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 final DBCollection collection;
+    private final WriteConcern writeConcern;
+
+    public MongoDbConnection(final DB database, final WriteConcern writeConcern, final String collectionName,
+            final Boolean isCapped, final Integer collectionSize) {
+        if (database.collectionExists(collectionName)) {
+            collection = database.getCollection(collectionName);
+        } else {
+            final BasicDBObject options = new BasicDBObject();
+            options.put("capped", isCapped);
+            options.put("size", collectionSize);
+            this.collection = database.createCollection(collectionName, options);
+        }
+        this.writeConcern = writeConcern;
+    }
+
+    @Override
+    public MongoDbObject createObject() {
+        return new MongoDbObject();
+    }
+
+    @Override
+    public MongoDbObject[] createList(final int length) {
+        return new MongoDbObject[length];
+    }
+
+    @Override
+    public void insertObject(final NoSqlObject<BasicDBObject> object) {
+        try {
+            this.collection.insert(object.unwrap(), this.writeConcern);
+        } catch (final MongoException e) {
+            throw new AppenderLoggingException("Failed to write log event to MongoDB due to error: " + e.getMessage(),
+                    e);
+        }
+    }
+
+    @Override
+    public void closeImpl() {
+        // LOG4J2-1196
+        this.collection.getDB().getMongo().close();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java
new file mode 100644
index 0000000..8eb6e46
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java
@@ -0,0 +1,66 @@
+/*
+ * 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.nosql.appender.mongodb;
+
+import java.util.Collections;
+
+import org.apache.logging.log4j.core.appender.nosql.NoSqlObject;
+
+import com.mongodb.BasicDBList;
+import com.mongodb.BasicDBObject;
+
+/**
+ * The MongoDB implementation of {@link NoSqlObject}.
+ */
+public final class MongoDbObject implements NoSqlObject<BasicDBObject> {
+    private final BasicDBObject mongoObject;
+
+    public MongoDbObject() {
+        this.mongoObject = new BasicDBObject();
+    }
+
+    @Override
+    public void set(final String field, final Object value) {
+        this.mongoObject.append(field, value);
+    }
+
+    @Override
+    public void set(final String field, final NoSqlObject<BasicDBObject> value) {
+        this.mongoObject.append(field, value.unwrap());
+    }
+
+    @Override
+    public void set(final String field, final Object[] values) {
+        final BasicDBList list = new BasicDBList();
+        Collections.addAll(list, values);
+        this.mongoObject.append(field, list);
+    }
+
+    @Override
+    public void set(final String field, final NoSqlObject<BasicDBObject>[] values) {
+        final BasicDBList list = new BasicDBList();
+        for (final NoSqlObject<BasicDBObject> value : values) {
+            list.add(value.unwrap());
+        }
+        this.mongoObject.append(field, list);
+    }
+
+    @Override
+    public BasicDBObject unwrap() {
+        return this.mongoObject;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java
new file mode 100644
index 0000000..5167c3e
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java
@@ -0,0 +1,351 @@
+/*
+ * 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.nosql.appender.mongodb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Core;
+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.PluginFactory;
+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.core.appender.nosql.NoSqlProvider;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.LoaderUtil;
+import org.apache.logging.log4j.util.Strings;
+
+import com.mongodb.DB;
+import com.mongodb.MongoClient;
+import com.mongodb.MongoCredential;
+import com.mongodb.ServerAddress;
+import com.mongodb.WriteConcern;
+
+/**
+ * The MongoDB implementation of {@link NoSqlProvider}.
+ */
+@Plugin(name = "MongoDb", category = Core.CATEGORY_NAME, printObject = true)
+public final class MongoDbProvider implements NoSqlProvider<MongoDbConnection> {
+
+    private static final WriteConcern DEFAULT_WRITE_CONCERN = WriteConcern.ACKNOWLEDGED;
+    private static final Logger LOGGER = StatusLogger.getLogger();
+    private static final int DEFAULT_PORT = 27017;
+    private static final int DEFAULT_COLLECTION_SIZE = 536870912;
+
+    private final String collectionName;
+    private final DB database;
+    private final String description;
+    private final WriteConcern writeConcern;
+    private final boolean isCapped;
+    private final Integer collectionSize;
+
+    private MongoDbProvider(final DB database, final WriteConcern writeConcern, final String collectionName,
+            final boolean isCapped, final Integer collectionSize, final String description) {
+        this.database = database;
+        this.writeConcern = writeConcern;
+        this.collectionName = collectionName;
+        this.isCapped = isCapped;
+        this.collectionSize = collectionSize;
+        this.description = "mongoDb{ " + description + " }";
+    }
+
+    @Override
+    public MongoDbConnection getConnection() {
+        return new MongoDbConnection(this.database, this.writeConcern, this.collectionName, this.isCapped, this.collectionSize);
+    }
+
+    @Override
+    public String toString() {
+        return this.description;
+    }
+
+    /**
+     * Factory method for creating a MongoDB provider within the plugin manager.
+     *
+     * @param collectionName The name of the MongoDB collection to which log events should be written.
+     * @param writeConcernConstant The {@link WriteConcern} constant to control writing details, defaults to
+     *                             {@link WriteConcern#ACKNOWLEDGED}.
+     * @param writeConcernConstantClassName The name of a class containing the aforementioned static WriteConcern
+     *                                      constant. Defaults to {@link WriteConcern}.
+     * @param databaseName The name of the MongoDB database containing the collection to which log events should be
+     *                     written. Mutually exclusive with {@code factoryClassName&factoryMethodName!=null}.
+     * @param server The host name of the MongoDB server, defaults to localhost and mutually exclusive with
+     *               {@code factoryClassName&factoryMethodName!=null}.
+     * @param port The port the MongoDB server is listening on, defaults to the default MongoDB port and mutually
+     *             exclusive with {@code factoryClassName&factoryMethodName!=null}.
+     * @param userName The username to authenticate against the MongoDB server with.
+     * @param password The password to authenticate against the MongoDB server with.
+     * @param factoryClassName A fully qualified class name containing a static factory method capable of returning a
+     *                         {@link DB} or a {@link MongoClient}.
+     * @param factoryMethodName The name of the public static factory method belonging to the aforementioned factory
+     *                          class.
+     * @return a new MongoDB provider.
+     * @deprecated in 2.8; use {@link #newBuilder()} instead.
+     */
+    @PluginFactory
+    public static MongoDbProvider createNoSqlProvider(
+            final String collectionName,
+            final String writeConcernConstant,
+            final String writeConcernConstantClassName,
+            final String databaseName,
+            final String server,
+            final String port,
+            final String userName,
+            final String password,
+            final String factoryClassName,
+			final String factoryMethodName) {
+    	LOGGER.info("createNoSqlProvider");
+		return newBuilder().setCollectionName(collectionName).setWriteConcernConstant(writeConcernConstantClassName)
+				.setWriteConcernConstant(writeConcernConstant).setDatabaseName(databaseName).setServer(server)
+				.setPort(port).setUserName(userName).setPassword(password).setFactoryClassName(factoryClassName)
+				.setFactoryMethodName(factoryMethodName).build();
+	}
+
+	@PluginBuilderFactory
+	public static <B extends Builder<B>> B newBuilder() {
+		return new Builder<B>().asBuilder();
+	}
+
+	public static class Builder<B extends Builder<B>> extends AbstractFilterable.Builder<B>
+			implements org.apache.logging.log4j.core.util.Builder<MongoDbProvider> {
+
+		@PluginBuilderAttribute
+		@ValidHost
+		private String server = "localhost";
+
+		@PluginBuilderAttribute
+		@ValidPort
+		private String port = "" + DEFAULT_PORT;
+
+		@PluginBuilderAttribute
+		@Required(message = "No database name provided")
+		private String databaseName;
+
+		@PluginBuilderAttribute
+		@Required(message = "No collection name provided")
+		private String collectionName;
+
+		@PluginBuilderAttribute
+		private String userName;
+
+		@PluginBuilderAttribute(sensitive = true)
+		private String password;
+
+		@PluginBuilderAttribute("capped")
+		private boolean isCapped = false;
+
+		@PluginBuilderAttribute
+		private int collectionSize = DEFAULT_COLLECTION_SIZE;
+
+		@PluginBuilderAttribute
+		private String factoryClassName;
+
+		@PluginBuilderAttribute
+		private String factoryMethodName;
+
+		@PluginBuilderAttribute
+		private String writeConcernConstantClassName;
+
+		@PluginBuilderAttribute
+		private String writeConcernConstant;
+
+		public B setServer(final String server) {
+			this.server = server;
+			return asBuilder();
+		}
+
+		public B setPort(final String port) {
+			this.port = port;
+			return asBuilder();
+		}
+
+		public B setDatabaseName(final String databaseName) {
+			this.databaseName = databaseName;
+			return asBuilder();
+		}
+
+		public B setCollectionName(final String collectionName) {
+			this.collectionName = collectionName;
+			return asBuilder();
+		}
+
+		public B setUserName(final String userName) {
+			this.userName = userName;
+			return asBuilder();
+		}
+
+		public B setPassword(final String password) {
+			this.password = password;
+			return asBuilder();
+		}
+
+		public B setCapped(final boolean isCapped) {
+			this.isCapped = isCapped;
+			return asBuilder();
+		}
+
+		public B setCollectionSize(final int collectionSize) {
+			this.collectionSize = collectionSize;
+			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 setWriteConcernConstantClassName(final String writeConcernConstantClassName) {
+			this.writeConcernConstantClassName = writeConcernConstantClassName;
+			return asBuilder();
+		}
+
+		public B setWriteConcernConstant(final String writeConcernConstant) {
+			this.writeConcernConstant = writeConcernConstant;
+			return asBuilder();
+		}
+        
+		@Override
+		public MongoDbProvider build() {
+	        DB database;
+	        String description;
+	        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 DB) {
+	                    database = (DB) object;
+	                } else if (object instanceof MongoClient) {
+	                    if (Strings.isNotEmpty(databaseName)) {
+	                        database = ((MongoClient) object).getDB(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;
+	                }
+
+	                description = "database=" + database.getName();
+	                final List<ServerAddress> addresses = database.getMongo().getAllAddress();
+	                if (addresses.size() == 1) {
+	                    description += ", server=" + addresses.get(0).getHost() + ", port=" + addresses.get(0).getPort();
+	                } else {
+	                    description += ", servers=[";
+	                    for (final ServerAddress address : addresses) {
+	                        description += " { " + address.getHost() + ", " + address.getPort() + " } ";
+	                    }
+	                    description += "]";
+	                }
+	            } 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)) {
+	            final List<MongoCredential> credentials = new ArrayList<>();
+	            description = "database=" + databaseName;
+	            if (Strings.isNotEmpty(userName) && Strings.isNotEmpty(password)) {
+	                description += ", username=" + userName + ", passwordHash="
+	                        + NameUtil.md5(password + MongoDbProvider.class.getName());
+	                credentials.add(MongoCredential.createCredential(userName, databaseName, password.toCharArray()));
+	            }
+	            try {
+	                final int portInt = TypeConverters.convert(port, int.class, DEFAULT_PORT);
+	                description += ", server=" + server + ", port=" + portInt;
+	                database = new MongoClient(new ServerAddress(server, portInt), credentials).getDB(databaseName);
+	            } catch (final Exception e) {
+	                LOGGER.error(
+	                        "Failed to obtain a database instance from the MongoClient at server [{}] and " + "port [{}].",
+	                        server, port);
+	                return null;
+	            }
+	        } else {
+	            LOGGER.error("No factory method was provided so the database name is required.");
+	            return null;
+	        }
+
+	        try {
+	            database.getCollectionNames(); // 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);
+	            return null;
+	        }
+
+	        final WriteConcern writeConcern = toWriteConcern(writeConcernConstant, writeConcernConstantClassName);
+
+	        return new MongoDbProvider(database, writeConcern, collectionName, isCapped, collectionSize, description);
+		}
+
+	    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;
+	    }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java
new file mode 100644
index 0000000..54a2878
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/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.nosql.appender.mongodb;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/site/markdown/index.md.vm
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/site/markdown/index.md.vm b/log4j-mongodb/src/site/markdown/index.md.vm
new file mode 100644
index 0000000..1bdd5a5
--- /dev/null
+++ b/log4j-mongodb/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/ebec215e/log4j-mongodb/src/site/site.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/site/site.xml b/log4j-mongodb/src/site/site.xml
new file mode 100644
index 0000000..54ea9be
--- /dev/null
+++ b/log4j-mongodb/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/ebec215e/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java
new file mode 100644
index 0000000..3641a75
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.nosql.appender.mongodb;
+
+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.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Ignore("Requires a running MongoDB server")
+@Category(Appenders.MongoDb.class)
+public class MongoDbAuthTest {
+
+    @ClassRule
+    public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb-auth.xml");
+
+    @Test
+    public void test() {
+        final Logger logger = LogManager.getLogger();
+        logger.info("Hello log");
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java
new file mode 100644
index 0000000..a001b4b
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.nosql.appender.mongodb;
+
+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.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Ignore("Requires a running MongoDB server")
+@Category(Appenders.MongoDb.class)
+public class MongoDbCappedTest {
+
+    @ClassRule
+    public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb-capped.xml");
+
+    @Test
+    public void test() {
+        final Logger logger = LogManager.getLogger();
+        logger.info("Hello log");
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java
new file mode 100644
index 0000000..59ef951
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.nosql.appender.mongodb;
+
+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.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Ignore("Requires a running MongoDB server")
+@Category(Appenders.MongoDb.class)
+public class MongoDbTest {
+
+    @ClassRule
+    public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb.xml");
+
+    @Test
+    public void test() {
+        final Logger logger = LogManager.getLogger();
+        logger.info("Hello log");
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/resources/log4j2-mongodb-auth.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/resources/log4j2-mongodb-auth.xml b/log4j-mongodb/src/test/resources/log4j2-mongodb-auth.xml
new file mode 100644
index 0000000..2eec2b6
--- /dev/null
+++ b/log4j-mongodb/src/test/resources/log4j2-mongodb-auth.xml
@@ -0,0 +1,30 @@
+<?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="error">
+  <Appenders>
+    <NoSql name="MongoDbAppender">
+      <MongoDb databaseName="test" collectionName="applog" server="localhost" userName="log4jUser" password="12345678"/>
+    </NoSql>
+  </Appenders>
+  <Loggers>
+    <Root level="ALL">
+      <AppenderRef ref="MongoDbAppender" />
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/resources/log4j2-mongodb-capped.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/resources/log4j2-mongodb-capped.xml b/log4j-mongodb/src/test/resources/log4j2-mongodb-capped.xml
new file mode 100644
index 0000000..24d964b
--- /dev/null
+++ b/log4j-mongodb/src/test/resources/log4j2-mongodb-capped.xml
@@ -0,0 +1,30 @@
+<?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="error">
+  <Appenders>
+    <NoSql name="MongoDbAppender">
+      <MongoDb databaseName="test" collectionName="applog" server="localhost" capped="true" collectionSize="1073741824" />
+    </NoSql>
+  </Appenders>
+  <Loggers>
+    <Root level="ALL">
+      <AppenderRef ref="MongoDbAppender" />
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/resources/log4j2-mongodb.xml
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/resources/log4j2-mongodb.xml b/log4j-mongodb/src/test/resources/log4j2-mongodb.xml
new file mode 100644
index 0000000..c759054
--- /dev/null
+++ b/log4j-mongodb/src/test/resources/log4j2-mongodb.xml
@@ -0,0 +1,30 @@
+<?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="error">
+  <Appenders>
+    <NoSql name="MongoDbAppender">
+      <MongoDb databaseName="test" collectionName="applog" server="localhost" />
+    </NoSql>
+  </Appenders>
+  <Loggers>
+    <Root level="ALL">
+      <AppenderRef ref="MongoDbAppender" />
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-nosql/pom.xml b/log4j-nosql/pom.xml
deleted file mode 100644
index 8572765..0000000
--- a/log4j-nosql/pom.xml
+++ /dev/null
@@ -1,194 +0,0 @@
-<?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.0-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>log4j-nosql</artifactId>
-  <name>Apache Log4j NoSQL</name>
-  <description>
-    NoSQL appenders for Log4j. These include appenders to databases such as MongoDB and Apache CouchDB.
-  </description>
-  <properties>
-    <log4jParentDir>${basedir}/..</log4jParentDir>
-    <docLabel>NoSQL Documentation</docLabel>
-    <projectDir>/log4j-nosql</projectDir>
-    <module.name>org.apache.logging.log4j.nosql</module.name>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.mongodb</groupId>
-      <artifactId>mongo-java-driver</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.lightcouch</groupId>
-      <artifactId>lightcouch</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>com.datastax.cassandra</groupId>
-      <artifactId>cassandra-driver-core</artifactId>
-      <optional>true</optional>
-    </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>
-  </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/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/AbstractNoSqlConnection.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/AbstractNoSqlConnection.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/AbstractNoSqlConnection.java
deleted file mode 100644
index ac52eba..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/AbstractNoSqlConnection.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.nosql.appender;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Facilitates implementations of {@link NoSqlConnection}.
- *
- * @param <W>
- *            See {@link NoSqlConnection}.
- * @param <T>See
- *            {@link NoSqlConnection}.
- */
-public abstract class AbstractNoSqlConnection<W, T extends NoSqlObject<W>> implements NoSqlConnection<W, T> {
-
-    private final AtomicBoolean closed = new AtomicBoolean(false);
-
-    @Override
-    public void close() {
-        if (this.closed.compareAndSet(false, true)) {
-            closeImpl();
-        }
-    }
-
-    protected abstract void closeImpl();
-
-    @Override
-    public boolean isClosed() {
-        return this.closed.get();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/DefaultNoSqlObject.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/DefaultNoSqlObject.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/DefaultNoSqlObject.java
deleted file mode 100644
index 4437e55..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/DefaultNoSqlObject.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.nosql.appender;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Default implementation of {@link org.apache.logging.log4j.nosql.appender.NoSqlObject}. Most NoSQL Java APIs tend
- * to re-use the Map interface for storage and retrieval of the underlying JSON documents. Therefore, this
- * implementation is provided for convenience.
- */
-public class DefaultNoSqlObject implements NoSqlObject<Map<String, Object>> {
-
-    private final Map<String, Object> map;
-
-    public DefaultNoSqlObject() {
-        this.map = new HashMap<>();
-    }
-
-    @Override
-    public void set(final String field, final Object value) {
-        this.map.put(field, value);
-    }
-
-    @Override
-    public void set(final String field, final NoSqlObject<Map<String, Object>> value) {
-        this.map.put(field, value.unwrap());
-    }
-
-    @Override
-    public void set(final String field, final Object[] values) {
-        this.map.put(field, Arrays.asList(values));
-    }
-
-    @Override
-    public void set(final String field, final NoSqlObject<Map<String, Object>>[] values) {
-        final List<Map<String, Object>> list = new ArrayList<>(values.length);
-        for (final NoSqlObject<Map<String, Object>> value : values) {
-            list.add(value.unwrap());
-        }
-        this.map.put(field, list);
-    }
-
-    @Override
-    public Map<String, Object> unwrap() {
-        return this.map;
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlAppender.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlAppender.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlAppender.java
deleted file mode 100644
index 55ecc61..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlAppender.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.nosql.appender;
-
-import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.Filter;
-import org.apache.logging.log4j.core.appender.AbstractAppender;
-import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
-import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
-import org.apache.logging.log4j.core.config.plugins.PluginElement;
-import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.util.Booleans;
-
-/**
- * This Appender writes logging events to a NoSQL database using a configured NoSQL provider. It requires
- * implementations of {@link NoSqlObject}, {@link NoSqlConnection}, and {@link NoSqlProvider} to "know" how to write
- * events to the chosen NoSQL database.
- * 
- * <p>
- * Two provider implementations are provided:
- * </p>
- * <ul>
- * <li>
- * MongoDB (org.mongodb:mongo-java-driver:3.0.4 or newer must be on the classpath)</li>
- * <li>
- * Apache CouchDB (org.lightcouch:lightcouch:0.0.6 or newer must be on the classpath).</li>
- * </ul>
- * <p>
- * For examples on how to write your own NoSQL provider, see the simple source code for the MongoDB and CouchDB
- * providers.
- * </p>
- * 
- * @see NoSqlObject
- * @see NoSqlConnection
- * @see NoSqlProvider
- */
-@Plugin(name = "NoSql", category = "Core", elementType = Appender.ELEMENT_TYPE, printObject = true)
-public final class NoSqlAppender extends AbstractDatabaseAppender<NoSqlDatabaseManager<?>> {
-    private final String description;
-
-    private NoSqlAppender(final String name, final Filter filter, final boolean ignoreExceptions,
-                          final NoSqlDatabaseManager<?> manager) {
-        super(name, filter, ignoreExceptions, manager);
-        this.description = this.getName() + "{ manager=" + this.getManager() + " }";
-    }
-
-    @Override
-    public String toString() {
-        return this.description;
-    }
-
-    /**
-     * Factory method for creating a NoSQL appender within the plugin manager.
-     *
-     * @param name The name of the appender.
-     * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise
-     *               they are propagated to the caller.
-     * @param filter The filter, if any, to use.
-     * @param bufferSize If an integer greater than 0, this causes the appender to buffer log events and flush whenever
-     *                   the buffer reaches this size.
-     * @param provider The NoSQL provider that provides connections to the chosen NoSQL database.
-     * @return a new NoSQL appender.
-     */
-    @PluginFactory
-    public static NoSqlAppender createAppender(
-            @PluginAttribute("name") final String name,
-            @PluginAttribute("ignoreExceptions") final String ignore,
-            @PluginElement("Filter") final Filter filter,
-            @PluginAttribute("bufferSize") final String bufferSize,
-            @PluginElement("NoSqlProvider") final NoSqlProvider<?> provider) {
-        if (provider == null) {
-            LOGGER.error("NoSQL provider not specified for appender [{}].", name);
-            return null;
-        }
-
-        final int bufferSizeInt = AbstractAppender.parseInt(bufferSize, 0);
-        final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
-
-        final String managerName = "noSqlManager{ description=" + name + ", bufferSize=" + bufferSizeInt
-                + ", provider=" + provider + " }";
-
-        final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager(
-                managerName, bufferSizeInt, provider
-        );
-        if (manager == null) {
-            return null;
-        }
-
-        return new NoSqlAppender(name, filter, ignoreExceptions, manager);
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlConnection.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlConnection.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlConnection.java
deleted file mode 100644
index 8df6eed..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlConnection.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.nosql.appender;
-
-import java.io.Closeable;
-
-/**
- * Represents a connection to the NoSQL database. Serves as a factory for new (empty) objects and an endpoint for
- * inserted objects.
- *
- * @param <T> Specifies which implementation of {@link NoSqlObject} this connection provides.
- * @param <W> Specifies which type of database object is wrapped by the {@link NoSqlObject} implementation provided.
- */
-public interface NoSqlConnection<W, T extends NoSqlObject<W>> extends Closeable {
-    /**
-     * Instantiates and returns a {@link NoSqlObject} instance whose properties can be configured before ultimate
-     * insertion via {@link #insertObject(NoSqlObject)}.
-     *
-     * @return a new object.
-     * @see NoSqlObject
-     */
-    T createObject();
-
-    /**
-     * Creates an array of the specified length typed to match the {@link NoSqlObject} implementation appropriate for
-     * this provider.
-     *
-     * @param length the length of the array to create.
-     * @return a new array.
-     * @see NoSqlObject
-     */
-    T[] createList(int length);
-
-    /**
-     * Inserts the given object into the underlying NoSQL database.
-     *
-     * @param object The object to insert.
-     */
-    void insertObject(NoSqlObject<W> object);
-
-    /**
-     * Closes the underlying connection. This method call should be idempotent. Only the first call should have any
-     * effect; all further calls should be ignored. It's possible the underlying connection is stateless (such as an
-     * HTTP web service), in which case this method would be a no-op. This method should also commit any open
-     * transactions, if applicable and if not already committed.
-     * <p>
-     * If this connection is part of a connection pool, executing this method should commit the transaction and return
-     * the connection to the pool, but it should not actually close the underlying connection.
-     * </p>
-     */
-    @Override
-    void close();
-
-    /**
-     * Indicates whether the underlying connection is closed. If the underlying connection is stateless (such as an
-     * HTTP web service), this method would likely always return true. Essentially, this method should only return
-     * {@code true} if a call to {@link #insertObject(NoSqlObject)} <b>will</b> fail due to the state of this object.
-     *
-     * @return {@code true} if this object is considered closed.
-     */
-    boolean isClosed();
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManager.java
----------------------------------------------------------------------
diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManager.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManager.java
deleted file mode 100644
index e1526fc..0000000
--- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManager.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * 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.nosql.appender;
-
-import org.apache.logging.log4j.Marker;
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.appender.AppenderLoggingException;
-import org.apache.logging.log4j.core.appender.ManagerFactory;
-import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager;
-import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.util.BiConsumer;
-import org.apache.logging.log4j.util.ReadOnlyStringMap;
-
-/**
- * An {@link AbstractDatabaseManager} implementation for all NoSQL databases.
- *
- * @param <W> A type parameter for reassuring the compiler that all operations are using the same {@link NoSqlObject}.
- */
-public final class NoSqlDatabaseManager<W> extends AbstractDatabaseManager {
-    private static final NoSQLDatabaseManagerFactory FACTORY = new NoSQLDatabaseManagerFactory();
-
-    private final NoSqlProvider<NoSqlConnection<W, ? extends NoSqlObject<W>>> provider;
-
-    private NoSqlConnection<W, ? extends NoSqlObject<W>> connection;
-
-    private NoSqlDatabaseManager(final String name, final int bufferSize,
-            final NoSqlProvider<NoSqlConnection<W, ? extends NoSqlObject<W>>> provider) {
-        super(name, bufferSize);
-        this.provider = provider;
-    }
-
-    @Override
-    protected void startupInternal() {
-        // nothing to see here
-    }
-
-    @Override
-    protected boolean shutdownInternal() {
-        // NoSQL doesn't use transactions, so all we need to do here is simply close the client
-        return Closer.closeSilently(this.connection);
-    }
-
-    @Override
-    protected void connectAndStart() {
-        try {
-            this.connection = this.provider.getConnection();
-        } catch (final Exception e) {
-            throw new AppenderLoggingException("Failed to get connection from NoSQL connection provider.", e);
-        }
-    }
-
-    @Override
-    protected void writeInternal(final LogEvent event) {
-        if (!this.isRunning() || this.connection == null || this.connection.isClosed()) {
-            throw new AppenderLoggingException(
-                    "Cannot write logging event; NoSQL manager not connected to the database.");
-        }
-
-        final NoSqlObject<W> entity = this.connection.createObject();
-        entity.set("level", event.getLevel());
-        entity.set("loggerName", event.getLoggerName());
-        entity.set("message", event.getMessage() == null ? null : event.getMessage().getFormattedMessage());
-
-        final StackTraceElement source = event.getSource();
-        if (source == null) {
-            entity.set("source", (Object) null);
-        } else {
-            entity.set("source", this.convertStackTraceElement(source));
-        }
-
-        final Marker marker = event.getMarker();
-        if (marker == null) {
-            entity.set("marker", (Object) null);
-        } else {
-            entity.set("marker", buildMarkerEntity(marker));
-        }
-
-        entity.set("threadId", event.getThreadId());
-        entity.set("threadName", event.getThreadName());
-        entity.set("threadPriority", event.getThreadPriority());
-        entity.set("millis", event.getTimeMillis());
-        entity.set("date", new java.util.Date(event.getTimeMillis()));
-
-        @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
-        Throwable thrown = event.getThrown();
-        if (thrown == null) {
-            entity.set("thrown", (Object) null);
-        } else {
-            final NoSqlObject<W> originalExceptionEntity = this.connection.createObject();
-            NoSqlObject<W> exceptionEntity = originalExceptionEntity;
-            exceptionEntity.set("type", thrown.getClass().getName());
-            exceptionEntity.set("message", thrown.getMessage());
-            exceptionEntity.set("stackTrace", this.convertStackTrace(thrown.getStackTrace()));
-            while (thrown.getCause() != null) {
-                thrown = thrown.getCause();
-                final NoSqlObject<W> causingExceptionEntity = this.connection.createObject();
-                causingExceptionEntity.set("type", thrown.getClass().getName());
-                causingExceptionEntity.set("message", thrown.getMessage());
-                causingExceptionEntity.set("stackTrace", this.convertStackTrace(thrown.getStackTrace()));
-                exceptionEntity.set("cause", causingExceptionEntity);
-                exceptionEntity = causingExceptionEntity;
-            }
-
-            entity.set("thrown", originalExceptionEntity);
-        }
-
-        final ReadOnlyStringMap contextMap = event.getContextData();
-        if (contextMap == null) {
-            entity.set("contextMap", (Object) null);
-        } else {
-            final NoSqlObject<W> contextMapEntity = this.connection.createObject();
-            contextMap.forEach(new BiConsumer<String, String>() {
-                @Override
-                public void accept(final String key, final String val) {
-                    contextMapEntity.set(key, val);
-                }
-            });
-            entity.set("contextMap", contextMapEntity);
-        }
-
-        final ThreadContext.ContextStack contextStack = event.getContextStack();
-        if (contextStack == null) {
-            entity.set("contextStack", (Object) null);
-        } else {
-            entity.set("contextStack", contextStack.asList().toArray());
-        }
-
-        this.connection.insertObject(entity);
-    }
-
-    private NoSqlObject<W> buildMarkerEntity(final Marker marker) {
-        final NoSqlObject<W> entity = this.connection.createObject();
-        entity.set("name", marker.getName());
-
-        final Marker[] parents = marker.getParents();
-        if (parents != null) {
-            @SuppressWarnings("unchecked")
-            final NoSqlObject<W>[] parentEntities = new NoSqlObject[parents.length];
-            for (int i = 0; i < parents.length; i++) {
-                parentEntities[i] = buildMarkerEntity(parents[i]);
-            }
-            entity.set("parents", parentEntities);
-        }
-        return entity;
-    }
-
-    @Override
-    protected boolean commitAndClose() {
-        // all NoSQL drivers auto-commit (since NoSQL doesn't generally use the concept of transactions).
-        // also, all our NoSQL drivers use internal connection pooling and provide clients, not connections.
-        // thus, we should not be closing the client until shutdown as NoSQL is very different from SQL.
-        // see LOG4J2-591 and LOG4J2-676
-    	return true;
-    }
-
-    private NoSqlObject<W>[] convertStackTrace(final StackTraceElement[] stackTrace) {
-        final NoSqlObject<W>[] stackTraceEntities = this.connection.createList(stackTrace.length);
-        for (int i = 0; i < stackTrace.length; i++) {
-            stackTraceEntities[i] = this.convertStackTraceElement(stackTrace[i]);
-        }
-        return stackTraceEntities;
-    }
-
-    private NoSqlObject<W> convertStackTraceElement(final StackTraceElement element) {
-        final NoSqlObject<W> elementEntity = this.connection.createObject();
-        elementEntity.set("className", element.getClassName());
-        elementEntity.set("methodName", element.getMethodName());
-        elementEntity.set("fileName", element.getFileName());
-        elementEntity.set("lineNumber", element.getLineNumber());
-        return elementEntity;
-    }
-
-    /**
-     * Creates a NoSQL manager for use within the {@link NoSqlAppender}, or returns a suitable one if it already exists.
-     *
-     * @param name The name of the manager, which should include connection details and hashed passwords where possible.
-     * @param bufferSize The size of the log event buffer.
-     * @param provider A provider instance which will be used to obtain connections to the chosen NoSQL database.
-     * @return a new or existing NoSQL manager as applicable.
-     */
-    public static NoSqlDatabaseManager<?> getNoSqlDatabaseManager(final String name, final int bufferSize,
-                                                                  final NoSqlProvider<?> provider) {
-        return AbstractDatabaseManager.getManager(name, new FactoryData(bufferSize, provider), FACTORY);
-    }
-
-    /**
-     * Encapsulates data that {@link NoSQLDatabaseManagerFactory} uses to create managers.
-     */
-    private static final class FactoryData extends AbstractDatabaseManager.AbstractFactoryData {
-        private final NoSqlProvider<?> provider;
-
-        protected FactoryData(final int bufferSize, final NoSqlProvider<?> provider) {
-            super(bufferSize);
-            this.provider = provider;
-        }
-    }
-
-    /**
-     * Creates managers.
-     */
-    private static final class NoSQLDatabaseManagerFactory implements
-            ManagerFactory<NoSqlDatabaseManager<?>, FactoryData> {
-        @Override
-        @SuppressWarnings("unchecked")
-        public NoSqlDatabaseManager<?> createManager(final String name, final FactoryData data) {
-            return new NoSqlDatabaseManager(name, data.getBufferSize(), data.provider);
-        }
-    }
-}