Expand entry-point and trigger detector coverage.

Detect fire/trigger wrappers as state-machine triggers, resolve Kafka topicPattern and additional Rabbit listener attributes, and add regression tests for WebFlux RouterFunction routes and messaging listeners.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-12 05:50:34 +02:00
parent b158179559
commit 23a14d8391
6 changed files with 217 additions and 9 deletions

View File

@@ -31,6 +31,9 @@ public class GenericEventDetector {
"eventString",
"version");
private static final Set<String> TRIGGER_METHOD_NAMES = Set.of(
"sendEvent", "sendEvents", "sendEventCollect", "sendEventMono", "fire", "trigger");
public List<TriggerPoint> detect(CompilationUnit cu) {
List<TriggerPoint> triggers = new ArrayList<>();
String fileName = "unknown";
@@ -45,15 +48,13 @@ public class GenericEventDetector {
public boolean visit(MethodInvocation node) {
String methodName = node.getName().getIdentifier();
if ("sendEvent".equals(methodName) || "sendEvents".equals(methodName) ||
"sendEventCollect".equals(methodName) || "sendEventMono".equals(methodName)) {
if (TRIGGER_METHOD_NAMES.contains(methodName)) {
processSendEvent(node, cu, triggers);
} else {
for (Object argObj : node.arguments()) {
if (argObj instanceof ExpressionMethodReference emr) {
String refMethod = emr.getName().getIdentifier();
if ("sendEvent".equals(refMethod) || "sendEvents".equals(refMethod) ||
"sendEventCollect".equals(refMethod) || "sendEventMono".equals(refMethod)) {
if (TRIGGER_METHOD_NAMES.contains(refMethod)) {
processSendEventMethodReference(node, emr, cu, triggers);
}
}

View File

@@ -40,6 +40,12 @@ public class MessagingDetector {
} else if (typeName.endsWith("RabbitListener")) {
type = EntryPoint.Type.RABBIT;
destination = resolveValue(annotation, "queues");
if ("unknown".equals(destination)) {
destination = resolveValue(annotation, "queue");
}
if ("unknown".equals(destination)) {
destination = resolveValue(annotation, "bindings");
}
} else if (typeName.endsWith("SqsListener")) {
type = EntryPoint.Type.SQS;
destination = resolveValue(annotation, "value");
@@ -55,6 +61,9 @@ public class MessagingDetector {
} else if (typeName.endsWith("KafkaListener")) {
type = EntryPoint.Type.KAFKA;
destination = resolveValue(annotation, "topics");
if ("unknown".equals(destination)) {
destination = resolveValue(annotation, "topicPattern");
}
}
if (type != null) {

View File

@@ -182,11 +182,11 @@ public class SpringMvcDetector {
}
private String getHttpVerb(String annotationName) {
if (annotationName.endsWith("PostMapping") || annotationName.endsWith("POST")) return "POST";
if (annotationName.endsWith("GetMapping") || annotationName.endsWith("GET")) return "GET";
if (annotationName.endsWith("PutMapping") || annotationName.endsWith("PUT")) return "PUT";
if (annotationName.endsWith("DeleteMapping") || annotationName.endsWith("DELETE")) return "DELETE";
if (annotationName.endsWith("PatchMapping") || annotationName.endsWith("PATCH")) return "PATCH";
if (annotationName.endsWith("PostMapping") || annotationName.endsWith("POST") || "POST".equals(annotationName)) return "POST";
if (annotationName.endsWith("GetMapping") || annotationName.endsWith("GET") || "GET".equals(annotationName)) return "GET";
if (annotationName.endsWith("PutMapping") || annotationName.endsWith("PUT") || "PUT".equals(annotationName)) return "PUT";
if (annotationName.endsWith("DeleteMapping") || annotationName.endsWith("DELETE") || "DELETE".equals(annotationName)) return "DELETE";
if (annotationName.endsWith("PatchMapping") || annotationName.endsWith("PATCH") || "PATCH".equals(annotationName)) return "PATCH";
if (annotationName.endsWith("RequestMapping")) return "REQUEST";
return null;
}