Skip to content

Commit

Permalink
Add a servletSpec setting to choose among runners
Browse files Browse the repository at this point in the history
  • Loading branch information
earldouglas committed Oct 23, 2024
1 parent 3724a34 commit d97ffe0
Show file tree
Hide file tree
Showing 72 changed files with 1,949 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
- uses: actions/setup-java@v1
with:
java-version: 11
- run: sbt javafmtCheckAll scalafmtCheckAll "scalafixAll --check" test scripted
- run: sbt javafmtCheckAll scalafmtCheckAll "scalafixAll --check" test publishLocal scripted
70 changes: 66 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,69 @@ ThisBuild / scalacOptions += s"-P:semanticdb:sourceroot:${baseDirectory.value}"
ThisBuild / libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % "test"
ThisBuild / Test / fork := true

lazy val warRunner =
lazy val warRunner_3_0 =
project
.in(file("runner"))
.in(file("runners/3.0"))
.settings(
name := "war-runner",
version := "3.0_" + version.value,
Compile / compile / javacOptions ++=
Seq(
"-source",
"11",
"-target",
"11",
"-g:lines"
),
crossPaths := false, // exclude Scala suffix from artifact names
autoScalaLibrary := false, // exclude scala-library from dependencies
libraryDependencies += "com.github.jsimone" % "webapp-runner" % "7.0.91.0"
)

lazy val warRunner_3_1 =
project
.in(file("runners/3.1"))
.settings(
name := "war-runner",
version := "3.1_" + version.value,
Compile / compile / javacOptions ++=
Seq(
"-source",
"11",
"-target",
"11",
"-g:lines"
),
crossPaths := false, // exclude Scala suffix from artifact names
autoScalaLibrary := false, // exclude scala-library from dependencies
libraryDependencies += "com.heroku" % "webapp-runner" % "8.5.68.1"
)

lazy val warRunner_4_0 =
project
.in(file("runners/4.0"))
.settings(
name := "war-runner",
version := "4.0_" + version.value,
Compile / compile / javacOptions ++=
Seq(
"-source",
"11",
"-target",
"11",
"-g:lines"
),
crossPaths := false, // exclude Scala suffix from artifact names
autoScalaLibrary := false, // exclude scala-library from dependencies
libraryDependencies += "com.heroku" % "webapp-runner" % "9.0.96.0"
)

lazy val warRunner_6_0 =
project
.in(file("runners/6.0"))
.settings(
name := "war-runner",
version := "6.0_" + version.value,
Compile / compile / javacOptions ++=
Seq(
"-source",
Expand Down Expand Up @@ -51,8 +109,12 @@ lazy val sbtWar =
buildInfoPackage := "com.earldouglas.sbt.war",
buildInfoKeys := Seq[BuildInfoKey](version)
)
.dependsOn(warRunner)
.aggregate(warRunner)
.aggregate(
warRunner_3_0,
warRunner_3_1,
warRunner_4_0,
warRunner_6_0
)

// Publish to Sonatype, https://www.scala-sbt.org/release/docs/Using-Sonatype.html
ThisBuild / credentials := List(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.earldouglas;

import java.io.IOException;

/** Launches a webapp composed of in-place resources, classes, and libraries. */
public class WebappComponentsRunner {

/**
* Load configuration from the file in the first argument, and use it to start a new
* WebappComponentsRunner.
*
* @param args the configuration filename to load and run
* @throws IOException if something goes wrong
*/
public static void main(final String[] args) throws IOException {
throw new RuntimeException("unsupported");
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
71 changes: 71 additions & 0 deletions runners/3.1/src/main/java/com/earldouglas/WarConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.earldouglas;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class WarConfiguration {

/** The port to use for the server, e.g. 8080 */
public final int port;

/** The .war file to serve. */
public final File warFile;

/**
* Read configuration from a file at the specified location.
*
* @param configurationFilename the configuration filename to load
* @throws IOException if something goes wrong
* @return WarConfiguration a loaded configuration
*/
public static WarConfiguration load(final String configurationFilename) throws IOException {
return WarConfiguration.load(new File(configurationFilename));
}

/**
* Read configuration from a file at the specified location.
*
* <p>The format of the file is a Properties file with the following fields:
*
* <ul>
* <li>port
* <li>warFile
* </ul>
*
* <p>Example:
*
* <pre>
* port=8989
* warFile=path/to/warfile.war
* </pre>
*
* @param configurationFile the configuration file to load
* @throws IOException if something goes wrong
* @return WarConfiguration a loaded configuration
*/
public static WarConfiguration load(final File configurationFile) throws IOException {

final InputStream inputStream = new FileInputStream(configurationFile);

final Properties properties = new Properties();
properties.load(inputStream);

return new WarConfiguration(
Integer.parseInt(properties.getProperty("port")),
new File(properties.getProperty("warFile")));
}

/**
* Construct a new configuration from the given parameters.
*
* @param port the port to use for the server, e.g. 8080
* @param warFile the .war file to serve
*/
public WarConfiguration(final int port, final File warFile) {
this.port = port;
this.warFile = warFile;
}
}
22 changes: 22 additions & 0 deletions runners/3.1/src/main/java/com/earldouglas/WarRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.earldouglas;

public class WarRunner {

/**
* Load configuration from the file in the first argument, and use it to start a new WarRunner.
*
* @param args the configuration filename to load and run
* @throws Exception if something goes wrong
*/
public static void main(final String[] args) throws Exception {

final WarConfiguration warConfiguration = WarConfiguration.load(args[0]);

final String[] warRunnerArgs =
new String[] {
"--port", Integer.toString(warConfiguration.port), warConfiguration.warFile.getPath(),
};

webapp.runner.launch.Main.main(warRunnerArgs);
}
}
Empty file.
Empty file.
Empty file.
Empty file.
1 change: 1 addition & 0 deletions runners/3.1/src/test/fakeproject/src/main/webapp/bar.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<marquee>bar</marquee>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
div.raz { font-weight: bold; }
1 change: 1 addition & 0 deletions runners/3.1/src/test/fakeproject/src/main/webapp/foo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<blink>foo</blink>
2 changes: 2 additions & 0 deletions runners/3.1/src/test/resources/war.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
port=8988
warFile=src/test/fakeproject/src/main/webapp
8 changes: 8 additions & 0 deletions runners/3.1/src/test/resources/webapp-components.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
hostname=localhost
port=8989
contextPath=
emptyWebappDir=target/empty
emptyClassesDir=target/empty
resourceMap=bar.html->src/test/fakeproject/src/main/webapp/bar.html,\
foo.html->src/test/fakeproject/src/main/webapp/foo.html,\
baz/raz.css->src/test/fakeproject/src/main/webapp/baz/raz.css
64 changes: 64 additions & 0 deletions runners/3.1/src/test/scala/com/earldouglas/HttpClient.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.earldouglas

import java.net.HttpURLConnection
import java.net.URI
import scala.collection.JavaConverters._
import scala.io.Source

object HttpClient {

case class Response(
status: Int,
headers: Map[String, String],
body: String
)

def request(
method: String,
url: String,
headers: Map[String, String],
body: Option[String]
): Response = {

val c =
new URI(url)
.toURL()
.openConnection()
.asInstanceOf[HttpURLConnection]

c.setInstanceFollowRedirects(false)
c.setRequestMethod(method)
c.setDoInput(true)
c.setDoOutput(body.isDefined)

headers foreach { case (k, v) =>
c.setRequestProperty(k, v)
}

body foreach { b =>
c.getOutputStream.write(b.getBytes("UTF-8"))
}

val response =
Response(
status = c.getResponseCode(),
headers = c
.getHeaderFields()
.asScala
.filter({ case (k, _) => k != null })
.map({ case (k, v) => (k, v.asScala.mkString(",")) })
.toMap - "Date" - "Content-Length" - "Server",
body = Source.fromInputStream {
if (c.getResponseCode() < 400) {
c.getInputStream
} else {
c.getErrorStream
}
}.mkString
)

c.disconnect()

response
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.earldouglas

import org.scalatest.BeforeAndAfterAll
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

import java.io.File

class WarConfigurationTest
extends AnyFunSuite
with Matchers
with BeforeAndAfterAll {

test("load") {

val configuration: WarConfiguration =
WarConfiguration.load("src/test/resources/war.properties")

configuration.port shouldBe 8988

configuration.warFile shouldBe
new File("src/test/fakeproject/src/main/webapp")
}
}
Loading

0 comments on commit d97ffe0

Please sign in to comment.