diff --git a/instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/build.gradle.kts b/instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/build.gradle.kts new file mode 100644 index 000000000000..83eea88dfb1b --- /dev/null +++ b/instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id("otel.java-conventions") +} + +dependencies { + implementation(project(":testing-common")) + implementation("org.testcontainers:testcontainers") + + compileOnly("org.hibernate.reactive:hibernate-reactive-core:2.0.0.Final") + compileOnly("io.vertx:vertx-sql-client:4.4.2") + compileOnly("io.vertx:vertx-codegen:4.4.2") +} + +otelJava { + minJavaVersionSupported.set(JavaVersion.VERSION_11) +} diff --git a/instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/AbstractHibernateReactiveTest.java b/instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/AbstractHibernateReactiveTest.java new file mode 100644 index 000000000000..75313bb9a294 --- /dev/null +++ b/instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/AbstractHibernateReactiveTest.java @@ -0,0 +1,313 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.hibernate.reactive.v2_0; + +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv; +import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS; +import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_NAME; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SQL_TABLE; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_USER; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.vertx.core.Vertx; +import jakarta.persistence.EntityManagerFactory; +import java.time.Duration; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import org.hibernate.reactive.mutiny.Mutiny; +import org.hibernate.reactive.stage.Stage; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.output.Slf4jLogConsumer; + +@SuppressWarnings("InterruptedExceptionSwallowed") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public abstract class AbstractHibernateReactiveTest { + private static final Logger logger = LoggerFactory.getLogger(AbstractHibernateReactiveTest.class); + + private static final String USER_DB = "SA"; + private static final String PW_DB = "password123"; + private static final String DB = "tempdb"; + + @RegisterExtension + protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + protected final Vertx vertx = Vertx.vertx(); + private GenericContainer container; + private String host; + private int port; + private EntityManagerFactory entityManagerFactory; + private Mutiny.SessionFactory mutinySessionFactory; + private Stage.SessionFactory stageSessionFactory; + + protected abstract EntityManagerFactory createEntityManagerFactory() throws Exception; + + @BeforeAll + void setUp() throws Exception { + container = + new GenericContainer<>("postgres:9.6.8") + .withEnv("POSTGRES_USER", USER_DB) + .withEnv("POSTGRES_PASSWORD", PW_DB) + .withEnv("POSTGRES_DB", DB) + .withExposedPorts(5432) + .withLogConsumer(new Slf4jLogConsumer(logger)) + .withStartupTimeout(Duration.ofMinutes(2)); + container.start(); + + host = container.getHost(); + port = container.getMappedPort(5432); + System.setProperty("db.host", host); + System.setProperty("db.port", String.valueOf(port)); + + entityManagerFactory = createEntityManagerFactory(); + + Value value = new Value("name"); + value.setId(1L); + + mutinySessionFactory = entityManagerFactory.unwrap(Mutiny.SessionFactory.class); + stageSessionFactory = entityManagerFactory.unwrap(Stage.SessionFactory.class); + + mutinySessionFactory + .withTransaction((session, tx) -> session.merge(value)) + .await() + .atMost(Duration.ofSeconds(30)); + } + + @AfterAll + void cleanUp() { + if (entityManagerFactory != null) { + entityManagerFactory.close(); + } + if (mutinySessionFactory != null) { + mutinySessionFactory.close(); + } + if (stageSessionFactory != null) { + stageSessionFactory.close(); + } + vertx.close(); + container.stop(); + } + + @Test + void testMutiny() { + testing.runWithSpan( + "parent", + () -> { + mutinySessionFactory + .withSession( + session -> { + if (!Span.current().getSpanContext().isValid()) { + throw new IllegalStateException("missing parent span"); + } + + return session + .find(Value.class, 1L) + .invoke(value -> testing.runWithSpan("callback", () -> {})); + }) + .await() + .atMost(Duration.ofSeconds(30)); + }); + + assertTrace(); + } + + @Test + void testStage() throws Exception { + testing + .runWithSpan( + "parent", + () -> + stageSessionFactory + .withSession( + session -> { + if (!Span.current().getSpanContext().isValid()) { + throw new IllegalStateException("missing parent span"); + } + + return session + .find(Value.class, 1L) + .thenAccept(value -> testing.runWithSpan("callback", () -> {})); + }) + .toCompletableFuture()) + .get(30, TimeUnit.SECONDS); + + assertTrace(); + } + + @Test + void testStageWithStatelessSession() throws Exception { + testing + .runWithSpan( + "parent", + () -> + stageSessionFactory + .withStatelessSession( + session -> { + if (!Span.current().getSpanContext().isValid()) { + throw new IllegalStateException("missing parent span"); + } + + return session + .get(Value.class, 1L) + .thenAccept(value -> testing.runWithSpan("callback", () -> {})); + }) + .toCompletableFuture()) + .get(30, TimeUnit.SECONDS); + + assertTrace(); + } + + @Test + void testStageSessionWithTransaction() throws Exception { + testing + .runWithSpan( + "parent", + () -> + stageSessionFactory + .withSession( + session -> { + if (!Span.current().getSpanContext().isValid()) { + throw new IllegalStateException("missing parent span"); + } + + return session + .withTransaction(transaction -> session.find(Value.class, 1L)) + .thenAccept(value -> testing.runWithSpan("callback", () -> {})); + }) + .toCompletableFuture()) + .get(30, TimeUnit.SECONDS); + + assertTrace(); + } + + @Test + void testStageStatelessSessionWithTransaction() throws Exception { + testing + .runWithSpan( + "parent", + () -> + stageSessionFactory + .withStatelessSession( + session -> { + if (!Span.current().getSpanContext().isValid()) { + throw new IllegalStateException("missing parent span"); + } + + return session + .withTransaction(transaction -> session.get(Value.class, 1L)) + .thenAccept(value -> testing.runWithSpan("callback", () -> {})); + }) + .toCompletableFuture()) + .get(30, TimeUnit.SECONDS); + + assertTrace(); + } + + @Test + void testStageOpenSession() throws Exception { + CompletableFuture result = new CompletableFuture<>(); + testing.runWithSpan( + "parent", + () -> + runWithVertx( + () -> + stageSessionFactory + .openSession() + .thenApply( + session -> { + if (!Span.current().getSpanContext().isValid()) { + throw new IllegalStateException("missing parent span"); + } + + return session + .find(Value.class, 1L) + .thenAccept(value -> testing.runWithSpan("callback", () -> {})); + }) + .whenComplete((value, throwable) -> complete(result, value, throwable)))); + result.get(30, TimeUnit.SECONDS); + + assertTrace(); + } + + @Test + void testStageOpenStatelessSession() throws Exception { + CompletableFuture result = new CompletableFuture<>(); + testing.runWithSpan( + "parent", + () -> + runWithVertx( + () -> + stageSessionFactory + .openStatelessSession() + .thenApply( + session -> { + if (!Span.current().getSpanContext().isValid()) { + throw new IllegalStateException("missing parent span"); + } + + return session + .get(Value.class, 1L) + .thenAccept(value -> testing.runWithSpan("callback", () -> {})); + }) + .whenComplete((value, throwable) -> complete(result, value, throwable)))); + result.get(30, TimeUnit.SECONDS); + + assertTrace(); + } + + private void runWithVertx(Runnable runnable) { + vertx.getOrCreateContext().runOnContext(event -> runnable.run()); + } + + private static void complete( + CompletableFuture completableFuture, Object result, Throwable throwable) { + if (throwable != null) { + completableFuture.completeExceptionally(throwable); + } else { + completableFuture.complete(result); + } + } + + @SuppressWarnings("deprecation") // using deprecated semconv + private void assertTrace() { + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL), + span -> + span.hasName("SELECT tempdb.Value") + .hasKind(SpanKind.CLIENT) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo(maybeStable(DB_NAME), DB), + equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB), + equalTo( + maybeStable(DB_STATEMENT), + "select v1_0.id,v1_0.name from Value v1_0 where v1_0.id=$1"), + equalTo(maybeStable(DB_OPERATION), "SELECT"), + equalTo(maybeStable(DB_SQL_TABLE), "Value"), + equalTo(SERVER_ADDRESS, host), + equalTo(SERVER_PORT, port)), + span -> + span.hasName("callback") + .hasKind(SpanKind.INTERNAL) + .hasParent(trace.getSpan(0)))); + } +} diff --git a/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive2Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/Value.java b/instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/Value.java similarity index 100% rename from instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive2Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/Value.java rename to instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/Value.java diff --git a/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive2Test/resources/META-INF/persistence.xml b/instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/src/main/resources/META-INF/persistence.xml similarity index 100% rename from instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive2Test/resources/META-INF/persistence.xml rename to instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/src/main/resources/META-INF/persistence.xml diff --git a/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/build.gradle.kts b/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/build.gradle.kts index 21d9621fb450..8e60b78a15f3 100644 --- a/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/build.gradle.kts +++ b/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { testInstrumentation(project(":instrumentation:netty:netty-4.1:javaagent")) testInstrumentation(project(":instrumentation:vertx:vertx-sql-client:vertx-sql-client-4.0:javaagent")) + testInstrumentation(project(":instrumentation:vertx:vertx-sql-client:vertx-sql-client-5.0:javaagent")) library("io.vertx:vertx-sql-client:4.4.2") compileOnly("io.vertx:vertx-codegen:4.4.2") @@ -45,8 +46,9 @@ testing { val hibernateReactive2Test by registering(JvmTestSuite::class) { dependencies { implementation("org.testcontainers:testcontainers") + implementation(project(":instrumentation:hibernate:hibernate-reactive-1.0:hibernate-reactive-2.0-testing")) if (latestDepTest) { - implementation("org.hibernate.reactive:hibernate-reactive-core:latest.release") + implementation("org.hibernate.reactive:hibernate-reactive-core:3.+") implementation("io.vertx:vertx-pg-client:4.+") } else { implementation("org.hibernate.reactive:hibernate-reactive-core:2.0.0.Final") @@ -55,6 +57,21 @@ testing { compileOnly("io.vertx:vertx-codegen:4.4.2") } } + + val hibernateReactive4Test by registering(JvmTestSuite::class) { + dependencies { + implementation("org.testcontainers:testcontainers") + implementation(project(":instrumentation:hibernate:hibernate-reactive-1.0:hibernate-reactive-2.0-testing")) + if (latestDepTest) { + implementation("org.hibernate.reactive:hibernate-reactive-core:latest.release") + implementation("io.vertx:vertx-pg-client:latest.release") + } else { + implementation("org.hibernate.reactive:hibernate-reactive-core:4.0.0.Final") + implementation("io.vertx:vertx-pg-client:5.0.0") + } + compileOnly("io.vertx:vertx-codegen:4.4.2") + } + } } } @@ -65,6 +82,9 @@ tasks { named("compileHibernateReactive2TestJava", JavaCompile::class).configure { options.release.set(11) } + named("compileHibernateReactive4TestJava", JavaCompile::class).configure { + options.release.set(17) + } val testJavaVersion = gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion) ?: JavaVersion.current() @@ -78,6 +98,11 @@ tasks { } } } + if (testJavaVersion.isJava8 || testJavaVersion.isJava11) { + named("hibernateReactive4Test", Test::class).configure { + enabled = false + } + } val testStableSemconv by registering(Test::class) { jvmArgs("-Dotel.semconv-stability.opt-in=database") diff --git a/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive2Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/HibernateReactiveTest.java b/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive2Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/HibernateReactiveTest.java index f78264ca3ff3..cfe2df524140 100644 --- a/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive2Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/HibernateReactiveTest.java +++ b/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive2Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/HibernateReactiveTest.java @@ -5,312 +5,20 @@ package io.opentelemetry.javaagent.instrumentation.hibernate.reactive.v2_0; -import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv; -import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; -import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS; -import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT; -import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_NAME; -import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; -import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SQL_TABLE; -import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; -import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_USER; - -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; -import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import io.vertx.core.Vertx; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; -import java.time.Duration; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; -import org.hibernate.reactive.mutiny.Mutiny; -import org.hibernate.reactive.stage.Stage; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; - -class HibernateReactiveTest { - private static final Logger logger = LoggerFactory.getLogger(HibernateReactiveTest.class); - - private static final String USER_DB = "SA"; - private static final String PW_DB = "password123"; - private static final String DB = "tempdb"; - - @RegisterExtension - protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); - - private static final Vertx vertx = Vertx.vertx(); - private static GenericContainer container; - private static String host; - private static int port; - private static EntityManagerFactory entityManagerFactory; - private static Mutiny.SessionFactory mutinySessionFactory; - private static Stage.SessionFactory stageSessionFactory; - - @BeforeAll - static void setUp() throws Exception { - container = - new GenericContainer<>("postgres:9.6.8") - .withEnv("POSTGRES_USER", USER_DB) - .withEnv("POSTGRES_PASSWORD", PW_DB) - .withEnv("POSTGRES_DB", DB) - .withExposedPorts(5432) - .withLogConsumer(new Slf4jLogConsumer(logger)) - .withStartupTimeout(Duration.ofMinutes(2)); - container.start(); - - host = container.getHost(); - port = container.getMappedPort(5432); - System.setProperty("db.host", host); - System.setProperty("db.port", String.valueOf(port)); - - entityManagerFactory = - vertx - .getOrCreateContext() - .executeBlocking( - promise -> promise.complete(Persistence.createEntityManagerFactory("test-pu"))) - .toCompletionStage() - .toCompletableFuture() - .get(30, TimeUnit.SECONDS); - - Value value = new Value("name"); - value.setId(1L); - - mutinySessionFactory = entityManagerFactory.unwrap(Mutiny.SessionFactory.class); - stageSessionFactory = entityManagerFactory.unwrap(Stage.SessionFactory.class); - - mutinySessionFactory - .withTransaction((session, tx) -> session.merge(value)) - .await() - .atMost(Duration.ofSeconds(30)); - } - - @AfterAll - static void cleanUp() { - if (entityManagerFactory != null) { - entityManagerFactory.close(); - } - if (mutinySessionFactory != null) { - mutinySessionFactory.close(); - } - if (stageSessionFactory != null) { - stageSessionFactory.close(); - } - vertx.close(); - container.stop(); - } - - @Test - void testMutiny() { - testing.runWithSpan( - "parent", - () -> { - mutinySessionFactory - .withSession( - session -> { - if (!Span.current().getSpanContext().isValid()) { - throw new IllegalStateException("missing parent span"); - } - - return session - .find(Value.class, 1L) - .invoke(value -> testing.runWithSpan("callback", () -> {})); - }) - .await() - .atMost(Duration.ofSeconds(30)); - }); - - assertTrace(); - } - - @Test - void testStage() throws Exception { - testing - .runWithSpan( - "parent", - () -> - stageSessionFactory - .withSession( - session -> { - if (!Span.current().getSpanContext().isValid()) { - throw new IllegalStateException("missing parent span"); - } - - return session - .find(Value.class, 1L) - .thenAccept(value -> testing.runWithSpan("callback", () -> {})); - }) - .toCompletableFuture()) - .get(30, TimeUnit.SECONDS); - - assertTrace(); - } - - @Test - void testStageWithStatelessSession() throws Exception { - testing - .runWithSpan( - "parent", - () -> - stageSessionFactory - .withStatelessSession( - session -> { - if (!Span.current().getSpanContext().isValid()) { - throw new IllegalStateException("missing parent span"); - } - return session - .get(Value.class, 1L) - .thenAccept(value -> testing.runWithSpan("callback", () -> {})); - }) - .toCompletableFuture()) - .get(30, TimeUnit.SECONDS); - - assertTrace(); - } - - @Test - void testStageSessionWithTransaction() throws Exception { - testing - .runWithSpan( - "parent", - () -> - stageSessionFactory - .withSession( - session -> { - if (!Span.current().getSpanContext().isValid()) { - throw new IllegalStateException("missing parent span"); - } - - return session - .withTransaction(transaction -> session.find(Value.class, 1L)) - .thenAccept(value -> testing.runWithSpan("callback", () -> {})); - }) - .toCompletableFuture()) - .get(30, TimeUnit.SECONDS); +class HibernateReactiveTest extends AbstractHibernateReactiveTest { - assertTrace(); - } - - @Test - void testStageStatelessSessionWithTransaction() throws Exception { - testing - .runWithSpan( - "parent", - () -> - stageSessionFactory - .withStatelessSession( - session -> { - if (!Span.current().getSpanContext().isValid()) { - throw new IllegalStateException("missing parent span"); - } - - return session - .withTransaction(transaction -> session.get(Value.class, 1L)) - .thenAccept(value -> testing.runWithSpan("callback", () -> {})); - }) - .toCompletableFuture()) + @Override + protected EntityManagerFactory createEntityManagerFactory() throws Exception { + return vertx + .getOrCreateContext() + .executeBlocking( + promise -> promise.complete(Persistence.createEntityManagerFactory("test-pu"))) + .toCompletionStage() + .toCompletableFuture() .get(30, TimeUnit.SECONDS); - - assertTrace(); - } - - @Test - void testStageOpenSession() throws Exception { - CompletableFuture result = new CompletableFuture<>(); - testing.runWithSpan( - "parent", - () -> - runWithVertx( - () -> - stageSessionFactory - .openSession() - .thenApply( - session -> { - if (!Span.current().getSpanContext().isValid()) { - throw new IllegalStateException("missing parent span"); - } - - return session - .find(Value.class, 1L) - .thenAccept(value -> testing.runWithSpan("callback", () -> {})); - }) - .whenComplete((value, throwable) -> complete(result, value, throwable)))); - result.get(30, TimeUnit.SECONDS); - - assertTrace(); - } - - @Test - void testStageOpenStatelessSession() throws Exception { - CompletableFuture result = new CompletableFuture<>(); - testing.runWithSpan( - "parent", - () -> - runWithVertx( - () -> - stageSessionFactory - .openStatelessSession() - .thenApply( - session -> { - if (!Span.current().getSpanContext().isValid()) { - throw new IllegalStateException("missing parent span"); - } - - return session - .get(Value.class, 1L) - .thenAccept(value -> testing.runWithSpan("callback", () -> {})); - }) - .whenComplete((value, throwable) -> complete(result, value, throwable)))); - result.get(30, TimeUnit.SECONDS); - - assertTrace(); - } - - private static void runWithVertx(Runnable runnable) { - vertx.getOrCreateContext().runOnContext(event -> runnable.run()); - } - - private static void complete( - CompletableFuture completableFuture, Object result, Throwable throwable) { - if (throwable != null) { - completableFuture.completeExceptionally(throwable); - } else { - completableFuture.complete(result); - } - } - - @SuppressWarnings("deprecation") // using deprecated semconv - private static void assertTrace() { - testing.waitAndAssertTraces( - trace -> - trace.hasSpansSatisfyingExactly( - span -> span.hasName("parent").hasKind(SpanKind.INTERNAL), - span -> - span.hasName("SELECT tempdb.Value") - .hasKind(SpanKind.CLIENT) - .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo(maybeStable(DB_NAME), DB), - equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB), - equalTo( - maybeStable(DB_STATEMENT), - "select v1_0.id,v1_0.name from Value v1_0 where v1_0.id=$1"), - equalTo(maybeStable(DB_OPERATION), "SELECT"), - equalTo(maybeStable(DB_SQL_TABLE), "Value"), - equalTo(SERVER_ADDRESS, host), - equalTo(SERVER_PORT, port)), - span -> - span.hasName("callback") - .hasKind(SpanKind.INTERNAL) - .hasParent(trace.getSpan(0)))); } } diff --git a/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive4Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v4_0/HibernateReactiveTest.java b/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive4Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v4_0/HibernateReactiveTest.java new file mode 100644 index 000000000000..7fd3dc07d3a3 --- /dev/null +++ b/instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive4Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v4_0/HibernateReactiveTest.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.hibernate.reactive.v4_0; + +import io.opentelemetry.javaagent.instrumentation.hibernate.reactive.v2_0.AbstractHibernateReactiveTest; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import java.util.concurrent.TimeUnit; + +class HibernateReactiveTest extends AbstractHibernateReactiveTest { + + @Override + protected EntityManagerFactory createEntityManagerFactory() throws Exception { + return vertx + .getOrCreateContext() + .executeBlocking(() -> Persistence.createEntityManagerFactory("test-pu")) + .toCompletionStage() + .toCompletableFuture() + .get(30, TimeUnit.SECONDS); + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index e117dc1566ba..260a703a98c5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -250,6 +250,7 @@ include(":instrumentation:hibernate:hibernate-6.0:spring-testing") include(":instrumentation:hibernate:hibernate-common:javaagent") include(":instrumentation:hibernate:hibernate-procedure-call-4.3:javaagent") include(":instrumentation:hibernate:hibernate-reactive-1.0:javaagent") +include(":instrumentation:hibernate:hibernate-reactive-1.0:hibernate-reactive-2.0-testing") include(":instrumentation:hikaricp-3.0:javaagent") include(":instrumentation:hikaricp-3.0:library") include(":instrumentation:hikaricp-3.0:testing")