You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2023/04/18 15:26:24 UTC
[camel-quarkus] 02/04: Test OpenTelemetry extension integration with opentelemetry-jdbc
This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch 2.13.x
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 2c8425d87254c4fd211426dbdfba8e0820767f93
Author: James Netherton <ja...@gmail.com>
AuthorDate: Tue Apr 18 09:57:28 2023 +0100
Test OpenTelemetry extension integration with opentelemetry-jdbc
Fixes #4789
---
integration-tests/opentelemetry/pom.xml | 44 +++++++++++++++++
...enTelemetryResource.java => JdbcQueryBean.java} | 50 +++++++++----------
.../opentelemetry/it/OpenTelemetryResource.java | 7 +++
.../it/OpenTelemetryRouteBuilder.java | 3 ++
.../src/main/resources/application.properties | 7 +++
.../opentelemetry/it/OpenTelemetryTest.java | 43 +++++++++++++++++
.../it/OpenTelemetryTestResource.java | 56 ++++++++++++++++++++++
7 files changed, 186 insertions(+), 24 deletions(-)
diff --git a/integration-tests/opentelemetry/pom.xml b/integration-tests/opentelemetry/pom.xml
index 81cdab23d9..5ab121b65f 100644
--- a/integration-tests/opentelemetry/pom.xml
+++ b/integration-tests/opentelemetry/pom.xml
@@ -59,10 +59,22 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-agroal</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-jdbc-postgresql</artifactId>
+ </dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-testing</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.opentelemetry.instrumentation</groupId>
+ <artifactId>opentelemetry-jdbc</artifactId>
+ </dependency>
<!-- test dependencies -->
<dependency>
@@ -75,6 +87,27 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>testcontainers</artifactId>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit4-mock</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
@@ -181,6 +214,17 @@
</dependency>
</dependencies>
</profile>
+ <profile>
+ <id>skip-testcontainers-tests</id>
+ <activation>
+ <property>
+ <name>skip-testcontainers-tests</name>
+ </property>
+ </activation>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </profile>
</profiles>
</project>
diff --git a/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryResource.java b/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/JdbcQueryBean.java
similarity index 50%
copy from integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryResource.java
copy to integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/JdbcQueryBean.java
index 23e1395ff5..2f25504af8 100644
--- a/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryResource.java
+++ b/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/JdbcQueryBean.java
@@ -16,34 +16,36 @@
*/
package org.apache.camel.quarkus.component.opentelemetry.it;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
-import org.apache.camel.ProducerTemplate;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
-@Path("/opentelemetry")
-@ApplicationScoped
-public class OpenTelemetryResource {
+import io.agroal.api.AgroalDataSource;
+import io.quarkus.runtime.annotations.RegisterForReflection;
+@Singleton
+@Named("jdbcQueryBean")
+@RegisterForReflection(fields = false)
+public class JdbcQueryBean {
@Inject
- ProducerTemplate producerTemplate;
-
- @Path("/trace")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public String traceRoute() {
- return producerTemplate.requestBody("direct:start", null, String.class);
- }
+ AgroalDataSource dataSource;
- @Path("/greet/{name}")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public String traceRoute(@PathParam("name") String name) {
- return producerTemplate.requestBody("direct:greet", name, String.class);
+ public long getNowTimestamp() {
+ try (Connection connection = dataSource.getConnection()) {
+ try (Statement statement = connection.createStatement()) {
+ ResultSet resultSet = statement.executeQuery("SELECT EXTRACT(EPOCH FROM NOW());");
+ if (resultSet.next()) {
+ return resultSet.getLong(1);
+ }
+ return 0;
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryResource.java b/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryResource.java
index 23e1395ff5..bb4cd3e2b2 100644
--- a/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryResource.java
+++ b/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryResource.java
@@ -46,4 +46,11 @@ public class OpenTelemetryResource {
public String traceRoute(@PathParam("name") String name) {
return producerTemplate.requestBody("direct:greet", name, String.class);
}
+
+ @Path("/jdbc/query")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public long jdbcQuery() {
+ return producerTemplate.requestBody("direct:jdbcQuery", null, Long.class);
+ }
}
diff --git a/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryRouteBuilder.java b/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryRouteBuilder.java
index 3c3f7e662b..b414a0df31 100644
--- a/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryRouteBuilder.java
+++ b/integration-tests/opentelemetry/src/main/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryRouteBuilder.java
@@ -38,5 +38,8 @@ public class OpenTelemetryRouteBuilder extends RouteBuilder {
from("timer:filtered?repeatCount=5&delay=-1")
.setBody().constant("Route filtered from tracing");
+
+ from("direct:jdbcQuery")
+ .to("bean:jdbcQueryBean");
}
}
diff --git a/integration-tests/opentelemetry/src/main/resources/application.properties b/integration-tests/opentelemetry/src/main/resources/application.properties
index e819cd6f00..abae23ff2e 100644
--- a/integration-tests/opentelemetry/src/main/resources/application.properties
+++ b/integration-tests/opentelemetry/src/main/resources/application.properties
@@ -20,3 +20,10 @@
#quarkus.camel.opentelemetry.exclude-patterns = platform-http:/opentelemetry/test/trace/filtered
quarkus.camel.opentelemetry.exclude-patterns = timer:filtered*
+
+quarkus.datasource.devservices.enabled=false
+quarkus.datasource.db-kind=postgresql
+quarkus.datasource.username=test
+quarkus.datasource.password=s3cr3t
+quarkus.datasource.jdbc.driver=io.opentelemetry.instrumentation.jdbc.OpenTelemetryDriver
+quarkus.datasource.jdbc.max-size=16
diff --git a/integration-tests/opentelemetry/src/test/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryTest.java b/integration-tests/opentelemetry/src/test/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryTest.java
index 876030f0cc..8ad60db61a 100644
--- a/integration-tests/opentelemetry/src/test/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryTest.java
+++ b/integration-tests/opentelemetry/src/test/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryTest.java
@@ -18,16 +18,20 @@ package org.apache.camel.quarkus.component.opentelemetry.it;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+import static org.awaitility.Awaitility.await;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+@QuarkusTestResource(OpenTelemetryTestResource.class)
@QuarkusTest
class OpenTelemetryTest {
@@ -96,6 +100,45 @@ class OpenTelemetryTest {
assertEquals(spans.get(1).get("parentId"), spans.get(2).get("spanId"));
}
+ @Test
+ public void testTracedJdbcQuery() {
+ String timestamp = RestAssured.get("/opentelemetry/jdbc/query")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .asString();
+
+ assertTrue(Long.parseLong(timestamp) > 0);
+
+ // Verify the span hierarchy is JAX-RS Service -> Direct Endpoint -> Bean Endpoint -> Bean method -> JDBC query
+ await().atMost(30, TimeUnit.SECONDS).pollDelay(50, TimeUnit.MILLISECONDS).until(() -> getSpans().size() >= 4);
+ List<Map<String, String>> spans = getSpans();
+
+ boolean asyncProcessingStartedEventPresent = false;
+ try {
+ Thread.currentThread().getContextClassLoader()
+ .loadClass("org.apache.camel.impl.event.ExchangeAsyncProcessingStartedEvent");
+ asyncProcessingStartedEventPresent = true;
+ } catch (ClassNotFoundException e) {
+ // Ignore
+ }
+
+ String expectedDbQuerySpanParent = asyncProcessingStartedEventPresent ? spans.get(0).get("parentId")
+ : spans.get(3).get("spanId");
+ assertEquals(expectedDbQuerySpanParent, spans.get(0).get("parentId"));
+ assertEquals("SELECT", spans.get(0).get("db.operation"));
+
+ assertEquals(spans.get(2).get("spanId"), spans.get(1).get("parentId"));
+ assertEquals("bean://jdbcQueryBean", spans.get(1).get("camel.uri"));
+
+ assertEquals(spans.get(3).get("spanId"), spans.get(2).get("parentId"));
+ assertEquals("direct://jdbcQuery", spans.get(2).get("camel.uri"));
+
+ assertEquals("0000000000000000", spans.get(3).get("parentId"));
+ assertEquals("/opentelemetry/jdbc/query", spans.get(3).get("http.target"));
+ }
+
private List<Map<String, String>> getSpans() {
return RestAssured.given()
.get("/opentelemetry/exporter/spans")
diff --git a/integration-tests/opentelemetry/src/test/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryTestResource.java b/integration-tests/opentelemetry/src/test/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryTestResource.java
new file mode 100644
index 0000000000..47bc190d78
--- /dev/null
+++ b/integration-tests/opentelemetry/src/test/java/org/apache/camel/quarkus/component/opentelemetry/it/OpenTelemetryTestResource.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.opentelemetry.it;
+
+import java.util.Map;
+
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+
+public class OpenTelemetryTestResource implements QuarkusTestResourceLifecycleManager {
+ private static final String POSTGRES_USER = "test";
+ private static final String POSTGRES_PASSWORD = "s3cr3t";
+ private static final String POSTGRES_DB = "otel";
+ private static final int POSTGRES_PORT = 5432;
+ private static final String POSTGRES_IMAGE = "postgres:13.0";
+
+ private GenericContainer<?> container;
+
+ @Override
+ public Map<String, String> start() {
+ container = new GenericContainer<>(POSTGRES_IMAGE)
+ .withExposedPorts(POSTGRES_PORT)
+ .withEnv("POSTGRES_USER", POSTGRES_USER)
+ .withEnv("POSTGRES_PASSWORD", POSTGRES_PASSWORD)
+ .withEnv("POSTGRES_DB", POSTGRES_DB)
+ .waitingFor(Wait.forListeningPort());
+
+ container.start();
+
+ String jdbcUrl = String.format("jdbc:otel:postgresql://localhost:%d/%s", container.getMappedPort(POSTGRES_PORT),
+ POSTGRES_DB);
+ return Map.of("quarkus.datasource.jdbc.url", jdbcUrl);
+ }
+
+ @Override
+ public void stop() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+}