diff --git a/docker-compose.yml b/docker-compose.yml index 086b985..3fc8ad8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -113,6 +113,28 @@ services: depends_on: postgres: condition: service_healthy + kontor-javalin: + build: + context: ./kontor-javalin + dockerfile: Dockerfile + tags: + - kontor-javalin:0.2.0-SNAPSHOT + image: kontor-javalin:0.2.0-SNAPSHOT + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://kontor-javalin:8400/health"] + interval: 10s + timeout: 5s + retries: 3 + networks: + - database + - integration + - frontend + ports: + - 8400:8400 + depends_on: + postgres: + condition: service_healthy networks: integration: diff --git a/kontor-javalin/Dockerfile b/kontor-javalin/Dockerfile index 1cfd701..9e50434 100644 --- a/kontor-javalin/Dockerfile +++ b/kontor-javalin/Dockerfile @@ -1,5 +1,25 @@ -FROM alpine/java:21-jdk +# ----------------------------------------------------------------------- # +FROM gradle:9.2.1-jdk21 AS builder WORKDIR / -ADD build/libs/kontor-spring-0.2.0-SNAPSHOT.jar app.jar -EXPOSE 8000 -CMD ["java", "-jar", "-Dspring.profiles.active=prod", "-Dvaadin.productionMode=true", "app.jar"] +COPY ./src/main/ ./src/main/ +COPY ./build.gradle ./ +COPY ./gradle.properties ./ +COPY ./settings.gradle ./ +COPY ./gradle/libs.versions.toml ./gradle/ +RUN gradle build --no-daemon + +# ----------------------------------------------------------------------- # +FROM alpine/java:21-jre AS run + +RUN apk --no-cache add curl + +RUN adduser --system appuser +USER appuser + +COPY --from=builder --chown=appuser:appuser /build/libs/kontor-javalin-0.2.0-SNAPSHOT.jar app.jar + +EXPOSE 8400 +USER appuser + +CMD ["java", "-jar", "app.jar"] + diff --git a/kontor-javalin/api/build.gradle b/kontor-javalin/api/build.gradle deleted file mode 100644 index e2cb6db..0000000 --- a/kontor-javalin/api/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -plugins { - id 'application' -} - -dependencies { - implementation project(":models") // We need this dependency for serializing persons to JSON - implementation project(":services") // We'll make use of the InMemoryPersonReader soon - - implementation libs.javalin // Pulling in Javalin - implementation libs.jackson // For JSON serialization of persons - implementation libs.slf4j // To see some Javalin logging -} - -application { - mainClass = "de.thpeetz.kontor.api.Main" - mainModule = "de.thpeetz.kontor.api" -} diff --git a/kontor-javalin/api/src/main/java/module-info.java b/kontor-javalin/api/src/main/java/module-info.java deleted file mode 100644 index de9b448..0000000 --- a/kontor-javalin/api/src/main/java/module-info.java +++ /dev/null @@ -1,10 +0,0 @@ -module de.thpeetz.kontor.api { - requires io.javalin; - requires com.fasterxml.jackson.databind; - requires org.slf4j; - requires kotlin.stdlib; - - requires de.thpeetz.kontor.services; - - uses de.thpeetz.kontor.services.api.PersonReader; -} diff --git a/kontor-javalin/build.gradle b/kontor-javalin/build.gradle index d25e5a5..468a464 100644 --- a/kontor-javalin/build.gradle +++ b/kontor-javalin/build.gradle @@ -1,14 +1,28 @@ plugins { - id 'org.javamodularity.moduleplugin' version '2.0.0' apply false + id 'java' } -subprojects { - repositories { - mavenCentral() - } - apply plugin: "org.javamodularity.moduleplugin" +repositories { + mavenCentral() } +dependencies { + implementation libs.javalin // Pulling in Javalin + implementation libs.jackson // For JSON serialization of persons + implementation libs.slf4j // To see some Javalin logging +} + +task fatJar(type: Jar) { + manifest { + attributes 'Main-Class': 'de.thpeetz.kontor.api.Main' + } + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } + with jar +} + +build.dependsOn fatJar + wrapper { gradleVersion = "9.2.1" } diff --git a/kontor-javalin/models/build.gradle b/kontor-javalin/models/build.gradle deleted file mode 100644 index 483b849..0000000 --- a/kontor-javalin/models/build.gradle +++ /dev/null @@ -1,4 +0,0 @@ -plugins { - id 'java-library' -} - diff --git a/kontor-javalin/models/src/main/java/module-info.java b/kontor-javalin/models/src/main/java/module-info.java deleted file mode 100644 index 5cb3b7a..0000000 --- a/kontor-javalin/models/src/main/java/module-info.java +++ /dev/null @@ -1,4 +0,0 @@ -module de.thpeetz.kontor.models { - // We're exporting the only package we have in this subproject - exports de.thpeetz.kontor.models; -} diff --git a/kontor-javalin/services/build.gradle b/kontor-javalin/services/build.gradle deleted file mode 100644 index 7d12b82..0000000 --- a/kontor-javalin/services/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -plugins { - id 'java-library' -} - -dependencies { - implementation project(":models") // <-- add dependency to models subproject -} diff --git a/kontor-javalin/services/src/main/java/module-info.java b/kontor-javalin/services/src/main/java/module-info.java deleted file mode 100644 index 9112de2..0000000 --- a/kontor-javalin/services/src/main/java/module-info.java +++ /dev/null @@ -1,11 +0,0 @@ -import de.thpeetz.kontor.services.api.PersonReader; -import de.thpeetz.kontor.services.inmemory.InMemoryPersonReader; - -module de.thpeetz.kontor.services { - exports de.thpeetz.kontor.services.api; - - requires de.thpeetz.kontor.models; - - // We're telling the ServiceLoader that the InMemoryPersonReader provides the implementation for the PersonReader interface - provides PersonReader with InMemoryPersonReader; -} diff --git a/kontor-javalin/settings.gradle b/kontor-javalin/settings.gradle index d245e05..d6456e7 100644 --- a/kontor-javalin/settings.gradle +++ b/kontor-javalin/settings.gradle @@ -1,6 +1 @@ rootProject.name = 'kontor-javalin' - -include ':models' -include ':services' -include ':api' - diff --git a/kontor-javalin/api/src/main/java/de/thpeetz/kontor/api/Main.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/api/Main.java similarity index 55% rename from kontor-javalin/api/src/main/java/de/thpeetz/kontor/api/Main.java rename to kontor-javalin/src/main/java/de/thpeetz/kontor/api/Main.java index 32ee536..41b2baa 100644 --- a/kontor-javalin/api/src/main/java/de/thpeetz/kontor/api/Main.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/api/Main.java @@ -1,21 +1,20 @@ package de.thpeetz.kontor.api; -import com.fasterxml.jackson.databind.ObjectMapper; +import de.thpeetz.kontor.services.inmemory.InMemoryPersonReader; import io.javalin.Javalin; -import de.thpeetz.kontor.services.api.PersonReader; + +import java.util.HashMap; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.util.ServiceLoader; +import com.fasterxml.jackson.databind.ObjectMapper; public class Main { private static Logger logger = LoggerFactory.getLogger(Main.class); - private static short port = 7312; + private static short port = 8400; public static void main(String[] args) { - var personReader = ServiceLoader.load(PersonReader.class).findFirst().get(); // <-- Getting an implementation - // for the PersonReader interface - // from the ServiceLoader + var personReader = new InMemoryPersonReader(); var objMapper = new ObjectMapper(); var result = objMapper.valueToTree(personReader.getAll()); @@ -23,7 +22,15 @@ public class Main { var app = Javalin.create().start(port); app.get("/ping", ctx -> ctx.result("pong")); - app.get("/persons", ctx -> ctx.json(result)); + app.get("/health", ctx -> { + HashMap status = new HashMap<>(); + status.put("status", "ok"); + ctx.json(status); + }); + app.get("/persons", ctx -> { + logger.info("persons called"); + ctx.json(result); + }); logger.info("API's alive for real :-)))"); } diff --git a/kontor-javalin/models/src/main/java/de/thpeetz/kontor/models/Person.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/Person.java similarity index 100% rename from kontor-javalin/models/src/main/java/de/thpeetz/kontor/models/Person.java rename to kontor-javalin/src/main/java/de/thpeetz/kontor/models/Person.java diff --git a/kontor-javalin/services/src/main/java/de/thpeetz/kontor/services/api/PersonReader.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/services/api/PersonReader.java similarity index 99% rename from kontor-javalin/services/src/main/java/de/thpeetz/kontor/services/api/PersonReader.java rename to kontor-javalin/src/main/java/de/thpeetz/kontor/services/api/PersonReader.java index 032567a..a864fbe 100644 --- a/kontor-javalin/services/src/main/java/de/thpeetz/kontor/services/api/PersonReader.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/services/api/PersonReader.java @@ -1,7 +1,6 @@ package de.thpeetz.kontor.services.api; import de.thpeetz.kontor.models.Person; - import java.util.List; public interface PersonReader { diff --git a/kontor-javalin/services/src/main/java/de/thpeetz/kontor/services/inmemory/InMemoryPersonReader.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/services/inmemory/InMemoryPersonReader.java similarity index 99% rename from kontor-javalin/services/src/main/java/de/thpeetz/kontor/services/inmemory/InMemoryPersonReader.java rename to kontor-javalin/src/main/java/de/thpeetz/kontor/services/inmemory/InMemoryPersonReader.java index 4600d74..39442c7 100644 --- a/kontor-javalin/services/src/main/java/de/thpeetz/kontor/services/inmemory/InMemoryPersonReader.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/services/inmemory/InMemoryPersonReader.java @@ -6,6 +6,7 @@ import java.util.List; import de.thpeetz.kontor.services.api.PersonReader; public class InMemoryPersonReader implements PersonReader { + @Override public List getAll() { return List.of( diff --git a/kontor-spring/Dockerfile b/kontor-spring/Dockerfile index 1cfd701..575c521 100644 --- a/kontor-spring/Dockerfile +++ b/kontor-spring/Dockerfile @@ -1,5 +1,25 @@ -FROM alpine/java:21-jdk +# ----------------------------------------------------------------------- # +FROM gradle:8.7-jdk AS builder WORKDIR / -ADD build/libs/kontor-spring-0.2.0-SNAPSHOT.jar app.jar -EXPOSE 8000 +COPY ./src/main/ ./src/main/ +COPY ./frontend/ ./frontend/ +COPY ./build.gradle ./ +COPY ./gradle.properties ./ +COPY ./settings.gradle ./ +COPY ./gradle/libs.versions.toml ./gradle/ +RUN gradle bootJar --no-daemon + +# ----------------------------------------------------------------------- # +FROM alpine/java:21-jdk AS run + +RUN mkdir -p /logs + +RUN adduser --system appuser + +COPY --from=builder --chown=appuser:appuser /build/libs/kontor-spring-0.2.0-SNAPSHOT.jar app.jar +RUN chown appuser:root /logs + +EXPOSE 8100 +USER appuser CMD ["java", "-jar", "-Dspring.profiles.active=prod", "-Dvaadin.productionMode=true", "app.jar"] + diff --git a/kontor-spring/src/main/resources/logback-spring.xml b/kontor-spring/src/main/resources/logback-spring.xml index b085f8c..702b86e 100644 --- a/kontor-spring/src/main/resources/logback-spring.xml +++ b/kontor-spring/src/main/resources/logback-spring.xml @@ -1,7 +1,7 @@ - +