From 73697db3c417f93554d0d83f8e5b6948cb23aeff Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Thu, 21 Nov 2024 10:21:15 +1100 Subject: [PATCH] chore(pact-jvm-server): Converted main Scala App to Kotlin --- pact-jvm-server/build.gradle | 17 +---- .../kotlin/au/com/dius/pact/server/Config.kt | 2 +- .../au/com/dius/pact/server/PactJvmServer.kt | 70 +++++++++++++++++++ .../au/com/dius/pact/server/Server.scala | 48 ------------- .../dius/pact/server/ListServersSpec.groovy | 1 - .../au/com/dius/pact/server/MainSpec.groovy | 40 ++++++----- settings.gradle | 2 +- 7 files changed, 95 insertions(+), 85 deletions(-) create mode 100644 pact-jvm-server/src/main/kotlin/au/com/dius/pact/server/PactJvmServer.kt delete mode 100644 pact-jvm-server/src/main/scala/au/com/dius/pact/server/Server.scala diff --git a/pact-jvm-server/build.gradle b/pact-jvm-server/build.gradle index 3e4def236..d8b30bdc0 100644 --- a/pact-jvm-server/build.gradle +++ b/pact-jvm-server/build.gradle @@ -1,26 +1,17 @@ plugins { id 'au.com.dius.pact.kotlin-application-conventions' - id 'scala' id 'maven-publish' id 'signing' } group = 'au.com.dius.pact' -mainClassName = 'au.com.dius.pact.server.Server' +mainClassName = 'au.com.dius.pact.server.PactJvmServer' dependencies { implementation project(':consumer') implementation project(':core:pactbroker') implementation 'ch.qos.logback:logback-core:1.5.6' implementation 'ch.qos.logback:logback-classic:1.5.6' - implementation 'com.github.scopt:scopt_2.12:3.5.0' - implementation('com.typesafe.scala-logging:scala-logging_2.12:3.7.2') { - exclude group: 'org.scala-lang' - } - implementation( 'ws.unfiltered:unfiltered-netty-server_2.12:0.10.4') { - exclude module: 'netty-transport-native-kqueue' - exclude module: 'netty-transport-native-epoll' - } implementation 'io.github.oshai:kotlin-logging-jvm' implementation 'org.apache.commons:commons-io:1.3.2' implementation 'org.apache.commons:commons-lang3' @@ -32,6 +23,7 @@ dependencies { implementation 'io.ktor:ktor-server-netty' implementation 'io.ktor:ktor-network-tls-certificates' implementation 'io.ktor:ktor-server-call-logging' + implementation 'com.github.ajalt.clikt:clikt:5.0.1' testImplementation 'org.apache.groovy:groovy' testImplementation 'org.apache.groovy:groovy-json' @@ -50,11 +42,6 @@ java { withSourcesJar() } -compileScala { - dependsOn compileKotlin - classpath = classpath.plus(files(compileKotlin.destinationDirectory)) -} - test { dependsOn(':pact-jvm-server:installDist') systemProperty('appExecutable', (new File(buildDir, 'install/pact-jvm-server/bin/pact-jvm-server')).path) diff --git a/pact-jvm-server/src/main/kotlin/au/com/dius/pact/server/Config.kt b/pact-jvm-server/src/main/kotlin/au/com/dius/pact/server/Config.kt index ab547569b..0fe9abfc3 100644 --- a/pact-jvm-server/src/main/kotlin/au/com/dius/pact/server/Config.kt +++ b/pact-jvm-server/src/main/kotlin/au/com/dius/pact/server/Config.kt @@ -14,7 +14,7 @@ data class Config @JvmOverloads constructor( val broker: String = "", val authToken: String = "" ) { - // Scala can't access the copy method correctly + // Scala/Groovy can't access the copy method correctly fun copyPort(port: Int) = this.copy(port = port) fun copyHost(host: String) = this.copy(host = host) fun copyDaemon(daemon: Boolean) = this.copy(daemon = daemon) diff --git a/pact-jvm-server/src/main/kotlin/au/com/dius/pact/server/PactJvmServer.kt b/pact-jvm-server/src/main/kotlin/au/com/dius/pact/server/PactJvmServer.kt new file mode 100644 index 000000000..53f1b0333 --- /dev/null +++ b/pact-jvm-server/src/main/kotlin/au/com/dius/pact/server/PactJvmServer.kt @@ -0,0 +1,70 @@ +package au.com.dius.pact.server + +import au.com.dius.pact.core.support.isNotEmpty +import ch.qos.logback.classic.Level +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.main +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.arguments.optional +import com.github.ajalt.clikt.parameters.options.flag +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.types.int +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +class PactJvmServer: CliktCommand() { + val port: Int? by argument(help = "port to run on (defaults to 29999)").int().optional() + val host by option("-h", "--host", help = "host to bind to (defaults to localhost)") + val portLowerBound: Int? by option("-l", "--mock-port-lower", help = "lower bound to allocate mock ports (defaults to 20000)").int() + val portUpperBound: Int? by option("-u", "--mock-port-upper", help = "upper bound to allocate mock ports (defaults to 40000)").int() + val daemon by option("--daemon", "-d", help = "run as a daemon process").flag(default = false) + val debug by option("--debug", help = "run with debug logging").flag(default = false) + val pactVersion: Int? by option("-v", "--pact-version", help = "pact version to generate for (2 or 3)").int() + val keystorePath by option("-k", "--keystore-path", help = "Path to keystore") + val keystorePassword by option("-p", "--keystore-password", help = "Keystore password") + val sslPort: Int? by option("-s", "--ssl-port", help = "Ssl port the mock server should run on. lower and upper bounds are ignored").int() + val brokerUrl by option("-b", "--broker", help = "URL of broker where to publish contracts to") + val brokerToken by option("-t", "--token", help = "Auth token for publishing the pact to broker") + + override fun run() { + var config = Config(daemon = daemon, debug = debug) + if (port != null) config = config.copy(port = port!!) + if (host != null) config = config.copy(host = host!!) + if (portLowerBound != null) config = config.copy(portLowerBound = portLowerBound!!) + if (portUpperBound != null) config = config.copy(portUpperBound = portUpperBound!!) + if (pactVersion != null) config = config.copy(pactVersion = pactVersion!!) + if (keystorePath != null) config = config.copy(keystorePath = keystorePath!!) + if (keystorePassword != null) config = config.copy(keystorePassword = keystorePassword!!) + if (sslPort != null) config = config.copy(sslPort = sslPort!!) + if (brokerUrl != null) config = config.copy(broker = brokerUrl!!) + if (brokerToken != null) config = config.copy(authToken = brokerToken!!) + + val logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) as ch.qos.logback.classic.Logger + if (debug) { + logger.setLevel(Level.DEBUG) + } else { + logger.setLevel(Level.INFO) + } + + val mainServer = MainServer(ServerStateStore(), config) + + if (keystorePath.isNotEmpty()) { + echo("Using keystore '${keystorePath}' for mock https server") + } + + echo("starting main server at ${config.host} on port ${config.port}") + if (!config.daemon) { + mainServer.server.start(false) + echo("press enter to stop server:\n") + readLine() + mainServer.server.stop(100, 1000) + } else { + mainServer.server.start(true) + } + } + + companion object { + @JvmStatic + fun main(args: Array) = PactJvmServer().main(args) + } +} diff --git a/pact-jvm-server/src/main/scala/au/com/dius/pact/server/Server.scala b/pact-jvm-server/src/main/scala/au/com/dius/pact/server/Server.scala deleted file mode 100644 index 372bafd78..000000000 --- a/pact-jvm-server/src/main/scala/au/com/dius/pact/server/Server.scala +++ /dev/null @@ -1,48 +0,0 @@ -package au.com.dius.pact.server - -import ch.qos.logback.classic.Level -import org.slf4j.{Logger, LoggerFactory} - -object Server extends App { - - val parser = new scopt.OptionParser[Config]("pact-jvm-server") { - arg[Int]("port") optional() action { (x, c) => c.copyPort(x) } text("port to run on (defaults to 29999)") - help("help") text("prints this usage text") - opt[String]('h', "host") action { (x, c) => c.copyHost(x) } text("host to bind to (defaults to localhost)") - opt[Int]('l', "mock-port-lower") action { (x, c) => c.copyPortLowerBound(x) } text("lower bound to allocate mock ports (defaults to 20000)") - opt[Int]('u', "mock-port-upper") action { (x, c) => c.copyPortUpperBound(x) } text("upper bound to allocate mock ports (defaults to 40000)") - opt[Unit]('d', "daemon") action { (_, c) => c.copyDaemon(true) } text("run as a daemon process") - opt[Unit]("debug") action { (_, c) => c.copyDebug(true) } text("run with debug logging") - opt[Int]('v', "pact-version") action { (x, c) => c.copyPactVersion(x) } text("pact version to generate for (2 or 3)") - opt[String]('k', "keystore-path") action { (x, c) => c.copyKeystorePath(x) } text("Path to keystore") - opt[String]('p', "keystore-password") action { (x, c) => c.copyKeystorePassword(x) } text("Keystore password") - opt[Int]('s', "ssl-port") action { (x, c) => c.copySslPort(x) } text("Ssl port the mock server should run on. lower and upper bounds are ignored") - opt[String]('b', "broker") action {(x, c) => c.copyBroker(x)} text("URL of broker where to publish contracts to") - opt[String]('t', "token") action {(x, c) => c.copyAuthToken(x)} text("Auth token for publishing the pact to broker") - } - - parser.parse(args, new Config()) match { - case Some(config) => - val logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME).asInstanceOf[ch.qos.logback.classic.Logger] - if (config.getDebug) { - logger.setLevel(Level.DEBUG) - } else { - logger.setLevel(Level.INFO) - } - val mainServer = new MainServer(new ServerStateStore(), config) - - if (config.getKeystorePath.nonEmpty) { - println(s"Using keystore '${config.getKeystorePath}' for mock https server") - } - - println(s"starting main server at ${config.getHost} on port ${config.getPort}") - mainServer.getServer.start(true) - if (!config.getDaemon) { - readLine("press enter to stop server:\n") - mainServer.getServer.stop(100, 1000) - } - - case None => - parser.showUsage - } -} diff --git a/pact-jvm-server/src/test/groovy/au/com/dius/pact/server/ListServersSpec.groovy b/pact-jvm-server/src/test/groovy/au/com/dius/pact/server/ListServersSpec.groovy index e940d5726..a5294b9bc 100644 --- a/pact-jvm-server/src/test/groovy/au/com/dius/pact/server/ListServersSpec.groovy +++ b/pact-jvm-server/src/test/groovy/au/com/dius/pact/server/ListServersSpec.groovy @@ -1,7 +1,6 @@ package au.com.dius.pact.server import spock.lang.Specification -import static scala.collection.JavaConverters.mapAsScalaMap class ListServersSpec extends Specification { def 'empty state'() { diff --git a/pact-jvm-server/src/test/groovy/au/com/dius/pact/server/MainSpec.groovy b/pact-jvm-server/src/test/groovy/au/com/dius/pact/server/MainSpec.groovy index aeeded403..d8ffe9a06 100644 --- a/pact-jvm-server/src/test/groovy/au/com/dius/pact/server/MainSpec.groovy +++ b/pact-jvm-server/src/test/groovy/au/com/dius/pact/server/MainSpec.groovy @@ -19,26 +19,28 @@ class MainSpec extends Specification { then: result == 0 - out == '''Usage: pact-jvm-server [options] [port] + out == '''Usage: pact-jvm-server [] [] | - | port port to run on (defaults to 29999) - | --help prints this usage text - | -h, --host host to bind to (defaults to localhost) - | -l, --mock-port-lower - | lower bound to allocate mock ports (defaults to 20000) - | -u, --mock-port-upper - | upper bound to allocate mock ports (defaults to 40000) - | -d, --daemon run as a daemon process - | --debug run with debug logging - | -v, --pact-version - | pact version to generate for (2 or 3) - | -k, --keystore-path - | Path to keystore - | -p, --keystore-password - | Keystore password - | -s, --ssl-port Ssl port the mock server should run on. lower and upper bounds are ignored - | -b, --broker URL of broker where to publish contracts to - | -t, --token Auth token for publishing the pact to broker + |Options: + | -h, --host= host to bind to (defaults to localhost) + | -l, --mock-port-lower= lower bound to allocate mock ports (defaults to + | 20000) + | -u, --mock-port-upper= upper bound to allocate mock ports (defaults to + | 40000) + | -d, --daemon run as a daemon process + | --debug run with debug logging + | -v, --pact-version= pact version to generate for (2 or 3) + | -k, --keystore-path= Path to keystore + | -p, --keystore-password= + | Keystore password + | -s, --ssl-port= Ssl port the mock server should run on. lower + | and upper bounds are ignored + | -b, --broker= URL of broker where to publish contracts to + | -t, --token= Auth token for publishing the pact to broker + | --help Show this message and exit + | + |Arguments: + | port to run on (defaults to 29999) |'''.stripMargin('|') } diff --git a/settings.gradle b/settings.gradle index 314d1e977..d9a8798b2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,7 +26,7 @@ if (System.getenv('GITHUB_WORKFLOW') == null) { } // Scala does not support JDK 20+ -//include 'pact-jvm-server' +include 'pact-jvm-server' include 'pact-specification-test' include 'pact-publish' include 'compatibility-suite'