From 1b1ad16eb5d24000bd3cc8042b49cf0ae1bac7ac Mon Sep 17 00:00:00 2001 From: Jerrico Gamis Date: Wed, 20 Mar 2024 07:35:43 +0900 Subject: [PATCH] * Add build info controller * Add tests * Do not use HTTPS * Upgrade dependencies --- .github/workflows/build.yml | 2 ++ Makefile | 2 ++ generate-build-info.sh | 12 +++++++ pom.xml | 7 +++- .../controller/BuildInfoController.java | 33 +++++++++++++++++++ src/main/resources/application.yml | 3 +- .../spring/boot/java/example/BaseAppTest.java | 16 +++++++++ .../java/example/BuildInfoControllerTest.java | 21 ++++++++++++ .../java/example/ProbeControllerTest.java | 25 ++++++++++++++ .../boot/java/example/RootControllerTest.java | 19 +++++++++++ 10 files changed, 137 insertions(+), 3 deletions(-) create mode 100755 generate-build-info.sh create mode 100644 src/main/java/spring/boot/java/example/controller/BuildInfoController.java create mode 100644 src/test/java/spring/boot/java/example/BaseAppTest.java create mode 100644 src/test/java/spring/boot/java/example/BuildInfoControllerTest.java create mode 100644 src/test/java/spring/boot/java/example/ProbeControllerTest.java create mode 100644 src/test/java/spring/boot/java/example/RootControllerTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3e04de4..4545129 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,6 +26,8 @@ jobs: restore-keys: ${{ runner.os }}-m2 - name: Generate keystore run: ./generate-keystore.sh + - name: Generate build info + run: ./generate-build-info.sh - name: Build with Maven run: mvn --batch-mode --update-snapshots verify - name: Extract metadata (tags, labels) for Docker diff --git a/Makefile b/Makefile index ca45118..869ae53 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,8 @@ run-bash: docker run -i -t $(IMAGE_NAME):$(IMAGE_TAG) /bin/bash keystore: @./generate-keystore.sh +build-info: + @./generate-build-info.sh chart: cd deployment/k8s/helm && make package all: dist image chart diff --git a/generate-build-info.sh b/generate-build-info.sh new file mode 100755 index 0000000..d900c3d --- /dev/null +++ b/generate-build-info.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +BRANCH=$(git rev-parse --abbrev-ref HEAD) +VERSION=$(git rev-parse HEAD) +BUILD_TIME=$(date +"%Y-%m-%dT%H:%M:%S%z") +BUILD_INFO_FILE=./src/main/resources/build-info.json + +cat < ${BUILD_INFO_FILE} +{ "branch": "${BRANCH}", "build-time": "${BUILD_TIME}", "version": "${VERSION}" } +EOF + +echo "Wrote $BUILD_INFO_FILE" && cat ${BUILD_INFO_FILE} diff --git a/pom.xml b/pom.xml index c0fd76d..ad43a74 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.0 + 3.2.3 @@ -79,6 +79,11 @@ guava 33.1.0-jre + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/src/main/java/spring/boot/java/example/controller/BuildInfoController.java b/src/main/java/spring/boot/java/example/controller/BuildInfoController.java new file mode 100644 index 0000000..14477d4 --- /dev/null +++ b/src/main/java/spring/boot/java/example/controller/BuildInfoController.java @@ -0,0 +1,33 @@ +package spring.boot.java.example.controller; + +import com.google.common.io.Resources; +import io.micrometer.core.annotation.Timed; +import org.springframework.http.CacheControl; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; +import java.nio.charset.Charset; + +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +@RestController +public class BuildInfoController { + private static String buildInfo = loadBuildInfo(); + + private static String loadBuildInfo() { + try { + return Resources.toString(Resources.getResource("build-info.json"), Charset.defaultCharset()); + } catch (IOException e) { + return "{}"; + } + } + + @RequestMapping(path = {"/buildInfo"}, method = {GET}, produces = {"application/json"}) + @Timed + public ResponseEntity buildInfo() { + return ResponseEntity.ok().cacheControl(CacheControl.noStore()).body(buildInfo); + } + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 296f6ea..2575850 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -9,8 +9,7 @@ server: enabled: true port: 8443 ssl: - key-store: classpath:keystore.pfx - key-store-password: changeit + enabled: false management: endpoints: diff --git a/src/test/java/spring/boot/java/example/BaseAppTest.java b/src/test/java/spring/boot/java/example/BaseAppTest.java new file mode 100644 index 0000000..0dd8c31 --- /dev/null +++ b/src/test/java/spring/boot/java/example/BaseAppTest.java @@ -0,0 +1,16 @@ +package spring.boot.java.example; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles({"dev"}) +public class BaseAppTest { + @Autowired + protected TestRestTemplate restTemplate; + @LocalServerPort + protected int port = 0; +} diff --git a/src/test/java/spring/boot/java/example/BuildInfoControllerTest.java b/src/test/java/spring/boot/java/example/BuildInfoControllerTest.java new file mode 100644 index 0000000..2fe114c --- /dev/null +++ b/src/test/java/spring/boot/java/example/BuildInfoControllerTest.java @@ -0,0 +1,21 @@ +package spring.boot.java.example; + + +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static java.lang.String.format; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class BuildInfoControllerTest extends BaseAppTest { + + @Test + public void testBuildInfo() { + var response = restTemplate.getForObject(format("http://127.0.0.1:%d/buildInfo", port), Map.class); + assertNotNull(response.get("version")); + assertNotNull(response.get("branch")); + assertNotNull(response.get("build-time")); + } + +} diff --git a/src/test/java/spring/boot/java/example/ProbeControllerTest.java b/src/test/java/spring/boot/java/example/ProbeControllerTest.java new file mode 100644 index 0000000..401b5d0 --- /dev/null +++ b/src/test/java/spring/boot/java/example/ProbeControllerTest.java @@ -0,0 +1,25 @@ +package spring.boot.java.example; + + +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static java.lang.String.format; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ProbeControllerTest extends BaseAppTest { + + @Test + public void testLivenessProbe() { + var response = restTemplate.getForObject(format("http://127.0.0.1:%d/probe/live", port), Map.class); + assertEquals("I'm alive!", response.get("message")); + } + + @Test + public void testReadinessProbe() { + var response = restTemplate.getForObject(format("http://127.0.0.1:%d/probe/ready", port), Map.class); + assertEquals("I'm ready!", response.get("message")); + } + +} diff --git a/src/test/java/spring/boot/java/example/RootControllerTest.java b/src/test/java/spring/boot/java/example/RootControllerTest.java new file mode 100644 index 0000000..086a536 --- /dev/null +++ b/src/test/java/spring/boot/java/example/RootControllerTest.java @@ -0,0 +1,19 @@ +package spring.boot.java.example; + + +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static java.lang.String.format; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class RootControllerTest extends BaseAppTest { + + @Test + public void testRootEndPoint() { + var response = restTemplate.getForObject(format("http://127.0.0.1:%d/", port), Map.class); + assertEquals("It works on my machine!", response.get("message")); + } + +}