diff --git a/log4j-core/.classpath b/log4j-core/.classpath
new file mode 100644
index 0000000..4d455a3
--- /dev/null
+++ b/log4j-core/.classpath
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/log4j-core/.gitignore b/log4j-core/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/log4j-core/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/log4j-core/.project b/log4j-core/.project
new file mode 100644
index 0000000..ac362ee
--- /dev/null
+++ b/log4j-core/.project
@@ -0,0 +1,37 @@
+
+
+ log4j-core
+
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.wst.common.project.facet.core.nature
+
+
diff --git a/log4j-core/.settings/org.eclipse.core.resources.prefs b/log4j-core/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..04cfa2c
--- /dev/null
+++ b/log4j-core/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
+encoding/=UTF-8
diff --git a/log4j-core/.settings/org.eclipse.jdt.core.prefs b/log4j-core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..62a317c
--- /dev/null
+++ b/log4j-core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/log4j-core/.settings/org.eclipse.m2e.core.prefs b/log4j-core/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..14b697b
--- /dev/null
+++ b/log4j-core/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/log4j-core/.settings/org.eclipse.pde.core.prefs b/log4j-core/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..394603c
--- /dev/null
+++ b/log4j-core/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,2 @@
+BUNDLE_ROOT_PATH=target/classes
+eclipse.preferences.version=1
diff --git a/log4j-core/.settings/org.eclipse.wst.common.component b/log4j-core/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..296886c
--- /dev/null
+++ b/log4j-core/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/log4j-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/log4j-core/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000..3471497
--- /dev/null
+++ b/log4j-core/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index d077e2f..5da5661 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -114,6 +114,19 @@
compile
true
+
+
+ org.apache.solr
+ solr-core
+
+ 4.7.2
+
+
+ jdk.tools
+ jdk.tools
+
+
+
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrConnection.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrConnection.java
new file mode 100644
index 0000000..cffcd4c
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrConnection.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender.db.nosql.solr;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.core.appender.AppenderLoggingException;
+import org.apache.logging.log4j.core.appender.db.nosql.NoSQLConnection;
+import org.apache.logging.log4j.core.appender.db.nosql.NoSQLObject;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.response.UpdateResponse;
+import org.apache.solr.common.SolrInputDocument;
+
+/**
+ * The Apache Solr implementation of {@link NoSQLConnection}.
+ * @author Markus Klose
+ */
+public final class SolrConnection implements NoSQLConnection {
+ // solr server instance to log to
+ private final SolrServer solrServer;
+ // amount of time before commit is done
+ private int commitWithinMs;
+
+ /**
+ * default constructor.
+ *
+ * @param solrServer
+ * solr server instance to log to
+ * @param commitWithinMs
+ * amount of time before commit is done
+ */
+ public SolrConnection(final SolrServer solrServer, int commitWithinMs) {
+ this.solrServer = solrServer;
+ this.commitWithinMs = commitWithinMs;
+ }
+
+ @Override
+ public SolrObject createObject() {
+ return new SolrObject();
+ }
+
+ @Override
+ public SolrObject[] createList(final int length) {
+ return new SolrObject[length];
+ }
+
+ @Override
+ public void insertObject(final NoSQLObject object) {
+ try {
+ UpdateResponse response;
+ // if commitWithinMs was specified ... use it
+ if (commitWithinMs < 0) {
+ response = this.solrServer.add(object.unwrap());
+ } else {
+ response = this.solrServer.add(object.unwrap(), commitWithinMs);
+ }
+
+ // check if solr response shows error
+ if (response.getStatus() != 0) {
+ throw new AppenderLoggingException("Failed to write log event to Solr. Request Status is: " + response.getStatus());
+ }
+ } catch (SolrServerException e) {
+ throw new AppenderLoggingException("Failed to write log event to Solr due to error: " + e.getMessage(), e);
+ } catch (IOException e) {
+ throw new AppenderLoggingException("Failed to write log event to Solr due to error: " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public synchronized void close() {
+ // there is nothing to do
+ }
+
+ @Override
+ public synchronized boolean isClosed() {
+ return false;
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrObject.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrObject.java
new file mode 100644
index 0000000..f461696
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrObject.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender.db.nosql.solr;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.apache.logging.log4j.core.appender.db.nosql.NoSQLObject;
+import org.apache.solr.common.SolrInputDocument;
+
+/**
+ * The Apache Solr implementation of {@link NoSQLObject}.
+ * its a wrapper class for the SolrInputDocument.
+ * @author Markus Klose
+ */
+public final class SolrObject implements NoSQLObject {
+ // solr document
+ private final SolrInputDocument solrDoc;
+
+ /**
+ * default constructor.
+ */
+ public SolrObject() {
+ this.solrDoc = new SolrInputDocument();
+ }
+
+ @Override
+ public void set(final String field, final Object value) {
+ // add a single valued field
+ this.solrDoc.addField(field, value);
+ }
+
+ @Override
+ public void set(final String field, final NoSQLObject value) {
+ // add a single nested document
+ this.solrDoc.addChildDocument(value.unwrap());
+
+ //TODO what is with field name?
+ }
+
+ @Override
+ public void set(final String field, final Object[] values) {
+ // add a multi valued field
+ this.solrDoc.addField(field, Arrays.asList(values));
+ }
+
+ @Override
+ public void set(final String field, final NoSQLObject[] values) {
+ // add a a list of nested documents
+ final ArrayList list = new ArrayList();
+ for (final NoSQLObject value : values) {
+ list.add(value.unwrap());
+ }
+ this.solrDoc.addChildDocuments(list);
+
+ //TODO what is with field name?
+ }
+
+ @Override
+ public SolrInputDocument unwrap() {
+ return this.solrDoc;
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrProvider.java
new file mode 100644
index 0000000..c52c874
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/solr/SolrProvider.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender.db.nosql.solr;
+
+import java.net.MalformedURLException;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.appender.db.nosql.NoSQLProvider;
+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.status.StatusLogger;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
+import org.apache.solr.client.solrj.impl.CloudSolrServer;
+import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.client.solrj.impl.LBHttpSolrServer;
+import org.apache.solr.core.CoreContainer;
+
+/**
+ * The Apache Solr implementation of {@link NoSQLProvider}.
+ * @author Markus Klose
+ */
+@Plugin(name = "Solr", category = "Core", printObject = true)
+public final class SolrProvider implements NoSQLProvider {
+ // status logger
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ // solr server instance to log to
+ private final SolrServer solrServer;
+
+ // amount of time before commit is done
+ private int commitWithinMs;
+
+ // description of the solr provider
+ private final String description;
+
+ // default coreName
+ private static String DEFAULT_CORENAME = "collection1";
+
+ /**
+ * constructor of the SolrProvider.
+ *
+ * @param solrServer
+ * solr server instance to log to
+ * @param commitWithinMs
+ * amount of time before commit is done
+ * @param description
+ * description of the solr provider
+ */
+ private SolrProvider(final SolrServer solrServer, int commitWithinMs, final String description) {
+ this.solrServer = solrServer;
+ this.description = "solr{ " + description + " }";
+ this.commitWithinMs = commitWithinMs;
+ }
+
+ @Override
+ public SolrConnection getConnection() {
+ return new SolrConnection(this.solrServer, this.commitWithinMs);
+ }
+
+ @Override
+ public String toString() {
+ return this.description;
+ }
+
+ /**
+ * Factory method for creating an Apache Solr provider within the plugin manager.
+ *
+ * @param coreName
+ * name of the core/collection. used by all solr server implementation ({@link HttpSolrServer}, {@link LBHttpSolrServer}, {@link CloudSolrServer}, {@link EmbeddedSolrServer}). NOT optional for {@link EmbeddedSolrServer}
+ * @param commitWithinMs
+ * amount of time before a commit is executed. used by all solr server implementation ({@link HttpSolrServer}, {@link LBHttpSolrServer}, {@link CloudSolrServer}, {@link EmbeddedSolrServer}).
+ * @param url
+ * solr URL used by {@link HttpSolrServer}
+ * @param solrServerUrls
+ * comma (",") separated list of solr urls. used by {@link LBHttpSolrServer}
+ * @param zkHost
+ * list of zooKeeper instances to connect to. used by {@link CloudSolrServer}
+ * @param solrHome
+ * path to the solr home directory. used by {@link EmbeddedSolrServer}
+ * @return
+ * new Apache Solr provider.
+ */
+ @PluginFactory
+ public static SolrProvider createNoSQLProvider (
+ @PluginAttribute("coreName") final String coreName,
+ @PluginAttribute("commitWithinMs") final String commitWithinMs,
+ @PluginAttribute("url") final String url,
+ @PluginAttribute("solrServerUrls") final String solrServerUrls,
+ @PluginAttribute("zkHost") final String zkHost,
+ @PluginAttribute("solrHome") final String solrHome) {
+
+ // init commitWithin
+ int commitWithin;
+ if(commitWithinMs == null) {
+ // default -1 -> not used by insertObject()
+ commitWithin = -1;
+ } else {
+ commitWithin = Integer.parseInt(commitWithinMs);
+ }
+
+ // create the correct solr server
+ SolrProvider solrProvider = null;
+
+ if (url != null && url.length() > 0) {
+ // create SolrProvider with HttpSolrServer
+ solrProvider = getHttpSolrServer(url, coreName, commitWithin);
+ } else if(solrServerUrls != null && solrServerUrls.length() > 0) {
+ // create SolrProvider with LBHttpSolrServer
+ solrProvider = getLBHttpSolrServer(solrServerUrls, coreName, commitWithin);
+ } else if(zkHost != null && zkHost.length() > 0) {
+ // create SolrProvider with CloudSolrServer
+ solrProvider = getCloudSolrServer(zkHost, coreName, commitWithin);
+ } else if((solrHome != null && solrHome.length() > 0)
+ && (coreName != null && coreName.length() > 0)) {
+ // create SolrProvider with EmbeddedSolrServer
+ solrProvider = getEmbeddedSolrServer(solrHome, coreName, commitWithin);
+ } else {
+ // no valid configuration found
+ LOGGER.error("No valid SolrProvider configuration found!");
+ }
+
+ return solrProvider;
+ }
+
+
+ // helper
+ /**
+ * create SolrProvider with HttpSolrServer.
+ */
+ private static SolrProvider getHttpSolrServer(String url, String coreName, int commitWithinMs) {
+ String solrUrl = url;
+
+ // handle coreName
+ if (coreName != null && coreName.length() > 0) {
+ solrUrl = url + "/" + coreName;
+ }
+
+ return new SolrProvider(new HttpSolrServer(solrUrl), commitWithinMs, "HttpSolrServer(\"" + solrUrl + "\")");
+ }
+
+ /**
+ * create SolrProvider with LBHttpSolrServer.
+ */
+ private static SolrProvider getLBHttpSolrServer(String solrServerUrls, String coreName, int commitWithinMs) {
+ String[] solrURLs = solrServerUrls.split(",");
+ String description = solrServerUrls;
+
+ // handle coreName
+ if (coreName != null && coreName.length() > 0) {
+ description = "";
+ for (int i = 0; i< solrURLs.length; i++) {
+ solrURLs[i] = solrURLs[i] + "/" + coreName;
+ description += "," + solrURLs[i];
+ }
+ description = description.replaceFirst(",", "");
+ }
+
+ try {
+ return new SolrProvider(new LBHttpSolrServer(solrURLs), commitWithinMs, "LBHttpSolrServer(\"" + description + "\")");
+ } catch (MalformedURLException murlEx) {
+ // LBHttpSolrServer does not throw this exception
+ return null;
+ }
+ }
+
+ /**
+ * create SolrProvider with CloudSolrServer.
+ */
+ private static SolrProvider getCloudSolrServer(String zkHost, String coreName, int commitWithinMs) {
+ SolrServer solrServer = new CloudSolrServer(zkHost);
+ String description = "CloudSolrServer(\"" + zkHost + "\")";
+
+ // handle coreName
+ if (coreName == null || coreName.length() == 0) {
+ coreName = DEFAULT_CORENAME;
+ }
+ ((CloudSolrServer)solrServer).setDefaultCollection(coreName);
+ description += ".setDefaultCollection(\"" + coreName + "\")";
+
+
+ return new SolrProvider(solrServer, commitWithinMs, description);
+ }
+
+ /**
+ * create SolrProvider with EmbeddedSolrServer.
+ */
+ private static SolrProvider getEmbeddedSolrServer(String solrHome, String coreName, int commitWithinMs) {
+ CoreContainer coreContainer = new CoreContainer(solrHome);
+ coreContainer.load();
+ String description = "EmbeddedSolrServer(\"" + solrHome + "\", \"" + coreName + "\")";
+
+ return new SolrProvider(new EmbeddedSolrServer(coreContainer, coreName), commitWithinMs, description);
+ }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrConnection.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrConnection.java
new file mode 100644
index 0000000..00d0727
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrConnection.java
@@ -0,0 +1,21 @@
+package org.apache.logging.log4j.core.appender.db.nosql.solr;
+
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * JUnit test for SolrConnection.
+ * @author Markus Klose
+ */
+public class TestSolrConnection {
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ //TODO what to test ???
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrObject.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrObject.java
new file mode 100644
index 0000000..c806c76
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrObject.java
@@ -0,0 +1,140 @@
+package org.apache.logging.log4j.core.appender.db.nosql.solr;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * JUnit test for SolrObject.
+ * @author Markus Klose
+ */
+public class TestSolrObject {
+ private SolrObject solrObject;
+
+ @Before
+ public void setUp() {
+ this.solrObject = new SolrObject();
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testConstructor() {
+ SolrObject solrObject = new SolrObject();
+ assertNotNull(solrObject.unwrap());
+ }
+
+ @Test
+ public void testSetSingleValuedField() {
+ //pre test
+ assertNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertNull(this.solrObject.unwrap().getFieldValue("b"));
+
+ // set
+ this.solrObject.set("a", "solr field");
+ this.solrObject.set("b", "another solr field");
+
+ // test set
+ assertNotNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertEquals("solr field", this.solrObject.unwrap().getFieldValue("a"));
+ assertEquals(1, this.solrObject.unwrap().getFieldValues("a").size());
+ assertNotNull(this.solrObject.unwrap().getFieldValue("b"));
+ assertEquals("another solr field", this.solrObject.unwrap().getFieldValue("b"));
+ assertEquals(1, this.solrObject.unwrap().getFieldValues("b").size());
+ }
+
+ @Test
+ public void testSetMultiValuedField() {
+ //pre test
+ assertNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertNull(this.solrObject.unwrap().getFieldValue("b"));
+
+ // set
+ String[] array1 = {"solr", "field"};
+ this.solrObject.set("a", array1);
+ String[] array2 = {"another", "solr", "field"};
+ this.solrObject.set("b", array2);
+
+ // test set
+ assertNotNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertArrayEquals(array1, this.solrObject.unwrap().getFieldValues("a").toArray());
+ assertEquals(2, this.solrObject.unwrap().getFieldValues("a").size());
+ assertNotNull(this.solrObject.unwrap().getFieldValues("b"));
+ assertArrayEquals(array2, this.solrObject.unwrap().getFieldValues("b").toArray());
+ assertEquals(3, this.solrObject.unwrap().getFieldValues("b").size());
+ }
+
+ @Test
+ public void testSetSingleNestedDoc() {
+ //pre test
+ assertNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertNull(this.solrObject.unwrap().getFieldValue("b"));
+
+ // set
+ this.solrObject.set("a", new SolrObject());
+ this.solrObject.set("b", new SolrObject());
+
+ // test set
+ assertNotNull(this.solrObject.unwrap().getChildDocuments());
+ assertEquals(2, this.solrObject.unwrap().getChildDocuments().size());
+ assertNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertNull(this.solrObject.unwrap().getFieldValue("b"));
+ }
+
+ @Test
+ public void testSetMultipleNestedDoc() {
+ //pre test
+ assertNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertNull(this.solrObject.unwrap().getFieldValue("b"));
+
+ // set
+ SolrObject[] array1 = {new SolrObject(), new SolrObject()};
+ this.solrObject.set("a", array1);
+ SolrObject[] array2 = {new SolrObject(), new SolrObject(), new SolrObject()};
+ this.solrObject.set("b", array2);
+
+ // test set
+ assertNotNull(this.solrObject.unwrap().getChildDocuments());
+ assertEquals(5, this.solrObject.unwrap().getChildDocuments().size());
+ assertNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertNull(this.solrObject.unwrap().getFieldValue("b"));
+ }
+
+ @Test
+ public void testSetComplex() {
+ //pre test
+ assertNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertNull(this.solrObject.unwrap().getFieldValue("b"));
+ assertNull(this.solrObject.unwrap().getFieldValue("c"));
+ assertNull(this.solrObject.unwrap().getFieldValue("d"));
+
+ // set
+ this.solrObject.set("a", "solr field");
+ String[] array1 = {"another", "solr", "field"};
+ this.solrObject.set("b", array1);
+ this.solrObject.set("c", new SolrObject());
+ SolrObject[] array2 = {new SolrObject(), new SolrObject(), new SolrObject()};
+ this.solrObject.set("d", array2);
+
+ // test set
+ assertNotNull(this.solrObject.unwrap().getFieldValue("a"));
+ assertEquals("solr field", this.solrObject.unwrap().getFieldValue("a"));
+ assertEquals(1, this.solrObject.unwrap().getFieldValues("a").size());
+
+ assertNotNull(this.solrObject.unwrap().getFieldValues("b"));
+ assertArrayEquals(array1, this.solrObject.unwrap().getFieldValues("b").toArray());
+ assertEquals(3, this.solrObject.unwrap().getFieldValues("b").size());
+
+ assertNotNull(this.solrObject.unwrap().getChildDocuments());
+ assertEquals(4, this.solrObject.unwrap().getChildDocuments().size());
+ assertNull(this.solrObject.unwrap().getFieldValue("c"));
+ assertNull(this.solrObject.unwrap().getFieldValue("d"));
+ }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrProvider.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrProvider.java
new file mode 100644
index 0000000..02198b3
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/solr/TestSolrProvider.java
@@ -0,0 +1,150 @@
+package org.apache.logging.log4j.core.appender.db.nosql.solr;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * JUnit tests for SolrProvider.
+ * test createNoSQLProvider by reviewing the description
+ * @author Markus Klose
+ */
+public class TestSolrProvider {
+ // provider to test
+ private SolrProvider solrProvider;
+
+ @Before
+ public void setUp() {
+ this.solrProvider = null;
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testHttpSolrServer() {
+ // pre test
+ assertNull(this.solrProvider);
+
+ // create provider
+ this.solrProvider = SolrProvider.createNoSQLProvider(null, null, "http://localhost:8983/solr", null, null, null);
+
+ // test provider
+ assertNotNull(this.solrProvider);
+ assertEquals("solr{ HttpSolrServer(\"http://localhost:8983/solr\") }", this.solrProvider.toString());
+ }
+
+ @Test
+ public void testHttpSolrServerWithCore() {
+ // pre test
+ assertNull(this.solrProvider);
+
+ // create provider
+ this.solrProvider = SolrProvider.createNoSQLProvider("myCore", null, "http://localhost:8983/solr", null, null, null);
+
+ // test provider
+ assertNotNull(this.solrProvider);
+ assertEquals("solr{ HttpSolrServer(\"http://localhost:8983/solr/myCore\") }", this.solrProvider.toString());
+ }
+
+ @Test
+ public void testLBHttpSolrServer() {
+ // pre test
+ assertNull(this.solrProvider);
+
+ // create provider
+ this.solrProvider = SolrProvider.createNoSQLProvider(null, null, null, "http://localhost:8983/solr,http://localhost:8984/solr", null, null);
+
+ // test provider
+ assertNotNull(this.solrProvider);
+ assertEquals("solr{ LBHttpSolrServer(\"http://localhost:8983/solr,http://localhost:8984/solr\") }", this.solrProvider.toString());
+ }
+
+ @Test
+ public void testLBHttpSolrServerWithCore() {
+ // pre test
+ assertNull(this.solrProvider);
+
+ // create provider
+ this.solrProvider = SolrProvider.createNoSQLProvider("myCore", null, null, "http://localhost:8983/solr,http://localhost:8984/solr", null, null);
+
+ // test provider
+ assertNotNull(this.solrProvider);
+ assertEquals("solr{ LBHttpSolrServer(\"http://localhost:8983/solr/myCore,http://localhost:8984/solr/myCore\") }", this.solrProvider.toString());
+ }
+
+ @Test
+ public void testCloudSolrServer() {
+ // pre test
+ assertNull(this.solrProvider);
+
+ // create provider
+ this.solrProvider = SolrProvider.createNoSQLProvider(null, null, null, null, "localhost:2181", null);
+
+ // test provider
+ assertNotNull(this.solrProvider);
+ assertEquals("solr{ CloudSolrServer(\"localhost:2181\").setDefaultCollection(\"collection1\") }", this.solrProvider.toString());
+ }
+
+ @Test
+ public void testCloudSolrServerWithCore() {
+ // pre test
+ assertNull(this.solrProvider);
+
+ // create provider
+ this.solrProvider = SolrProvider.createNoSQLProvider("myCore", null, null, null, "localhost:2181", null);
+
+ // test provider
+ assertNotNull(this.solrProvider);
+ assertEquals("solr{ CloudSolrServer(\"localhost:2181\").setDefaultCollection(\"myCore\") }", this.solrProvider.toString());
+ }
+
+ @Test
+ public void testEmbeddedSolrServer() {
+ // pre test
+ assertNull(this.solrProvider);
+
+ // create provider
+ String solrHome = TestSolrProvider.class.getResource("/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home").getPath();
+ this.solrProvider = SolrProvider.createNoSQLProvider("myCore", null, null, null, null, solrHome);
+
+ // test provider
+ assertNotNull(this.solrProvider);
+ assertEquals("solr{ EmbeddedSolrServer(\"" + solrHome + "\", \"myCore\") }", this.solrProvider.toString());
+ }
+
+ @Test
+ public void testNoValidConfiguration() {
+ // pre test
+ assertNull(this.solrProvider);
+
+ // create provider
+ this.solrProvider = SolrProvider.createNoSQLProvider(null, null, null, null, null, null);
+ assertNull(this.solrProvider);
+
+ //empty coreName
+ this.solrProvider = SolrProvider.createNoSQLProvider(null, null, "", null, null, null);
+ assertNull(this.solrProvider);
+
+ // empty url
+ this.solrProvider = SolrProvider.createNoSQLProvider("", null, null, null, null, null);
+ assertNull(this.solrProvider);
+
+ // empty list of Solr server
+ this.solrProvider = SolrProvider.createNoSQLProvider(null, null, null, "", null, null);
+ assertNull(this.solrProvider);
+
+ // empty zkHost
+ this.solrProvider = SolrProvider.createNoSQLProvider(null, null, null, null, "", null);
+ assertNull(this.solrProvider);
+
+ // empty solrHome
+ this.solrProvider = SolrProvider.createNoSQLProvider(null, null, null, null, null, "");
+ assertNull(this.solrProvider);
+ }
+}
diff --git a/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.html b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.html
new file mode 100644
index 0000000..8f2b32a
--- /dev/null
+++ b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.html
@@ -0,0 +1,24 @@
+
+
+
diff --git a/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.menu-bottom.html b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.menu-bottom.html
new file mode 100644
index 0000000..5f5eddd
--- /dev/null
+++ b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.menu-bottom.html
@@ -0,0 +1,25 @@
+
+
+
+
diff --git a/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.menu-top.html b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.menu-top.html
new file mode 100644
index 0000000..6c980eb
--- /dev/null
+++ b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/admin-extra.menu-top.html
@@ -0,0 +1,25 @@
+
+
+
+
diff --git a/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/schema.xml b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/schema.xml
new file mode 100644
index 0000000..97c25cf
--- /dev/null
+++ b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/schema.xml
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/solrconfig.xml b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/solrconfig.xml
new file mode 100644
index 0000000..ad040c4
--- /dev/null
+++ b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/conf/solrconfig.xml
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+ 4.7
+
+
+ ${solr.data.dir:}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.ulog.dir:}
+
+
+
+ ${solr.autoCommit.maxTime:15000}
+ false
+
+
+
+ ${solr.autoSoftCommit.maxTime:-1}
+
+
+
+
+
+ 1024
+
+
+
+
+
+ true
+ 20
+ 200
+
+
+
+
+
+
+
+
+
+ static firstSearcher warming in solrconfig.xml
+
+
+
+ false
+ 2
+
+
+
+
+
+
+
+
+
+
+ explicit
+ 10
+ text
+
+
+
+
+
+
+ explicit
+ json
+ true
+ text
+
+
+
+
+
+ true
+ json
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+ solrpingquery
+
+
+ all
+
+
+
+
+
+
+ explicit
+ true
+
+
+
+
+
+
+
+
+ *:*
+
+
+
diff --git a/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/core.properties b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/core.properties
new file mode 100644
index 0000000..a70b08d
--- /dev/null
+++ b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/collection1/core.properties
@@ -0,0 +1 @@
+name=collection1
diff --git a/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/solr.xml b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/solr.xml
new file mode 100644
index 0000000..e8bdfb4
--- /dev/null
+++ b/log4j-core/src/test/resources/org/apache/logging/log4j/core/appender/db/nosql/solr/solr_home/solr.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+ ${host:}
+ ${jetty.port:8983}
+ ${hostContext:solr}
+ ${zkClientTimeout:30000}
+ ${genericCoreNodeNames:true}
+
+
+
+ ${socketTimeout:0}
+ ${connTimeout:0}
+
+
+