From 7c33bbdae576aca8558a7e96b83dcb3fce5562f9 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Wed, 11 Dec 2024 14:54:04 +0700 Subject: [PATCH] feat: add basic healthcheck endpoint --- java/app/src/main/java/org/vss/KVStore.java | 2 + .../main/java/org/vss/api/HealthCheckApi.java | 45 +++++++++++++++++++ .../main/java/org/vss/api/VssApiEndpoint.java | 1 + .../impl/postgres/PostgresBackendImpl.java | 14 ++++++ 4 files changed, 62 insertions(+) create mode 100644 java/app/src/main/java/org/vss/api/HealthCheckApi.java diff --git a/java/app/src/main/java/org/vss/KVStore.java b/java/app/src/main/java/org/vss/KVStore.java index ea09991..e4ed960 100644 --- a/java/app/src/main/java/org/vss/KVStore.java +++ b/java/app/src/main/java/org/vss/KVStore.java @@ -11,4 +11,6 @@ public interface KVStore { DeleteObjectResponse delete(String userToken, DeleteObjectRequest request); ListKeyVersionsResponse listKeyVersions(String userToken, ListKeyVersionsRequest request); + + void checkHealth(); } diff --git a/java/app/src/main/java/org/vss/api/HealthCheckApi.java b/java/app/src/main/java/org/vss/api/HealthCheckApi.java new file mode 100644 index 0000000..6b29116 --- /dev/null +++ b/java/app/src/main/java/org/vss/api/HealthCheckApi.java @@ -0,0 +1,45 @@ +package org.vss.api; + +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import lombok.extern.slf4j.Slf4j; +import org.vss.GetObjectRequest; +import org.vss.GetObjectResponse; +import org.vss.KVStore; +import org.vss.auth.AuthResponse; +import org.vss.auth.Authorizer; + +@Path(VssApiEndpoint.HEALTHCHECK) +@Slf4j +public class HealthCheckApi { + KVStore kvStore; + + @Inject + public HealthCheckApi(KVStore kvstore) { + this.kvStore = kvstore; + } + + @GET + public Response execute(@Context HttpHeaders headers) { + try { + log.info("Healthcheck requested"); + kvStore.checkHealth(); + log.info("Healthcheck passed"); + + return Response + .status(Response.Status.OK) + .build(); + } catch (Exception e) { + log.error("Exception in HealthCheckApi: ", e); + return Response.status(500) + .entity("an unexpected error occurred: " + e.getMessage()) + .build(); + } + } +} diff --git a/java/app/src/main/java/org/vss/api/VssApiEndpoint.java b/java/app/src/main/java/org/vss/api/VssApiEndpoint.java index 983bc27..b4171a7 100644 --- a/java/app/src/main/java/org/vss/api/VssApiEndpoint.java +++ b/java/app/src/main/java/org/vss/api/VssApiEndpoint.java @@ -1,6 +1,7 @@ package org.vss.api; public class VssApiEndpoint { + public static final String HEALTHCHECK = "/health"; public static final String GET_OBJECT = "/getObject"; public static final String PUT_OBJECTS = "/putObjects"; public static final String DELETE_OBJECT = "/deleteObject"; diff --git a/java/app/src/main/java/org/vss/impl/postgres/PostgresBackendImpl.java b/java/app/src/main/java/org/vss/impl/postgres/PostgresBackendImpl.java index c9330d8..749c610 100644 --- a/java/app/src/main/java/org/vss/impl/postgres/PostgresBackendImpl.java +++ b/java/app/src/main/java/org/vss/impl/postgres/PostgresBackendImpl.java @@ -47,6 +47,20 @@ public PostgresBackendImpl(DSLContext context) { this.context = context; } + @Override + public void checkHealth() { + OffsetDateTime yesterday = OffsetDateTime.now().minusDays(1); + + VssDbRecord vssDbRecord = context.selectFrom(VSS_DB) + .where(VSS_DB.LAST_UPDATED_AT.gt(yesterday)) + .limit(1) + .fetchOne(); + + if (vssDbRecord == null) { + throw new IllegalStateException("No recent records found"); + } + } + @Override public GetObjectResponse get(String userToken, GetObjectRequest request) {