Skip to content

Commit

Permalink
Replace the usage of the JDBC Vert.x SQL client with the PostGreSQL c…
Browse files Browse the repository at this point in the history
…lient to actually verify that opentelemetry works with reactive SQL clients
  • Loading branch information
cescoffier committed May 17, 2023
1 parent e029a5b commit 5e31628
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 92 deletions.
77 changes: 40 additions & 37 deletions integration-tests/opentelemetry-vertx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer</artifactId>
Expand Down Expand Up @@ -57,26 +53,9 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-sql-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-jdbc-client</artifactId>
<scope>test</scope>
<artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>

<!-- Minimal test dependencies to *-deployment artifacts for consistent build order -->
Expand Down Expand Up @@ -108,20 +87,7 @@
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2-deployment</artifactId>
<artifactId>quarkus-micrometer-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
Expand All @@ -134,7 +100,7 @@
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-deployment</artifactId>
<artifactId>quarkus-reactive-pg-client-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
Expand All @@ -149,6 +115,18 @@

<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
Expand All @@ -164,6 +142,31 @@
</build>

<profiles>
<profile>
<id>test-postgresql</id>
<activation>
<property>
<name>test-containers</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<profile>
<id>native-image</id>
<activation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,18 @@
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.DB_CONNECTION_STRING;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.DB_OPERATION;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.DB_STATEMENT;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.DB_SYSTEM;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.DB_USER;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_STATUS_CODE;
import static io.restassured.RestAssured.given;
import static java.net.HttpURLConnection.HTTP_OK;
import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.sql.DataSource;

import jakarta.inject.Inject;

import org.junit.jupiter.api.AfterEach;
Expand All @@ -27,57 +24,31 @@

import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.quarkus.agroal.runtime.DataSourcesJdbcRuntimeConfig;
import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.h2.H2DatabaseTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.jdbc.spi.DataSourceProvider;
import io.vertx.ext.web.Router;
import io.vertx.jdbcclient.JDBCPool;
import io.vertx.mutiny.pgclient.PgPool;

// H2 is not supported in native mode
@QuarkusTest
@QuarkusTestResource(H2DatabaseTestResource.class)
public class SqlClientTest {
@Inject
Router router;

@Inject
Vertx vertx;
@Inject
DataSource dataSource;
@Inject
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig;
@Inject
DataSourcesRuntimeConfig dataSourcesRuntimeConfig;
@Inject
DataSourcesJdbcRuntimeConfig dataSourcesJdbcRuntimeConfig;
PgPool pool;

@Inject
InMemorySpanExporter inMemorySpanExporter;

@Test
void sqlClient() {
router.get("/sqlClient").handler(rc -> {
JsonObject config = new JsonObject()
.put("jdbcUrl", dataSourcesJdbcRuntimeConfig.jdbc.url.orElse(""))
.put("username", dataSourcesRuntimeConfig.defaultDataSource.username.orElse(""))
.put("database", dataSourcesBuildTimeConfig.defaultDataSource.dbKind.orElse(""));
pool.query("CREATE TABLE IF NOT EXISTS USERS (id INT, name VARCHAR(100));")
.execute().await().indefinitely();

JDBCPool pool = JDBCPool.pool(vertx, DataSourceProvider.create(dataSource, config));
router.get("/sqlClient").handler(rc -> {
pool
.query("SELECT * FROM USERS")
.execute()
.onSuccess(event -> {
})
.onFailure(event -> {
})
.compose(rows -> pool.close())
// onComplete is executed before the end of Sql Telemetry data. This causes warnings in Scope.close
.onComplete(event -> rc.response().end());
.subscribe().with(event -> rc.response().end());

});

Expand All @@ -86,25 +57,38 @@ void sqlClient() {
.then()
.statusCode(HTTP_OK);

await().atMost(5, TimeUnit.SECONDS).until(() -> inMemorySpanExporter.getFinishedSpanItems().size() == 2);
// Why 3 spans:
// Table creation + HTTP + Query = 3

await().atMost(5, TimeUnit.SECONDS).until(() -> inMemorySpanExporter.getFinishedSpanItems().size() == 3);
List<SpanData> spans = inMemorySpanExporter.getFinishedSpanItems();
assertEquals(2, spans.size());

assertEquals(spans.get(0).getTraceId(), spans.get(1).getTraceId());
assertEquals(spans.get(0).getSpanId(), spans.get(1).getParentSpanId());

assertEquals("GET /sqlClient", spans.get(0).getName());
assertEquals(HTTP_OK, spans.get(0).getAttributes().get(HTTP_STATUS_CODE));

assertEquals("SELECT USERS", spans.get(1).getName());
assertEquals(CLIENT, spans.get(1).getKind());
assertEquals("h2", spans.get(1).getAttributes().get(DB_SYSTEM));
assertEquals("SELECT", spans.get(1).getAttributes().get(DB_OPERATION));
assertEquals("SELECT * FROM USERS", spans.get(1).getAttributes().get(DB_STATEMENT));
assertEquals("quarkus", spans.get(1).getAttributes().get(DB_USER));
assertNotNull(spans.get(1).getAttributes().get(DB_CONNECTION_STRING));
//noinspection ConstantConditions
assertTrue(spans.get(1).getAttributes().get(DB_CONNECTION_STRING).startsWith("jdbc:h2:tcp://localhost"));
assertEquals(3, spans.size());

// We cannot rely on the order, we must identify the spans.
SpanData tableCreation = inMemorySpanExporter.getFinishedSpanItems().stream()
.filter(sd -> sd.getName().contains("DB Query")).findFirst().orElseThrow();
SpanData httpSpan = inMemorySpanExporter.getFinishedSpanItems().stream()
.filter(sd -> sd.getName().contains("GET /sqlClient")).findFirst().orElseThrow();
SpanData querySpan = inMemorySpanExporter.getFinishedSpanItems().stream()
.filter(sd -> sd.getName().contains("SELECT USERS")).findFirst().orElseThrow();

assertNotEquals(httpSpan.getTraceId(), tableCreation.getTraceId()); // No relationship
assertEquals(httpSpan.getTraceId(), querySpan.getTraceId());
assertEquals(httpSpan.getSpanId(), querySpan.getParentSpanId());

assertEquals("GET /sqlClient", httpSpan.getName());
assertEquals(HTTP_OK, httpSpan.getAttributes().get(HTTP_STATUS_CODE));

assertEquals("SELECT USERS", querySpan.getName());
assertEquals(CLIENT, querySpan.getKind());
assertEquals("SELECT", querySpan.getAttributes().get(DB_OPERATION));
assertEquals("SELECT * FROM USERS", querySpan.getAttributes().get(DB_STATEMENT));
assertEquals("quarkus", querySpan.getAttributes().get(DB_USER));
assertNotNull(querySpan.getAttributes().get(DB_CONNECTION_STRING));

assertEquals("CREATE TABLE IF NOT EXISTS USERS (id INT, name VARCHAR(?));",
tableCreation.getAttributes().get(DB_STATEMENT));
assertEquals("quarkus", tableCreation.getAttributes().get(DB_USER));
}

@BeforeEach
Expand Down

0 comments on commit 5e31628

Please sign in to comment.