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

   ## What
   
   Adds `evaluationMode=wasm`, evaluating a WebAssembly bundle in-process, 
**alongside** the existing REST client rather than replacing it.
   
   ## Why now
   
   The component docs recorded WASM as deliberately deferred because the 
artifact was at 0.0.6. That is no longer true:
   
   - `com.styra.opa:opa-java-wasm` **1.1.0** (2026-06), Apache-2.0, on Maven 
Central
   - its runtime is `run.endive:runtime` — 
[bytecodealliance/endive](https://github.com/bytecodealliance/endive), **pure 
Java** (it compiles WASM to JVM bytecode via ASM). No native libraries, no 
platform classifiers, so no ppc64le/s390x constraint
   - `opa build -t wasm` is supported by the `openpolicyagent/opa:1.9.0-static` 
image the component's ITs already use
   
   ## Why additive rather than a replacement
   
   They are complementary, not competing:
   
   | | `rest` | `wasm` |
   |---|---|---|
   | Policy source | a server, centrally managed | a bundle built with your app 
|
   | Updates | bundle polling, live | rebuild and redeploy |
   | Decision logs | yes | none |
   | Latency | a round-trip per exchange | in-process |
   | Unreachable PDP | a real failure mode | cannot happen |
   
   Dropping REST would lose decision logging, bundle distribution and central 
policy management — a capability regression for the sidecar deployment most OPA 
users run. `rest` stays the default, so existing routes are untouched.
   
   ## How the engines are kept honest
   
   `OpaPolicyEvaluator` becomes an abstract base owning **everything a route 
observes** — input building, verdict reading, decision headers, fail-closed 
handling — with a single hook, `evaluateDecision(input)`. `OpaRestEvaluator` 
and `OpaWasmEvaluator` supply only that. The engines *cannot* diverge on 
anything visible to a route, rather than being two implementations hoped to 
stay in step.
   
   **One place this needed real care.** A spike against a compiled bundle 
showed:
   
   ```
   allow(alice)      = [{"result":true}]
   decision(alice)   = [{"result":{"allow":true,"reasons":[]}}]
   decision(mallory) = []          ← undefined, not [{"result":false}]
   ```
   
   The WASM ABI represents an undefined rule as an **empty array**, where the 
REST client raises an error. Unwrapped naively that becomes `null` → a 
**deny**, while the same policy and input under `rest` **aborts the exchange**. 
An empty array therefore throws, so the base class turns it into the identical 
fail-closed error. `failsClosedOnAnUndefinedDecisionJustLikeTheRestEngine` 
locks it.
   
   ## Thread safety is not optional
   
   `OpaPolicy` carries mutable input/data and is not thread-safe — the library 
ships `OpaPolicyPool` precisely for this — while a Camel producer is invoked 
concurrently. A shared instance would interleave input between exchanges and 
corrupt decisions under load, which a functional test would never catch. Each 
exchange borrows an instance; `poolSize` (default 8) bounds concurrent 
evaluation, and there is a test driving 128 exchanges across 16 threads 
asserting every verdict matched its own input.
   
   ## Usability
   
   `policyBundle` accepts a `file:`, `classpath:` or `http:` location holding 
either the `bundle.tar.gz` that `opa build` emits **or** a bare `.wasm` — the 
tarball is what an operator will actually have. `entrypoint` defaults to the 
policy path, which is the name `opa build -e` gives it, while remaining 
separately settable because an entrypoint is a build-time artefact and not a 
data path.
   
   ## Testing
   
   7 new tests (47 in the module): allow, deny, decision-object, the 
undefined-decision consistency case, the tarball form, fail-fast when 
`policyBundle` is missing, and the concurrency test. Full reactor build green, 
with catalog and both DSL mirrors regenerated.
   
   ## Known gap, tracked
   
   The `.wasm` fixtures are **committed binaries**, which is exactly what 
**CAMEL-24742** argues against — nothing checks they still agree with the 
`authz.rego` beside them. They are here only so this mode is testable now; a 
README records their provenance and the regeneration command, and 24742 should 
delete both files once test-infra compiles them. **CAMEL-24743** covers gating 
`serverUrl`/`bearerToken`/`failOpen` and the health checks, which have no 
meaning in `wasm` mode.
   
   `main` only. Additive; `rest` remains the default.
   
   _Claude Code on behalf of @oscerd_
   
   🤖 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