Repository navigation
Description
Problem and scope
Operators can see that a plugin was entered without knowing whether its selector/rule matched, which candidate won, or whether a positive/negative match cache supplied the result. Plugin completion is also not proof that authentication or another business policy succeeded.
This is the focused matching adapter implementation referenced by #8203. It observes decisions made while a real request traverses AbstractShenyuPlugin. Reuse #8203's optional observer identity/delivery conventions; do not introduce another observer registry, telemetry backend or matching engine. #7922 remains the separate hypothetical-request explanation API, which must not execute production request side effects.
Reviewed baseline: apache/shenyu@750673e3f619e335333150ff1b2d14070d5d5c31 (2.7.3-SNAPSHOT). This issue proposes new behavior; it does not claim that the extension is implemented.
Verified source boundaries
- Base execution and early exits separately handle missing/disabled plugin configuration, absent/unmatched selectors and rules, and cache resolution. Selector continuation/full-flow handling can use a synthetic default rule or the last enabled rule without ordinary rule matching.
- Selector winner selection and rule winner selection are private and compare specificity and sort. External hooks cannot reliably reconstruct these results.
- Cache population and negative results have their own eligibility rules. A cache hit can bypass evaluation of the entire candidate set; path-only eligibility explicitly accounts for time predicates and unknown SPI operators.
- AND and OR short-circuit. Custom predicates/strategies may depend on additional state.
- The chain checks plugin.skip first. Therefore a base-class adapter alone cannot report every skipped plugin or cover plugins that do not extend this class.
First delivery
- Add a small optional matching-result adapter at the real base-plugin decision branches. Emit a bounded immutable summary correlated with the actual plugin invocation: plugin identity, selected selector/rule identifiers when known, decision reason, and independent selector/rule cache resolution. Distinguish not-consulted, disabled, miss, positive-hit and negative-hit as applicable. Preserve distinctions such as no candidates versus evaluated no-match, synthetic default rule, and full-flow rule selection.
- Report the winner/selection basis actually known on that path. A positive cache hit reports the cached identity/source; it must not claim that current candidates or conditions were evaluated. Matching success means only that matching selected configuration, not successful business execution or authorization.
- Record available configuration provenance only when the runtime actually provides it. Unknown or potentially mixed observations must remain explicit; reading several live caches does not establish an atomic request configuration revision. Immutable records must not retain live mutable configuration DTOs.
- Keep the initial delivery at summary level. Any future detailed-condition adapter must report only evaluations that really occurred: short-circuited conditions are
not-evaluated; unsupported custom-strategy detail isunknown. Do not rerun matching, evaluate additional predicates, consume request bodies, warm caches, or perform remote calls to improve an explanation. ExistingParameterData,PredicateJudgeandMatchStrategySPIs remain authoritative. - Use no-op defaults and existing sampled diagnostics/tracing integration from [Feature][Plugin API] Add optional per-plugin subscription lifecycle observation #8203. Define sampling, per-request record/byte limits and an observable truncation/drop indication. Keep diagnostic selector/rule identifiers out of unbounded metric labels. Exclude raw request paths, condition values, credentials, cookies, bodies and sensitive headers; no additional gateway SERVER span or new telemetry backend is required.
- Observers receive no mutable exchange, configuration objects or chain controls. Observer failures cannot change matching, response, continuation, error or cancellation behavior. Delivery must not block event-loop execution; any asynchronous export queue must be bounded and must not retain the request/exchange.
Acceptance criteria
- Tests exercise the real base-plugin/default-chain path, covering outer skip, missing/disabled plugin data, absent and unmatched selectors/rules, positive/negative cache hits and misses,
continued=false, full-flow selection, specificity and sort, and a plugin outsideAbstractShenyuPlugin. Outer skip and plugins outside this base class remain attributed to the chain boundary/[Feature][Plugin API] Add optional per-plugin subscription lifecycle observation #8203 or explicitly unsupported by this adapter; matching events must not be fabricated for them. - With identical configuration and cache history, instrumentation enabled/disabled produces identical selected objects, downstream calls, responses and cache behavior. Predicate invocation counters prove no additional evaluation, including cache-hit and short-circuit cases. Include a stateful/counting custom predicate fixture.
- A cached decision does not contain invented condition evaluations or a recomputed winner reason. If detailed events are included, AND/OR short-circuit and unsupported custom strategies are represented honestly.
- Invocation correlation remains correct for repeated subscriptions and supported fork/internal dispatch according to [Feature][Plugin API] Add optional per-plugin subscription lifecycle observation #8203; no events imply that
fork()isolates a shared exchange or enables safe parallel execution. - Observer exceptions, slow/export-saturated consumers, truncation and sampling do not alter request outcome, hold an unbounded queue or retain request bodies. Labels and record-size limits have executable tests.
- A reproducible allocation/throughput comparison documents disabled and sampled-enabled overhead; no unmeasured performance benefit is claimed. Existing matching/cache tests still pass without semantic changes.
Compatibility and relationships
Preserve legacy ordering, matching/cache semantics, execute/continuation behavior, protected no-match hooks, SPI names, and before/after publisher-construction timing. No new mandatory abstract methods or graph-mode dependency.
Coordinate the small observation envelope and invocation identity with #8203; share reason vocabulary with #7922 where appropriate. This issue does not deliver #7922's diagnostic API/UI or its separate side-effect-free hypothetical evaluation path, #8017's installed/active inventory, #8060's atomic configuration revisions, or fixes to existing cache-correctness issues. No selector/rule replacement, policy enforcement, arbitrary interceptor, matching override or authentication-bypass capability is added.
Plugin-system tracking: #8199.
Activity
konlue commentedon Oct 31, 2026
/assign
[ISSUE apache#8208] Address review: registration token, full-flow dec…
[ISSUE #8208] Observe actual selector and rule matching decisions wit…