mirror of https://github.com/dapr/java-sdk.git
Merge pull request #508 from artursouza/tracing_example_validate
Auto-validation for tracing sample.
This commit is contained in:
commit
dcaffe8932
|
@ -112,6 +112,10 @@ jobs:
|
||||||
working-directory: ./examples
|
working-directory: ./examples
|
||||||
run: |
|
run: |
|
||||||
mm.py ./src/main/java/io/dapr/examples/invoke/grpc/README.md
|
mm.py ./src/main/java/io/dapr/examples/invoke/grpc/README.md
|
||||||
|
- name: Validate tracing example
|
||||||
|
working-directory: ./examples
|
||||||
|
run: |
|
||||||
|
mm.py ./src/main/java/io/dapr/examples/tracing/README.md
|
||||||
- name: Validate expection handling example
|
- name: Validate expection handling example
|
||||||
working-directory: ./examples
|
working-directory: ./examples
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -74,6 +74,11 @@
|
||||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||||
<version>2.3.5.RELEASE</version>
|
<version>2.3.5.RELEASE</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
<artifactId>json-path</artifactId>
|
||||||
|
<version>2.4.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.opentelemetry</groupId>
|
<groupId>io.opentelemetry</groupId>
|
||||||
<artifactId>opentelemetry-sdk</artifactId>
|
<artifactId>opentelemetry-sdk</artifactId>
|
||||||
|
|
|
@ -66,18 +66,15 @@ public class InvokeClient {
|
||||||
}).subscriberContext(getReactorContext()).block();
|
}).subscriberContext(getReactorContext()).block();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an example, so for simplicity we are just exiting here.
|
|
||||||
// Normally a dapr app would be a web service and not exit main.
|
|
||||||
System.out.println("Done");
|
|
||||||
}
|
}
|
||||||
span.end();
|
span.end();
|
||||||
shutdown();
|
shutdown();
|
||||||
|
System.out.println("Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void shutdown() {
|
private static void shutdown() throws Exception {
|
||||||
OpenTelemetrySdk.getGlobalTracerManagement().shutdown();
|
OpenTelemetrySdk.getGlobalTracerManagement().shutdown();
|
||||||
|
Validation.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,10 +126,19 @@ The instrumentation for the service happens via the `OpenTelemetryIterceptor` cl
|
||||||
|
|
||||||
Use the follow command to execute the service:
|
Use the follow command to execute the service:
|
||||||
|
|
||||||
```sh
|
<!-- STEP
|
||||||
|
name: Run demo service
|
||||||
|
expected_stdout_lines:
|
||||||
|
background: true
|
||||||
|
sleep: 20
|
||||||
|
-->
|
||||||
|
|
||||||
|
```bash
|
||||||
dapr run --app-id tracingdemo --app-port 3000 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.TracingDemoService -p 3000
|
dapr run --app-id tracingdemo --app-port 3000 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.TracingDemoService -p 3000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<!-- END_STEP -->
|
||||||
|
|
||||||
Once running, the TracingDemoService is now ready to be invoked by Dapr.
|
Once running, the TracingDemoService is now ready to be invoked by Dapr.
|
||||||
|
|
||||||
### Running the Demo middle service app
|
### Running the Demo middle service app
|
||||||
|
@ -208,10 +217,19 @@ public class OpenTelemetryConfig {
|
||||||
|
|
||||||
Use the follow command to execute the service:
|
Use the follow command to execute the service:
|
||||||
|
|
||||||
```sh
|
<!-- STEP
|
||||||
|
name: Run proxy service
|
||||||
|
expected_stdout_lines:
|
||||||
|
background: true
|
||||||
|
sleep: 20
|
||||||
|
-->
|
||||||
|
|
||||||
|
```bash
|
||||||
dapr run --app-id tracingdemoproxy --app-port 3001 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.TracingDemoService -p 3001
|
dapr run --app-id tracingdemoproxy --app-port 3001 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.TracingDemoService -p 3001
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<!-- END_STEP -->
|
||||||
|
|
||||||
### Running the InvokeClient app
|
### Running the InvokeClient app
|
||||||
|
|
||||||
This sample code uses the Dapr SDK for invoking two remote methods (`proxy_echo` and `proxy_sleep`). It is also instrumented with OpenTelemetry. See the code snippet below:
|
This sample code uses the Dapr SDK for invoking two remote methods (`proxy_echo` and `proxy_sleep`). It is also instrumented with OpenTelemetry. See the code snippet below:
|
||||||
|
@ -247,13 +265,10 @@ private static final String SERVICE_APP_ID = "tracingdemoproxy";
|
||||||
}).subscriberContext(getReactorContext()).block();
|
}).subscriberContext(getReactorContext()).block();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an example, so for simplicity we are just exiting here.
|
|
||||||
// Normally a dapr app would be a web service and not exit main.
|
|
||||||
System.out.println("Done");
|
|
||||||
}
|
}
|
||||||
span.end();
|
span.end();
|
||||||
shutdown();
|
shutdown();
|
||||||
|
System.out.println("Done");
|
||||||
}
|
}
|
||||||
///...
|
///...
|
||||||
}
|
}
|
||||||
|
@ -262,9 +277,21 @@ private static final String SERVICE_APP_ID = "tracingdemoproxy";
|
||||||
The class knows the app id for the remote application. It uses `invokeMethod` method to invoke API calls on the service endpoint. The request object includes an instance of `io.opentelemetry.context.Context` for the proper tracing headers to be propagated.
|
The class knows the app id for the remote application. It uses `invokeMethod` method to invoke API calls on the service endpoint. The request object includes an instance of `io.opentelemetry.context.Context` for the proper tracing headers to be propagated.
|
||||||
|
|
||||||
Execute the follow script in order to run the InvokeClient example, passing two messages for the remote method:
|
Execute the follow script in order to run the InvokeClient example, passing two messages for the remote method:
|
||||||
```sh
|
|
||||||
|
<!-- STEP
|
||||||
|
name: Run demo client
|
||||||
|
expected_stdout_lines:
|
||||||
|
- '== APP == Done'
|
||||||
|
background: true
|
||||||
|
sleep: 20
|
||||||
|
-->
|
||||||
|
|
||||||
|
```bash
|
||||||
dapr run -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.InvokeClient "message one" "message two"
|
dapr run -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.InvokeClient "message one" "message two"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<!-- END_STEP -->
|
||||||
|
|
||||||
Open the `tracingdemo` console and check the output as follows:
|
Open the `tracingdemo` console and check the output as follows:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation and Dapr Contributors.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.dapr.examples.tracing;
|
||||||
|
|
||||||
|
import com.jayway.jsonpath.DocumentContext;
|
||||||
|
import com.jayway.jsonpath.JsonPath;
|
||||||
|
import net.minidev.json.JSONArray;
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to verify that traces are present as expected.
|
||||||
|
*/
|
||||||
|
final class Validation {
|
||||||
|
|
||||||
|
private static final OkHttpClient HTTP_CLIENT = new OkHttpClient();
|
||||||
|
|
||||||
|
public static final String JSONPATH_PROXY_ECHO_SPAN_ID =
|
||||||
|
"$..[?(@.parentId=='%s' && @.name=='calllocal/tracingdemoproxy/proxy_echo')]['id']";
|
||||||
|
|
||||||
|
public static final String JSONPATH_ECHO_SPAN_ID =
|
||||||
|
"$..[?(@.parentId=='%s' && @.name=='calllocal/tracingdemo/echo')]['id']";
|
||||||
|
|
||||||
|
public static final String JSONPATH_PROXY_SLEEP_SPAN_ID =
|
||||||
|
"$..[?(@.parentId=='%s' && @.duration > 1000000 && @.name=='calllocal/tracingdemoproxy/proxy_sleep')]['id']";
|
||||||
|
|
||||||
|
public static final String JSONPATH_SLEEP_SPAN_ID =
|
||||||
|
"$..[?(@.parentId=='%s' && @.duration > 1000000 && @.name=='calllocal/tracingdemo/sleep')]['id']";
|
||||||
|
|
||||||
|
static void validate() throws Exception {
|
||||||
|
// Must wait for some time to make sure Zipkin receives all spans.
|
||||||
|
Thread.sleep(5000);
|
||||||
|
HttpUrl.Builder urlBuilder = new HttpUrl.Builder();
|
||||||
|
urlBuilder.scheme("http")
|
||||||
|
.host("localhost")
|
||||||
|
.port(9411);
|
||||||
|
urlBuilder.addPathSegments("api/v2/traces");
|
||||||
|
Request.Builder requestBuilder = new Request.Builder()
|
||||||
|
.url(urlBuilder.build());
|
||||||
|
requestBuilder.method("GET", null);
|
||||||
|
|
||||||
|
Request request = requestBuilder.build();
|
||||||
|
|
||||||
|
Response response = HTTP_CLIENT.newCall(request).execute();
|
||||||
|
DocumentContext documentContext = JsonPath.parse(response.body().string());
|
||||||
|
String mainSpanId = readOne(documentContext, "$..[?(@.name == \"example's main\")]['id']").toString();
|
||||||
|
|
||||||
|
// Validate echo
|
||||||
|
assertCount(documentContext,
|
||||||
|
String.format(JSONPATH_PROXY_ECHO_SPAN_ID, mainSpanId),
|
||||||
|
2);
|
||||||
|
String proxyEchoSpanId = readOne(documentContext,
|
||||||
|
String.format(JSONPATH_PROXY_ECHO_SPAN_ID, mainSpanId))
|
||||||
|
.toString();
|
||||||
|
String proxyEchoSpanId2 = readOne(documentContext,
|
||||||
|
String.format(JSONPATH_PROXY_ECHO_SPAN_ID, proxyEchoSpanId))
|
||||||
|
.toString();
|
||||||
|
readOne(documentContext,
|
||||||
|
String.format(JSONPATH_ECHO_SPAN_ID, proxyEchoSpanId2));
|
||||||
|
|
||||||
|
// Validate sleep
|
||||||
|
assertCount(documentContext,
|
||||||
|
String.format(JSONPATH_PROXY_SLEEP_SPAN_ID, mainSpanId),
|
||||||
|
2);
|
||||||
|
String proxySleepSpanId = readOne(documentContext,
|
||||||
|
String.format(JSONPATH_PROXY_SLEEP_SPAN_ID, mainSpanId))
|
||||||
|
.toString();
|
||||||
|
String proxySleepSpanId2 = readOne(documentContext,
|
||||||
|
String.format(JSONPATH_PROXY_SLEEP_SPAN_ID, proxySleepSpanId))
|
||||||
|
.toString();
|
||||||
|
readOne(documentContext,
|
||||||
|
String.format(JSONPATH_SLEEP_SPAN_ID, proxySleepSpanId2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object readOne(DocumentContext documentContext, String path) {
|
||||||
|
JSONArray arr = documentContext.read(path);
|
||||||
|
if (arr.size() == 0) {
|
||||||
|
throw new RuntimeException("No record found for " + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertCount(DocumentContext documentContext, String path, int expectedCount) {
|
||||||
|
JSONArray arr = documentContext.read(path);
|
||||||
|
if (arr.size() != expectedCount) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
String.format("Unexpected count %d vs expected %d for %s", arr.size(), expectedCount, path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue