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/19 19:47:40 UTC

[1/2] logging-log4j2 git commit: LOG4J2-2076 Rename packages

Repository: logging-log4j2
Updated Branches:
  refs/heads/LOG4J2-2076 98a66a145 -> 44db87d0e


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/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
deleted file mode 100644
index cdae592..0000000
--- a/log4j-couchdb/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.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/44db87d0/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
deleted file mode 100644
index b783f87..0000000
--- a/log4j-couchdb/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/44db87d0/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbConnection.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbConnection.java
new file mode 100644
index 0000000..4ad0671
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbObject.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbObject.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbObject.java
new file mode 100644
index 0000000..541d941
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
new file mode 100644
index 0000000..f7077b3
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/package-info.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/package-info.java
new file mode 100644
index 0000000..f944511
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/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.mongodb;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/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
deleted file mode 100644
index 66e205d..0000000
--- a/log4j-mongodb/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.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/44db87d0/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
deleted file mode 100644
index 8eb6e46..0000000
--- a/log4j-mongodb/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.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/44db87d0/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
deleted file mode 100644
index 5167c3e..0000000
--- a/log4j-mongodb/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.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/44db87d0/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
deleted file mode 100644
index 54a2878..0000000
--- a/log4j-mongodb/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/44db87d0/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbAuthTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbAuthTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbAuthTest.java
new file mode 100644
index 0000000..142a470
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCappedTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCappedTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCappedTest.java
new file mode 100644
index 0000000..d5aa5a9
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbTest.java
new file mode 100644
index 0000000..eab3c1c
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/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.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/44db87d0/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
deleted file mode 100644
index 3641a75..0000000
--- a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/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.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/44db87d0/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
deleted file mode 100644
index a001b4b..0000000
--- a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/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.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/44db87d0/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
deleted file mode 100644
index 59ef951..0000000
--- a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/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.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/44db87d0/src/site/xdoc/manual/appenders.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/appenders.xml
index ae86b54..bdfeddd 100644
--- a/src/site/xdoc/manual/appenders.xml
+++ b/src/site/xdoc/manual/appenders.xml
@@ -380,7 +380,7 @@
     </Cassandra>
   </Appenders>
   <Loggers>
-    <Logger name="org.apache.logging.log4j.nosql.appender.cassandra" level="DEBUG">
+    <Logger name="org.apache.logging.log4j.cassandra" level="DEBUG">
       <AppenderRef ref="Cassandra"/>
     </Logger>
     <Root level="ERROR"/>


[2/2] logging-log4j2 git commit: LOG4J2-2076 Rename packages

Posted by mi...@apache.org.
LOG4J2-2076 Rename packages


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

Branch: refs/heads/LOG4J2-2076
Commit: 44db87d0e921bac3b207f575889618ced5288e5f
Parents: 98a66a1
Author: Mikael Ståldal <mi...@staldal.nu>
Authored: Thu Oct 19 21:47:31 2017 +0200
Committer: Mikael Ståldal <mi...@staldal.nu>
Committed: Thu Oct 19 21:47:31 2017 +0200

----------------------------------------------------------------------
 .../log4j/cassandra/CassandraAppender.java      | 185 ++++++++++
 .../log4j/cassandra/CassandraManager.java       | 218 ++++++++++++
 .../cassandra/ClockTimestampGenerator.java      |  34 ++
 .../logging/log4j/cassandra/package-info.java   |  23 ++
 .../appender/cassandra/CassandraAppender.java   | 185 ----------
 .../appender/cassandra/CassandraManager.java    | 218 ------------
 .../cassandra/ClockTimestampGenerator.java      |  34 --
 .../nosql/appender/cassandra/package-info.java  |  23 --
 .../log4j/cassandra/CassandraAppenderIT.java    |  96 +++++
 .../logging/log4j/cassandra/CassandraRule.java  | 141 ++++++++
 .../appender/cassandra/CassandraAppenderIT.java |  96 -----
 .../nosql/appender/cassandra/CassandraRule.java | 141 --------
 .../test/resources/CassandraAppenderTest.xml    |   2 +-
 .../log4j/couchdb/CouchDbConnection.java        |  69 ++++
 .../logging/log4j/couchdb/CouchDbProvider.java  | 161 +++++++++
 .../logging/log4j/couchdb/package-info.java     |  20 ++
 .../appender/couchdb/CouchDbConnection.java     |  69 ----
 .../nosql/appender/couchdb/CouchDbProvider.java | 161 ---------
 .../nosql/appender/couchdb/package-info.java    |  20 --
 .../log4j/mongodb/MongoDbConnection.java        |  96 +++++
 .../logging/log4j/mongodb/MongoDbObject.java    |  66 ++++
 .../logging/log4j/mongodb/MongoDbProvider.java  | 351 +++++++++++++++++++
 .../logging/log4j/mongodb/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 --
 .../logging/log4j/mongodb/MongoDbAuthTest.java  |  40 +++
 .../log4j/mongodb/MongoDbCappedTest.java        |  40 +++
 .../logging/log4j/mongodb/MongoDbTest.java      |  40 +++
 .../nosql/appender/mongodb/MongoDbAuthTest.java |  40 ---
 .../appender/mongodb/MongoDbCappedTest.java     |  40 ---
 .../nosql/appender/mongodb/MongoDbTest.java     |  40 ---
 src/site/xdoc/manual/appenders.xml              |   2 +-
 34 files changed, 1602 insertions(+), 1602 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
new file mode 100644
index 0000000..7a9ade9
--- /dev/null
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
@@ -0,0 +1,185 @@
+/*
+ * 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.cassandra;
+
+import com.datastax.driver.core.BatchStatement;
+import org.apache.logging.log4j.core.Core;
+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.appender.db.ColumnMapping;
+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.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.core.net.SocketAddress;
+import org.apache.logging.log4j.core.util.Clock;
+
+/**
+ * Appender plugin that uses a Cassandra database.
+ *
+ * @see SocketAddress
+ * @see ColumnMapping
+ */
+@Plugin(name = "Cassandra", category = Core.CATEGORY_NAME, elementType = CassandraAppender.ELEMENT_TYPE, printObject = true)
+public class CassandraAppender extends AbstractDatabaseAppender<CassandraManager> {
+
+    private CassandraAppender(final String name, final Filter filter, final boolean ignoreExceptions,
+                              final CassandraManager manager) {
+        super(name, filter, ignoreExceptions, manager);
+    }
+
+    @PluginBuilderFactory
+    public static <B extends Builder<B>> B newBuilder() {
+        return new Builder<B>().asBuilder();
+    }
+
+    public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
+        implements org.apache.logging.log4j.core.util.Builder<CassandraAppender> {
+
+        /**
+         * List of Cassandra node contact points. Addresses without a port (or port set to 0) will use the default
+         * Cassandra port (9042).
+         */
+        @PluginElement("ContactPoints")
+        @Required(message = "No Cassandra servers provided")
+        private SocketAddress[] contactPoints = new SocketAddress[]{SocketAddress.getLoopback()};
+
+        /**
+         * List of column mappings to convert a LogEvent into a database row.
+         */
+        @PluginElement("Columns")
+        @Required(message = "No Cassandra columns provided")
+        private ColumnMapping[] columns;
+
+        @PluginBuilderAttribute
+        private boolean useTls;
+
+        @PluginBuilderAttribute
+        @Required(message = "No cluster name provided")
+        private String clusterName;
+
+        @PluginBuilderAttribute
+        @Required(message = "No keyspace provided")
+        private String keyspace;
+
+        @PluginBuilderAttribute
+        @Required(message = "No table name provided")
+        private String table;
+
+        @PluginBuilderAttribute
+        private String username;
+
+        @PluginBuilderAttribute(sensitive = true)
+        private String password;
+
+        /**
+         * Override the default TimestampGenerator with one based on the configured {@link Clock}.
+         */
+        @PluginBuilderAttribute
+        private boolean useClockForTimestampGenerator;
+
+        /**
+         * Number of LogEvents to buffer before writing. Can be used with or without batch statements.
+         */
+        @PluginBuilderAttribute
+        private int bufferSize;
+
+        /**
+         * Whether or not to use batch statements when inserting records.
+         */
+        @PluginBuilderAttribute
+        private boolean batched;
+
+        /**
+         * If batch statements are enabled, use this type of batch statement.
+         */
+        @PluginBuilderAttribute
+        private BatchStatement.Type batchType = BatchStatement.Type.LOGGED;
+
+        public B setContactPoints(final SocketAddress... contactPoints) {
+            this.contactPoints = contactPoints;
+            return asBuilder();
+        }
+
+        public B setColumns(final ColumnMapping... columns) {
+            this.columns = columns;
+            return asBuilder();
+        }
+
+        public B setUseTls(final boolean useTls) {
+            this.useTls = useTls;
+            return asBuilder();
+        }
+
+        public B setClusterName(final String clusterName) {
+            this.clusterName = clusterName;
+            return asBuilder();
+        }
+
+        public B setKeyspace(final String keyspace) {
+            this.keyspace = keyspace;
+            return asBuilder();
+        }
+
+        public B setTable(final String table) {
+            this.table = table;
+            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 setUseClockForTimestampGenerator(final boolean useClockForTimestampGenerator) {
+            this.useClockForTimestampGenerator = useClockForTimestampGenerator;
+            return asBuilder();
+        }
+
+        public B setBufferSize(final int bufferSize) {
+            this.bufferSize = bufferSize;
+            return asBuilder();
+        }
+
+        public B setBatched(final boolean batched) {
+            this.batched = batched;
+            return asBuilder();
+        }
+
+        public B setBatchType(final BatchStatement.Type batchType) {
+            this.batchType = batchType;
+            return asBuilder();
+        }
+
+        @Override
+        public CassandraAppender build() {
+            final CassandraManager manager = CassandraManager.getManager(getName(), contactPoints, columns, useTls,
+                clusterName, keyspace, table, username, password, useClockForTimestampGenerator, bufferSize, batched,
+                batchType);
+            return new CassandraAppender(getName(), getFilter(), isIgnoreExceptions(), manager);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraManager.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraManager.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraManager.java
new file mode 100644
index 0000000..5ca82d3
--- /dev/null
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraManager.java
@@ -0,0 +1,218 @@
+/*
+ * 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.cassandra;
+
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.datastax.driver.core.BatchStatement;
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.Session;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.ManagerFactory;
+import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager;
+import org.apache.logging.log4j.core.appender.db.ColumnMapping;
+import org.apache.logging.log4j.core.config.plugins.convert.DateTypeConverter;
+import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
+import org.apache.logging.log4j.core.net.SocketAddress;
+import org.apache.logging.log4j.spi.ThreadContextMap;
+import org.apache.logging.log4j.spi.ThreadContextStack;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+import org.apache.logging.log4j.util.Strings;
+
+/**
+ * Manager for a Cassandra appender instance.
+ */
+public class CassandraManager extends AbstractDatabaseManager {
+
+    private static final int DEFAULT_PORT = 9042;
+
+    private final Cluster cluster;
+    private final String keyspace;
+    private final String insertQueryTemplate;
+    private final List<ColumnMapping> columnMappings;
+    private final BatchStatement batchStatement;
+    // re-usable argument binding array
+    private final Object[] values;
+
+    private Session session;
+    private PreparedStatement preparedStatement;
+
+    private CassandraManager(final String name, final int bufferSize, final Cluster cluster,
+                             final String keyspace, final String insertQueryTemplate,
+                             final List<ColumnMapping> columnMappings, final BatchStatement batchStatement) {
+        super(name, bufferSize);
+        this.cluster = cluster;
+        this.keyspace = keyspace;
+        this.insertQueryTemplate = insertQueryTemplate;
+        this.columnMappings = columnMappings;
+        this.batchStatement = batchStatement;
+        this.values = new Object[columnMappings.size()];
+    }
+
+    @Override
+    protected void startupInternal() throws Exception {
+        session = cluster.connect(keyspace);
+        preparedStatement = session.prepare(insertQueryTemplate);
+    }
+
+    @Override
+    protected boolean shutdownInternal() throws Exception {
+        session.close();
+        cluster.close();
+        return true;
+    }
+
+    @Override
+    protected void connectAndStart() {
+        // a Session automatically manages connections for us
+    }
+
+    @Override
+    protected void writeInternal(final LogEvent event) {
+        for (int i = 0; i < columnMappings.size(); i++) {
+            final ColumnMapping columnMapping = columnMappings.get(i);
+            if (ThreadContextMap.class.isAssignableFrom(columnMapping.getType())
+                || ReadOnlyStringMap.class.isAssignableFrom(columnMapping.getType())) {
+                values[i] = event.getContextData().toMap();
+            } else if (ThreadContextStack.class.isAssignableFrom(columnMapping.getType())) {
+                values[i] = event.getContextStack().asList();
+            } else if (Date.class.isAssignableFrom(columnMapping.getType())) {
+                values[i] = DateTypeConverter.fromMillis(event.getTimeMillis(), columnMapping.getType().asSubclass(Date.class));
+            } else {
+                values[i] = TypeConverters.convert(columnMapping.getLayout().toSerializable(event),
+                    columnMapping.getType(), null);
+            }
+        }
+        final BoundStatement boundStatement = preparedStatement.bind(values);
+        if (batchStatement == null) {
+            session.execute(boundStatement);
+        } else {
+            batchStatement.add(boundStatement);
+        }
+    }
+
+    @Override
+    protected boolean commitAndClose() {
+        if (batchStatement != null) {
+            session.execute(batchStatement);
+        }
+        return true;
+    }
+
+    public static CassandraManager getManager(final String name, final SocketAddress[] contactPoints,
+                                              final ColumnMapping[] columns, final boolean useTls,
+                                              final String clusterName, final String keyspace, final String table,
+                                              final String username, final String password,
+                                              final boolean useClockForTimestampGenerator, final int bufferSize,
+                                              final boolean batched, final BatchStatement.Type batchType) {
+        return getManager(name,
+            new FactoryData(contactPoints, columns, useTls, clusterName, keyspace, table, username, password,
+                useClockForTimestampGenerator, bufferSize, batched, batchType), CassandraManagerFactory.INSTANCE);
+    }
+
+    private static class CassandraManagerFactory implements ManagerFactory<CassandraManager, FactoryData> {
+
+        private static final CassandraManagerFactory INSTANCE = new CassandraManagerFactory();
+
+        @Override
+        public CassandraManager createManager(final String name, final FactoryData data) {
+            final Cluster.Builder builder = Cluster.builder()
+                .addContactPointsWithPorts(data.contactPoints)
+                .withClusterName(data.clusterName);
+            if (data.useTls) {
+                builder.withSSL();
+            }
+            if (Strings.isNotBlank(data.username)) {
+                builder.withCredentials(data.username, data.password);
+            }
+            if (data.useClockForTimestampGenerator) {
+                builder.withTimestampGenerator(new ClockTimestampGenerator());
+            }
+            final Cluster cluster = builder.build();
+
+            final StringBuilder sb = new StringBuilder("INSERT INTO ").append(data.table).append(" (");
+            for (final ColumnMapping column : data.columns) {
+                sb.append(column.getName()).append(',');
+            }
+            sb.setCharAt(sb.length() - 1, ')');
+            sb.append(" VALUES (");
+            final List<ColumnMapping> columnMappings = new ArrayList<>(data.columns.length);
+            for (final ColumnMapping column : data.columns) {
+                if (Strings.isNotEmpty(column.getLiteralValue())) {
+                    sb.append(column.getLiteralValue());
+                } else {
+                    sb.append('?');
+                    columnMappings.add(column);
+                }
+                sb.append(',');
+            }
+            sb.setCharAt(sb.length() - 1, ')');
+            final String insertQueryTemplate = sb.toString();
+            LOGGER.debug("Using CQL for appender {}: {}", name, insertQueryTemplate);
+            return new CassandraManager(name, data.getBufferSize(), cluster, data.keyspace, insertQueryTemplate,
+                columnMappings, data.batched ? new BatchStatement(data.batchType) : null);
+        }
+    }
+
+    private static class FactoryData extends AbstractFactoryData {
+        private final InetSocketAddress[] contactPoints;
+        private final ColumnMapping[] columns;
+        private final boolean useTls;
+        private final String clusterName;
+        private final String keyspace;
+        private final String table;
+        private final String username;
+        private final String password;
+        private final boolean useClockForTimestampGenerator;
+        private final boolean batched;
+        private final BatchStatement.Type batchType;
+
+        private FactoryData(final SocketAddress[] contactPoints, final ColumnMapping[] columns, final boolean useTls,
+                            final String clusterName, final String keyspace, final String table, final String username,
+                            final String password, final boolean useClockForTimestampGenerator, final int bufferSize,
+                            final boolean batched, final BatchStatement.Type batchType) {
+            super(bufferSize);
+            this.contactPoints = convertAndAddDefaultPorts(contactPoints);
+            this.columns = columns;
+            this.useTls = useTls;
+            this.clusterName = clusterName;
+            this.keyspace = keyspace;
+            this.table = table;
+            this.username = username;
+            this.password = password;
+            this.useClockForTimestampGenerator = useClockForTimestampGenerator;
+            this.batched = batched;
+            this.batchType = batchType;
+        }
+
+        private static InetSocketAddress[] convertAndAddDefaultPorts(final SocketAddress... socketAddresses) {
+            final InetSocketAddress[] inetSocketAddresses = new InetSocketAddress[socketAddresses.length];
+            for (int i = 0; i < inetSocketAddresses.length; i++) {
+                final SocketAddress socketAddress = socketAddresses[i];
+                inetSocketAddresses[i] = socketAddress.getPort() == 0
+                    ? new InetSocketAddress(socketAddress.getAddress(), DEFAULT_PORT)
+                    : socketAddress.getSocketAddress();
+            }
+            return inetSocketAddresses;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/ClockTimestampGenerator.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/ClockTimestampGenerator.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/ClockTimestampGenerator.java
new file mode 100644
index 0000000..1c7328b
--- /dev/null
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/ClockTimestampGenerator.java
@@ -0,0 +1,34 @@
+/*
+ * 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.cassandra;
+
+import com.datastax.driver.core.TimestampGenerator;
+import org.apache.logging.log4j.core.util.Clock;
+import org.apache.logging.log4j.core.util.ClockFactory;
+
+/**
+ * A {@link TimestampGenerator} implementation using the configured {@link Clock}.
+ */
+public class ClockTimestampGenerator implements TimestampGenerator {
+
+    private final Clock clock = ClockFactory.getClock();
+
+    @Override
+    public long next() {
+        return clock.currentTimeMillis();
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/package-info.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/package-info.java
new file mode 100644
index 0000000..0336dd0
--- /dev/null
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+/**
+ * Log4j appender plugin and supporting classes for Apache Cassandra.
+ *
+ * @see <a href="https://logging.apache.org/log4j/2.x/manual/appenders.html#CassandraAppender">Cassandra Appender manual</a>
+ * @since 2.8
+ */
+package org.apache.logging.log4j.cassandra;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppender.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppender.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppender.java
deleted file mode 100644
index fb344c2..0000000
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppender.java
+++ /dev/null
@@ -1,185 +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.cassandra;
-
-import com.datastax.driver.core.BatchStatement;
-import org.apache.logging.log4j.core.Core;
-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.appender.db.ColumnMapping;
-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.PluginElement;
-import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
-import org.apache.logging.log4j.core.net.SocketAddress;
-import org.apache.logging.log4j.core.util.Clock;
-
-/**
- * Appender plugin that uses a Cassandra database.
- *
- * @see SocketAddress
- * @see ColumnMapping
- */
-@Plugin(name = "Cassandra", category = Core.CATEGORY_NAME, elementType = CassandraAppender.ELEMENT_TYPE, printObject = true)
-public class CassandraAppender extends AbstractDatabaseAppender<CassandraManager> {
-
-    private CassandraAppender(final String name, final Filter filter, final boolean ignoreExceptions,
-                              final CassandraManager manager) {
-        super(name, filter, ignoreExceptions, manager);
-    }
-
-    @PluginBuilderFactory
-    public static <B extends Builder<B>> B newBuilder() {
-        return new Builder<B>().asBuilder();
-    }
-
-    public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
-        implements org.apache.logging.log4j.core.util.Builder<CassandraAppender> {
-
-        /**
-         * List of Cassandra node contact points. Addresses without a port (or port set to 0) will use the default
-         * Cassandra port (9042).
-         */
-        @PluginElement("ContactPoints")
-        @Required(message = "No Cassandra servers provided")
-        private SocketAddress[] contactPoints = new SocketAddress[]{SocketAddress.getLoopback()};
-
-        /**
-         * List of column mappings to convert a LogEvent into a database row.
-         */
-        @PluginElement("Columns")
-        @Required(message = "No Cassandra columns provided")
-        private ColumnMapping[] columns;
-
-        @PluginBuilderAttribute
-        private boolean useTls;
-
-        @PluginBuilderAttribute
-        @Required(message = "No cluster name provided")
-        private String clusterName;
-
-        @PluginBuilderAttribute
-        @Required(message = "No keyspace provided")
-        private String keyspace;
-
-        @PluginBuilderAttribute
-        @Required(message = "No table name provided")
-        private String table;
-
-        @PluginBuilderAttribute
-        private String username;
-
-        @PluginBuilderAttribute(sensitive = true)
-        private String password;
-
-        /**
-         * Override the default TimestampGenerator with one based on the configured {@link Clock}.
-         */
-        @PluginBuilderAttribute
-        private boolean useClockForTimestampGenerator;
-
-        /**
-         * Number of LogEvents to buffer before writing. Can be used with or without batch statements.
-         */
-        @PluginBuilderAttribute
-        private int bufferSize;
-
-        /**
-         * Whether or not to use batch statements when inserting records.
-         */
-        @PluginBuilderAttribute
-        private boolean batched;
-
-        /**
-         * If batch statements are enabled, use this type of batch statement.
-         */
-        @PluginBuilderAttribute
-        private BatchStatement.Type batchType = BatchStatement.Type.LOGGED;
-
-        public B setContactPoints(final SocketAddress... contactPoints) {
-            this.contactPoints = contactPoints;
-            return asBuilder();
-        }
-
-        public B setColumns(final ColumnMapping... columns) {
-            this.columns = columns;
-            return asBuilder();
-        }
-
-        public B setUseTls(final boolean useTls) {
-            this.useTls = useTls;
-            return asBuilder();
-        }
-
-        public B setClusterName(final String clusterName) {
-            this.clusterName = clusterName;
-            return asBuilder();
-        }
-
-        public B setKeyspace(final String keyspace) {
-            this.keyspace = keyspace;
-            return asBuilder();
-        }
-
-        public B setTable(final String table) {
-            this.table = table;
-            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 setUseClockForTimestampGenerator(final boolean useClockForTimestampGenerator) {
-            this.useClockForTimestampGenerator = useClockForTimestampGenerator;
-            return asBuilder();
-        }
-
-        public B setBufferSize(final int bufferSize) {
-            this.bufferSize = bufferSize;
-            return asBuilder();
-        }
-
-        public B setBatched(final boolean batched) {
-            this.batched = batched;
-            return asBuilder();
-        }
-
-        public B setBatchType(final BatchStatement.Type batchType) {
-            this.batchType = batchType;
-            return asBuilder();
-        }
-
-        @Override
-        public CassandraAppender build() {
-            final CassandraManager manager = CassandraManager.getManager(getName(), contactPoints, columns, useTls,
-                clusterName, keyspace, table, username, password, useClockForTimestampGenerator, bufferSize, batched,
-                batchType);
-            return new CassandraAppender(getName(), getFilter(), isIgnoreExceptions(), manager);
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraManager.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraManager.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraManager.java
deleted file mode 100644
index cfbc528..0000000
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraManager.java
+++ /dev/null
@@ -1,218 +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.cassandra;
-
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import com.datastax.driver.core.BatchStatement;
-import com.datastax.driver.core.BoundStatement;
-import com.datastax.driver.core.Cluster;
-import com.datastax.driver.core.PreparedStatement;
-import com.datastax.driver.core.Session;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.appender.ManagerFactory;
-import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager;
-import org.apache.logging.log4j.core.appender.db.ColumnMapping;
-import org.apache.logging.log4j.core.config.plugins.convert.DateTypeConverter;
-import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
-import org.apache.logging.log4j.core.net.SocketAddress;
-import org.apache.logging.log4j.spi.ThreadContextMap;
-import org.apache.logging.log4j.spi.ThreadContextStack;
-import org.apache.logging.log4j.util.ReadOnlyStringMap;
-import org.apache.logging.log4j.util.Strings;
-
-/**
- * Manager for a Cassandra appender instance.
- */
-public class CassandraManager extends AbstractDatabaseManager {
-
-    private static final int DEFAULT_PORT = 9042;
-
-    private final Cluster cluster;
-    private final String keyspace;
-    private final String insertQueryTemplate;
-    private final List<ColumnMapping> columnMappings;
-    private final BatchStatement batchStatement;
-    // re-usable argument binding array
-    private final Object[] values;
-
-    private Session session;
-    private PreparedStatement preparedStatement;
-
-    private CassandraManager(final String name, final int bufferSize, final Cluster cluster,
-                             final String keyspace, final String insertQueryTemplate,
-                             final List<ColumnMapping> columnMappings, final BatchStatement batchStatement) {
-        super(name, bufferSize);
-        this.cluster = cluster;
-        this.keyspace = keyspace;
-        this.insertQueryTemplate = insertQueryTemplate;
-        this.columnMappings = columnMappings;
-        this.batchStatement = batchStatement;
-        this.values = new Object[columnMappings.size()];
-    }
-
-    @Override
-    protected void startupInternal() throws Exception {
-        session = cluster.connect(keyspace);
-        preparedStatement = session.prepare(insertQueryTemplate);
-    }
-
-    @Override
-    protected boolean shutdownInternal() throws Exception {
-        session.close();
-        cluster.close();
-        return true;
-    }
-
-    @Override
-    protected void connectAndStart() {
-        // a Session automatically manages connections for us
-    }
-
-    @Override
-    protected void writeInternal(final LogEvent event) {
-        for (int i = 0; i < columnMappings.size(); i++) {
-            final ColumnMapping columnMapping = columnMappings.get(i);
-            if (ThreadContextMap.class.isAssignableFrom(columnMapping.getType())
-                || ReadOnlyStringMap.class.isAssignableFrom(columnMapping.getType())) {
-                values[i] = event.getContextData().toMap();
-            } else if (ThreadContextStack.class.isAssignableFrom(columnMapping.getType())) {
-                values[i] = event.getContextStack().asList();
-            } else if (Date.class.isAssignableFrom(columnMapping.getType())) {
-                values[i] = DateTypeConverter.fromMillis(event.getTimeMillis(), columnMapping.getType().asSubclass(Date.class));
-            } else {
-                values[i] = TypeConverters.convert(columnMapping.getLayout().toSerializable(event),
-                    columnMapping.getType(), null);
-            }
-        }
-        final BoundStatement boundStatement = preparedStatement.bind(values);
-        if (batchStatement == null) {
-            session.execute(boundStatement);
-        } else {
-            batchStatement.add(boundStatement);
-        }
-    }
-
-    @Override
-    protected boolean commitAndClose() {
-        if (batchStatement != null) {
-            session.execute(batchStatement);
-        }
-        return true;
-    }
-
-    public static CassandraManager getManager(final String name, final SocketAddress[] contactPoints,
-                                              final ColumnMapping[] columns, final boolean useTls,
-                                              final String clusterName, final String keyspace, final String table,
-                                              final String username, final String password,
-                                              final boolean useClockForTimestampGenerator, final int bufferSize,
-                                              final boolean batched, final BatchStatement.Type batchType) {
-        return getManager(name,
-            new FactoryData(contactPoints, columns, useTls, clusterName, keyspace, table, username, password,
-                useClockForTimestampGenerator, bufferSize, batched, batchType), CassandraManagerFactory.INSTANCE);
-    }
-
-    private static class CassandraManagerFactory implements ManagerFactory<CassandraManager, FactoryData> {
-
-        private static final CassandraManagerFactory INSTANCE = new CassandraManagerFactory();
-
-        @Override
-        public CassandraManager createManager(final String name, final FactoryData data) {
-            final Cluster.Builder builder = Cluster.builder()
-                .addContactPointsWithPorts(data.contactPoints)
-                .withClusterName(data.clusterName);
-            if (data.useTls) {
-                builder.withSSL();
-            }
-            if (Strings.isNotBlank(data.username)) {
-                builder.withCredentials(data.username, data.password);
-            }
-            if (data.useClockForTimestampGenerator) {
-                builder.withTimestampGenerator(new ClockTimestampGenerator());
-            }
-            final Cluster cluster = builder.build();
-
-            final StringBuilder sb = new StringBuilder("INSERT INTO ").append(data.table).append(" (");
-            for (final ColumnMapping column : data.columns) {
-                sb.append(column.getName()).append(',');
-            }
-            sb.setCharAt(sb.length() - 1, ')');
-            sb.append(" VALUES (");
-            final List<ColumnMapping> columnMappings = new ArrayList<>(data.columns.length);
-            for (final ColumnMapping column : data.columns) {
-                if (Strings.isNotEmpty(column.getLiteralValue())) {
-                    sb.append(column.getLiteralValue());
-                } else {
-                    sb.append('?');
-                    columnMappings.add(column);
-                }
-                sb.append(',');
-            }
-            sb.setCharAt(sb.length() - 1, ')');
-            final String insertQueryTemplate = sb.toString();
-            LOGGER.debug("Using CQL for appender {}: {}", name, insertQueryTemplate);
-            return new CassandraManager(name, data.getBufferSize(), cluster, data.keyspace, insertQueryTemplate,
-                columnMappings, data.batched ? new BatchStatement(data.batchType) : null);
-        }
-    }
-
-    private static class FactoryData extends AbstractFactoryData {
-        private final InetSocketAddress[] contactPoints;
-        private final ColumnMapping[] columns;
-        private final boolean useTls;
-        private final String clusterName;
-        private final String keyspace;
-        private final String table;
-        private final String username;
-        private final String password;
-        private final boolean useClockForTimestampGenerator;
-        private final boolean batched;
-        private final BatchStatement.Type batchType;
-
-        private FactoryData(final SocketAddress[] contactPoints, final ColumnMapping[] columns, final boolean useTls,
-                            final String clusterName, final String keyspace, final String table, final String username,
-                            final String password, final boolean useClockForTimestampGenerator, final int bufferSize,
-                            final boolean batched, final BatchStatement.Type batchType) {
-            super(bufferSize);
-            this.contactPoints = convertAndAddDefaultPorts(contactPoints);
-            this.columns = columns;
-            this.useTls = useTls;
-            this.clusterName = clusterName;
-            this.keyspace = keyspace;
-            this.table = table;
-            this.username = username;
-            this.password = password;
-            this.useClockForTimestampGenerator = useClockForTimestampGenerator;
-            this.batched = batched;
-            this.batchType = batchType;
-        }
-
-        private static InetSocketAddress[] convertAndAddDefaultPorts(final SocketAddress... socketAddresses) {
-            final InetSocketAddress[] inetSocketAddresses = new InetSocketAddress[socketAddresses.length];
-            for (int i = 0; i < inetSocketAddresses.length; i++) {
-                final SocketAddress socketAddress = socketAddresses[i];
-                inetSocketAddresses[i] = socketAddress.getPort() == 0
-                    ? new InetSocketAddress(socketAddress.getAddress(), DEFAULT_PORT)
-                    : socketAddress.getSocketAddress();
-            }
-            return inetSocketAddresses;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/ClockTimestampGenerator.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/ClockTimestampGenerator.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/ClockTimestampGenerator.java
deleted file mode 100644
index 06758dd..0000000
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/ClockTimestampGenerator.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.
- */
-package org.apache.logging.log4j.nosql.appender.cassandra;
-
-import com.datastax.driver.core.TimestampGenerator;
-import org.apache.logging.log4j.core.util.Clock;
-import org.apache.logging.log4j.core.util.ClockFactory;
-
-/**
- * A {@link TimestampGenerator} implementation using the configured {@link Clock}.
- */
-public class ClockTimestampGenerator implements TimestampGenerator {
-
-    private final Clock clock = ClockFactory.getClock();
-
-    @Override
-    public long next() {
-        return clock.currentTimeMillis();
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/package-info.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/package-info.java
deleted file mode 100644
index 79107c9..0000000
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-/**
- * Log4j appender plugin and supporting classes for Apache Cassandra.
- *
- * @see <a href="https://logging.apache.org/log4j/2.x/manual/appenders.html#CassandraAppender">Cassandra Appender manual</a>
- * @since 2.8
- */
-package org.apache.logging.log4j.nosql.appender.cassandra;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
new file mode 100644
index 0000000..9cd0794
--- /dev/null
+++ b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.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.cassandra;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.RuleChain;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration test for CassandraAppender.
+ */
+@Category(Appenders.Cassandra.class)
+public class CassandraAppenderIT {
+
+    private static final String DDL = "CREATE TABLE logs (" +
+        "id timeuuid PRIMARY KEY," +
+        "timeid timeuuid," +
+        "message text," +
+        "level text," +
+        "marker text," +
+        "logger text," +
+        "timestamp timestamp," +
+        "mdc map<text,text>," +
+        "ndc list<text>" +
+        ")";
+
+    private static final LoggerContextRule CTX = new LoggerContextRule("CassandraAppenderTest.xml");
+    private static final CassandraRule CASSANDRA = new CassandraRule("test", DDL);
+
+    @ClassRule
+    public static RuleChain rules = RuleChain.outerRule(CASSANDRA).around(CTX);
+
+    @Test
+    public void appendManyEvents() throws Exception {
+        final Logger logger = CTX.getLogger();
+        ThreadContext.put("test", "mdc");
+        ThreadContext.push("ndc");
+        for (int i = 0; i < 20; i++) {
+            logger.info(MarkerManager.getMarker("MARKER"), "Test log message");
+        }
+        ThreadContext.clearAll();
+
+        TimeUnit.SECONDS.sleep(3);
+
+        int i = 0;
+        try (final Session session = CASSANDRA.connect()) {
+            for (final Row row : session.execute("SELECT * FROM logs")) {
+                assertNotNull(row.get("id", UUID.class));
+                assertNotNull(row.get("timeid", UUID.class));
+                assertNotNull(row.get("timestamp", Date.class));
+                assertEquals("Test log message", row.getString("message"));
+                assertEquals("MARKER", row.getString("marker"));
+                assertEquals("INFO", row.getString("level"));
+                assertEquals(getClass().getName(), row.getString("logger"));
+                final Map<String, String> mdc = row.getMap("mdc", String.class, String.class);
+                assertEquals(1, mdc.size());
+                assertEquals("mdc", mdc.get("test"));
+                final List<String> ndc = row.getList("ndc", String.class);
+                assertEquals(1, ndc.size());
+                assertEquals("ndc", ndc.get(0));
+                ++i;
+            }
+        }
+        assertEquals(20, i);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java
new file mode 100644
index 0000000..2939d07
--- /dev/null
+++ b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java
@@ -0,0 +1,141 @@
+/*
+ * 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.cassandra;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.Permission;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadFactory;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+import org.apache.cassandra.service.CassandraDaemon;
+import org.apache.logging.log4j.LoggingException;
+import org.apache.logging.log4j.core.util.Cancellable;
+import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.core.util.Log4jThreadFactory;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.junit.rules.ExternalResource;
+
+/**
+ * JUnit rule to set up and tear down a Cassandra database instance.
+ */
+public class CassandraRule extends ExternalResource {
+
+    private static final ThreadFactory THREAD_FACTORY = Log4jThreadFactory.createThreadFactory("Cassandra");
+
+    private final CountDownLatch latch = new CountDownLatch(1);
+    private final Cancellable embeddedCassandra = new EmbeddedCassandra(latch);
+    private final String keyspace;
+    private final String tableDdl;
+    private Cluster cluster;
+
+    public CassandraRule(final String keyspace, final String tableDdl) {
+        this.keyspace = keyspace;
+        this.tableDdl = tableDdl;
+    }
+
+    public Cluster getCluster() {
+        return cluster;
+    }
+
+    public Session connect() {
+        return cluster.connect(keyspace);
+    }
+
+    @Override
+    protected void before() throws Throwable {
+        final Path root = Files.createTempDirectory("cassandra");
+        Files.createDirectories(root.resolve("data"));
+        final Path config = root.resolve("cassandra.yml");
+        Files.copy(getClass().getResourceAsStream("/cassandra.yaml"), config);
+        System.setProperty("cassandra.config", "file:" + config.toString());
+        System.setProperty("cassandra.storagedir", root.toString());
+        System.setProperty("cassandra-foreground", "true"); // prevents Cassandra from closing stdout/stderr
+        THREAD_FACTORY.newThread(embeddedCassandra).start();
+        latch.await();
+        cluster = Cluster.builder().addContactPoints(InetAddress.getLoopbackAddress()).build();
+        try (final Session session = cluster.connect()) {
+            session.execute("CREATE KEYSPACE " + keyspace + " WITH REPLICATION = " +
+                "{ 'class': 'SimpleStrategy', 'replication_factor': 2 };");
+        }
+        try (final Session session = connect()) {
+            session.execute(tableDdl);
+        }
+    }
+
+    @Override
+    protected void after() {
+        Closer.closeSilently(cluster);
+        embeddedCassandra.cancel();
+    }
+
+    private static class EmbeddedCassandra implements Cancellable {
+
+        private final CassandraDaemon daemon = new CassandraDaemon();
+        private final CountDownLatch latch;
+
+        private EmbeddedCassandra(final CountDownLatch latch) {
+            this.latch = latch;
+        }
+
+        @Override
+        public void cancel() {
+            // LOG4J2-1850 Cassandra on Windows calls System.exit in the daemon stop method
+            if (PropertiesUtil.getProperties().isOsWindows()) {
+                cancelOnWindows();
+            } else {
+                daemon.stop();
+            }
+        }
+
+        private void cancelOnWindows() {
+            final SecurityManager currentSecurityManager = System.getSecurityManager();
+            try {
+                final SecurityManager securityManager = new SecurityManager() {
+                    @Override
+                    public void checkPermission(final Permission permission) {
+                        final String permissionName = permission.getName();
+                        if (permissionName != null && permissionName.startsWith("exitVM")) {
+                            throw new SecurityException("test");
+                        }
+                    }
+                };
+                System.setSecurityManager(securityManager);
+                daemon.stop();
+            } catch (final SecurityException ex) {
+                // ignore
+            } finally {
+                System.setSecurityManager(currentSecurityManager);
+            }
+        }
+
+        @Override
+        public void run() {
+            try {
+                daemon.init(null);
+            } catch (final IOException e) {
+                throw new LoggingException("Cannot initialize embedded Cassandra instance", e);
+            }
+            daemon.start();
+            latch.countDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppenderIT.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppenderIT.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppenderIT.java
deleted file mode 100644
index caf72d5..0000000
--- a/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppenderIT.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.cassandra;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import com.datastax.driver.core.Row;
-import com.datastax.driver.core.Session;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
-
-import static org.junit.Assert.*;
-
-/**
- * Integration test for CassandraAppender.
- */
-@Category(Appenders.Cassandra.class)
-public class CassandraAppenderIT {
-
-    private static final String DDL = "CREATE TABLE logs (" +
-        "id timeuuid PRIMARY KEY," +
-        "timeid timeuuid," +
-        "message text," +
-        "level text," +
-        "marker text," +
-        "logger text," +
-        "timestamp timestamp," +
-        "mdc map<text,text>," +
-        "ndc list<text>" +
-        ")";
-
-    private static final LoggerContextRule CTX = new LoggerContextRule("CassandraAppenderTest.xml");
-    private static final CassandraRule CASSANDRA = new CassandraRule("test", DDL);
-
-    @ClassRule
-    public static RuleChain rules = RuleChain.outerRule(CASSANDRA).around(CTX);
-
-    @Test
-    public void appendManyEvents() throws Exception {
-        final Logger logger = CTX.getLogger();
-        ThreadContext.put("test", "mdc");
-        ThreadContext.push("ndc");
-        for (int i = 0; i < 20; i++) {
-            logger.info(MarkerManager.getMarker("MARKER"), "Test log message");
-        }
-        ThreadContext.clearAll();
-
-        TimeUnit.SECONDS.sleep(3);
-
-        int i = 0;
-        try (final Session session = CASSANDRA.connect()) {
-            for (final Row row : session.execute("SELECT * FROM logs")) {
-                assertNotNull(row.get("id", UUID.class));
-                assertNotNull(row.get("timeid", UUID.class));
-                assertNotNull(row.get("timestamp", Date.class));
-                assertEquals("Test log message", row.getString("message"));
-                assertEquals("MARKER", row.getString("marker"));
-                assertEquals("INFO", row.getString("level"));
-                assertEquals(getClass().getName(), row.getString("logger"));
-                final Map<String, String> mdc = row.getMap("mdc", String.class, String.class);
-                assertEquals(1, mdc.size());
-                assertEquals("mdc", mdc.get("test"));
-                final List<String> ndc = row.getList("ndc", String.class);
-                assertEquals(1, ndc.size());
-                assertEquals("ndc", ndc.get(0));
-                ++i;
-            }
-        }
-        assertEquals(20, i);
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraRule.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraRule.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraRule.java
deleted file mode 100644
index 36e2672..0000000
--- a/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraRule.java
+++ /dev/null
@@ -1,141 +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.cassandra;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.Permission;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ThreadFactory;
-
-import com.datastax.driver.core.Cluster;
-import com.datastax.driver.core.Session;
-import org.apache.cassandra.service.CassandraDaemon;
-import org.apache.logging.log4j.LoggingException;
-import org.apache.logging.log4j.core.util.Cancellable;
-import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.core.util.Log4jThreadFactory;
-import org.apache.logging.log4j.util.PropertiesUtil;
-import org.junit.rules.ExternalResource;
-
-/**
- * JUnit rule to set up and tear down a Cassandra database instance.
- */
-public class CassandraRule extends ExternalResource {
-
-    private static final ThreadFactory THREAD_FACTORY = Log4jThreadFactory.createThreadFactory("Cassandra");
-
-    private final CountDownLatch latch = new CountDownLatch(1);
-    private final Cancellable embeddedCassandra = new EmbeddedCassandra(latch);
-    private final String keyspace;
-    private final String tableDdl;
-    private Cluster cluster;
-
-    public CassandraRule(final String keyspace, final String tableDdl) {
-        this.keyspace = keyspace;
-        this.tableDdl = tableDdl;
-    }
-
-    public Cluster getCluster() {
-        return cluster;
-    }
-
-    public Session connect() {
-        return cluster.connect(keyspace);
-    }
-
-    @Override
-    protected void before() throws Throwable {
-        final Path root = Files.createTempDirectory("cassandra");
-        Files.createDirectories(root.resolve("data"));
-        final Path config = root.resolve("cassandra.yml");
-        Files.copy(getClass().getResourceAsStream("/cassandra.yaml"), config);
-        System.setProperty("cassandra.config", "file:" + config.toString());
-        System.setProperty("cassandra.storagedir", root.toString());
-        System.setProperty("cassandra-foreground", "true"); // prevents Cassandra from closing stdout/stderr
-        THREAD_FACTORY.newThread(embeddedCassandra).start();
-        latch.await();
-        cluster = Cluster.builder().addContactPoints(InetAddress.getLoopbackAddress()).build();
-        try (final Session session = cluster.connect()) {
-            session.execute("CREATE KEYSPACE " + keyspace + " WITH REPLICATION = " +
-                "{ 'class': 'SimpleStrategy', 'replication_factor': 2 };");
-        }
-        try (final Session session = connect()) {
-            session.execute(tableDdl);
-        }
-    }
-
-    @Override
-    protected void after() {
-        Closer.closeSilently(cluster);
-        embeddedCassandra.cancel();
-    }
-
-    private static class EmbeddedCassandra implements Cancellable {
-
-        private final CassandraDaemon daemon = new CassandraDaemon();
-        private final CountDownLatch latch;
-
-        private EmbeddedCassandra(final CountDownLatch latch) {
-            this.latch = latch;
-        }
-
-        @Override
-        public void cancel() {
-            // LOG4J2-1850 Cassandra on Windows calls System.exit in the daemon stop method
-            if (PropertiesUtil.getProperties().isOsWindows()) {
-                cancelOnWindows();
-            } else {
-                daemon.stop();
-            }
-        }
-
-        private void cancelOnWindows() {
-            final SecurityManager currentSecurityManager = System.getSecurityManager();
-            try {
-                final SecurityManager securityManager = new SecurityManager() {
-                    @Override
-                    public void checkPermission(final Permission permission) {
-                        final String permissionName = permission.getName();
-                        if (permissionName != null && permissionName.startsWith("exitVM")) {
-                            throw new SecurityException("test");
-                        }
-                    }
-                };
-                System.setSecurityManager(securityManager);
-                daemon.stop();
-            } catch (final SecurityException ex) {
-                // ignore
-            } finally {
-                System.setSecurityManager(currentSecurityManager);
-            }
-        }
-
-        @Override
-        public void run() {
-            try {
-                daemon.init(null);
-            } catch (final IOException e) {
-                throw new LoggingException("Cannot initialize embedded Cassandra instance", e);
-            }
-            daemon.start();
-            latch.countDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml b/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml
index b3956d1..e1f37e9 100644
--- a/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml
+++ b/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml
@@ -32,7 +32,7 @@
     </Cassandra>
   </Appenders>
   <Loggers>
-    <Logger name="org.apache.logging.log4j.nosql.appender.cassandra" level="DEBUG">
+    <Logger name="org.apache.logging.log4j.cassandra" level="DEBUG">
       <AppenderRef ref="Cassandra"/>
     </Logger>
     <Root level="ERROR"/>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbConnection.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbConnection.java
new file mode 100644
index 0000000..822f4a2
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/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.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/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbProvider.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbProvider.java
new file mode 100644
index 0000000..2b233a8
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/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.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/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/package-info.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/package-info.java
new file mode 100644
index 0000000..9fc2513
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/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.couchdb;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/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
deleted file mode 100644
index 2c3248d..0000000
--- a/log4j-couchdb/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.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();
-    }
-
-}