The Cameleer agent now supports camel-native data extraction taps, business attributes on executions, enhanced replay with editable payloads, per-route recording toggles, and success compression. The agent-side implementation is deployed and live.
The shared models (`TapDefinition`, extended `ApplicationConfig` with `taps`, `tapVersion`, `routeRecording`, `compressSuccess`) exist in `cameleer-common` (agent repo). The server already depends on this library and persists `ApplicationConfig` as JSONB in the `application_config` table. However, the server-side execution DTOs (`ExecutionDetail`, `ExecutionSummary`, `ProcessorNode`) do not yet carry `attributes` fields, and the `CommandType` enum lacks `TEST_EXPRESSION`.
This spec covers all UI surfaces and the backend changes needed to support them.
## Design Decisions
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Tap management location | RouteDetail contextual + AppConfigDetail overview | Taps target processors; processor list is contextual to a route. Admin overview for cross-route visibility. |
| Business attributes display | Header badges + per-processor + dashboard table | Primary value of taps — must be front-and-center for quick identification |
| Replay trigger | Button in ExchangeDetail header | Route-level action, clear and discoverable |
1.**Update `cameleer-common` dependency** — ensure the server pulls a version that includes `TapDefinition`, and `ApplicationConfig` with `taps`, `tapVersion`, `routeRecording`, `compressSuccess` fields.
2.**Add `attributes` to execution DTOs** — `ExecutionDetail`, `ProcessorNode`, and `ExecutionSummary` need a `Map<String, String> attributes` field. This requires changes to the PostgreSQL ingestion pipeline (store attributes from agent-submitted `RouteExecution`/`ProcessorExecution`), the detail service (reconstruct attributes), and the OpenSearch indexing (index attributes for search results).
3.**Add `TEST_EXPRESSION` to `CommandType`** enum.
4.**Enhance `CommandAckRequest`** — add an optional `data` field (`String`, JSON) to carry structured results (currently only `status` + `message`). The test-expression endpoint needs the result value from the ACK.
5.**Regenerate `openapi.json`** after all backend REST API changes.
## Page Changes
### 1. ExchangeDetail
**Business attributes strip** between header info and stat boxes:
- Route-level attributes as auto-colored badges (`key: value`, monospace)
- Wraps on overflow
- Empty state: section not rendered when no attributes exist
**Per-processor attributes** in processor detail panel:
- Badges below processor info, before message IN/OUT sections
- Shows attributes extracted at that specific processor
**Replay button** in header action area (top-right), primary blue. Requires OPERATOR or ADMIN role:
- Opens large Modal with:
- Warning banner ("This will re-execute the exchange on the selected agent")
- Target Agent select — uses `useAgents(application, 'LIVE')` to populate. Disabled with message when no LIVE agents available.
- Tabs: Headers (editable key-value table with add/remove) | Body (editable monospace textarea, JSON indicator)
- Pre-populated from original exchange's `inputHeaders` and `inputBody` (already available on `ExecutionDetail`)
- Cancel / Replay footer
- Sends REPLAY command via `POST /api/v1/agents/{agentId}/commands`
- Recent Exchange: auto-selects most recent exchange with captured data at selected processor. Dropdown to change. Test button sends expression to live agent. Result display.
- Custom Payload: editable textarea pre-populated from most recent exchange body. Switching from Recent Exchange carries the payload over. Test button → result display.
- Result: green success box with extracted value, or red error box with message
- Loading state: spinner on Test button while awaiting agent response
- No agents state: "No LIVE agents available to test expression" with Test button disabled
- Note showing which agent evaluated and which language was used
- Save / Cancel footer
- Save writes the tap to the `taps` array in ApplicationConfig via existing `PUT /api/v1/config/{application}`
### 4. AppConfigDetailPage
Restructured to **3 sections** (from 4):
**Section 1 — Settings:** Merged Logging + Observability. All settings as badges in flex row: Log Forwarding, Engine Level, Payload Capture, Metrics, Sampling Rate, Compress Success (new). Edit mode: badges become dropdowns/toggles.
**Section 2 — Traces & Taps:** Merged Traced Processors + Data Extraction Taps. Table columns: Route, Processor, Capture (badge or em-dash), Taps (attribute name badges with enabled/disabled indicator). Sorted by route. Capture editable in edit mode; taps read-only with "manage taps on route pages" hint. Summary: "N traced · M taps".
Processor-to-route mapping: Taps carry a `processorId` that belongs to a specific route. The route association is derived by cross-referencing with route diagram data (via `useDiagramLayout` per route from the route catalog). If a processor cannot be mapped to a route (e.g., route no longer active), show "unknown" in the Route column.
**Section 3 — Route Recording:** Table: Route + Recording toggle. Summary: "N of M routes recording". Toggles editable in edit mode. Route list from `useRouteCatalog` filtered by application. Routes not present in the `routeRecording` map default to recording enabled (consistent with agent behavior where absence = enabled).
### 5. AgentHealth Config Bar
No changes. New features managed at AppConfig level, not per-agent.
## RBAC Permissions
| Action | Minimum Role |
|--------|-------------|
| View business attributes | VIEWER |
| View taps / traces / recording state | VIEWER |
| Create / edit / delete taps | OPERATOR |
| Toggle route recording | OPERATOR |
| Edit app config settings | OPERATOR |
| Replay exchange | OPERATOR |
| Test expression | OPERATOR |
These align with the existing pattern where VIEWER sees data and OPERATOR can modify configuration.
{ "error": "Expression evaluation timed out (50ms limit)" }
```
**Request-reply mechanism:** The server selects a LIVE agent for the application, sends a `TEST_EXPRESSION` command via SSE, then awaits the ACK with a `CompletableFuture` (timeout 5s). The `CommandAckRequest` record is extended with an optional `data` field (JSON string) to carry the evaluation result. The controller completes the future when the ACK arrives, returning the result to the HTTP caller. If no LIVE agent is available or the timeout expires, the endpoint returns an appropriate error response.
### Replay Command Payload
The REPLAY command (already exists in `CommandType`) is sent via `POST /api/v1/agents/{agentId}/commands`:
```json
{
"type": "replay",
"payload": {
"headers": {
"Content-Type": "application/json",
"X-Correlation-Id": "corr-abc123"
},
"body": "{\"orderId\": \"ORD-2024-78542\", ...}"
}
}
```
The agent uses `ProducerTemplate.send()` to replay the exchange on the original route with the provided headers and body.
**`ExecutionSummary`** — add `Map<String, String> attributes` (route-level, for dashboard table)
These require:
- PostgreSQL ingestion: store attributes from incoming `RouteExecution` and `ProcessorExecution` (the agent already sends them)
- Detail service: include attributes when reconstructing the execution tree
- OpenSearch indexing: index route-level attributes for search result enrichment
### CommandType Addition
Add `TEST_EXPRESSION` to the `CommandType` enum.
### CommandAckRequest Enhancement
Extend from `(String status, String message)` to `(String status, String message, String data)` where `data` is an optional JSON string for structured results.
## Design System Impact
No new components required. Uses existing: Modal, DataTable, Badge, Toggle, Select, Input, Textarea, FormField, Tabs, Button, CodeBlock, Collapsible.