diff --git a/template/java11-vert-x/Dockerfile b/template/java11-vert-x/Dockerfile index 7d2d139d..0ee354cb 100644 --- a/template/java11-vert-x/Dockerfile +++ b/template/java11-vert-x/Dockerfile @@ -1,46 +1,21 @@ -FROM openjdk:11-jdk-slim as builder - -ENV GRADLE_VER=6.1.1 -RUN apt-get update -qqy \ - && apt-get install -qqy \ - --no-install-recommends \ - curl \ - ca-certificates \ - unzip - -RUN mkdir -p /opt/ && cd /opt/ \ - && echo "Downloading gradle.." \ - && curl -sSfL "https://services.gradle.org/distributions/gradle-${GRADLE_VER}-bin.zip" -o gradle-$GRADLE_VER-bin.zip \ - && unzip gradle-$GRADLE_VER-bin.zip -d /opt/ \ - && rm gradle-$GRADLE_VER-bin.zip - -# Export some environment variables -ENV GRADLE_HOME=/opt/gradle-$GRADLE_VER/ -ENV PATH=$PATH:$GRADLE_HOME/bin - -RUN mkdir -p /home/app/libs +FROM gradle:7-jdk11 as builder ENV GRADLE_OPTS="-Dorg.gradle.daemon=false" WORKDIR /home/app COPY . /home/app/ -RUN gradle build +RUN gradle shadowJar RUN find . FROM ghcr.io/openfaas/of-watchdog:0.9.3 as watchdog -FROM openjdk:11-jre-slim as ship -RUN apt-get update -qqy \ - && apt-get install -qqy \ - --no-install-recommends \ - unzip +FROM openjdk:11-slim as ship COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog RUN chmod +x /usr/bin/fwatchdog WORKDIR /home/app -COPY --from=builder /home/app/entrypoint/build/distributions/entrypoint-1.0.zip ./entrypoint-1.0.zip -RUN unzip ./entrypoint-1.0.zip +COPY --from=builder /home/app/entrypoint/build/libs/entrypoint-1.0-all.jar ./entrypoint-1.0.jar RUN addgroup --system app \ && adduser --system --ingroup app app @@ -52,9 +27,8 @@ USER app ENV upstream_url="http://127.0.0.1:8082" ENV mode="http" -ENV CLASSPATH="/home/app/entrypoint-1.0/lib/*" -ENV fprocess="java -XX:+UseContainerSupport -Dvertx.cacheDirBase=/tmp/.vertx-cache com.openfaas.entrypoint.App" +ENV fprocess="java -XX:+UseContainerSupport -jar /home/app/entrypoint-1.0.jar" EXPOSE 8080 HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1 diff --git a/template/java11-vert-x/README.md b/template/java11-vert-x/README.md index a407c0c5..a4122843 100644 --- a/template/java11-vert-x/README.md +++ b/template/java11-vert-x/README.md @@ -2,7 +2,7 @@ The Java11-Vert.x template uses gradle as a build system. -Gradle version: 4.8.1 +Gradle version: 7.4 ### Structure @@ -11,15 +11,27 @@ There are two projects which make up a single gradle build: - function - (Library) your function code as a developer, you will only ever see this folder - entrypoint - (App) Vert.x HTTP server -### Handler +### Function -The handler is written in the `./src/main/java/com/openfaas/function/Handler.java` folder +The function is written in the `./src/main/java/com/openfaas/function/Handler.java` file Tests are supported with junit via files in `./src/test` +### Body Parsing + +HTTP Request body is disabled by default. This means that the environment variable `RAW_BODY` is set either missing or +set to `true`. When the variable is explicitly set to `false`, then vert.x internal BodyHandler is used. + +#### Limiting Body Length + +By default, vert.x allows any request body length. For security reasons or resource constraints, you might want to limit +this value. In order to do this set the `BODY_MAX_SIZE` environment variable to the allowed number of bytes, or `-1` for +unlimited. + ### External dependencies -External dependencies can be specified in ./build.gradle in the normal way using jcenter, a local JAR or some other remote repository. +External dependencies can be specified in ./build.gradle in the normal way using mavenCentral, a local JAR or some other +remote repository. ### Serve a "pure" static html web application @@ -52,6 +64,8 @@ functions: lang: java11-vert-x environment: FRONTAPP: true + RAW_BODY: false + MAX_BODY_SIZE: 102400 handler: ./function image: registry.test:5000/hello-vert-x:latest ``` diff --git a/template/java11-vert-x/build.gradle b/template/java11-vert-x/build.gradle index 6ad512d3..6082adf9 100644 --- a/template/java11-vert-x/build.gradle +++ b/template/java11-vert-x/build.gradle @@ -7,7 +7,7 @@ allprojects { repositories { - jcenter() + mavenCentral() } } diff --git a/template/java11-vert-x/entrypoint/build.gradle b/template/java11-vert-x/entrypoint/build.gradle index e4514524..c154f4e5 100644 --- a/template/java11-vert-x/entrypoint/build.gradle +++ b/template/java11-vert-x/entrypoint/build.gradle @@ -13,25 +13,31 @@ plugins { // Apply the application plugin to add support for building an application id 'application' + id("com.github.johnrengelman.shadow") version "6.0.0" } // Define the main class for the application -mainClassName = 'App' +mainClassName = 'io.vertx.core.Launcher' dependencies { // Vert.x project - compile 'io.vertx:vertx-web:3.5.4' + implementation 'io.vertx:vertx-web:4.2.4' // Use JUnit test framework - testCompile 'junit:junit:4.12' + testImplementation 'junit:junit:4.13.2' - compile project(':function') + implementation project(':function') } jar { manifest { - attributes 'Implementation-Title': 'OpenFaaS Function', - 'Implementation-Version': version + attributes( + 'Implementation-Title': 'OpenFaaS Function', + 'Implementation-Version': archiveVersion, + 'Main-Class': mainClassName, + 'Main-Command': 'run', + 'Main-Verticle': 'com.openfaas.entrypoint.App' + ) } } @@ -39,13 +45,5 @@ jar { repositories { // Use jcenter for resolving your dependencies. // You can declare any Maven/Ivy/file repository here. - jcenter() -} - -uploadArchives { - repositories { - flatDir { - dirs 'repos' - } - } + mavenCentral() } diff --git a/template/java11-vert-x/entrypoint/src/main/java/com/openfaas/entrypoint/App.java b/template/java11-vert-x/entrypoint/src/main/java/com/openfaas/entrypoint/App.java index 84c41bed..14ec5f58 100644 --- a/template/java11-vert-x/entrypoint/src/main/java/com/openfaas/entrypoint/App.java +++ b/template/java11-vert-x/entrypoint/src/main/java/com/openfaas/entrypoint/App.java @@ -2,34 +2,52 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. package com.openfaas.entrypoint; -import io.vertx.core.http.HttpServer; -import io.vertx.core.Vertx; +import com.openfaas.function.Handler; +import io.vertx.core.AbstractVerticle; +import io.vertx.core.Promise; +import io.vertx.ext.web.Route; import io.vertx.ext.web.Router; -import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.handler.BodyHandler; import io.vertx.ext.web.handler.StaticHandler; + +import java.util.Map; import java.util.Optional; -public class App { - public static void main(String[] args) throws Exception { - Vertx vertx = Vertx.vertx(); - Integer httpPort = Integer.parseInt(Optional.ofNullable(System.getenv("PORT")).orElse("8082")); - HttpServer server = vertx.createHttpServer(); - Router router = Router.router(vertx); +public class App extends AbstractVerticle { - if (Boolean.parseBoolean(Optional.ofNullable(System.getenv("FRONTAPP")).orElse("false"))) { - // serve static assets, see /resources/webroot directory - router.route("/*").handler(StaticHandler.create()); - } else { - io.vertx.core.Handler handler = new com.openfaas.function.Handler(); - router.route().handler(handler); + private void fatal(Throwable err) { + err.printStackTrace(); + vertx.close() + .onComplete(ar -> System.exit(-1)); } - server.requestHandler(router::accept).listen(httpPort, result -> { - if(result.succeeded()) { - System.out.println("Listening on port " + httpPort); - } else { - System.out.println("Unable to start server: " + result.cause().getMessage()); - } - }); - } + @Override + public void start(Promise start) { + final Router router = Router.router(vertx); + final Route route = router.route(); + + final Map env = System.getenv(); + // FRONTAPP + if (Boolean.parseBoolean(env.getOrDefault("FRONTAPP", "false"))) { + // serve static assets, see /resources/webroot directory + route.handler(StaticHandler.create()); + } else { + // RAW_BODY + final boolean rawBody = Boolean.parseBoolean(env.getOrDefault("RAW_BODY", "true")); + if (!rawBody) { + final int maxBodySize = Integer.parseInt(env.getOrDefault("RAW_BODY_SIZE", "-1")); + route.handler(BodyHandler.create().setBodyLimit(maxBodySize)); + } + final Handler fn = new Handler(); + route + .handler(fn::handle); + } + + vertx + .createHttpServer() + .requestHandler(router) + .listen(Integer.parseInt(Optional.ofNullable(System.getenv("PORT")).orElse("8082"))) + .onFailure(this::fatal) + .onSuccess(server -> System.out.println("Listening on port " + server.actualPort())); + } } diff --git a/template/java11-vert-x/function/build.gradle b/template/java11-vert-x/function/build.gradle index 2e8b4339..5425e198 100644 --- a/template/java11-vert-x/function/build.gradle +++ b/template/java11-vert-x/function/build.gradle @@ -13,15 +13,16 @@ plugins { dependencies { // Vert.x project - compile 'io.vertx:vertx-web:3.5.4' + implementation 'io.vertx:vertx-web:4.2.4' // Use JUnit test framework - testImplementation 'junit:junit:4.12' + testImplementation 'io.vertx:vertx-unit:4.2.4' + testImplementation 'junit:junit:4.13.2' } // In this section you declare where to find the dependencies of your project repositories { // Use jcenter for resolving your dependencies. // You can declare any Maven/Ivy/file repository here. - jcenter() + mavenCentral() } diff --git a/template/java11-vert-x/function/src/main/java/com/openfaas/function/Handler.java b/template/java11-vert-x/function/src/main/java/com/openfaas/function/Handler.java index 6736fc28..2aa60a76 100644 --- a/template/java11-vert-x/function/src/main/java/com/openfaas/function/Handler.java +++ b/template/java11-vert-x/function/src/main/java/com/openfaas/function/Handler.java @@ -3,15 +3,11 @@ import io.vertx.ext.web.RoutingContext; import io.vertx.core.json.JsonObject; -public class Handler implements io.vertx.core.Handler { +public class Handler { - public void handle(RoutingContext routingContext) { - routingContext.response() - .putHeader("content-type", "application/json;charset=UTF-8") - .end( - new JsonObject() - .put("status", "ok") - .encodePrettily() - ); - } + public void handle(RoutingContext ctx) { + ctx.json( + new JsonObject() + .put("status", "ok")); + } } diff --git a/template/java11-vert-x/function/src/test/java/HandlerTest.java b/template/java11-vert-x/function/src/test/java/HandlerTest.java index 99ab40a7..37e1bfb6 100644 --- a/template/java11-vert-x/function/src/test/java/HandlerTest.java +++ b/template/java11-vert-x/function/src/test/java/HandlerTest.java @@ -1,11 +1,23 @@ +import io.vertx.ext.unit.TestContext; +import io.vertx.ext.unit.junit.RunTestOnContext; +import io.vertx.ext.unit.junit.VertxUnitRunner; +import org.junit.Rule; import org.junit.Test; + import static org.junit.Assert.*; import com.openfaas.function.Handler; +import org.junit.runner.RunWith; +@RunWith(VertxUnitRunner.class) public class HandlerTest { - @Test public void handlerIsNotNull() { - Handler handler = new Handler(); - assertTrue("Expected handler not to be null", handler != null); - } + + @Rule + public RunTestOnContext rule = new RunTestOnContext(); + + @Test + public void handlerIsNotNull(TestContext should) { + Handler handler = new Handler(); + assertTrue("Expected handler not to be null", handler != null); + } }