allthingssecurity opened a new pull request, #28716:
URL: https://github.com/apache/camel/pull/28716

   # Description
   
   [CAMEL-26330](https://issues.apache.org/jira/browse/CAMEL-26330): the first 
part of the `camel-chaos` module from `design/chaos.adoc` (#28539). It uses the 
send hook ([CAMEL-26331](https://issues.apache.org/jira/browse/CAMEL-26331), 
merged as #28598) and the step hook 
([CAMEL-26338](https://issues.apache.org/jira/browse/CAMEL-26338), merged as 
#28646), only through their public SPI (`SendHook`, `StepHook` and the getters 
and setters on `ExtendedCamelContext`).
   
   With the JAR on the classpath and profile `dev` (or 
`camel.chaos.enabled=true`), a developer adds rules such as 
`endpoint=kafka:orders* error rate=0.3 until=1m` or `step=enrich delay 
duration=500ms` while the application runs, and sees how `onException`, 
redelivery and the dead letter channel cope. A report says what each rule did. 
Never with profile `prod`.
   
   This is the core only: the switch, the options, the rules, the faults at 
sends (`error`, `delay`, `drop`) and steps (`error`, `delay`), and a report per 
rule. A second PR on top adds the poll and route-entry faults, `corrupt`, 
`error status=` for HTTP, the counts per route and the expectations with a 
verdict; none of that is here (the parser rejects `route=`, `at=poll`, 
`corrupt`, `status=`, `expect=`, and the docs do not mention them). The 
console, CLI and MCP tools, and `stall`/`lifecycle`, come after.
   
   ## What is in it
   
   - `components/camel-chaos`: a `ContextServicePlugin` that decides when the 
context initializes (`prod` never; `camel.chaos.enabled` wins otherwise; 
without it only `dev`). When off, nothing is installed but that idle lifecycle 
strategy. When on: the send hook, the step hook, the manager, a WARN, and the 
startup rules; an invalid rule or option vetoes the start. A hand-written rule 
parser (no regular expressions, at most 2000 characters), copy-on-write rule 
sets, a seeded random sequence per rule, and delays that wait through 
`TimeSource` on the calling thread. Docs page and registration files.
   - camel-main: `camel.chaos.*` (`ChaosConfigurationProperties`: `enabled`, 
`seed`, `rules`, `maxDuration`, `reportOnShutdown`) with the generated 
configurer and metadata. `rules` is `insecure:dev`, so `prod` refuses to start 
with rules.
   - camel-util: `SecurityUtils` matches `camel.chaos.rules` by its whole key; 
the `TimeSource` Javadoc says camel-chaos reads the clock through it 
(camel-core waits for its delays through it).
   
   Public API (`@since 4.24`): `ChaosManager.get(context)`, `addRule`, 
`changeRule`, `removeRule`, `clearRules`, `report()`, and `ChaosReport` 
(`getSeed`, `toText`, `toJson`), so tests and a plain `Main` can use chaos 
before the CLI and MCP tools exist.
   
   ## Where this differs from the design
   
   - **A rule ends** when `TimeSource` time passes its end, checked at each 
match, not by a scheduled task: no thread to manage, and virtual time in a DST 
world.
   - **Options outside camel-main.** camel-main publishes `camel.chaos.*` in 
the properties component (as for `camel.aiObservability.enabled`), and the 
plugin reads them there. So `camel.chaos.enabled=true` also works on Spring 
Boot and Quarkus, but there (and for rules set from Java) camel-main's 
`insecure:dev` check does not run; chaos stays off in `prod` anyway.
   - **`SecurityUtils`.** The generated map is keyed by the bare option name, 
and `rules` would also catch schematron's option. So a small hand-written map 
matches the whole key first; its `insecureValue` is `null`, meaning any 
non-blank value.
   - **Patterns** are globs matched without backtracking: case-sensitive, `*` 
anywhere, no regular-expression fallback, unlike `PatternHelper`. Rules can 
come from tools, so matching must stay cheap.
   - **Limits the design leaves open:** 100 rules (ended ones move to the 
history to make room), a history of 100, 2000 characters per rule, `delay` and 
`until` at most `camel.chaos.maxDuration`, the first matching rule that fires 
decides, and a changed rule keeps its id and starts again.
   
   **Cost** (no JMH; a `ProducerTemplate` into three routes, the mean of 3 JVM 
runs of 9 x 100,000 calls, ns per call, in the order no JAR / chaos off / on 
without rules / on with three rules that match nothing): empty route 411 / 413 
/ 431 / 464; one `to` 609 / 600 / 622 / 732; a recipient list of two 1800 / 
1778 / 1820 / 1971. Development-time cost only.
   
   **Promised fold-in moved:** the `SendHelper` parentheses gnodet-bot asked 
for in #28598 wait for the next chaos PR that touches camel-support.
   
   ## Tests
   
   - camel-chaos: 130 tests in 12 classes, no `Thread.sleep`. They cover the 
parser (57, with a fuzz test and adversarial inputs), fail-closed activation 
(22, including `prod` with rules and `enabled=true`), camel-main, send and step 
faults under the error handlers, the report, the seed, and a stress test (8 
threads, 16,000 sends, rules added, changed and removed 30 times; every send is 
failed, dropped or delivered exactly once). Delays and rule ends run on a 
virtual `TimeSource` clock.
   - Each class ran 20 times alone, one JVM per run: 240 runs, 0 failures. Ten 
negative controls (the key behaviours broken one at a time) each fail at least 
one test.
   - camel-main: `ChaosConfigurationPropertiesTest` (8) and 
`MainSecurityPolicyTest`; the whole camel-main suite passes (318). camel-util: 
`SecurityUtilsTest` (22, 3 new).
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL-26330) 
filed for the change (usually before you start working on it): 
[CAMEL-26330](https://issues.apache.org/jira/browse/CAMEL-26330).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
     (I built the core modules, camel-main and the module with the formatter, 
impsort and camel-main generators; the catalog and docs copies are 
byte-identical to their sources. I did not run the full root build.)
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
     This PR was prepared with Claude Code (Claude Opus 5.5). The commit 
carries a `Co-Authored-By` trailer.
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to