gnodet-bot commented on code in PR #29388:
URL: https://github.com/apache/camel/pull/29388#discussion_r4503486269


##########
components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosStepHook.java:
##########
@@ -39,26 +39,54 @@ final class ChaosStepHook implements StepHook, Ordered {
 
     @Override
     public long beforeStep(Exchange exchange, String nodeId) {
-        ChaosRule[] rules = manager.ruleSet().step;
+        ChaosManager.RuleSet ruleSet = manager.ruleSet();
+        if (ruleSet.entryAtStep) {
+            ChaosRule entry = entryFault(exchange);
+            if (entry != null) {
+                // fired as the exchange entered the route: it counted there
+                return fault(entry, exchange);
+            }
+        }
+        ChaosRule[] rules = ruleSet.step;
         if (rules.length == 0 || nodeId == null) {
             return PROCEED;
         }
         long now = TimeSource.currentTimeMillis();
         for (ChaosRule rule : rules) {
-            if (rule.live(now) && rule.matchesId(nodeId) && rule.fires(now)) {
+            if (rule.live(now) && rule.matchesId(nodeId) && 
rule.matchesIn(exchange) && rule.fires(now)) {
                 rule.fired(Hook.STEP, exchange, null, nodeId);
-                if (rule.fault == Fault.DELAY) {
-                    return rule.delayFor();
-                }
-                if (ChaosFaults.waitBeforeError(rule, exchange)) {
-                    exchange.setException(ChaosFaults.newException(rule));
-                }
-                return PROCEED;
+                return fault(rule, exchange);
             }
         }
         return PROCEED;
     }
 
+    /**
+     * The rule with route= that fired as the exchange entered the route it is 
in now, which acts at this step, the
+     * first step of the route, once: a redelivery of the step by the error 
handler runs the step itself.
+     */
+    private static ChaosRule entryFault(Exchange exchange) {
+        ChaosExchangeState state = ChaosExchangeState.peek(exchange);
+        if (state == null || state.entryFault == null) {
+            return null;
+        }
+        ChaosRule rule = state.entryFault;
+        String route = state.entryRoute;
+        state.entryFault = null;
+        state.entryRoute = null;
+        return route.equals(ChaosExchangeState.routeId(exchange)) ? rule : 
null;

Review Comment:
   🔍 **Check-then-clear ordering:** `state.entryFault` and `state.entryRoute` 
are cleared unconditionally before the route-id validation. If the exchange's 
current route doesn't match (e.g. a custom interceptor that fires `beforeStep` 
for a different route first), the fault is silently lost — not deferred to the 
correct route's first step, just gone. The safe pattern is to check first, 
clear only on match:
   
   ```suggestion
           ChaosRule rule = state.entryFault;
           String route = state.entryRoute;
           if (!route.equals(ChaosExchangeState.routeId(exchange))) {
               return null;
           }
           state.entryFault = null;
           state.entryRoute = null;
           return rule;
   ```



##########
components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosRule.java:
##########
@@ -727,6 +738,19 @@ boolean matchesUri(String uri) {
         return ChaosPatterns.matchesUriPattern(uriPattern, uri);
     }
 
+    /**
+     * Whether the exchange is in a route of {@code in=}: the route of its 
unit of work, which is the route a
+     * {@code direct} call is in, not the route that called it. True for a 
rule without {@code in=}.
+     */
+    boolean matchesIn(Exchange exchange) {
+        return in == null || matchesIn(ChaosExchangeState.routeId(exchange));
+    }
+
+    /** Whether the route is one of {@code in=} (true for a rule without it). 
*/
+    boolean matchesIn(String routeId) {
+        return in == null || routeId != null && ChaosPatterns.matches(in, 
routeId);

Review Comment:
   🔍 **Operator precedence:** `&&` binds tighter than `||` in Java so this is 
correct, but it reads ambiguously. The intent (`in == null` OR `(routeId != 
null AND matches)`) is clearer with explicit parentheses:
   
   ```suggestion
           return in == null || (routeId != null && ChaosPatterns.matches(in, 
routeId));
   ```



##########
components/camel-chaos/src/main/docs/chaos.adoc:
##########
@@ -205,6 +207,26 @@ the endpoint URI `netty-http://http://inventory/stock`, 
and a camel-netty-http c
 matched with `netty-http` in front too. A `route=` pattern is matched against 
the route id, and a `step=` pattern against the id of the step
 (`to1`, or the id set with `id("enrich")`).
 
+=== The sends and steps of a route
+
+`in=` narrows the target of a rule to the routes whose id it matches, for the 
sends, steps and polls that you know by
+their route rather than by an endpoint URI or a step id (which are often 
generated, such as `to3`):
+
+[source]
+----
+endpoint=http:* in=orders error status=503      # the HTTP calls of route 
orders
+step=* in=orders delay duration=500ms           # every step of route orders
+component=kafka in=order* drop                  # the Kafka sends of the 
routes whose id starts with order
+endpoint=* in=orders error at=send rate=0.1     # 10% of all the sends of 
route orders
+----
+
+The route is the route of the exchange: a send in a route that `orders` calls 
with `direct:` is in that other route,
+not in `orders`; take more routes with a pattern (`in=order*`). With `at=poll` 
it is the route whose consumer polls.
+`in=` is checked before the rate, so `rate` and an `until` count count only 
the matches in those routes. A `route=`

Review Comment:
   🔍 **Typo:** double word `count count`.
   
   ```suggestion
   `in=` is checked before the rate, so `rate` and an `until` count only the 
matches in those routes. A `route=`
   ```



-- 
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