From 8b9f2d965555882aa10dad684a53a358a8c20e40 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 27 Apr 2016 03:11:33 -0800 Subject: [PATCH] Jersey work. --- .idea/libraries/kobalt__Compile_.xml | 54 +++++++-- .idea/libraries/kobalt__Test_.xml | 4 +- .../libraries/kobalt_plugin_api__Compile_.xml | 8 +- kobalt/src/Build.kt | 19 ++- .../com/beust/kobalt/internal/SourceSet.kt | 2 +- .../beust/kobalt/app/remote/KobaltClient.kt | 109 ++++++++++-------- .../beust/kobalt/app/remote/KobaltServer.kt | 67 ++++++++++- 7 files changed, 196 insertions(+), 67 deletions(-) diff --git a/.idea/libraries/kobalt__Compile_.xml b/.idea/libraries/kobalt__Compile_.xml index b9d203df..cca04162 100644 --- a/.idea/libraries/kobalt__Compile_.xml +++ b/.idea/libraries/kobalt__Compile_.xml @@ -1,25 +1,57 @@ - - + + - + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.idea/libraries/kobalt__Test_.xml b/.idea/libraries/kobalt__Test_.xml index 354d02d6..a93b84bc 100644 --- a/.idea/libraries/kobalt__Test_.xml +++ b/.idea/libraries/kobalt__Test_.xml @@ -1,7 +1,9 @@ - + + + diff --git a/.idea/libraries/kobalt_plugin_api__Compile_.xml b/.idea/libraries/kobalt_plugin_api__Compile_.xml index 797adc13..ad839a58 100644 --- a/.idea/libraries/kobalt_plugin_api__Compile_.xml +++ b/.idea/libraries/kobalt_plugin_api__Compile_.xml @@ -5,26 +5,26 @@ - + - + - + - + diff --git a/kobalt/src/Build.kt b/kobalt/src/Build.kt index b790fe9f..d3e1b63d 100644 --- a/kobalt/src/Build.kt +++ b/kobalt/src/Build.kt @@ -1,14 +1,18 @@ -import com.beust.kobalt.* + +import com.beust.kobalt.TaskResult import com.beust.kobalt.api.License import com.beust.kobalt.api.Project import com.beust.kobalt.api.Scm import com.beust.kobalt.api.annotation.Task +import com.beust.kobalt.homeDir import com.beust.kobalt.plugin.application.application import com.beust.kobalt.plugin.java.javaCompiler import com.beust.kobalt.plugin.kotlin.kotlinCompiler import com.beust.kobalt.plugin.packaging.assemble import com.beust.kobalt.plugin.publish.bintray import com.beust.kobalt.plugin.publish.github +import com.beust.kobalt.project +import com.beust.kobalt.test import java.io.File import java.nio.file.Files import java.nio.file.Paths @@ -22,6 +26,8 @@ object Versions { val aether = "1.1.0" val sonatypeAether = "1.13.1" val maven = "3.3.9" + val jersey = "2.22.2" + val jetty = "8.1.19.v20160209" // "9.3.9.M1" } val wrapper = project { @@ -57,7 +63,7 @@ val kobaltPluginApi = project { directory = "modules/kobalt-plugin-api" description = "A build system in Kotlin" url = "http://beust.com/kobalt" - licenses = arrayListOf(License("Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0")) + licenses = listOf(License("Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0")) scm = Scm(url = "http://github.com/cbeust/kobalt", connection = "https://github.com/cbeust/kobalt.git", developerConnection = "git@github.com:cbeust/kobalt.git") @@ -135,7 +141,14 @@ val kobaltApp = project(kobaltPluginApi, wrapper) { "com.squareup.retrofit2:retrofit:${Versions.retrofit}", "com.squareup.retrofit2:converter-gson:${Versions.retrofit}", "org.codehaus.plexus:plexus-utils:3.0.22", - "biz.aQute.bnd:bndlib:2.4.0" + "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" ) } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/SourceSet.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/SourceSet.kt index e0a3178f..7d606906 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/SourceSet.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/SourceSet.kt @@ -16,7 +16,7 @@ enum class SourceSet(val outputDir: String) { companion object { fun of(isTest: Boolean) = if (isTest) TEST else MAIN - private fun unknown(sourceSet: SourceSet) = throw KobaltException("Unknown source set: $sourceSet") + private fun unknown(sourceSet: SourceSet) : Nothing = throw KobaltException("Unknown source set: $sourceSet") } } diff --git a/src/main/kotlin/com/beust/kobalt/app/remote/KobaltClient.kt b/src/main/kotlin/com/beust/kobalt/app/remote/KobaltClient.kt index e474998d..21963d43 100644 --- a/src/main/kotlin/com/beust/kobalt/app/remote/KobaltClient.kt +++ b/src/main/kotlin/com/beust/kobalt/app/remote/KobaltClient.kt @@ -9,24 +9,83 @@ import com.beust.kobalt.internal.KobaltSettings import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.log import com.beust.kobalt.misc.warn -import com.google.gson.Gson import com.google.gson.JsonObject import com.google.gson.JsonParser import com.google.inject.Guice +import okhttp3.OkHttpClient +import retrofit2.Call +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.http.POST +import retrofit2.http.Query import java.io.* -import java.net.ConnectException import java.net.Socket import java.nio.file.Paths import java.util.* import java.util.concurrent.Executors -import javax.inject.Inject fun main(argv: Array) { Kobalt.INJECTOR = Guice.createInjector(MainModule(Args(), KobaltSettings.readSettingsXml())) - val port = ServerProcess().launch() - println("SERVER RUNNING ON PORT $port") + KobaltClient().run() } +interface Api { + @POST("/getDependencies") + fun getDependencies(@Query("buildFile") buildFile: String) : Call> +} + +class KobaltClient : Runnable { + var outgoing: PrintWriter? = null + + private val service = Retrofit.Builder() + .client(OkHttpClient.Builder().build()) + .baseUrl("http://localhost:1252") + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(Api::class.java) + + override fun run() { + val buildFile = Paths.get(SystemProperties.homeDir, "kotlin/klaxon/kobalt/src/Build.kt").toString() + val dependencies = service.getDependencies(buildFile) + val results = dependencies.execute() + println("Dependencies: $results") +// .toString()) +// var done = false +// var attempts = 1 +// while (attempts < 10 && ! done) { +// try { +// val socket = Socket("localhost", portNumber) +// outgoing = PrintWriter(socket.outputStream, true) +// val testBuildfile = Paths.get(SystemProperties.homeDir, "kotlin/klaxon/kobalt/src/Build.kt") +// .toFile().absolutePath +// val c : String = """{ "name": "getDependencies", "buildFile": "$testBuildfile"}""" +// outgoing!!.println(c) +// val ins = BufferedReader(InputStreamReader(socket.inputStream)) +// var line = ins.readLine() +// while (! done && line != null) { +// log(1, "Received from server:\n" + line) +// val jo = JsonParser().parse(line) as JsonObject +// if (jo.has("name") && "quit" == jo.get("name").asString.toLowerCase()) { +// log(1, "Quitting") +//// outgoing!!.println("{ \"name\": \"Quit\" }") +// done = true +// } else { +// val data = jo.get("data").asString +// val dd = Gson().fromJson(data, DependencyData.GetDependenciesData::class.java) +// println("Read GetDependencyData, project count: ${dd.projects.size}") +// line = ins.readLine() +// } +// } +// } catch(ex: ConnectException) { +// log(1, "Server not up, sleeping a bit") +// Thread.sleep(2000) +// attempts++ +// } +// } + } +} + + class ServerProcess { val SERVER_FILE = KFiles.joinDir(homeDir(KFiles.KOBALT_DOT_DIR, "kobaltServer.properties")) val KEY_PORT = "port" @@ -123,43 +182,3 @@ class ServerProcess { } } -class KobaltClient @Inject constructor() : Runnable { - var outgoing: PrintWriter? = null - - override fun run() { - val portNumber = 1234 - - var done = false - var attempts = 1 - while (attempts < 10 && ! done) { - try { - val socket = Socket("localhost", portNumber) - outgoing = PrintWriter(socket.outputStream, true) - val testBuildfile = Paths.get(SystemProperties.homeDir, "kotlin/klaxon/kobalt/src/Build.kt") - .toFile().absolutePath - val c : String = """{ "name": "getDependencies", "buildFile": "$testBuildfile"}""" - outgoing!!.println(c) - val ins = BufferedReader(InputStreamReader(socket.inputStream)) - var line = ins.readLine() - while (! done && line != null) { - log(1, "Received from server:\n" + line) - val jo = JsonParser().parse(line) as JsonObject - if (jo.has("name") && "quit" == jo.get("name").asString.toLowerCase()) { - log(1, "Quitting") -// outgoing!!.println("{ \"name\": \"Quit\" }") - done = true - } else { - val data = jo.get("data").asString - val dd = Gson().fromJson(data, DependencyData.GetDependenciesData::class.java) - println("Read GetDependencyData, project count: ${dd.projects.size}") - line = ins.readLine() - } - } - } catch(ex: ConnectException) { - log(1, "Server not up, sleeping a bit") - Thread.sleep(2000) - attempts++ - } - } - } -} diff --git a/src/main/kotlin/com/beust/kobalt/app/remote/KobaltServer.kt b/src/main/kotlin/com/beust/kobalt/app/remote/KobaltServer.kt index d6e82844..0f291e15 100644 --- a/src/main/kotlin/com/beust/kobalt/app/remote/KobaltServer.kt +++ b/src/main/kotlin/com/beust/kobalt/app/remote/KobaltServer.kt @@ -1,5 +1,6 @@ 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 @@ -11,12 +12,21 @@ 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.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 @@ -31,6 +41,16 @@ class KobaltServer(val force: Boolean, val port: Int = 1234, // var outgoing: PrintWriter? = null val pending = arrayListOf() + companion object { + lateinit var initCallback: (String) -> List + lateinit var cleanUpCallback: () -> Unit + } + + 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) } @@ -39,8 +59,9 @@ class KobaltServer(val force: Boolean, val port: Int = 1234, override fun call() : Int { val availablePort = ProcessUtil.findAvailablePort(port) try { - if (createServerFile(availablePort, force)) { - privateRun(availablePort) + if (createServerFile(port, force)) { +// oldRun(port) + privateRun(port) } } catch(ex: Exception) { ex.printStackTrace() @@ -97,8 +118,50 @@ class KobaltServer(val force: Boolean, val port: Int = 1234, } } + @Path("/v0") + class MyResource : ResourceConfig() { + init { + property(ServerProperties.TRACING, "ALL") + } + + @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 data = CommandData("getDependencies", Gson().toJson(dd), dd.errorMessage) + + return Gson().toJson(data) + } 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) {