Rename Java packages from com.cameleer3 to com.cameleer, module directories from cameleer3-* to cameleer-*, and all references throughout workflows, Dockerfiles, docs, migrations, and pom.xml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 KiB
Taps, Business Attributes & Enhanced Replay — UI Design
Context
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 |
| Route recording location | RouteDetail toggle + AppConfigDetail bulk table | Contextual single-route control + centralized bulk management |
| Compress success | Badge in AppConfigDetail Settings section | Simple boolean toggle, admin-level concern |
| Expression testing | Agent-side evaluation via TEST_EXPRESSION command | Only the agent has the Camel expression engine; works for all languages |
| AppConfigDetail layout | 3 sections: Settings, Traces & Taps, Route Recording | Collapsed from 4 sections; Logging+Observability merged, TracedProcessors+Taps merged |
Prerequisites
Before UI work can begin, the following backend changes are required:
- Update
cameleer-commondependency — ensure the server pulls a version that includesTapDefinition, andApplicationConfigwithtaps,tapVersion,routeRecording,compressSuccessfields. - Add
attributesto execution DTOs —ExecutionDetail,ProcessorNode, andExecutionSummaryneed aMap<String, String> attributesfield. This requires changes to the PostgreSQL ingestion pipeline (store attributes from agent-submittedRouteExecution/ProcessorExecution), the detail service (reconstruct attributes), and the OpenSearch indexing (index attributes for search results). - Add
TEST_EXPRESSIONtoCommandTypeenum. - Enhance
CommandAckRequest— add an optionaldatafield (String, JSON) to carry structured results (currently onlystatus+message). The test-expression endpoint needs the result value from the ACK. - Regenerate
openapi.jsonafter 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
inputHeadersandinputBody(already available onExecutionDetail) - Cancel / Replay footer
- Sends REPLAY command via
POST /api/v1/agents/{agentId}/commands - Payload:
{ "type": "replay", "payload": { "headers": {...}, "body": "..." } } - Success: toast with confirmation message from ACK
- Failure: toast with error message
- Loading state: Replay button shows spinner while awaiting ACK
2. Dashboard Exchanges Table
New "Attributes" column between App and Exchange ID:
- First 2 attribute values as compact auto-colored badges (value only; key shown via native
titleattribute on hover) - "+N" overflow indicator when more than 2
- Em-dash when no attributes
3. RouteDetail
Recording toggle in route header (top-right):
- Toggle in pill container with "Recording" label
- Updates
routeRecordingmap in ApplicationConfig via PUT - Requires OPERATOR or ADMIN role
"Active Taps" KPI card added to KPI strip.
New "Taps" tab (fourth tab alongside Performance, Recent Executions, Error Patterns):
- Header: "Data Extraction Taps" + "Add Tap" button (OPERATOR or ADMIN only)
- DataTable columns: Attribute, Processor, Expression, Language, Target, Type, Enabled (toggle), Actions (edit/delete)
- Add/edit opens tap modal
- Empty state: "No taps configured for this route. Add a tap to extract business attributes from exchange data."
Add/Edit Tap modal (Modal size="md"):
- Fields: Attribute Name (input), Processor (select from route diagram via
useDiagramLayout), Language + Target (side-by-side selects), Expression (monospace textarea), Attribute Type (pill selector: BUSINESS_OBJECT / CORRELATION / EVENT / CUSTOM), Enabled toggle - Test Expression section (collapsible, default expanded):
- Tabs: "Recent Exchange" | "Custom Payload"
- 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
tapsarray in ApplicationConfig via existingPUT /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.
TypeScript Interface Changes
// Add to ApplicationConfig in commands.ts
interface ApplicationConfig {
// ... existing fields ...
taps: TapDefinition[]
tapVersion: number
routeRecording: Record<string, boolean>
compressSuccess: boolean
}
interface TapDefinition {
tapId: string
processorId: string
target: 'INPUT' | 'OUTPUT' | 'BOTH'
expression: string
language: string
attributeName: string
attributeType: 'BUSINESS_OBJECT' | 'CORRELATION' | 'EVENT' | 'CUSTOM'
enabled: boolean
version: number
}
Backend Changes
New Endpoint: Test Expression
POST /api/v1/config/{application}/test-expression
Request:
{
"expression": "${body.orderId}",
"language": "simple",
"body": "{\"orderId\": \"ORD-123\"}",
"target": "OUTPUT"
}
Response (success):
{ "result": "ORD-123" }
Response (failure):
{ "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:
{
"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.
Execution DTO Changes
ExecutionDetail — add Map<String, String> attributes (route-level aggregated)
ProcessorNode — add Map<String, String> attributes (per-processor)
ExecutionSummary — add Map<String, String> attributes (route-level, for dashboard table)
These require:
- PostgreSQL ingestion: store attributes from incoming
RouteExecutionandProcessorExecution(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.
Files Touched
Frontend (ui/src/)
api/queries/commands.ts— TapDefinition interface, extend ApplicationConfig, add test-expression mutation, add replay mutationpages/ExchangeDetail/ExchangeDetail.tsx— attributes strip, per-processor attributes, replay button + modalpages/ExchangeDetail/ExchangeDetail.module.css— attributes strip styles, replay modal stylespages/Dashboard/Dashboard.tsx— attributes column in exchanges tablepages/Routes/RouteDetail.tsx— recording toggle, active taps KPI, taps tab, tap modal with test sectionpages/Routes/RouteDetail.module.css— taps tab, recording toggle, tap modal stylespages/Admin/AppConfigDetailPage.tsx— restructure to 3 sections, traces & taps merged table, route recording table, compress success badgepages/Admin/AppConfigDetailPage.module.css— updated section styles
Backend (cameleer-server-app/)
controller/ApplicationConfigController.java— add test-expression endpointdto/CommandAckRequest.java— add optionaldatafieldcontroller/AgentCommandController.java— support CompletableFuture-based ACK for test-expression
Backend (cameleer-server-core/)
agent/CommandType.java— add TEST_EXPRESSIONdetail/ExecutionDetail.java— add attributes fielddetail/ProcessorNode.java— add attributes fieldsearch/ExecutionSummary.java— add attributes fielddetail/DetailService.java— include attributes in reconstructionstorage/— store attributes from ingested executionssearch/SearchService.java— include attributes in search results
Generated
ui/src/api/schema.d.ts— regenerate from openapi.jsonopenapi.json— regenerate after backend changes