Skip to content

Commit cddf3fa

Browse files
committed
add okhttp to spring boot sample, add e2e test
1 parent 7074cdd commit cddf3fa

6 files changed

Lines changed: 62 additions & 1 deletion

File tree

‎sentry-samples/sentry-samples-spring-boot-4/build.gradle.kts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ dependencies {
6464
implementation(libs.springboot4.starter.kafka)
6565
implementation(projects.sentryKafka)
6666

67+
// okhttp client instrumentation
68+
implementation(projects.sentryOkhttp)
69+
implementation(libs.okhttp)
70+
6771
// database query tracing
6872
implementation(projects.sentryJdbc)
6973
runtimeOnly(libs.hsqldb)

‎sentry-samples/sentry-samples-spring-boot-4/src/main/java/io/sentry/samples/spring/boot4/SentryDemoApplication.java‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import io.sentry.samples.spring.boot4.quartz.SampleJob;
66
import java.util.Collections;
7+
import okhttp3.OkHttpClient;
78
import org.quartz.JobDetail;
89
import org.quartz.SimpleTrigger;
910
import org.springframework.boot.SpringApplication;
@@ -42,6 +43,12 @@ RestClient restClient(RestClient.Builder builder) {
4243
return builder.build();
4344
}
4445

46+
@Bean
47+
OkHttpClient okHttpClient() {
48+
// automatically instrumented by Sentry via sentry.clients.ok-http-enabled=true
49+
return new OkHttpClient.Builder().build();
50+
}
51+
4552
@Bean
4653
public JobDetailFactoryBean jobDetail() {
4754
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();

‎sentry-samples/sentry-samples-spring-boot-4/src/main/java/io/sentry/samples/spring/boot4/TodoController.java‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package io.sentry.samples.spring.boot4;
22

33
import io.sentry.reactor.SentryReactorUtils;
4+
import java.io.IOException;
5+
import java.io.UncheckedIOException;
6+
import okhttp3.OkHttpClient;
7+
import okhttp3.Request;
8+
import okhttp3.Response;
49
import org.springframework.web.bind.annotation.GetMapping;
510
import org.springframework.web.bind.annotation.PathVariable;
611
import org.springframework.web.bind.annotation.RestController;
@@ -10,17 +15,27 @@
1015
import reactor.core.publisher.Hooks;
1116
import reactor.core.publisher.Mono;
1217
import reactor.core.scheduler.Schedulers;
18+
import tools.jackson.databind.ObjectMapper;
1319

1420
@RestController
1521
public class TodoController {
1622
private final RestTemplate restTemplate;
1723
private final WebClient webClient;
1824
private final RestClient restClient;
25+
private final OkHttpClient okHttpClient;
26+
private final ObjectMapper objectMapper;
1927

20-
public TodoController(RestTemplate restTemplate, WebClient webClient, RestClient restClient) {
28+
public TodoController(
29+
RestTemplate restTemplate,
30+
WebClient webClient,
31+
RestClient restClient,
32+
OkHttpClient okHttpClient,
33+
ObjectMapper objectMapper) {
2134
this.restTemplate = restTemplate;
2235
this.webClient = webClient;
2336
this.restClient = restClient;
37+
this.okHttpClient = okHttpClient;
38+
this.objectMapper = objectMapper;
2439
}
2540

2641
@GetMapping("/todo/{id}")
@@ -54,4 +69,15 @@ Todo todoRestClient(@PathVariable Long id) {
5469
.retrieve()
5570
.body(Todo.class);
5671
}
72+
73+
@GetMapping("/todo-okhttp/{id}")
74+
Todo todoOkHttp(@PathVariable Long id) {
75+
final Request request =
76+
new Request.Builder().url("https://jsonplaceholder.typicode.com/todos/" + id).build();
77+
try (Response response = okHttpClient.newCall(request).execute()) {
78+
return objectMapper.readValue(response.body().byteStream(), Todo.class);
79+
} catch (IOException e) {
80+
throw new UncheckedIOException(e);
81+
}
82+
}
5783
}

‎sentry-samples/sentry-samples-spring-boot-4/src/main/resources/application.properties‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ sentry.profile-session-sample-rate=1.0
2121
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
2222
sentry.profile-lifecycle=TRACE
2323
sentry.enable-cache-tracing=true
24+
# Automatically instrument Spring-managed OkHttpClient beans
25+
sentry.clients.ok-http-enabled=true
2426
spring.cache.cache-names=todos
2527
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s
2628

‎sentry-samples/sentry-samples-spring-boot-4/src/test/kotlin/io/sentry/systemtest/TodoSystemTest.kt‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,20 @@ class TodoSystemTest {
5858
)
5959
}
6060
}
61+
62+
@Test
63+
fun `get todo okhttp works`() {
64+
val restClient = testHelper.restClient
65+
restClient.getTodoOkHttp(1L)
66+
assertEquals(200, restClient.lastKnownStatusCode)
67+
68+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
69+
transaction.transaction == "GET /todo-okhttp/{id}" &&
70+
testHelper.doesTransactionContainSpanWithOpAndDescription(
71+
transaction,
72+
"http.client",
73+
"GET https://jsonplaceholder.typicode.com/todos/1",
74+
)
75+
}
76+
}
6177
}

‎sentry-system-test-support/src/main/kotlin/io/sentry/systemtest/util/RestTestClient.kt‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ class RestTestClient(private val backendBaseUrl: String) : LoggingInsecureRestCl
5050
return callTyped(request, true)
5151
}
5252

53+
fun getTodoOkHttp(id: Long): Todo? {
54+
val request = Request.Builder().url("$backendBaseUrl/todo-okhttp/$id")
55+
56+
return callTyped(request, true)
57+
}
58+
5359
fun getCachedTodo(id: Long): Todo? {
5460
val request = Request.Builder().url("$backendBaseUrl/cache/$id")
5561

0 commit comments

Comments
 (0)