1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 00:17:11 -07:00

Jersey server.

This commit is contained in:
Cedric Beust 2016-04-27 23:10:54 -08:00
parent 4424db7e0c
commit f79d9f9497
9 changed files with 254 additions and 193 deletions

View file

@ -49,8 +49,8 @@
<root url="jar://$USER_HOME$/.kobalt/repository/org/glassfish/jersey/bundles/repackaged/jersey-guava/2.22.2/jersey-guava-2.22.2.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.0.0/kotlin-compiler-embeddable-1.0.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/com/squareup/retrofit2/converter-gson/2.0.0/converter-gson-2.0.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/eclipse/persistence/org.eclipse.persistence.moxy/2.6.0/org.eclipse.persistence.moxy-2.6.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/eclipse/persistence/org.eclipse.persistence.asm/2.6.0/org.eclipse.persistence.asm-2.6.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/eclipse/persistence/org.eclipse.persistence.moxy/2.6.0/org.eclipse.persistence.moxy-2.6.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/glassfish/hk2/hk2-locator/2.4.0-b34/hk2-locator-2.4.0-b34.jar!/" />
</CLASSES>
<JAVADOC />

View file

@ -1,15 +1,15 @@
<component name="libraryTable">
<library name="kobalt-plugin-api (Compile)">
<CLASSES>
<root url="jar://$USER_HOME$/.kobalt/repository/org/jetbrains/kotlinx/kotlinx.dom/0.0.10/kotlinx.dom-0.0.10.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/com/google/inject/extensions/guice-assistedinject/4.0/guice-assistedinject-4.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/jetbrains/kotlinx/kotlinx.dom/0.0.10/kotlinx.dom-0.0.10.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/sonatype/sisu/sisu-inject-plexus/2.2.3/sisu-inject-plexus-2.2.3.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/eclipse/aether/aether-impl/1.1.0/aether-impl-1.1.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/codehaus/plexus/plexus-interpolation/1.21/plexus-interpolation-1.21.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/com/google/code/gson/gson/2.6.2/gson-2.6.2.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/maven/maven-artifact/3.3.9/maven-artifact-3.3.9.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/com/beust/jcommander/1.48/jcommander-1.48.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/maven/maven-artifact/3.3.9/maven-artifact-3.3.9.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/sonatype/aether/aether-util/1.13.1/aether-util-1.13.1.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/eclipse/aether/aether-transport-http/1.1.0/aether-transport-http-1.1.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/slf4j/slf4j-nop/1.6.0/slf4j-nop-1.6.0.jar!/" />
@ -21,10 +21,10 @@
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/maven/maven-model-builder/3.3.9/maven-model-builder-3.3.9.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/sonatype/aether/aether-api/1.13.1/aether-api-1.13.1.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/io/reactivex/rxjava/1.0.16/rxjava-1.0.16.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/maven/maven-aether-provider/3.3.9/maven-aether-provider-3.3.9.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/sonatype/sisu/sisu-inject-bean/2.2.3/sisu-inject-bean-2.2.3.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/codehaus/plexus/plexus-component-annotations/1.6/plexus-component-annotations-1.6.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/maven/maven-aether-provider/3.3.9/maven-aether-provider-3.3.9.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/com/google/guava/guava/19.0-rc2/guava-19.0-rc2.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/codehaus/plexus/plexus-component-annotations/1.6/plexus-component-annotations-1.6.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/com/google/inject/guice/4.0/guice-4.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/maven/wagon/wagon-provider-api/1.0-beta-6/wagon-provider-api-1.0-beta-6.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/sonatype/sisu/sisu-guice/3.0.3/sisu-guice-3.0.3.jar!/" />
@ -42,8 +42,8 @@
<root url="jar://$USER_HOME$/.kobalt/repository/com/squareup/retrofit2/retrofit/2.0.0/retrofit-2.0.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/maven/maven-builder-support/3.3.9/maven-builder-support-3.3.9.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/sonatype/sisu/sisu-guice/3.0.3/sisu-guice-3.0.3.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/httpcomponents/httpclient/4.3.5/httpclient-4.3.5.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/eclipse/aether/aether-transport-file/1.1.0/aether-transport-file-1.1.0.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/httpcomponents/httpclient/4.3.5/httpclient-4.3.5.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/apache/maven/maven-repository-metadata/3.3.9/maven-repository-metadata-3.3.9.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/codehaus/plexus/plexus-classworlds/2.4/plexus-classworlds-2.4.jar!/" />
<root url="jar://$USER_HOME$/.kobalt/repository/org/slf4j/jcl-over-slf4j/1.6.2/jcl-over-slf4j-1.6.2.jar!/" />

View file

@ -142,13 +142,15 @@ val kobaltApp = project(kobaltPluginApi, wrapper) {
"com.squareup.retrofit2:converter-gson:${Versions.retrofit}",
"org.codehaus.plexus:plexus-utils:3.0.22",
"biz.aQute.bnd:bndlib:2.4.0",
"org.eclipse.jetty:jetty-server:${Versions.jetty}",
"org.eclipse.jetty:jetty-servlet:${Versions.jetty}",
"org.glassfish.jersey.core:jersey-server:${Versions.jersey}",
"org.glassfish.jersey.containers:jersey-container-servlet-core:${Versions.jersey}",
"org.glassfish.jersey.containers:jersey-container-jetty-http:${Versions.jersey}",
"org.glassfish.jersey.media:jersey-media-moxy:${Versions.jersey}"
// "org.eclipse.jetty.aggregate:jetty-all::uber:9.3.9.M1"
// "org.wasabi:wasabi:0.1.182"
)
}

View file

@ -48,10 +48,6 @@ class Args {
@Parameter(names = arrayOf("--noIncremental"), description = "Turn off incremental builds")
var noIncremental: Boolean = false
companion object {
const val DEFAULT_SERVER_PORT = 1234
}
@Parameter(names = arrayOf("--plugins"), description = "Comma-separated list of plug-in Maven id's")
var pluginIds: String? = null
@ -59,7 +55,7 @@ class Args {
var pluginJarFiles: String? = null
@Parameter(names = arrayOf("--port"), description = "Port, if --server was specified")
var port: Int = DEFAULT_SERVER_PORT
var port: Int? = null
@Parameter(names = arrayOf("--profiles"), description = "Comma-separated list of profiles to run")
var profiles: String? = null

View file

@ -10,12 +10,12 @@ object Constants {
internal val DEFAULT_REPOS = listOf<String>(
// "https://maven-central.storage.googleapis.com/",
"http://repo1.maven.org/maven2/",
"https://jcenter.bintray.com/"
"https://jcenter.bintray.com/",
"http://repository.jetbrains.com/all/"
// snapshots
// "https://oss.sonatype.org/content/repositories/snapshots/"
// , "https://repository.jboss.org/nexus/content/repositories/root_repository/"
// , "http://repository.jetbrains.com/all/"
)
}

View file

@ -0,0 +1,74 @@
package com.beust.kobalt.app.remote
import com.beust.kobalt.Args
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.Project
import com.google.gson.Gson
import org.glassfish.jersey.jetty.JettyHttpContainerFactory
import org.glassfish.jersey.server.ResourceConfig
import org.glassfish.jersey.server.ServerProperties
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.UriBuilder
class JerseyServer(val initCallback: (String) -> List<Project>, val cleanUpCallback: () -> Unit)
: KobaltServer .IServer {
companion object {
lateinit var initCallback: (String) -> List<Project>
lateinit var cleanUpCallback: () -> Unit
}
init {
JerseyServer.initCallback = initCallback
JerseyServer.cleanUpCallback = cleanUpCallback
}
override fun run(port: Int) {
val baseUri = UriBuilder.fromUri("http://localhost/").port(port).build()
val config = ResourceConfig(KobaltResource::class.java)
with (JettyHttpContainerFactory.createServer(baseUri, config)) {
try {
start()
join()
} finally {
destroy()
}
}
}
}
@Path("/v0")
class KobaltResource : ResourceConfig() {
init {
property(ServerProperties.TRACING, "ALL")
}
@GET
@Path("ping")
@Produces(MediaType.TEXT_PLAIN)
fun getDependencies() = "pong"
@GET
@Path("getDependencies")
@Produces(MediaType.APPLICATION_JSON)
fun getDependencies(@QueryParam("buildFile") buildFile: String) : String {
try {
val dependencyData = Kobalt.INJECTOR.getInstance(DependencyData::class.java)
val args = Kobalt.INJECTOR.getInstance(Args::class.java)
val projects = JerseyServer.initCallback(buildFile)
val dd = dependencyData.dependenciesDataFor(buildFile, args)
val result = Gson().toJson(dd)
return result
} catch(ex: Exception) {
return "Error: " + ex.message
} finally {
JerseyServer.cleanUpCallback()
}
}
}

View file

@ -1,32 +1,14 @@
package com.beust.kobalt.app.remote
import com.beust.kobalt.Args
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.Project
import com.beust.kobalt.homeDir
import com.beust.kobalt.internal.remote.CommandData
import com.beust.kobalt.internal.remote.ICommandSender
import com.beust.kobalt.internal.remote.PingCommand
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.log
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import org.glassfish.jersey.jetty.JettyHttpContainerFactory
import org.glassfish.jersey.server.ResourceConfig
import org.glassfish.jersey.server.ServerProperties
import java.io.*
import java.io.File
import java.io.FileWriter
import java.lang.management.ManagementFactory
import java.net.ServerSocket
import java.net.SocketException
import java.util.*
import java.util.concurrent.Callable
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.UriBuilder
/**
* Launch a Kobalt server. If @param{force} is specified, a new server will be launched even if one was detected
@ -35,40 +17,29 @@ import javax.ws.rs.core.UriBuilder
* The callbacks are used to initialize and clean up the state before and after each command, so that Kobalt's state
* can be properly reset, making the server reentrant.
*/
class KobaltServer(val force: Boolean, val port: Int = 1234,
class KobaltServer(val force: Boolean, val givenPort: Int? = null,
val initCallback: (String) -> List<Project>,
val cleanUpCallback: () -> Unit) : Callable<Int>, ICommandSender {
val cleanUpCallback: () -> Unit) : Callable<Int> {
// var outgoing: PrintWriter? = null
val pending = arrayListOf<CommandData>()
companion object {
lateinit var initCallback: (String) -> List<Project>
lateinit var cleanUpCallback: () -> Unit
interface IServer {
fun run(port: Int)
}
init {
KobaltServer.initCallback = initCallback
KobaltServer.cleanUpCallback = cleanUpCallback
}
private val COMMAND_CLASSES = listOf(GetDependenciesCommand::class.java, PingCommand::class.java)
private val COMMANDS = COMMAND_CLASSES.map {
Kobalt.INJECTOR.getInstance(it).let { Pair(it.name, it) }
}.toMap()
override fun call() : Int {
val availablePort = ProcessUtil.findAvailablePort(port)
val port = givenPort ?: ProcessUtil.findAvailablePort(1234)
try {
if (createServerFile(port, force)) {
// oldRun(port)
privateRun(port)
// OldServer(initCallback, cleanUpCallback).run(port)
JerseyServer(initCallback, cleanUpCallback).run(port)
// WasabiServer(initCallback, cleanUpCallback).run(port)
}
} catch(ex: Exception) {
ex.printStackTrace()
} finally {
deleteServerFile()
}
return availablePort
return port
}
val SERVER_FILE = KFiles.joinDir(homeDir(KFiles.KOBALT_DOT_DIR, "kobaltServer.properties"))
@ -95,144 +66,5 @@ class KobaltServer(val force: Boolean, val port: Int = 1234,
log(1, "KobaltServer deleting $SERVER_FILE")
File(SERVER_FILE).delete()
}
lateinit var serverInfo: ServerInfo
class ServerInfo(val port: Int) {
lateinit var reader: BufferedReader
lateinit var writer: PrintWriter
var serverSocket : ServerSocket? = null
init {
reset()
}
fun reset() {
if (serverSocket != null) {
serverSocket!!.close()
}
serverSocket = ServerSocket(port)
var clientSocket = serverSocket!!.accept()
reader = BufferedReader(InputStreamReader(clientSocket.inputStream))
writer = PrintWriter(clientSocket.outputStream, true)
}
}
@Path("/v0")
class MyResource : ResourceConfig() {
init {
property(ServerProperties.TRACING, "ALL")
}
@GET
@Path("ping")
@Produces(MediaType.TEXT_PLAIN)
fun getDependencies() = "pong"
@GET
@Path("getDependencies")
@Produces(MediaType.APPLICATION_JSON)
fun getDependencies(@QueryParam("buildFile") buildFile: String) : String {
try {
val dependencyData = Kobalt.INJECTOR.getInstance(DependencyData::class.java)
val args = Kobalt.INJECTOR.getInstance(Args::class.java)
val projects = initCallback(buildFile)
val dd = dependencyData.dependenciesDataFor(buildFile, args)
val result = Gson().toJson(dd)
return result
} catch(ex: Exception) {
return "Error: " + ex.message
} finally {
cleanUpCallback()
}
}
}
private fun privateRun(port: Int) {
log(1, "Listening to port $port")
val baseUri = UriBuilder.fromUri("http://localhost/").port(port).build()
val config = ResourceConfig(MyResource::class.java)
with (JettyHttpContainerFactory.createServer(baseUri, config)) {
try {
start()
join()
} finally {
destroy()
}
}
}
private fun oldRun(port: Int) {
log(1, "Listening to port $port")
var quit = false
serverInfo = ServerInfo(port)
while (!quit) {
if (pending.size > 0) {
log(1, "Emptying the queue, size $pending.size()")
synchronized(pending) {
pending.forEach { sendData(it) }
pending.clear()
}
}
var commandName: String? = null
try {
var line = serverInfo.reader.readLine()
while (!quit && line != null) {
log(1, "Received from client $line")
val jo = JsonParser().parse(line) as JsonObject
commandName = jo.get("name").asString
if ("quit" == commandName) {
log(1, "Quitting")
quit = true
} else {
runCommand(jo, initCallback)
// Done, send a quit to the client
sendData(CommandData("quit", ""))
// Clean up all the plug-in actors
cleanUpCallback()
line = serverInfo.reader.readLine()
}
}
if (line == null) {
log(1, "Received null line, resetting the server")
serverInfo.reset()
}
} catch(ex: SocketException) {
log(1, "Client disconnected, resetting")
serverInfo.reset()
} catch(ex: Throwable) {
ex.printStackTrace()
if (commandName != null) {
sendData(CommandData(commandName, null, ex.message))
}
log(1, "Command failed: ${ex.message}")
}
}
}
private fun runCommand(jo: JsonObject, initCallback: (String) -> List<Project>) {
val command = jo.get("name").asString
if (command != null) {
(COMMANDS[command] ?: COMMANDS["ping"])!!.run(this, jo, initCallback)
} else {
error("Did not find a name in command: $jo")
}
}
override fun sendData(commandData: CommandData) {
val content = Gson().toJson(commandData)
if (serverInfo.writer != null) {
serverInfo.writer!!.println(content)
} else {
log(1, "Queuing $content")
synchronized(pending) {
pending.add(commandData)
}
}
}
}

View file

@ -0,0 +1,120 @@
package com.beust.kobalt.app.remote
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.Project
import com.beust.kobalt.internal.remote.CommandData
import com.beust.kobalt.internal.remote.ICommandSender
import com.beust.kobalt.internal.remote.PingCommand
import com.beust.kobalt.misc.log
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.ServerSocket
import java.net.SocketException
class OldServer(val initCallback: (String) -> List<Project>, val cleanUpCallback: () -> Unit)
: KobaltServer.IServer, ICommandSender {
val pending = arrayListOf<CommandData>()
override fun run(port: Int) {
log(1, "Listening to port $port")
var quit = false
serverInfo = ServerInfo(port)
while (!quit) {
if (pending.size > 0) {
log(1, "Emptying the queue, size $pending.size()")
synchronized(pending) {
pending.forEach { sendData(it) }
pending.clear()
}
}
var commandName: String? = null
try {
var line = serverInfo.reader.readLine()
while (!quit && line != null) {
log(1, "Received from client $line")
val jo = JsonParser().parse(line) as JsonObject
commandName = jo.get("name").asString
if ("quit" == commandName) {
log(1, "Quitting")
quit = true
} else {
runCommand(jo, initCallback)
// Done, send a quit to the client
sendData(CommandData("quit", ""))
// Clean up all the plug-in actors
cleanUpCallback()
line = serverInfo.reader.readLine()
}
}
if (line == null) {
log(1, "Received null line, resetting the server")
serverInfo.reset()
}
} catch(ex: SocketException) {
log(1, "Client disconnected, resetting")
serverInfo.reset()
} catch(ex: Throwable) {
ex.printStackTrace()
if (commandName != null) {
sendData(CommandData(commandName, null, ex.message))
}
log(1, "Command failed: ${ex.message}")
}
}
}
private val COMMAND_CLASSES = listOf(GetDependenciesCommand::class.java, PingCommand::class.java)
private val COMMANDS = COMMAND_CLASSES.map {
Kobalt.INJECTOR.getInstance(it).let { Pair(it.name, it) }
}.toMap()
private fun runCommand(jo: JsonObject, initCallback: (String) -> List<Project>) {
val command = jo.get("name").asString
if (command != null) {
(COMMANDS[command] ?: COMMANDS["ping"])!!.run(this, jo, initCallback)
} else {
error("Did not find a name in command: $jo")
}
}
lateinit var serverInfo: ServerInfo
class ServerInfo(val port: Int) {
lateinit var reader: BufferedReader
lateinit var writer: PrintWriter
var serverSocket : ServerSocket? = null
init {
reset()
}
fun reset() {
if (serverSocket != null) {
serverSocket!!.close()
}
serverSocket = ServerSocket(port)
var clientSocket = serverSocket!!.accept()
reader = BufferedReader(InputStreamReader(clientSocket.inputStream))
writer = PrintWriter(clientSocket.outputStream, true)
}
}
override fun sendData(commandData: CommandData) {
val content = Gson().toJson(commandData)
if (serverInfo.writer != null) {
serverInfo.writer!!.println(content)
} else {
log(1, "Queuing $content")
synchronized(pending) {
pending.add(commandData)
}
}
}
}

View file

@ -0,0 +1,37 @@
//package com.beust.kobalt.app.remote
//
//import com.beust.kobalt.Args
//import com.beust.kobalt.api.Project
//
//class WasabiServer(val initCallback: (String) -> List<Project>, val cleanUpCallback: () -> Unit)
// : KobaltServer.IServer {
// override fun run(port: Int) {
// with(AppServer(AppConfiguration(port))) {
// get("/", { response.send("Hello World!") })
// get("/v0/getDependencies",
// {
// val buildFile = request.queryParams["buildFile"]
// if (buildFile != null) {
//
// val projects = initCallback(buildFile)
// val result = try {
// val dependencyData = Kobalt.INJECTOR.getInstance(DependencyData::class.java)
// val args = Kobalt.INJECTOR.getInstance(Args::class.java)
//
// val dd = dependencyData.dependenciesDataFor(buildFile, args)
// Gson().toJson(dd)
// } catch(ex: Exception) {
// "Error: " + ex.message
// } finally {
// cleanUpCallback()
// }
//
// response.send(result)
// }
// }
// )
// start()
// }
// }
//}
//