diff --git a/utils/_context/containers.py b/utils/_context/containers.py
index 43b5275fcc..248362768f 100644
--- a/utils/_context/containers.py
+++ b/utils/_context/containers.py
@@ -698,7 +698,7 @@ def configure(self, replay):
)
# https://github.com/DataDog/system-tests/issues/2799
- if self.library in ("cpp", "dotnet", "nodejs", "php", "python", "golang", "ruby"):
+ if self.library in ("cpp", "dotnet", "nodejs", "php", "python", "golang", "ruby", "java"):
self.healthcheck = {
"test": f"curl --fail --silent --show-error --max-time 2 localhost:{self.port}/healthcheck",
"retries": 60,
@@ -727,7 +727,7 @@ def post_start(self):
# new way of getting info from the weblog. Only working for nodejs and python right now
# https://github.com/DataDog/system-tests/issues/2799
- if self.library in ("cpp", "dotnet", "nodejs", "python", "php", "golang", "ruby"):
+ if self.library in ("cpp", "dotnet", "nodejs", "python", "php", "golang", "ruby", "java"):
with open(self.healthcheck_log_file, mode="r", encoding="utf-8") as f:
data = json.load(f)
lib = data["library"]
diff --git a/utils/build/docker/java/akka-http/pom.xml b/utils/build/docker/java/akka-http/pom.xml
index 41b3644a73..6489065085 100644
--- a/utils/build/docker/java/akka-http/pom.xml
+++ b/utils/build/docker/java/akka-http/pom.xml
@@ -91,6 +91,11 @@
jaxb-api
2.3.0
+
+ io.spray
+ spray-json_2.13
+ 1.3.6
+
diff --git a/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/HealthcheckRoutes.scala b/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/HealthcheckRoutes.scala
new file mode 100644
index 0000000000..9c746a98de
--- /dev/null
+++ b/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/HealthcheckRoutes.scala
@@ -0,0 +1,41 @@
+package com.datadoghq.akka_http
+
+import akka.http.scaladsl.model._
+import akka.http.scaladsl.server.Directives._
+import akka.http.scaladsl.server.Route
+import scala.io.Source
+import spray.json._
+import scala.util.{Failure, Success, Try}
+
+object HealthcheckRoutes {
+
+ def route: Route = path("healthcheck") {
+ get {
+ val version: String = getVersion match {
+ case Success(v) => v
+ case Failure(_) => throw new RuntimeException("Can't get version")
+ }
+
+ val library = JsObject(
+ "language" -> JsString("java"),
+ "version" -> JsString(version)
+ )
+
+ val response = JsObject(
+ "status" -> JsString("ok"),
+ "library" -> library
+ )
+
+ complete(HttpEntity(ContentTypes.`application/json`, response.prettyPrint))
+ }
+ }
+
+ private def getVersion: Try[String] = {
+ Try {
+ val source = Source.fromResource("dd-java-agent.version")
+ val version = source.getLines().toList.headOption.getOrElse(throw new RuntimeException("File is empty"))
+ source.close()
+ version
+ }
+ }
+}
diff --git a/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/Main.scala b/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/Main.scala
index 21a3ee0509..d4f7376c57 100644
--- a/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/Main.scala
+++ b/utils/build/docker/java/akka-http/src/main/scala/com/datadoghq/akka_http/Main.scala
@@ -1,16 +1,21 @@
package com.datadoghq.akka_http
import akka.http.scaladsl.Http
+import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
+import akka.http.scaladsl.server.Route
+
import com.datadoghq.system_tests.iast.infra.{LdapServer, SqlServer}
import org.slf4j.LoggerFactory
import scala.concurrent.Future
+import scala.io.Source
+import scala.util.{Failure, Success, Try}
object Main extends App {
private val bindingFuture: Future[Http.ServerBinding] =
- Http().newServerAt("0.0.0.0", 7777).bindFlow(AppSecRoutes.route ~ IastRoutes.route ~ RaspRoutes.route)
+ Http().newServerAt("0.0.0.0", 7777).bindFlow(AppSecRoutes.route ~ IastRoutes.route ~ RaspRoutes.route ~ HealthcheckRoutes.route)
LoggerFactory.getLogger(this.getClass).info("Server online at port 7777")
}
diff --git a/utils/build/docker/java/jersey-grizzly2/src/main/java/com/datadoghq/jersey/MyResource.java b/utils/build/docker/java/jersey-grizzly2/src/main/java/com/datadoghq/jersey/MyResource.java
index c52f7674c0..1e06064ff6 100644
--- a/utils/build/docker/java/jersey-grizzly2/src/main/java/com/datadoghq/jersey/MyResource.java
+++ b/utils/build/docker/java/jersey-grizzly2/src/main/java/com/datadoghq/jersey/MyResource.java
@@ -21,8 +21,13 @@
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
+import java.util.HashMap;
import java.util.List;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
import com.fasterxml.jackson.databind.ObjectMapper;
@SuppressWarnings("Convert2MethodRef")
@@ -42,6 +47,36 @@ public String hello() {
}
}
+ @GET
+ @Path("/healthcheck")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Map healthcheck() {
+ String version;
+
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(
+ getClass().getClassLoader().getResourceAsStream("dd-java-agent.version"),
+ StandardCharsets.ISO_8859_1))) {
+ String line = reader.readLine();
+ if (line == null) {
+ throw new RuntimeException("Can't get version");
+ }
+ version = line;
+ } catch (Exception e) {
+ throw new RuntimeException("Can't get version", e);
+ }
+
+ Map library = new HashMap<>();
+ library.put("language", "java");
+ library.put("version", version);
+
+ Map response = new HashMap<>();
+ response.put("status", "ok");
+ response.put("library", library);
+
+ return response;
+ }
+
@GET
@Path("/headers")
public Response headers() {
diff --git a/utils/build/docker/java/play/app/controllers/AppSecController.scala b/utils/build/docker/java/play/app/controllers/AppSecController.scala
index 2241af20e6..9177f0a2b2 100644
--- a/utils/build/docker/java/play/app/controllers/AppSecController.scala
+++ b/utils/build/docker/java/play/app/controllers/AppSecController.scala
@@ -16,6 +16,10 @@ import java.util
import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future, Promise}
+import java.io.BufferedReader
+import java.io.InputStreamReader
+import java.nio.charset.StandardCharsets
+import scala.util.{Failure, Success, Try}
@Singleton
class AppSecController @Inject()(cc: MessagesControllerComponents, ws: WSClient, mat: Materializer)
@@ -28,6 +32,36 @@ class AppSecController @Inject()(cc: MessagesControllerComponents, ws: WSClient,
}
}
+ def healthcheck = Action {
+ val version: String = getVersion match {
+ case Success(v) => v
+ case Failure(_) => "0.0.0"
+ }
+
+ // Créer l'objet JSON pour la réponse
+ val response = Json.obj(
+ "status" -> "ok",
+ "library" -> Json.obj(
+ "language" -> "java",
+ "version" -> version
+ )
+ )
+
+ Ok(response)
+ }
+
+ // Méthode pour lire la version du fichier
+ private def getVersion: Try[String] = {
+ Try {
+ val source = Option(getClass.getClassLoader.getResourceAsStream("dd-java-agent.version"))
+ .getOrElse(throw new RuntimeException("File not found"))
+ val reader = new BufferedReader(new InputStreamReader(source, StandardCharsets.ISO_8859_1))
+ val version = reader.readLine()
+ reader.close()
+ version
+ }
+ }
+
def headers = Action {
Results.Ok("012345678901234567890123456789012345678901")
.as("text/plain; charset=utf-8")
diff --git a/utils/build/docker/java/play/conf/routes b/utils/build/docker/java/play/conf/routes
index a86dd4b7d9..2ecabaf515 100644
--- a/utils/build/docker/java/play/conf/routes
+++ b/utils/build/docker/java/play/conf/routes
@@ -1,4 +1,5 @@
GET / controllers.AppSecController.index
+GET /healthcheck controllers.AppSecController.healthcheck
GET /headers controllers.AppSecController.headers
GET /tag_value/:value/:code controllers.AppSecController.tagValue(value: String, code: Int)
POST /tag_value/:value/:code controllers.AppSecController.tagValuePost(value: String, code: Int)
diff --git a/utils/build/docker/java/ratpack/src/main/java/com/datadoghq/ratpack/Main.java b/utils/build/docker/java/ratpack/src/main/java/com/datadoghq/ratpack/Main.java
index 861f090dd4..be87dd62c1 100644
--- a/utils/build/docker/java/ratpack/src/main/java/com/datadoghq/ratpack/Main.java
+++ b/utils/build/docker/java/ratpack/src/main/java/com/datadoghq/ratpack/Main.java
@@ -11,14 +11,19 @@
import ratpack.http.HttpMethod;
import ratpack.http.Response;
import ratpack.server.RatpackServer;
+import ratpack.jackson.Jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.InetAddress;
import java.util.logging.LogManager;
+import java.util.Optional;
import java.util.HashMap;
import java.net.HttpURLConnection;
@@ -60,6 +65,16 @@ private static final Map createMetadata() {
return h;
}
+ private static Optional getVersion() {
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("dd-java-agent.version"), StandardCharsets.ISO_8859_1))) {
+ String line = reader.readLine();
+ return Optional.ofNullable(line);
+ } catch (Exception e) {
+ return Optional.empty();
+ }
+ }
+
private static void setRootSpanTag(final String key, final String value) {
final Span span = GlobalTracer.get().activeSpan();
if (span instanceof MutableSpan) {
@@ -90,6 +105,18 @@ public static void main(String[] args) throws Exception {
span.finish();
}
})
+ .get("healthcheck", ctx -> {
+ String version = getVersion().orElse("0.0.0");
+
+ Map response = new HashMap<>();
+ Map library = new HashMap<>();
+ library.put("language", "java");
+ library.put("version", version);
+ response.put("status", "ok");
+ response.put("library", library);
+
+ ctx.render(Jackson.json(response));
+ })
.get("headers", ctx -> {
Response response = ctx.getResponse();
response.getHeaders()
diff --git a/utils/build/docker/java/resteasy-netty3/src/main/java/com/datadoghq/resteasy/MyResource.java b/utils/build/docker/java/resteasy-netty3/src/main/java/com/datadoghq/resteasy/MyResource.java
index 57981fc7eb..20e018def5 100644
--- a/utils/build/docker/java/resteasy-netty3/src/main/java/com/datadoghq/resteasy/MyResource.java
+++ b/utils/build/docker/java/resteasy-netty3/src/main/java/com/datadoghq/resteasy/MyResource.java
@@ -24,6 +24,10 @@
import java.util.Map;
import java.util.List;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
import com.fasterxml.jackson.databind.ObjectMapper;
@Path("/")
@@ -42,6 +46,36 @@ public String hello() {
}
}
+ @GET
+ @Path("/healthcheck")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Map healthcheck() {
+ String version;
+
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(
+ getClass().getClassLoader().getResourceAsStream("dd-java-agent.version"),
+ StandardCharsets.ISO_8859_1))) {
+ String line = reader.readLine();
+ if (line == null) {
+ throw new RuntimeException("Can't get version");
+ }
+ version = line;
+ } catch (Exception e) {
+ throw new RuntimeException("Can't get version", e);
+ }
+
+ Map library = new HashMap<>();
+ library.put("language", "java");
+ library.put("version", version);
+
+ Map response = new HashMap<>();
+ response.put("status", "ok");
+ response.put("library", library);
+
+ return response;
+ }
+
@GET
@Path("/headers")
public Response headers() {
diff --git a/utils/build/docker/java/spring-boot-3-native/src/main/java/com/datadoghq/springbootnative/WebController.java b/utils/build/docker/java/spring-boot-3-native/src/main/java/com/datadoghq/springbootnative/WebController.java
index 54f9a584c1..2443879bac 100644
--- a/utils/build/docker/java/spring-boot-3-native/src/main/java/com/datadoghq/springbootnative/WebController.java
+++ b/utils/build/docker/java/spring-boot-3-native/src/main/java/com/datadoghq/springbootnative/WebController.java
@@ -11,12 +11,16 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ResponseStatusException;
import jakarta.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -28,6 +32,36 @@ String home() {
return "Hello World!";
}
+ @RequestMapping("/healthcheck")
+ Map healtchcheck() {
+
+ String version;
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+
+ try (final BufferedReader reader =
+ new BufferedReader(
+ new InputStreamReader(
+ cl.getResourceAsStream("dd-java-agent.version"), StandardCharsets.ISO_8859_1))) {
+ String line = reader.readLine();
+ if (line == null) {
+ throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Can't get version");
+ }
+ version = line;
+ } catch (Exception e) {
+ throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Can't get version");
+ }
+
+ Map library = new HashMap<>();
+ library.put("language", "java");
+ library.put("version", version);
+
+ Map response = new HashMap<>();
+ response.put("status", "ok");
+ response.put("library", library);
+
+ return response;
+ }
+
@GetMapping("/headers")
String headers(HttpServletResponse response) {
response.setHeader("content-language", "en-US");
diff --git a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/App.java b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/App.java
index 5006755189..2173990e12 100644
--- a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/App.java
+++ b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/App.java
@@ -25,6 +25,12 @@
import datadog.trace.api.Trace;
import datadog.trace.api.experimental.*;
import datadog.trace.api.interceptor.MutableSpan;
+
+
+import java.nio.charset.StandardCharsets;
+import org.springframework.web.server.ResponseStatusException;
+
+
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
@@ -123,6 +129,36 @@ String home(HttpServletResponse response) {
return "Hello World!";
}
+ @RequestMapping("/healthcheck")
+ Map healtchcheck() {
+
+ String version;
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+
+ try (final BufferedReader reader =
+ new BufferedReader(
+ new InputStreamReader(
+ cl.getResourceAsStream("dd-java-agent.version"), StandardCharsets.ISO_8859_1))) {
+ String line = reader.readLine();
+ if (line == null) {
+ throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Can't get version");
+ }
+ version = line;
+ } catch (Exception e) {
+ throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Can't get version");
+ }
+
+ Map library = new HashMap<>();
+ library.put("language", "java");
+ library.put("version", version);
+
+ Map response = new HashMap<>();
+ response.put("status", "ok");
+ response.put("library", library);
+
+ return response;
+ }
+
@GetMapping("/headers")
String headers(HttpServletResponse response) {
response.setHeader("content-language", "en-US");
diff --git a/utils/build/docker/java/vertx3/pom.xml b/utils/build/docker/java/vertx3/pom.xml
index 088d825035..70854dcf2b 100644
--- a/utils/build/docker/java/vertx3/pom.xml
+++ b/utils/build/docker/java/vertx3/pom.xml
@@ -15,6 +15,11 @@
vertx-web
3.9.13
+
+ io.vertx
+ vertx-core
+ 3.9.13
+
io.opentracing
opentracing-api
diff --git a/utils/build/docker/java/vertx3/src/main/java/com/datadoghq/vertx3/Main.java b/utils/build/docker/java/vertx3/src/main/java/com/datadoghq/vertx3/Main.java
index 220ac7b609..dc30cb14df 100644
--- a/utils/build/docker/java/vertx3/src/main/java/com/datadoghq/vertx3/Main.java
+++ b/utils/build/docker/java/vertx3/src/main/java/com/datadoghq/vertx3/Main.java
@@ -30,6 +30,11 @@
import java.util.logging.LogManager;
import java.util.stream.Stream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+
import okhttp3.*;
public class Main {
@@ -63,6 +68,9 @@ public static void main(String[] args) {
span.finish();
}
});
+
+ router.get("/healthcheck").handler(Main::healthCheck);
+
router.get("/headers")
.produces("text/plain")
.handler(ctx -> ctx.response()
@@ -258,4 +266,32 @@ private static void consumeParsedBody(final RoutingContext ctx) {
ctx.getBodyAsString();
}
}
+
+
+ private static void healthCheck(RoutingContext context) {
+ String version = getVersion().orElse("0.0.0");
+
+ Map response = new HashMap<>();
+ Map library = new HashMap<>();
+ library.put("language", "java");
+ library.put("version", version);
+ response.put("status", "ok");
+ response.put("library", library);
+
+ JsonObject jsonResponse = new JsonObject(response);
+
+ context.response()
+ .putHeader("content-type", "application/json")
+ .end(jsonResponse.encode());
+ }
+
+ private static Optional getVersion() {
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("dd-java-agent.version"), StandardCharsets.ISO_8859_1))) {
+ String line = reader.readLine();
+ return Optional.ofNullable(line);
+ } catch (Exception e) {
+ return Optional.empty();
+ }
+ }
}
diff --git a/utils/build/docker/java/vertx4/pom.xml b/utils/build/docker/java/vertx4/pom.xml
index 6197079870..7762cfb024 100644
--- a/utils/build/docker/java/vertx4/pom.xml
+++ b/utils/build/docker/java/vertx4/pom.xml
@@ -15,6 +15,11 @@
vertx-web
4.4.0
+
+ io.vertx
+ vertx-core
+ 4.4.0
+
io.opentracing
opentracing-api
diff --git a/utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/Main.java b/utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/Main.java
index a3213ae76f..000a2846ad 100644
--- a/utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/Main.java
+++ b/utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/Main.java
@@ -29,6 +29,11 @@
import java.util.logging.LogManager;
import java.util.stream.Stream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+
import okhttp3.*;
public class Main {
@@ -62,6 +67,9 @@ public static void main(String[] args) {
span.finish();
}
});
+
+ router.get("/healthcheck").handler(Main::healthCheck);
+
router.get("/headers")
.produces("text/plain")
.handler(ctx -> ctx.response()
@@ -257,4 +265,31 @@ private static void consumeParsedBody(final RoutingContext ctx) {
ctx.getBodyAsString();
}
}
+
+ private static void healthCheck(RoutingContext context) {
+ String version = getVersion().orElse("0.0.0");
+
+ Map response = new HashMap<>();
+ Map library = new HashMap<>();
+ library.put("language", "java");
+ library.put("version", version);
+ response.put("status", "ok");
+ response.put("library", library);
+
+ JsonObject jsonResponse = new JsonObject(response);
+
+ context.response()
+ .putHeader("content-type", "application/json")
+ .end(jsonResponse.encode());
+ }
+
+ private static Optional getVersion() {
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("dd-java-agent.version"), StandardCharsets.ISO_8859_1))) {
+ String line = reader.readLine();
+ return Optional.ofNullable(line);
+ } catch (Exception e) {
+ return Optional.empty();
+ }
+ }
}