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 2021/07/13 06:22:08 UTC

[camel-quarkus] 02/02: Test OpenTelemetry invocation of Camel routes from JAX-RS services

This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git

commit 9344d527b2979a859e3678746bb55e54fa1abcc5
Author: James Netherton <ja...@gmail.com>
AuthorDate: Mon Jul 12 13:18:16 2021 +0100

    Test OpenTelemetry invocation of Camel routes from JAX-RS services
---
 integration-tests/opentelemetry/pom.xml            | 34 ++++++++++++++
 .../opentelemetry/it/OpenTelemetryResource.java    | 36 +++------------
 .../it/OpenTelemetryRouteBuilder.java              |  6 +++
 ...etryResource.java => SpanExporterResource.java} | 30 ++++++++-----
 .../src/main/resources/application.properties      |  6 ++-
 .../opentelemetry/it/OpenTelemetryTest.java        | 52 ++++++++++++++++------
 6 files changed, 109 insertions(+), 55 deletions(-)

diff --git a/integration-tests/opentelemetry/pom.xml b/integration-tests/opentelemetry/pom.xml
index 81095d2..863db79 100644
--- a/integration-tests/opentelemetry/pom.xml
+++ b/integration-tests/opentelemetry/pom.xml
@@ -47,6 +47,10 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-direct</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-opentelemetry</artifactId>
         </dependency>
         <dependency>
@@ -54,6 +58,10 @@
             <artifactId>camel-quarkus-platform-http</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-timer</artifactId>
+        </dependency>
+        <dependency>
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-resteasy</artifactId>
         </dependency>
@@ -81,6 +89,19 @@
         <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-direct-deployment</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-opentelemetry-deployment</artifactId>
             <version>${project.version}</version>
             <type>pom</type>
@@ -105,6 +126,19 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-timer-deployment</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <profiles>
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 4525aab..06e8bc2 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
@@ -16,50 +16,26 @@
  */
 package org.apache.camel.quarkus.component.opentelemetry.it;
 
-import java.util.Map;
-
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObjectBuilder;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
-import io.opentelemetry.api.common.AttributeKey;
-import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
-import io.opentelemetry.sdk.trace.data.SpanData;
+import org.apache.camel.ProducerTemplate;
 
 @Path("/opentelemetry")
 @ApplicationScoped
 public class OpenTelemetryResource {
 
     @Inject
-    InMemorySpanExporter exporter;
+    ProducerTemplate producerTemplate;
 
-    @Path("/spans")
+    @Path("/trace")
     @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    public JsonArray getSpans() {
-        JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
-
-        for (SpanData span : exporter.getFinishedSpanItems()) {
-
-            Map<AttributeKey<?>, Object> attributes = span.getAttributes().asMap();
-            if (attributes.containsKey(AttributeKey.stringKey("component"))) {
-                JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
-                objectBuilder.add("spanId", span.getSpanId());
-                objectBuilder.add("traceId", span.getTraceId());
-
-                attributes.forEach((k, v) -> objectBuilder.add(String.valueOf(k), v.toString()));
-
-                arrayBuilder.add(objectBuilder.build());
-            }
-        }
-
-        return arrayBuilder.build();
+    @Produces(MediaType.TEXT_PLAIN)
+    public String traceRoute() {
+        return producerTemplate.requestBody("direct:start", null, String.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 12a3a0e..375b71f 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
@@ -29,5 +29,11 @@ public class OpenTelemetryRouteBuilder extends RouteBuilder {
 
         from("platform-http:/opentelemetry/test/trace/filtered")
                 .setBody(constant("GET: /opentelemetry/test/trace/filtered"));
+
+        from("direct:start")
+                .setBody().constant("Traced direct:start");
+
+        from("timer:filtered?repeatCount=5&delay=-1")
+                .setBody().constant("Route filtered from tracing");
     }
 }
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/SpanExporterResource.java
similarity index 70%
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/SpanExporterResource.java
index 4525aab..0fc85b4 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/SpanExporterResource.java
@@ -18,13 +18,13 @@ package org.apache.camel.quarkus.component.opentelemetry.it;
 
 import java.util.Map;
 
-import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonObjectBuilder;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
@@ -33,9 +33,8 @@ import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
 import io.opentelemetry.sdk.trace.data.SpanData;
 
-@Path("/opentelemetry")
-@ApplicationScoped
-public class OpenTelemetryResource {
+@Path("/opentelemetry/exporter")
+public class SpanExporterResource {
 
     @Inject
     InMemorySpanExporter exporter;
@@ -47,19 +46,28 @@ public class OpenTelemetryResource {
         JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
 
         for (SpanData span : exporter.getFinishedSpanItems()) {
+            if (span.getName().contains("exporter")) {
+                // Ignore any trace events on this resource
+                continue;
+            }
 
             Map<AttributeKey<?>, Object> attributes = span.getAttributes().asMap();
-            if (attributes.containsKey(AttributeKey.stringKey("component"))) {
-                JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
-                objectBuilder.add("spanId", span.getSpanId());
-                objectBuilder.add("traceId", span.getTraceId());
+            JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
+            objectBuilder.add("spanId", span.getSpanId());
+            objectBuilder.add("traceId", span.getTraceId());
+            objectBuilder.add("parentId", span.getParentSpanId());
 
-                attributes.forEach((k, v) -> objectBuilder.add(String.valueOf(k), v.toString()));
+            attributes.forEach((k, v) -> objectBuilder.add(String.valueOf(k), v.toString()));
 
-                arrayBuilder.add(objectBuilder.build());
-            }
+            arrayBuilder.add(objectBuilder.build());
         }
 
         return arrayBuilder.build();
     }
+
+    @POST
+    @Path("/spans/reset")
+    public void resetSpanExporter() {
+        exporter.reset();
+    }
 }
diff --git a/integration-tests/opentelemetry/src/main/resources/application.properties b/integration-tests/opentelemetry/src/main/resources/application.properties
index 0d36a0a..e819cd6 100644
--- a/integration-tests/opentelemetry/src/main/resources/application.properties
+++ b/integration-tests/opentelemetry/src/main/resources/application.properties
@@ -15,4 +15,8 @@
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
 
-quarkus.camel.opentelemetry.exclude-patterns = platform-http:/opentelemetry/test/trace/filtered
+# TODO: Reinstate this when platform-http route excludes are fixed
+# https://github.com/apache/camel-quarkus/issues/2897
+#quarkus.camel.opentelemetry.exclude-patterns = platform-http:/opentelemetry/test/trace/filtered
+
+quarkus.camel.opentelemetry.exclude-patterns = timer:filtered*
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 3419a4c..3e78556 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
@@ -21,15 +21,23 @@ import java.util.Map;
 
 import io.quarkus.test.junit.QuarkusTest;
 import io.restassured.RestAssured;
-import io.restassured.path.json.JsonPath;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 
+import static org.hamcrest.CoreMatchers.equalTo;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @QuarkusTest
 class OpenTelemetryTest {
 
+    @AfterEach
+    public void afterEach() {
+        RestAssured.post("/opentelemetry/exporter/spans/reset")
+                .then()
+                .statusCode(204);
+    }
+
     @Test
     public void testTraceRoute() {
         // Generate messages
@@ -40,21 +48,15 @@ class OpenTelemetryTest {
 
             // No spans should be recorded for this route as they are excluded by camel.opentelemetry.exclude-patterns in
             // application.properties
-            RestAssured.get("/opentelemetry/test/trace/filtered")
-                    .then()
-                    .statusCode(200);
+            // TODO: Reinstate this when platform-http route excludes are fixed. For now, a timer endpoint stands in for filter tests
+            // https://github.com/apache/camel-quarkus/issues/2897
+            // RestAssured.get("/opentelemetry/test/trace/filtered")
+            //        .then()
+            //        .statusCode(200);
         }
 
         // Retrieve recorded spans
-        JsonPath jsonPath = RestAssured.given()
-                .get("/opentelemetry/spans")
-                .then()
-                .statusCode(200)
-                .extract()
-                .body()
-                .jsonPath();
-
-        List<Map<String, String>> spans = jsonPath.get();
+        List<Map<String, String>> spans = getSpans();
         assertEquals(5, spans.size());
 
         for (Map<String, String> span : spans) {
@@ -65,4 +67,28 @@ class OpenTelemetryTest {
             assertTrue(span.get("http.url").endsWith("/opentelemetry/test/trace/"));
         }
     }
+
+    @Test
+    public void testTracedCamelRouteInvokedFromJaxRsService() {
+        RestAssured.get("/opentelemetry/trace")
+                .then()
+                .statusCode(200)
+                .body(equalTo("Traced direct:start"));
+
+        // Verify the span hierarchy is JAX-RS Service -> Direct Endpoint
+        List<Map<String, String>> spans = getSpans();
+        assertEquals(2, spans.size());
+        assertEquals(spans.get(0).get("parentId"), spans.get(1).get("spanId"));
+    }
+
+    private List<Map<String, String>> getSpans() {
+        return RestAssured.given()
+                .get("/opentelemetry/exporter/spans")
+                .then()
+                .statusCode(200)
+                .extract()
+                .body()
+                .jsonPath()
+                .get();
+    }
 }