Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.sentry.samples.spring.boot4;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/cache/")
public class CacheController {
private final TodoService todoService;

public CacheController(TodoService todoService) {
this.todoService = todoService;
}

@GetMapping("{id}")
Todo get(@PathVariable Long id) {
return todoService.get(id);
}

@PostMapping
Todo save(@RequestBody Todo todo) {
return todoService.save(todo);
}

@DeleteMapping("{id}")
void delete(@PathVariable Long id) {
todoService.delete(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
Expand All @@ -19,12 +22,18 @@
import org.springframework.web.reactive.function.client.WebClient;

@SpringBootApplication
@EnableCaching
@EnableScheduling
public class SentryDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SentryDemoApplication.class, args);
}

@Bean
CacheManager cacheManager() {
return new ConcurrentMapCacheManager("todos");
}

@Bean
RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.sentry.samples.spring.boot4;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class TodoService {
private final Map<Long, Todo> store = new ConcurrentHashMap<>();

@Cacheable(value = "todos", key = "#id")
public Todo get(Long id) {
return store.get(id);
}

@CachePut(value = "todos", key = "#todo.id")
public Todo save(Todo todo) {
store.put(todo.getId(), todo);
return todo;
}

@CacheEvict(value = "todos", key = "#id")
public void delete(Long id) {
store.remove(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ sentry.logs.enabled=true
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
sentry.profile-lifecycle=TRACE
sentry.enable-cache-tracing=true

# Uncomment and set to true to enable aot compatibility
# This flag disables all AOP related features (i.e. @SentryTransaction, @SentrySpan)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.sentry.systemtest

import io.sentry.systemtest.util.TestHelper
import kotlin.test.Test
import kotlin.test.assertEquals
import org.junit.Before

class CacheSystemTest {
lateinit var testHelper: TestHelper

@Before
fun setup() {
testHelper = TestHelper("http://localhost:8080")
testHelper.reset()
}

@Test
fun `cache put and get produce spans`() {
val restClient = testHelper.restClient

// Save a todo (triggers @CachePut -> cache.put span)
val todo = Todo(1L, "test-todo", false)
restClient.saveCachedTodo(todo)
assertEquals(200, restClient.lastKnownStatusCode)

testHelper.ensureTransactionReceived { transaction, _ ->
testHelper.doesTransactionContainSpanWithOp(transaction, "cache.put")
}

testHelper.reset()

// Get the todo (triggers @Cacheable -> cache.get span, should be a hit)
restClient.getCachedTodo(1L)
assertEquals(200, restClient.lastKnownStatusCode)

testHelper.ensureTransactionReceived { transaction, _ ->
testHelper.doesTransactionContainSpanWithOp(transaction, "cache.get")
}
}

@Test
fun `cache evict produces span`() {
val restClient = testHelper.restClient

restClient.deleteCachedTodo(1L)

testHelper.ensureTransactionReceived { transaction, _ ->
testHelper.doesTransactionContainSpanWithOp(transaction, "cache.remove")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,9 @@ public final class io/sentry/systemtest/util/RestTestClient : io/sentry/systemte
public static synthetic fun createPerson$default (Lio/sentry/systemtest/util/RestTestClient;Lio/sentry/systemtest/Person;Ljava/util/Map;ILjava/lang/Object;)Lio/sentry/systemtest/Person;
public final fun createPersonDistributedTracing (Lio/sentry/systemtest/Person;Ljava/util/Map;)Lio/sentry/systemtest/Person;
public static synthetic fun createPersonDistributedTracing$default (Lio/sentry/systemtest/util/RestTestClient;Lio/sentry/systemtest/Person;Ljava/util/Map;ILjava/lang/Object;)Lio/sentry/systemtest/Person;
public final fun deleteCachedTodo (J)V
public final fun errorWithFeatureFlag (Ljava/lang/String;)Ljava/lang/String;
public final fun getCachedTodo (J)Lio/sentry/systemtest/Todo;
public final fun getCountMetric ()Ljava/lang/String;
public final fun getDistributionMetric (J)Ljava/lang/String;
public final fun getGaugeMetric (J)Ljava/lang/String;
Expand All @@ -558,6 +560,7 @@ public final class io/sentry/systemtest/util/RestTestClient : io/sentry/systemte
public final fun getTodo (J)Lio/sentry/systemtest/Todo;
public final fun getTodoRestClient (J)Lio/sentry/systemtest/Todo;
public final fun getTodoWebclient (J)Lio/sentry/systemtest/Todo;
public final fun saveCachedTodo (Lio/sentry/systemtest/Todo;)Lio/sentry/systemtest/Todo;
}

public final class io/sentry/systemtest/util/SentryMockServerClient : io/sentry/systemtest/util/LoggingInsecureRestClient {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ class RestTestClient(private val backendBaseUrl: String) : LoggingInsecureRestCl
return callTyped(request, true)
}

fun getCachedTodo(id: Long): Todo? {
val request = Request.Builder().url("$backendBaseUrl/cache/$id")

return callTyped(request, true)
}

fun saveCachedTodo(todo: Todo): Todo? {
val request = Request.Builder().url("$backendBaseUrl/cache/").post(toRequestBody(todo))

return callTyped(request, true)
}

fun deleteCachedTodo(id: Long) {
val request = Request.Builder().url("$backendBaseUrl/cache/$id").delete()

call(request, true)
}

fun checkFeatureFlag(flagKey: String): FeatureFlagResponse? {
val request = Request.Builder().url("$backendBaseUrl/feature-flag/check/$flagKey")

Expand Down
Loading