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(); + } + } }