feat: add is_replay flag to execution pipeline and UI

Detect replayed exchanges via X-Cameleer-Replay header during ingestion,
persist the flag through PostgreSQL and OpenSearch, and surface it in
the dashboard (amber replay icon) and exchange detail chain view.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-31 14:39:40 +02:00
parent cf3cec0164
commit ab7031e6ed
11 changed files with 35 additions and 12 deletions

View File

@@ -79,7 +79,7 @@ public class SearchIndexer implements SearchIndexerStats {
exec.status(), exec.correlationId(), exec.exchangeId(),
exec.startTime(), exec.endTime(), exec.durationMs(),
exec.errorMessage(), exec.errorStacktrace(), processorDocs,
exec.attributes(), exec.hasTraceData()));
exec.attributes(), exec.hasTraceData(), exec.isReplay()));
indexedCount.incrementAndGet();
lastIndexedAt = Instant.now();

View File

@@ -102,6 +102,12 @@ public class IngestionService {
boolean hasTraceData = hasAnyTraceData(exec.getProcessors());
boolean isReplay = false;
if (inputSnapshot != null && inputSnapshot.getHeaders() != null) {
isReplay = "true".equalsIgnoreCase(
String.valueOf(inputSnapshot.getHeaders().get("X-Cameleer-Replay")));
}
return new ExecutionRecord(
exec.getExchangeId(), exec.getRouteId(), agentId, applicationName,
exec.getStatus() != null ? exec.getStatus().name() : "RUNNING",
@@ -117,7 +123,8 @@ public class IngestionService {
exec.getRootCauseType(), exec.getRootCauseMessage(),
exec.getTraceId(), exec.getSpanId(),
toJsonObject(exec.getProcessors()),
hasTraceData
hasTraceData,
isReplay
);
}

View File

@@ -34,6 +34,7 @@ public record ExecutionSummary(
String diagramContentHash,
String highlight,
Map<String, String> attributes,
boolean hasTraceData
boolean hasTraceData,
boolean isReplay
) {
}

View File

@@ -30,7 +30,8 @@ public interface ExecutionStore {
String rootCauseType, String rootCauseMessage,
String traceId, String spanId,
String processorsJson,
boolean hasTraceData
boolean hasTraceData,
boolean isReplay
) {}
record ProcessorRecord(

View File

@@ -10,7 +10,8 @@ public record ExecutionDocument(
String errorMessage, String errorStacktrace,
List<ProcessorDoc> processors,
String attributes,
boolean hasTraceData
boolean hasTraceData,
boolean isReplay
) {
public record ProcessorDoc(
String processorId, String processorType, String status,