diff --git a/pom.xml b/pom.xml
index 6dbe33b..fe8a0ad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,6 +49,14 @@
io.quarkus
quarkus-rest-jackson
+
+ io.quarkus
+ quarkus-smallrye-stork
+
+
+ io.smallrye.stork
+ stork-service-registration-consul
+
io.quarkus
quarkus-junit
diff --git a/src/main/docker-compose/jvm.yml b/src/main/docker-compose/jvm.yml
new file mode 100644
index 0000000..53b1818
--- /dev/null
+++ b/src/main/docker-compose/jvm.yml
@@ -0,0 +1,22 @@
+services:
+ shikimori-metadata-service:
+ build:
+ context: ../../../.
+ dockerfile: src/main/docker/Dockerfile.jvm
+ container_name: shikimori-metadata-service
+ restart: on-failure
+ networks:
+ - anyame-consul
+ deploy:
+ resources:
+ limits:
+ memory: 512M
+ cpus: "1"
+ reservations:
+ memory: 128M
+ cpus: "0.3"
+
+networks:
+ anyame-consul:
+ name: anyame-consul
+ external: true
diff --git a/src/main/docker-compose/native.yml b/src/main/docker-compose/native.yml
new file mode 100644
index 0000000..bbbe8c7
--- /dev/null
+++ b/src/main/docker-compose/native.yml
@@ -0,0 +1,22 @@
+services:
+ shikimori-metadata-service:
+ build:
+ context: ../../../.
+ dockerfile: src/main/docker/Dockerfile.native-micro
+ container_name: shikimori-metadata-service
+ restart: on-failure
+ networks:
+ - anyame-consul
+ deploy:
+ resources:
+ limits:
+ memory: 512M
+ cpus: "1"
+ reservations:
+ memory: 128M
+ cpus: "0.3"
+
+networks:
+ anyame-consul:
+ name: anyame-consul
+ external: true
diff --git a/src/main/docker/Dockerfile.jvm b/src/main/docker/Dockerfile.jvm
index b491681..7fe95c4 100644
--- a/src/main/docker/Dockerfile.jvm
+++ b/src/main/docker/Dockerfile.jvm
@@ -80,7 +80,7 @@
# You can find more information about the UBI base runtime images and their configuration here:
# https://rh-openjdk.github.io/redhat-openjdk-containers/
###
-FROM registry.access.redhat.com/ubi9/openjdk-25:1.23
+FROM registry.access.redhat.com/ubi9/openjdk-25:1.24
ENV LANGUAGE='en_US:en'
diff --git a/src/main/java/com/backend/metadata/shikimori/ApplicationBeanProducer.java b/src/main/java/com/backend/metadata/shikimori/ApplicationBeanProducer.java
new file mode 100644
index 0000000..109f6b3
--- /dev/null
+++ b/src/main/java/com/backend/metadata/shikimori/ApplicationBeanProducer.java
@@ -0,0 +1,30 @@
+package com.backend.metadata.shikimori;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.jboss.logging.Logger;
+
+import io.quarkus.arc.lookup.LookupIfProperty;
+import io.vertx.core.Vertx;
+import io.vertx.ext.consul.ConsulClient;
+import io.vertx.ext.consul.ConsulClientOptions;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.inject.Produces;
+
+@ApplicationScoped
+public class ApplicationBeanProducer {
+ Logger logger = Logger.getLogger(ApplicationBeanProducer.class);
+
+ @ConfigProperty(name = "consul.host", defaultValue = "consul")
+ String host;
+ @ConfigProperty(name = "consul.port", defaultValue = "8500")
+ int port;
+
+ @Produces
+ @LookupIfProperty(name = "quarkus.stork.shikimori-search-service.service-registrar.type", stringValue = "consul")
+ public ConsulClient consulClient(Vertx vertx) {
+ return ConsulClient.create(vertx, new ConsulClientOptions()
+ .setHost(host)
+ .setPort(port));
+ }
+
+}
diff --git a/src/main/java/com/backend/metadata/shikimori/ApplicationLifecycle.java b/src/main/java/com/backend/metadata/shikimori/ApplicationLifecycle.java
new file mode 100644
index 0000000..c871d55
--- /dev/null
+++ b/src/main/java/com/backend/metadata/shikimori/ApplicationLifecycle.java
@@ -0,0 +1,56 @@
+package com.backend.metadata.shikimori;
+
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.jboss.logging.Logger;
+
+import io.quarkus.runtime.ShutdownEvent;
+import io.quarkus.runtime.StartupEvent;
+import io.vertx.ext.consul.ConsulClient;
+import io.vertx.ext.consul.ServiceOptions;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Observes;
+import jakarta.enterprise.inject.Instance;
+
+@ApplicationScoped
+public class ApplicationLifecycle {
+
+ @ConfigProperty(name = "quarkus.application.name")
+ private String appName;
+ @ConfigProperty(name = "quarkus.application.port", defaultValue = "8080")
+ private int port;
+
+ private Logger logger;
+ private Instance consulClient;
+ private ScheduledExecutorService executor;
+
+ public ApplicationLifecycle(Logger logger,
+ Instance consulClient,
+ ScheduledExecutorService executor) {
+ this.logger = logger;
+ this.consulClient = consulClient;
+ this.executor = executor;
+ }
+
+ void onStart(@Observes StartupEvent ev) {
+ if (consulClient.isResolvable()) {
+ executor.schedule(() -> {
+ consulClient.get().registerService(new ServiceOptions()
+ .setPort(port)
+ .setAddress(appName)
+ .setName(appName)
+ .setId(appName),
+ result -> logger.infof("Service %s-%d registered", appName, port));
+ }, 1000, TimeUnit.MILLISECONDS);
+ }
+ }
+
+ void onStop(@Observes ShutdownEvent ev) {
+ if (consulClient.isResolvable()) {
+ consulClient.get().deregisterService(appName + "-" + port,
+ result -> logger.infof("Service %s-%d deregistered", appName, port));
+ }
+ }
+}
diff --git a/src/main/java/com/backend/metadata/shikimori/resource/ShikimoriResource.java b/src/main/java/com/backend/metadata/shikimori/resource/ShikimoriResource.java
index bd9c984..b310a2f 100644
--- a/src/main/java/com/backend/metadata/shikimori/resource/ShikimoriResource.java
+++ b/src/main/java/com/backend/metadata/shikimori/resource/ShikimoriResource.java
@@ -19,6 +19,7 @@ public class ShikimoriResource {
}
@GET
+ @Path("/search")
public Anime findById(@QueryParam("id") String id) {
List result = shikimoriAPI.animes(1, 1, id, null, null);
if (result.isEmpty())
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 3e99f5e..9d77cb5 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,3 +1,4 @@
-# Shikimori API configuration
-shikimori-api/mp-rest/url=https://shikimori.one
-shikimori-api/mp-rest/scope=jakarta.inject.Singleton
+quarkus.application.name=shikimori-metadata-service
+
+quarkus.stork.shikimori-search-service.service-registrar.type=consul
+
diff --git a/src/test/java/com/backend/metadata/shikimori/service/GreetingResourceIT.java b/src/test/java/com/backend/metadata/shikimori/service/GreetingResourceIT.java
index 0adde8d..e343459 100644
--- a/src/test/java/com/backend/metadata/shikimori/service/GreetingResourceIT.java
+++ b/src/test/java/com/backend/metadata/shikimori/service/GreetingResourceIT.java
@@ -3,6 +3,6 @@ package com.backend.metadata.shikimori.service;
import io.quarkus.test.junit.QuarkusIntegrationTest;
@QuarkusIntegrationTest
-class GreetingResourceIT extends GreetingResourceTest {
+class GreetingResourceIT {
// Execute the same tests but in packaged mode.
}
diff --git a/src/test/java/com/backend/metadata/shikimori/service/GreetingResourceTest.java b/src/test/java/com/backend/metadata/shikimori/service/GreetingResourceTest.java
deleted file mode 100644
index e1e2d04..0000000
--- a/src/test/java/com/backend/metadata/shikimori/service/GreetingResourceTest.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.backend.metadata.shikimori.service;
-
-import io.quarkus.test.junit.QuarkusTest;
-import org.junit.jupiter.api.Test;
-
-import static io.restassured.RestAssured.given;
-import static org.hamcrest.CoreMatchers.is;
-
-@QuarkusTest
-class GreetingResourceTest {
- @Test
- void testHelloEndpoint() {
- given()
- .when().get("/hello")
- .then()
- .statusCode(200)
- .body(is("Hello from Quarkus REST"));
- }
-
-}
\ No newline at end of file