Skip to content

Commit

Permalink
release 1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
apatrida committed Oct 12, 2015
1 parent 63bde67 commit c5f330e
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 65 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ solr-undertow

This application launches a Solr distribution as a standalone server running a high performance HTTP front-end based on [undertow.io](http://undertow.io) (the engine behind WildFly, the new JBoss). It has no features of an application server, does nothing more than load Solr servlets and also service the Admin UI. It is production-quality for a stand-alone Solr server.

**NOTE:** Solr 5.3 WAR-less distribution are now supported. Use the full `solr-5.3.0.zip` distribution in place of the WAR. Also works for older versions (tested 5.2.1) that contain the WAR inside the distribution, use the full distribution .zip file, NOT the .tgz. Solr 5.x is hiding the WAR to provide a more simplified Solr server experience, but they have so far kept Jetty under the covers with the harder-to-tune 10,000 default threads. This doesn't change the need for Solr-Undertow.
**NOTE:** Solr 5.3 WAR-less distribution are now supported. Use the full `solr-5.3.1.zip` distribution in place of the WAR. Also works for older versions (tested 5.2.1) that contain the WAR inside the distribution, use the full distribution .zip file, NOT the .tgz. Solr 5.x is hiding the WAR to provide a more simplified Solr server experience, but they have so far kept Jetty under the covers with the harder-to-tune 10,000 default threads. This doesn't change the need for Solr-Undertow.

Releases [are available here](https://github.com/bremeld/solr-undertow/releases) on GitHub supporting versions of Solr 4.x and 5.x. Releases before 4.4.0 are untested, but should work.

Expand Down Expand Up @@ -40,7 +40,7 @@ solr.undertow: {
solrHome: "./solr-home"
solrLogs: "./solr-logs"
tempDir: "./solr-temp"
solrVersion: "5.3.0"
solrVersion: "5.3.1"
solrWarFile: ./solr-wars/solr-${solr.undertow.solrVersion}.zip
}
```
Expand Down Expand Up @@ -99,7 +99,7 @@ Other Notes

#### Solr Distributions (prefered for Solr 5.x and newer)

For Solr 5.3 and newer, you only have the option to use the full Solr distribution ZIP file. Download the version you desire from the main [Solr website](http://lucene.apache.org/solr/) or [past version archives](http://archive.apache.org/dist/lucene/solr/). We have tested versions 5.2.1 (with embedded WAR) and 5.3.0 (no WAR no more) and any that have the same directory structure will work.
For Solr 5.3 and newer, you only have the option to use the full Solr distribution ZIP file. Download the version you desire from the main [Solr website](http://lucene.apache.org/solr/) or [past version archives](http://archive.apache.org/dist/lucene/solr/). We have tested versions 5.2.1 (with embedded WAR) and 5.3.x (no WAR no more) and any that have the same directory structure will work.

#### Solr WAR Files (only 5.2.1 or earlier)

Expand Down
2 changes: 1 addition & 1 deletion example/example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ solr.undertow: {
solrHome: "./solr-home"
solrLogs: "./solr-logs"
tempDir: "./solr-temp"
solrVersion: "5.3.0"
solrVersion: "5.3.1"
solrWarFile: ./solr-wars/solr-${solr.undertow.solrVersion}.zip
}
10 changes: 5 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
group=org.bremeld
version=1.5.0-RC1
version=1.5.0

systemProp.file.encoding=UTF-8

version_kotlin=0.12.1230
version_kotlin=0.14.451

version_undertow=1.3.0.Beta9
version_solr=5.3.0
version_undertow=1.3.0.Final
version_solr=5.3.1

version_klutter=0.2.4
version_klutter=0.7.2
version_typesafe_config=1.2.1

version_slf4j=1.7.12
Expand Down
79 changes: 38 additions & 41 deletions src/main/kotlin/org/bremeld/solr/undertow/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,68 +16,65 @@
package org.bremeld.solr.undertow

import com.typesafe.config.Config
import kotlin.reflect.KMemberProperty
import org.slf4j.Logger
import java.nio.file.Files
import java.util.HashMap
import java.util.Properties
import java.nio.file.Path
import org.slf4j.LoggerFactory
import uy.klutter.config.typesafe.*
import uy.klutter.config.typesafe.ReferenceConfig
import uy.klutter.config.typesafe.jdk7.*
import uy.klutter.config.typesafe.jdk7.FileConfig
import uy.klutter.config.typesafe.loadConfig
import uy.klutter.config.typesafe.jdk7.asPathSibling
import uy.klutter.core.common.initializedBy
import uy.klutter.core.jdk.minimum
import uy.klutter.core.jdk7.notExists
import java.nio.file.Files
import java.nio.file.Path
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.reflect.KProperty1

internal val SOLR_UNDERTOW_CONFIG_PREFIX = "solr.undertow"
public val SOLR_UNDERTOW_CONFIG_PREFIX = "solr.undertow"

internal val SYS_PROP_JETTY_PORT = "jetty.port"
internal val OUR_PROP_HTTP_PORT = "httpClusterPort"
public val SYS_PROP_JETTY_PORT = "jetty.port"
public val OUR_PROP_HTTP_PORT = "httpClusterPort"

internal val SYS_PROP_ZKRUN = "zkRun"
internal val OUR_PROP_ZKRUN = "zkRun"
public val SYS_PROP_ZKRUN = "zkRun"
public val OUR_PROP_ZKRUN = "zkRun"

internal val SYS_PROP_ZKHOST = "zkHost"
internal val OUR_PROP_ZKHOST = "zkHost"
public val SYS_PROP_ZKHOST = "zkHost"
public val OUR_PROP_ZKHOST = "zkHost"

internal val SYS_PROP_SOLR_LOG = "solr.log"
internal val OUR_PROP_SOLR_LOG = "solrLogs"
public val SYS_PROP_SOLR_LOG = "solr.log"
public val OUR_PROP_SOLR_LOG = "solrLogs"

internal val SYS_PROP_HOST_CONTEXT = "hostContext"
internal val OUR_PROP_HOST_CONTEXT = "solrContextPath"
public val SYS_PROP_HOST_CONTEXT = "hostContext"
public val OUR_PROP_HOST_CONTEXT = "solrContextPath"

internal val OUR_PROP_HTTP_HOST = "httpHost"
public val OUR_PROP_HTTP_HOST = "httpHost"

internal val SYS_PROP_SOLR_HOME = "solr.solr.home"
internal val OUR_PROP_SOLR_HOME = "solrHome"
public val SYS_PROP_SOLR_HOME = "solr.solr.home"
public val OUR_PROP_SOLR_HOME = "solrHome"

internal val SYS_PROP_JBOSS_LOGGING = "org.jboss.logging.provider"
public val SYS_PROP_JBOSS_LOGGING = "org.jboss.logging.provider"

internal val OUR_PROP_HTTP_IO_THREADS = "httpIoThreads"
internal val OUR_PROP_HTTP_WORKER_THREADS = "httpWorkerThreads"
internal val OUR_PROP_SOLR_WAR = "solrWarFile"
internal val OUR_PROP_SOLR_VERSION = "solrVersion"
internal val OUR_PROP_TEMP_DIR = "tempDir"
internal val OUR_PROP_LIBEXT_DIR = "libExtDir"
public val OUR_PROP_HTTP_IO_THREADS = "httpIoThreads"
public val OUR_PROP_HTTP_WORKER_THREADS = "httpWorkerThreads"
public val OUR_PROP_SOLR_WAR = "solrWarFile"
public val OUR_PROP_SOLR_VERSION = "solrVersion"
public val OUR_PROP_TEMP_DIR = "tempDir"
public val OUR_PROP_LIBEXT_DIR = "libExtDir"



// system and environment variables that need to be treated the same as our configuration items
internal val SOLR_OVERRIDES = mapOf(SYS_PROP_JETTY_PORT to OUR_PROP_HTTP_PORT,
public val SOLR_OVERRIDES = mapOf(SYS_PROP_JETTY_PORT to OUR_PROP_HTTP_PORT,
SYS_PROP_ZKRUN to OUR_PROP_ZKRUN,
SYS_PROP_ZKHOST to OUR_PROP_ZKHOST,
SYS_PROP_SOLR_LOG to OUR_PROP_SOLR_LOG,
SYS_PROP_HOST_CONTEXT to OUR_PROP_HOST_CONTEXT,
SYS_PROP_SOLR_HOME to OUR_PROP_SOLR_HOME)
internal val SYS_PROPERTIES_THAT_ARE_PATHS = setOf(SYS_PROP_SOLR_LOG, SYS_PROP_SOLR_HOME)
public val SYS_PROPERTIES_THAT_ARE_PATHS = setOf(SYS_PROP_SOLR_LOG, SYS_PROP_SOLR_HOME)

// These allow substitution of Env variables for unit tests.
internal var SERVER_ENV_WRAPPER: Map<out Any, Any> = System.getenv()
internal var SERVER_SYS_WRAPPER: MutableMap<Any, Any> = System.getProperties()
public var SERVER_ENV_WRAPPER: Map<out Any, Any> = System.getenv()
public var SERVER_SYS_WRAPPER: MutableMap<Any, Any> = System.getProperties()

public class ServerConfigLoader(val configFile: Path) {
// our config chain wants Env variables to override Reference Config because that is how Solr would work,
Expand Down Expand Up @@ -181,12 +178,12 @@ public class ServerConfig(private val log: Logger, val loader: ServerConfigLoade
fun hasLibExtDir(): Boolean = configured.value(OUR_PROP_LIBEXT_DIR).isNotEmptyString()


private fun printF(p: KMemberProperty<ServerConfig, Path>) = log.info(" ${p.name}: ${p.get(this)}")
private fun printS(p: KMemberProperty<ServerConfig, String>) = log.info(" ${p.name}: ${p.get(this)}")
private fun printSA(p: KMemberProperty<ServerConfig, Array<String>>) = log.info(" ${p.name}: ${p.get(this).joinToString(",")}")
private fun printB(p: KMemberProperty<ServerConfig, Boolean>) = log.info(" ${p.name}: ${p.get(this)}")
private fun printI(p: KMemberProperty<ServerConfig, Int>) = log.info(" ${p.name}: ${p.get(this)}")
private fun printI(p: KMemberProperty<ServerConfig, Int>, defaultVal: Int) = log.info(" ${p.name}: ${p.get(this)} ${if (p.get(this) == defaultVal) "(no setting, using default)" else ""}")
private fun printF(p: KProperty1<ServerConfig, Path>) = log.info(" ${p.name}: ${p.get(this)}")
private fun printS(p: KProperty1<ServerConfig, String>) = log.info(" ${p.name}: ${p.get(this)}")
private fun printSA(p: KProperty1<ServerConfig, Array<String>>) = log.info(" ${p.name}: ${p.get(this).joinToString(",")}")
private fun printB(p: KProperty1<ServerConfig, Boolean>) = log.info(" ${p.name}: ${p.get(this)}")
private fun printI(p: KProperty1<ServerConfig, Int>) = log.info(" ${p.name}: ${p.get(this)}")
private fun printI(p: KProperty1<ServerConfig, Int>, defaultVal: Int) = log.info(" ${p.name}: ${p.get(this)} ${if (p.get(this) == defaultVal) "(no setting, using default)" else ""}")

fun print() {
log.info("=== [ Config File settings from: ${loader.configFile} ] ===")
Expand Down Expand Up @@ -229,7 +226,7 @@ public class ServerConfig(private val log: Logger, val loader: ServerConfigLoade
isValid = false
}

fun existsIsWriteable(p: KMemberProperty<ServerConfig, Path>) {
fun existsIsWriteable(p: KProperty1<ServerConfig, Path>) {
val dir = p.get(this)
if (dir.notExists()) {
err("${p.name} dir does not exist: ${dir}")
Expand All @@ -239,7 +236,7 @@ public class ServerConfig(private val log: Logger, val loader: ServerConfigLoade
}
}

fun existsIsReadable(p: KMemberProperty<ServerConfig, Path>) {
fun existsIsReadable(p: KProperty1<ServerConfig, Path>) {
val dir = p.get(this)
if (dir.notExists()) {
err("${p.name} does not exist: ${dir}")
Expand Down
23 changes: 12 additions & 11 deletions src/main/kotlin/org/bremeld/solr/undertow/SolrUndertow.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import java.net.URL
import java.net.URLClassLoader
import java.nio.file.*
import java.nio.file.attribute.BasicFileAttributes
import java.util.ArrayList
import java.util.*
import javax.servlet.DispatcherType
import javax.servlet.Filter
import javax.servlet.Servlet
Expand All @@ -56,7 +56,7 @@ public data class ServerStartupStatus(val started: Boolean, val errorMessage: St

public class Server(cfgLoader: ServerConfigLoader) {
val log = LoggerFactory.getLogger("SolrServer")
val cfg by Delegates.lazy { ServerConfig(log, cfgLoader) }
val cfg by lazy { ServerConfig(log, cfgLoader) }
var server: Undertow by Delegates.notNull()

public fun run(): ServerStartupStatus {
Expand All @@ -82,7 +82,7 @@ public class Server(cfgLoader: ServerConfigLoader) {
override fun logMessage(message: String?) {
cfg.accessLogger.info(message)
}
}, cfg.accessLogFormat, javaClass<Server>().getClassLoader())
}, cfg.accessLogFormat, Server::class.java.getClassLoader())

val gracefulShutdownWrapperHandler = Handlers.gracefulShutdown(loggedHandler)

Expand Down Expand Up @@ -145,11 +145,11 @@ public class Server(cfgLoader: ServerConfigLoader) {
private inner class ShutdownRequestHandler(val servletDeploymentMgr: DeploymentManager, val gracefulShutdownWrapperHandler: GracefulShutdownHandler) : HttpHandler {
override fun handleRequest(exchange: HttpServerExchange) {
if (cfg.shutdownConfig.password.isNullOrBlank()) {
exchange.setResponseCode(403).getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain")
exchange.setStatusCode(403).getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain")
exchange.getResponseSender().send("forbidden")
log.error("Forbidden attempt to talk to shutdown port")
} else if (exchange.getQueryParameters().get("password")?.firstOrNull() != cfg.shutdownConfig.password) {
exchange.setResponseCode(401).getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain")
exchange.setStatusCode(401).getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain")
exchange.getResponseSender().send("unauthorized")
log.error("Unauthorized attempt to talk to shutdown port")
} else {
Expand All @@ -162,15 +162,15 @@ public class Server(cfgLoader: ServerConfigLoader) {
val wasGraceful = shutdownNicely(servletDeploymentMgr, gracefulShutdownWrapperHandler)
if (wasGraceful) {
try {
exchange.setResponseCode(200).getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain")
exchange.setStatusCode(200).getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain")
exchange.getResponseSender().send("OK")
} finally {
server.stop()
log.warn("Undeploy complete and graceful.")
}
} else {
try {
exchange.setResponseCode(500).getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain")
exchange.setStatusCode(500).getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain")
exchange.getResponseSender().send("ERROR")
} finally {
server.stop()
Expand Down Expand Up @@ -330,10 +330,10 @@ public class Server(cfgLoader: ServerConfigLoader) {

private fun buildSolrServletHandler(solrWarDeployment: DeployedDistributionInfo): ServletDeploymentAndHandler {
// load all by name so we have no direct dependency on Solr
val solrDispatchFilterClass = solrWarDeployment.classLoader.loadClass("org.apache.solr.servlet.SolrDispatchFilter").asSubclass(javaClass<Filter>())
val solrZookeeprServletClass = solrWarDeployment.classLoader.loadClass("org.apache.solr.servlet.ZookeeperInfoServlet").asSubclass(javaClass<Servlet>())
val solrAdminUiServletClass = solrWarDeployment.classLoader.loadClass("org.apache.solr.servlet.LoadAdminUiServlet").asSubclass(javaClass<Servlet>())
val solrRestApiServletClass = solrWarDeployment.classLoader.loadClass("org.restlet.ext.servlet.ServerServlet").asSubclass(javaClass<Servlet>())
val solrDispatchFilterClass = solrWarDeployment.classLoader.loadClass("org.apache.solr.servlet.SolrDispatchFilter").asSubclass(Filter::class.java)
val solrZookeeprServletClass = solrWarDeployment.classLoader.loadClass("org.apache.solr.servlet.ZookeeperInfoServlet").asSubclass(Servlet::class.java)
val solrAdminUiServletClass = solrWarDeployment.classLoader.loadClass("org.apache.solr.servlet.LoadAdminUiServlet").asSubclass(Servlet::class.java)
val solrRestApiServletClass = solrWarDeployment.classLoader.loadClass("org.restlet.ext.servlet.ServerServlet").asSubclass(Servlet::class.java)
val solrRestApiClass = try {
solrWarDeployment.classLoader.loadClass("org.apache.solr.rest.SolrSchemaRestApi")
} catch (ex: ClassNotFoundException) {
Expand Down Expand Up @@ -424,6 +424,7 @@ public class Server(cfgLoader: ServerConfigLoader) {
// TODO: Undertow says "This class is deprecated, the default servlet should be configured via context params." but not sure what they mean as the alternative
// given we are embedded, so think we are stuck with this model.

@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
public class SolrDefaultServletConfig() : DefaultServletConfig() {
private val defaultAllowed: Boolean = false
private val allowed = setOf("ico", "swf", "js", "css", "png", "jpg", "gif", "html", "htm", "txt", "pdf", "svg")
Expand Down
6 changes: 3 additions & 3 deletions src/main/kotlin/org/bremeld/solr/undertow/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ package org.bremeld.solr.undertow

import org.slf4j.Logger

private fun printErrorAndExit(msg: String?, errCode: Int = -1) {
internal fun printErrorAndExit(msg: String?, errCode: Int = -1) {
System.err.println(msg ?: "Unknown Error")
System.exit(errCode)
}

private fun <T> T.then(initWith: (T) -> Unit): T {
internal fun <T> T.then(initWith: (T) -> Unit): T {
initWith(this)
return this
}

private inline fun Logger.debug(foo: () -> String): Unit = if (this.isDebugEnabled()) this.debug(foo())
internal inline fun Logger.debug(foo: () -> String): Unit = if (this.isDebugEnabled()) this.debug(foo())
2 changes: 1 addition & 1 deletion test-data/solr-standalone/standalone.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ solr.undertow: {
solrHome: "./solr-home"
solrLogs: "./solr-logs"
tempDir: "./solr-temp"
solrVersion: "5.3.0"
solrVersion: "5.3.1"
solrWarFile: ../solr-wars/solr-${solr.undertow.solrVersion}.zip
shutdown: {
password: "diediedie"
Expand Down

0 comments on commit c5f330e

Please sign in to comment.