This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new ac28671dfc12 CAMEL-26838: Support bundle-aware server readiness checks 
(#29833)
ac28671dfc12 is described below

commit ac28671dfc12fa1a42c91b4414ae258db6fd6711
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Nov 13 15:54:52 2026 +0100

    CAMEL-26838: Support bundle-aware server readiness checks (#29833)
    
    Co-authored-by: Codex <[email protected]>
---
 .../camel/catalog/beans/OpaSecurityPolicy.json     |  2 +-
 .../org/apache/camel/catalog/components/opa.json   | 32 ++++-----
 .../apache/camel/catalog/docs/opa-component.adoc   | 30 +++++++++
 .../component/opa/OpaComponentConfigurer.java      |  6 ++
 .../camel/component/opa/OpaEndpointConfigurer.java |  6 ++
 .../camel/component/opa/OpaEndpointUriFactory.java |  3 +-
 .../opa/security/OpaSecurityPolicyConfigurer.java  |  6 ++
 .../org/apache/camel/component/opa/opa.json        | 32 ++++-----
 .../org/apache/camel/bean/OpaSecurityPolicy.json   |  2 +-
 .../camel-opa/src/main/docs/opa-component.adoc     | 30 +++++++++
 .../camel/component/opa/OpaConfiguration.java      | 18 ++++++
 .../apache/camel/component/opa/OpaEndpoint.java    |  3 +
 .../apache/camel/component/opa/OpaHealthProbe.java | 23 ++++++-
 .../apache/camel/component/opa/OpaProducer.java    |  3 +-
 .../component/opa/OpaProducerHealthCheck.java      |  9 ++-
 .../component/opa/security/OpaSecurityPolicy.java  | 22 ++++++-
 .../opa/security/OpaSecurityPolicyHealthCheck.java |  9 ++-
 .../opa/OpaHealthCheckRegistrationTest.java        | 55 ++++++++++++++++
 .../component/opa/OpaProducerHealthCheckTest.java  | 75 ++++++++++++++++++++++
 .../security/OpaSecurityPolicyHealthCheckTest.java | 31 ++++++++-
 .../component/dsl/OpaComponentBuilderFactory.java  | 21 ++++++
 .../endpoint/dsl/OpaEndpointBuilderFactory.java    | 36 +++++++++++
 22 files changed, 414 insertions(+), 40 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/OpaSecurityPolicy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/OpaSecurityPolicy.json
index aa6c5e6247e8..d1504304e6d2 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/OpaSecurityPolicy.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/OpaSecurityPolicy.json
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-opa",
     "version": "4.24.0-SNAPSHOT",
-    "properties": { "serverUrl": { "index": 0, "kind": "property", 
"displayName": "Server Url", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "http:\/\/localhost:8181", "description": "The base URL of the 
OPA server, without the \/v1\/data suffix. Not used in wasm mode." }, 
"policyPath": { "index": 1, "kind": "property", "displayName": "Policy Path", 
"required": true, "type": "string", "javaT [...]
+    "properties": { "serverUrl": { "index": 0, "kind": "property", 
"displayName": "Server Url", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "http:\/\/localhost:8181", "description": "The base URL of the 
OPA server, without the \/v1\/data suffix. Not used in wasm mode." }, 
"policyPath": { "index": 1, "kind": "property", "displayName": "Policy Path", 
"required": true, "type": "string", "javaT [...]
   }
 }
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
index 7eec7e2fdf00..2fcbffcb3426 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
@@ -38,15 +38,16 @@
     "autowiredEnabled": { "index": 11, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
     "borrowTimeout": { "index": 12, "kind": "property", "displayName": "Borrow 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the e [...]
     "connectionTimeout": { "index": 13, "kind": "property", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest mo [...]
-    "opaClient": { "index": 14, "kind": "property", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"autowired": true, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "An existing OPAClient to use. When set, 
serverUrl and bearerToken are ignored." },
-    "poolSize": { "index": 15, "kind": "property", "displayName": "Pool Size", 
"group": "advanced", "label": "advanced", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thre [...]
-    "requestTimeout": { "index": 16, "kind": "property", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out  [...]
-    "healthCheckConsumerEnabled": { "index": 17, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
-    "healthCheckProducerEnabled": { "index": 18, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on produce [...]
-    "bearerToken": { "index": 19, "kind": "property", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance that [...]
-    "failOpen": { "index": 20, "kind": "property", "displayName": "Fail Open", 
"group": "security", "label": "security", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "security": "insecure:dev", "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to allow the exchange to proceed when 
the policy decision point i [...]
-    "sslContextParameters": { "index": 21, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server in [...]
-    "useGlobalSslContextParameters": { "index": 22, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
+    "healthCheckBundles": { "index": 14, "kind": "property", "displayName": 
"Health Check Bundles", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether the server 
readiness check also requires activation of OPA's configured  [...]
+    "opaClient": { "index": 15, "kind": "property", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"autowired": true, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "An existing OPAClient to use. When set, 
serverUrl and bearerToken are ignored." },
+    "poolSize": { "index": 16, "kind": "property", "displayName": "Pool Size", 
"group": "advanced", "label": "advanced", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thre [...]
+    "requestTimeout": { "index": 17, "kind": "property", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out  [...]
+    "healthCheckConsumerEnabled": { "index": 18, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
+    "healthCheckProducerEnabled": { "index": 19, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on produce [...]
+    "bearerToken": { "index": 20, "kind": "property", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance that [...]
+    "failOpen": { "index": 21, "kind": "property", "displayName": "Fail Open", 
"group": "security", "label": "security", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "security": "insecure:dev", "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to allow the exchange to proceed when 
the policy decision point i [...]
+    "sslContextParameters": { "index": 22, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server in [...]
+    "useGlobalSslContextParameters": { "index": 23, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
   },
   "headers": {
     "CamelOpaDecisionAllow": { "index": 0, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "autowired": false, "secret": false, 
"description": "The allow\/deny verdict of the policy evaluation. Always 
overwritten by the component, so a value set by an inbound message never 
survives into the route.", "constantName": 
"org.apache.camel.component.opa.OpaConstants#DECISION_ALLOW" },
@@ -74,11 +75,12 @@
     "lazyStartProducer": { "index": 10, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
     "borrowTimeout": { "index": 11, "kind": "parameter", "displayName": 
"Borrow Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the  [...]
     "connectionTimeout": { "index": 12, "kind": "parameter", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest m [...]
-    "opaClient": { "index": 13, "kind": "parameter", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"autowired": true, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "An existing OPAClient to use. When set, 
serverUrl and bearerToken are ignored." },
-    "poolSize": { "index": 14, "kind": "parameter", "displayName": "Pool 
Size", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thr [...]
-    "requestTimeout": { "index": 15, "kind": "parameter", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out [...]
-    "bearerToken": { "index": 16, "kind": "parameter", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance tha [...]
-    "failOpen": { "index": 17, "kind": "parameter", "displayName": "Fail 
Open", "group": "security", "label": "security", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "security": "insecure:dev", "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether to allow the 
exchange to proceed when the policy decision point  [...]
-    "sslContextParameters": { "index": 18, "kind": "parameter", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server i [...]
+    "healthCheckBundles": { "index": 13, "kind": "parameter", "displayName": 
"Health Check Bundles", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether the server 
readiness check also requires activation of OPA's configured [...]
+    "opaClient": { "index": 14, "kind": "parameter", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"autowired": true, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "An existing OPAClient to use. When set, 
serverUrl and bearerToken are ignored." },
+    "poolSize": { "index": 15, "kind": "parameter", "displayName": "Pool 
Size", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thr [...]
+    "requestTimeout": { "index": 16, "kind": "parameter", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out [...]
+    "bearerToken": { "index": 17, "kind": "parameter", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance tha [...]
+    "failOpen": { "index": 18, "kind": "parameter", "displayName": "Fail 
Open", "group": "security", "label": "security", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "security": "insecure:dev", "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether to allow the 
exchange to proceed when the policy decision point  [...]
+    "sslContextParameters": { "index": 19, "kind": "parameter", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server i [...]
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opa-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opa-component.adoc
index 0c92bf687881..f1d966bed6bc 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opa-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opa-component.adoc
@@ -688,6 +688,36 @@ component with `healthCheckProducerEnabled`. The check 
reports DOWN with the und
 server and a server answering its health endpoint with an error are reported 
differently, so a deny is never
 confused with an outage.
 
+Set `healthCheckBundles=true` on the endpoint or `OpaSecurityPolicy` bean to 
request
+`/health?bundles=true`. OPA then includes activation/readiness of its 
configured bundles and discovery in the
+server's health result. This is useful when a server starts downloading 
bundles after startup: a reachable server
+can otherwise report healthy before it has activated its policy bundle. The 
default remains the basic `/health`
+check. This option does not itself enable producer health checks or change 
policy evaluation.
+
+For example, with producer checks enabled:
+
+[source,java]
+----
+.to("opa:authz/orders/allow?healthCheckBundles=true")
+----
+
+For a policy bean:
+
+[source,yaml]
+----
+- beans:
+    - name: opaPolicy
+      type: org.apache.camel.component.opa.security.OpaSecurityPolicy
+      properties:
+        serverUrl: http://localhost:8181
+        policyPath: authz/orders/allow
+        healthCheckBundles: true
+----
+
+Bundle-aware readiness follows OPA's health semantics. It does not verify a 
particular bundle revision,
+guarantee policy freshness, or validate business permissions for a message. It 
is unused in `wasm` mode,
+with an injected `opaClient`, or when the corresponding health check is 
disabled.
+
 `OpaSecurityPolicy` registers an equivalent check, under an id starting 
`security-policy:opa-`. It is arguably the
 more important of the two: a denied producer merely records a verdict the 
route can inspect, while the policy throws
 `CamelAuthorizationException` and stops the exchange, so an unreachable server 
there fails every message outright.
diff --git 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaComponentConfigurer.java
 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaComponentConfigurer.java
index dcca3a47a6b3..45ff639df719 100644
--- 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaComponentConfigurer.java
+++ 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaComponentConfigurer.java
@@ -48,6 +48,8 @@ public class OpaComponentConfigurer extends 
PropertyConfigurerSupport implements
         case "evaluationMode": 
getOrCreateConfiguration(target).setEvaluationMode(property(camelContext, 
java.lang.String.class, value)); return true;
         case "failopen":
         case "failOpen": 
getOrCreateConfiguration(target).setFailOpen(property(camelContext, 
boolean.class, value)); return true;
+        case "healthcheckbundles":
+        case "healthCheckBundles": 
getOrCreateConfiguration(target).setHealthCheckBundles(property(camelContext, 
boolean.class, value)); return true;
         case "healthcheckconsumerenabled":
         case "healthCheckConsumerEnabled": 
target.setHealthCheckConsumerEnabled(property(camelContext, boolean.class, 
value)); return true;
         case "healthcheckproducerenabled":
@@ -103,6 +105,8 @@ public class OpaComponentConfigurer extends 
PropertyConfigurerSupport implements
         case "evaluationMode": return java.lang.String.class;
         case "failopen":
         case "failOpen": return boolean.class;
+        case "healthcheckbundles":
+        case "healthCheckBundles": return boolean.class;
         case "healthcheckconsumerenabled":
         case "healthCheckConsumerEnabled": return boolean.class;
         case "healthcheckproducerenabled":
@@ -154,6 +158,8 @@ public class OpaComponentConfigurer extends 
PropertyConfigurerSupport implements
         case "evaluationMode": return 
getOrCreateConfiguration(target).getEvaluationMode();
         case "failopen":
         case "failOpen": return getOrCreateConfiguration(target).isFailOpen();
+        case "healthcheckbundles":
+        case "healthCheckBundles": return 
getOrCreateConfiguration(target).isHealthCheckBundles();
         case "healthcheckconsumerenabled":
         case "healthCheckConsumerEnabled": return 
target.isHealthCheckConsumerEnabled();
         case "healthcheckproducerenabled":
diff --git 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointConfigurer.java
 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointConfigurer.java
index 164499d6e7ea..1a18746d109c 100644
--- 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointConfigurer.java
+++ 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointConfigurer.java
@@ -38,6 +38,8 @@ public class OpaEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "evaluationMode": 
target.getConfiguration().setEvaluationMode(property(camelContext, 
java.lang.String.class, value)); return true;
         case "failopen":
         case "failOpen": 
target.getConfiguration().setFailOpen(property(camelContext, boolean.class, 
value)); return true;
+        case "healthcheckbundles":
+        case "healthCheckBundles": 
target.getConfiguration().setHealthCheckBundles(property(camelContext, 
boolean.class, value)); return true;
         case "includebody":
         case "includeBody": 
target.getConfiguration().setIncludeBody(property(camelContext, boolean.class, 
value)); return true;
         case "includeheaders":
@@ -84,6 +86,8 @@ public class OpaEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "evaluationMode": return java.lang.String.class;
         case "failopen":
         case "failOpen": return boolean.class;
+        case "healthcheckbundles":
+        case "healthCheckBundles": return boolean.class;
         case "includebody":
         case "includeBody": return boolean.class;
         case "includeheaders":
@@ -126,6 +130,8 @@ public class OpaEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "evaluationMode": return 
target.getConfiguration().getEvaluationMode();
         case "failopen":
         case "failOpen": return target.getConfiguration().isFailOpen();
+        case "healthcheckbundles":
+        case "healthCheckBundles": return 
target.getConfiguration().isHealthCheckBundles();
         case "includebody":
         case "includeBody": return target.getConfiguration().isIncludeBody();
         case "includeheaders":
diff --git 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointUriFactory.java
 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointUriFactory.java
index 4658a482ab99..670b50f9c6b6 100644
--- 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointUriFactory.java
+++ 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointUriFactory.java
@@ -24,7 +24,7 @@ public class OpaEndpointUriFactory extends 
org.apache.camel.support.component.En
     private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(19);
+        Set<String> props = new HashSet<>(20);
         props.add("allowKey");
         props.add("batch");
         props.add("bearerToken");
@@ -33,6 +33,7 @@ public class OpaEndpointUriFactory extends 
org.apache.camel.support.component.En
         props.add("entrypoint");
         props.add("evaluationMode");
         props.add("failOpen");
+        props.add("healthCheckBundles");
         props.add("includeBody");
         props.add("includeHeaders");
         props.add("includeProperties");
diff --git 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/security/OpaSecurityPolicyConfigurer.java
 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/security/OpaSecurityPolicyConfigurer.java
index 422629ed63db..abfe3940d152 100644
--- 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/security/OpaSecurityPolicyConfigurer.java
+++ 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/security/OpaSecurityPolicyConfigurer.java
@@ -37,6 +37,8 @@ public class OpaSecurityPolicyConfigurer extends 
org.apache.camel.support.compon
         case "evaluationMode": target.setEvaluationMode(property(camelContext, 
java.lang.String.class, value)); return true;
         case "failopen":
         case "failOpen": target.setFailOpen(property(camelContext, 
boolean.class, value)); return true;
+        case "healthcheckbundles":
+        case "healthCheckBundles": 
target.setHealthCheckBundles(property(camelContext, boolean.class, value)); 
return true;
         case "healthcheckenabled":
         case "healthCheckEnabled": 
target.setHealthCheckEnabled(property(camelContext, boolean.class, value)); 
return true;
         case "includebody":
@@ -81,6 +83,8 @@ public class OpaSecurityPolicyConfigurer extends 
org.apache.camel.support.compon
         case "evaluationMode": return java.lang.String.class;
         case "failopen":
         case "failOpen": return boolean.class;
+        case "healthcheckbundles":
+        case "healthCheckBundles": return boolean.class;
         case "healthcheckenabled":
         case "healthCheckEnabled": return boolean.class;
         case "includebody":
@@ -126,6 +130,8 @@ public class OpaSecurityPolicyConfigurer extends 
org.apache.camel.support.compon
         case "evaluationMode": return target.getEvaluationMode();
         case "failopen":
         case "failOpen": return target.isFailOpen();
+        case "healthcheckbundles":
+        case "healthCheckBundles": return target.isHealthCheckBundles();
         case "healthcheckenabled":
         case "healthCheckEnabled": return target.isHealthCheckEnabled();
         case "includebody":
diff --git 
a/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
 
b/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
index 7eec7e2fdf00..2fcbffcb3426 100644
--- 
a/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
+++ 
b/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
@@ -38,15 +38,16 @@
     "autowiredEnabled": { "index": 11, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
     "borrowTimeout": { "index": 12, "kind": "property", "displayName": "Borrow 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the e [...]
     "connectionTimeout": { "index": 13, "kind": "property", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest mo [...]
-    "opaClient": { "index": 14, "kind": "property", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"autowired": true, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "An existing OPAClient to use. When set, 
serverUrl and bearerToken are ignored." },
-    "poolSize": { "index": 15, "kind": "property", "displayName": "Pool Size", 
"group": "advanced", "label": "advanced", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thre [...]
-    "requestTimeout": { "index": 16, "kind": "property", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out  [...]
-    "healthCheckConsumerEnabled": { "index": 17, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
-    "healthCheckProducerEnabled": { "index": 18, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on produce [...]
-    "bearerToken": { "index": 19, "kind": "property", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance that [...]
-    "failOpen": { "index": 20, "kind": "property", "displayName": "Fail Open", 
"group": "security", "label": "security", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "security": "insecure:dev", "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to allow the exchange to proceed when 
the policy decision point i [...]
-    "sslContextParameters": { "index": 21, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server in [...]
-    "useGlobalSslContextParameters": { "index": 22, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
+    "healthCheckBundles": { "index": 14, "kind": "property", "displayName": 
"Health Check Bundles", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether the server 
readiness check also requires activation of OPA's configured  [...]
+    "opaClient": { "index": 15, "kind": "property", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"autowired": true, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "An existing OPAClient to use. When set, 
serverUrl and bearerToken are ignored." },
+    "poolSize": { "index": 16, "kind": "property", "displayName": "Pool Size", 
"group": "advanced", "label": "advanced", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thre [...]
+    "requestTimeout": { "index": 17, "kind": "property", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out  [...]
+    "healthCheckConsumerEnabled": { "index": 18, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
+    "healthCheckProducerEnabled": { "index": 19, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on produce [...]
+    "bearerToken": { "index": 20, "kind": "property", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance that [...]
+    "failOpen": { "index": 21, "kind": "property", "displayName": "Fail Open", 
"group": "security", "label": "security", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "security": "insecure:dev", "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to allow the exchange to proceed when 
the policy decision point i [...]
+    "sslContextParameters": { "index": 22, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server in [...]
+    "useGlobalSslContextParameters": { "index": 23, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
   },
   "headers": {
     "CamelOpaDecisionAllow": { "index": 0, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "autowired": false, "secret": false, 
"description": "The allow\/deny verdict of the policy evaluation. Always 
overwritten by the component, so a value set by an inbound message never 
survives into the route.", "constantName": 
"org.apache.camel.component.opa.OpaConstants#DECISION_ALLOW" },
@@ -74,11 +75,12 @@
     "lazyStartProducer": { "index": 10, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
     "borrowTimeout": { "index": 11, "kind": "parameter", "displayName": 
"Borrow Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the  [...]
     "connectionTimeout": { "index": 12, "kind": "parameter", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest m [...]
-    "opaClient": { "index": 13, "kind": "parameter", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"autowired": true, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "An existing OPAClient to use. When set, 
serverUrl and bearerToken are ignored." },
-    "poolSize": { "index": 14, "kind": "parameter", "displayName": "Pool 
Size", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thr [...]
-    "requestTimeout": { "index": 15, "kind": "parameter", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out [...]
-    "bearerToken": { "index": 16, "kind": "parameter", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance tha [...]
-    "failOpen": { "index": 17, "kind": "parameter", "displayName": "Fail 
Open", "group": "security", "label": "security", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "security": "insecure:dev", "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether to allow the 
exchange to proceed when the policy decision point  [...]
-    "sslContextParameters": { "index": 18, "kind": "parameter", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server i [...]
+    "healthCheckBundles": { "index": 13, "kind": "parameter", "displayName": 
"Health Check Bundles", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether the server 
readiness check also requires activation of OPA's configured [...]
+    "opaClient": { "index": 14, "kind": "parameter", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"autowired": true, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "An existing OPAClient to use. When set, 
serverUrl and bearerToken are ignored." },
+    "poolSize": { "index": 15, "kind": "parameter", "displayName": "Pool 
Size", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thr [...]
+    "requestTimeout": { "index": 16, "kind": "parameter", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out [...]
+    "bearerToken": { "index": 17, "kind": "parameter", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance tha [...]
+    "failOpen": { "index": 18, "kind": "parameter", "displayName": "Fail 
Open", "group": "security", "label": "security", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "security": "insecure:dev", "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether to allow the 
exchange to proceed when the policy decision point  [...]
+    "sslContextParameters": { "index": 19, "kind": "parameter", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server i [...]
   }
 }
diff --git 
a/components/camel-opa/src/generated/resources/META-INF/services/org/apache/camel/bean/OpaSecurityPolicy.json
 
b/components/camel-opa/src/generated/resources/META-INF/services/org/apache/camel/bean/OpaSecurityPolicy.json
index aa6c5e6247e8..d1504304e6d2 100644
--- 
a/components/camel-opa/src/generated/resources/META-INF/services/org/apache/camel/bean/OpaSecurityPolicy.json
+++ 
b/components/camel-opa/src/generated/resources/META-INF/services/org/apache/camel/bean/OpaSecurityPolicy.json
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-opa",
     "version": "4.24.0-SNAPSHOT",
-    "properties": { "serverUrl": { "index": 0, "kind": "property", 
"displayName": "Server Url", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "http:\/\/localhost:8181", "description": "The base URL of the 
OPA server, without the \/v1\/data suffix. Not used in wasm mode." }, 
"policyPath": { "index": 1, "kind": "property", "displayName": "Policy Path", 
"required": true, "type": "string", "javaT [...]
+    "properties": { "serverUrl": { "index": 0, "kind": "property", 
"displayName": "Server Url", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "http:\/\/localhost:8181", "description": "The base URL of the 
OPA server, without the \/v1\/data suffix. Not used in wasm mode." }, 
"policyPath": { "index": 1, "kind": "property", "displayName": "Policy Path", 
"required": true, "type": "string", "javaT [...]
   }
 }
 
diff --git a/components/camel-opa/src/main/docs/opa-component.adoc 
b/components/camel-opa/src/main/docs/opa-component.adoc
index 0c92bf687881..f1d966bed6bc 100644
--- a/components/camel-opa/src/main/docs/opa-component.adoc
+++ b/components/camel-opa/src/main/docs/opa-component.adoc
@@ -688,6 +688,36 @@ component with `healthCheckProducerEnabled`. The check 
reports DOWN with the und
 server and a server answering its health endpoint with an error are reported 
differently, so a deny is never
 confused with an outage.
 
+Set `healthCheckBundles=true` on the endpoint or `OpaSecurityPolicy` bean to 
request
+`/health?bundles=true`. OPA then includes activation/readiness of its 
configured bundles and discovery in the
+server's health result. This is useful when a server starts downloading 
bundles after startup: a reachable server
+can otherwise report healthy before it has activated its policy bundle. The 
default remains the basic `/health`
+check. This option does not itself enable producer health checks or change 
policy evaluation.
+
+For example, with producer checks enabled:
+
+[source,java]
+----
+.to("opa:authz/orders/allow?healthCheckBundles=true")
+----
+
+For a policy bean:
+
+[source,yaml]
+----
+- beans:
+    - name: opaPolicy
+      type: org.apache.camel.component.opa.security.OpaSecurityPolicy
+      properties:
+        serverUrl: http://localhost:8181
+        policyPath: authz/orders/allow
+        healthCheckBundles: true
+----
+
+Bundle-aware readiness follows OPA's health semantics. It does not verify a 
particular bundle revision,
+guarantee policy freshness, or validate business permissions for a message. It 
is unused in `wasm` mode,
+with an injected `opaClient`, or when the corresponding health check is 
disabled.
+
 `OpaSecurityPolicy` registers an equivalent check, under an id starting 
`security-policy:opa-`. It is arguably the
 more important of the two: a denied producer merely records a verdict the 
route can inspect, while the policy throws
 `CamelAuthorizationException` and stops the exchange, so an unreachable server 
there fails every message outright.
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConfiguration.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConfiguration.java
index 3ec7e5d27174..4d6c8c67d067 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConfiguration.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConfiguration.java
@@ -74,6 +74,12 @@ public class OpaConfiguration implements Cloneable {
     @UriParam(label = "producer")
     private boolean batch;
 
+    @UriParam(label = "advanced", defaultValue = "false",
+              description = "Whether the server readiness check also requires 
activation of OPA's configured bundles."
+                            + " Sends /health?bundles=true. Does not enable 
health checks, change policy evaluation"
+                            + " or guarantee a particular policy revision. Not 
used in wasm mode or with an injected client.")
+    private boolean healthCheckBundles;
+
     @UriParam(label = "advanced",
               description = "An existing OPAClient to use. When set, serverUrl 
and bearerToken are ignored.")
     @Metadata(autowired = true)
@@ -307,6 +313,18 @@ public class OpaConfiguration implements Cloneable {
     /**
      * An already-configured {@link OPAClient} to use instead of letting the 
endpoint create one.
      */
+    public boolean isHealthCheckBundles() {
+        return healthCheckBundles;
+    }
+
+    /**
+     * Whether the server readiness check also requires activation of OPA's 
configured bundles. Does not enable health
+     * checks or change policy evaluation. Not used in wasm mode or with an 
injected client.
+     */
+    public void setHealthCheckBundles(boolean healthCheckBundles) {
+        this.healthCheckBundles = healthCheckBundles;
+    }
+
     public OPAClient getOpaClient() {
         return opaClient;
     }
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
index 434e6473899d..f941042acd8c 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
@@ -151,6 +151,9 @@ public class OpaEndpoint extends DefaultEndpoint {
      * between the producer and {@code .policy(...)}.
      */
     private void warnAboutIgnoredServerOptions() {
+        if (configuration.isHealthCheckBundles()) {
+            LOG.warn("healthCheckBundles is ignored when evaluationMode=wasm: 
there is no server to probe");
+        }
         if (configuration.getOpaClient() != null) {
             LOG.warn("opaClient is ignored when evaluationMode=wasm: the 
policy is evaluated in-process");
         }
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaHealthProbe.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaHealthProbe.java
index c1ef4af7618f..a683c42a669c 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaHealthProbe.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaHealthProbe.java
@@ -117,19 +117,38 @@ public final class OpaHealthProbe implements 
AutoCloseable {
     public static void probe(
             HealthCheckResultBuilder builder, String serverUrl, String 
bearerToken, String policyPath,
             SSLContext sslContext) {
+        probe(builder, serverUrl, bearerToken, policyPath, sslContext, false);
+    }
+
+    /**
+     * Probes server readiness, optionally requiring activation of OPA's 
configured bundles.
+     *
+     * @param healthCheckBundles whether to include OPA's configured bundle 
activation in readiness
+     */
+    public static void probe(
+            HealthCheckResultBuilder builder, String serverUrl, String 
bearerToken, String policyPath,
+            SSLContext sslContext, boolean healthCheckBundles) {
         try (OpaHealthProbe probe = new OpaHealthProbe(sslContext)) {
-            probe.probe(builder, serverUrl, bearerToken, policyPath);
+            probe.probe(builder, serverUrl, bearerToken, policyPath, 
healthCheckBundles);
         }
     }
 
     public void probe(HealthCheckResultBuilder builder, String serverUrl, 
String bearerToken, String policyPath) {
+        probe(builder, serverUrl, bearerToken, policyPath, false);
+    }
+
+    public void probe(
+            HealthCheckResultBuilder builder, String serverUrl, String 
bearerToken, String policyPath,
+            boolean healthCheckBundles) {
         builder.detail("opa.serverUrl", URISupport.sanitizeUri(serverUrl));
         builder.detail("opa.policyPath", policyPath);
+        builder.detail("opa.healthCheckBundles", healthCheckBundles);
 
         HttpRequest.Builder request = HttpRequest.newBuilder()
                 // a serverUrl with a trailing slash would build //health, 
which OPA's router answers with a
                 // redirect the client is not configured to follow - reporting 
a healthy server DOWN on HTTP 301
-                .uri(URI.create(FileUtil.stripTrailingSeparator(serverUrl) + 
"/health"))
+                .uri(URI.create(FileUtil.stripTrailingSeparator(serverUrl) + 
"/health"
+                                + (healthCheckBundles ? "?bundles=true" : "")))
                 .timeout(TIMEOUT)
                 .GET();
         if (ObjectHelper.isNotEmpty(bearerToken)) {
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducer.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducer.java
index d571fe334b73..b0c69da973c4 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducer.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducer.java
@@ -61,7 +61,8 @@ public class OpaProducer extends DefaultProducer {
                     configuration.getServerUrl(), 
configuration.getBearerToken(),
                     // the endpoint URI is unique within the context, so two 
endpoints sharing a policy path but
                     // pointing at different servers get distinct health-check 
ids instead of colliding
-                    getEndpoint().getPolicyPath(), 
getEndpoint().getEndpointUri(), getEndpoint().getSslContext());
+                    getEndpoint().getPolicyPath(), 
getEndpoint().getEndpointUri(), getEndpoint().getSslContext(),
+                    configuration.isHealthCheckBundles());
             
producerHealthCheck.setEnabled(getEndpoint().getComponent().isHealthCheckProducerEnabled());
             healthCheckRepository.addHealthCheck(producerHealthCheck);
         }
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducerHealthCheck.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducerHealthCheck.java
index 91385f25bfc5..2370514b7825 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducerHealthCheck.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducerHealthCheck.java
@@ -37,9 +37,15 @@ public class OpaProducerHealthCheck extends 
AbstractHealthCheck implements AutoC
     private final String bearerToken;
     private final String policyPath;
     private final OpaHealthProbe probe;
+    private final boolean healthCheckBundles;
 
     public OpaProducerHealthCheck(String serverUrl, String bearerToken, String 
policyPath, String id,
                                   SSLContext sslContext) {
+        this(serverUrl, bearerToken, policyPath, id, sslContext, false);
+    }
+
+    public OpaProducerHealthCheck(String serverUrl, String bearerToken, String 
policyPath, String id,
+                                  SSLContext sslContext, boolean 
healthCheckBundles) {
         // the id is built from the endpoint URI so that two endpoints sharing 
a policy path stay distinct, but that
         // URI carries the bearerToken in the clear and the id is published in 
the health output, so sanitize it
         super("camel", "producer:opa-" + URISupport.sanitizeUri(id));
@@ -47,11 +53,12 @@ public class OpaProducerHealthCheck extends 
AbstractHealthCheck implements AutoC
         this.bearerToken = bearerToken;
         this.policyPath = policyPath;
         this.probe = new OpaHealthProbe(sslContext);
+        this.healthCheckBundles = healthCheckBundles;
     }
 
     @Override
     protected void doCall(HealthCheckResultBuilder builder, Map<String, 
Object> options) {
-        probe.probe(builder, serverUrl, bearerToken, policyPath);
+        probe.probe(builder, serverUrl, bearerToken, policyPath, 
healthCheckBundles);
     }
 
     @Override
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/security/OpaSecurityPolicy.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/security/OpaSecurityPolicy.java
index 3dd52eaabdc2..7b21e2aeed4d 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/security/OpaSecurityPolicy.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/security/OpaSecurityPolicy.java
@@ -137,6 +137,11 @@ public class OpaSecurityPolicy implements 
AuthorizationPolicy {
                             + " denies every exchange it guards while the 
server is unreachable, so a route that cannot"
                             + " reach it is not ready.")
     private boolean healthCheckEnabled = true;
+    @Metadata(label = "advanced", defaultValue = "false",
+              description = "Whether the server readiness check also requires 
activation of OPA's configured bundles."
+                            + " Sends /health?bundles=true. Does not enable 
health checks, change policy evaluation"
+                            + " or guarantee a particular policy revision. Not 
used in wasm mode or with an injected client.")
+    private boolean healthCheckBundles;
     @Metadata(label = "advanced", defaultValue = "10000",
               description = "How long to wait, in milliseconds, for the 
connection to the OPA server to be established.")
     private long connectionTimeout = 10000;
@@ -234,6 +239,9 @@ public class OpaSecurityPolicy implements 
AuthorizationPolicy {
      * injected {@code opaClient} address, authenticate to or replace a server 
there is none of in {@code wasm} mode.
      */
     private void warnIgnoredServerOptions() {
+        if (healthCheckBundles) {
+            LOG.warn("healthCheckBundles is ignored when evaluationMode=wasm: 
there is no server to probe");
+        }
         if (opaClient != null) {
             LOG.warn("opaClient is ignored when evaluationMode=wasm: the 
policy is evaluated in-process");
         }
@@ -262,7 +270,7 @@ public class OpaSecurityPolicy implements 
AuthorizationPolicy {
         if (registry == null) {
             return;
         }
-        healthCheck = new OpaSecurityPolicyHealthCheck(serverUrl, bearerToken, 
policyPath, sslContext);
+        healthCheck = new OpaSecurityPolicyHealthCheck(serverUrl, bearerToken, 
policyPath, sslContext, healthCheckBundles);
         registry.register(healthCheck);
     }
 
@@ -557,6 +565,18 @@ public class OpaSecurityPolicy implements 
AuthorizationPolicy {
         this.healthCheckEnabled = healthCheckEnabled;
     }
 
+    public boolean isHealthCheckBundles() {
+        return healthCheckBundles;
+    }
+
+    /**
+     * Whether the server readiness check also requires activation of OPA's 
configured bundles. Does not enable health
+     * checks or change policy evaluation. Not used in wasm mode or with an 
injected client.
+     */
+    public void setHealthCheckBundles(boolean healthCheckBundles) {
+        this.healthCheckBundles = healthCheckBundles;
+    }
+
     public OPAClient getOpaClient() {
         return opaClient;
     }
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/security/OpaSecurityPolicyHealthCheck.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/security/OpaSecurityPolicyHealthCheck.java
index de154182c1c0..7d632b364b24 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/security/OpaSecurityPolicyHealthCheck.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/security/OpaSecurityPolicyHealthCheck.java
@@ -39,9 +39,15 @@ public class OpaSecurityPolicyHealthCheck extends 
AbstractHealthCheck implements
     private final String bearerToken;
     private final String policyPath;
     private final OpaHealthProbe probe;
+    private final boolean healthCheckBundles;
 
     public OpaSecurityPolicyHealthCheck(String serverUrl, String bearerToken, 
String policyPath,
                                         SSLContext sslContext) {
+        this(serverUrl, bearerToken, policyPath, sslContext, false);
+    }
+
+    public OpaSecurityPolicyHealthCheck(String serverUrl, String bearerToken, 
String policyPath,
+                                        SSLContext sslContext, boolean 
healthCheckBundles) {
         // serverUrl and policyPath together identify the decision this policy 
enforces, so two policies pointing at
         // different servers stay distinct; sanitized because the id is 
published in the health output
         super("camel", "security-policy:opa-" + 
URISupport.sanitizeUri(serverUrl + "/" + policyPath));
@@ -49,11 +55,12 @@ public class OpaSecurityPolicyHealthCheck extends 
AbstractHealthCheck implements
         this.bearerToken = bearerToken;
         this.policyPath = policyPath;
         this.probe = new OpaHealthProbe(sslContext);
+        this.healthCheckBundles = healthCheckBundles;
     }
 
     @Override
     protected void doCall(HealthCheckResultBuilder builder, Map<String, 
Object> options) {
-        probe.probe(builder, serverUrl, bearerToken, policyPath);
+        probe.probe(builder, serverUrl, bearerToken, policyPath, 
healthCheckBundles);
     }
 
     @Override
diff --git 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaHealthCheckRegistrationTest.java
 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaHealthCheckRegistrationTest.java
index e62274016043..ef0c86dc6827 100644
--- 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaHealthCheckRegistrationTest.java
+++ 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaHealthCheckRegistrationTest.java
@@ -16,8 +16,12 @@
  */
 package org.apache.camel.component.opa;
 
+import java.net.InetSocketAddress;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
 
+import com.sun.net.httpserver.HttpServer;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckHelper;
@@ -74,4 +78,55 @@ public class OpaHealthCheckRegistrationTest extends 
CamelTestSupport {
         assertThat(ids).anySatisfy(id -> 
assertThat(id).contains("opa-primary"));
         assertThat(ids).anySatisfy(id -> 
assertThat(id).contains("opa-secondary"));
     }
+
+    @Test
+    void passesTheEndpointBundleRequirementToItsRegisteredCheck() throws 
Exception {
+        HttpServer server = HttpServer.create(new 
InetSocketAddress("localhost", 0), 0);
+        AtomicReference<String> query = new AtomicReference<>();
+        server.createContext("/health", exchange -> {
+            query.set(exchange.getRequestURI().getRawQuery());
+            exchange.sendResponseHeaders(200, -1);
+            exchange.close();
+        });
+        server.start();
+        try {
+            OpaEndpoint endpoint = context.getEndpoint(
+                    "opa:authz/bundles?serverUrl=http://localhost:"; + 
server.getAddress().getPort(), OpaEndpoint.class);
+            endpoint.getConfiguration().setHealthCheckBundles(true);
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() {
+                    from("direct:bundles").to(endpoint);
+                }
+            });
+            HealthCheck check = registeredChecks().stream()
+                    .filter(hc -> hc.getId().contains("authz/bundles"))
+                    .findFirst().orElseThrow();
+            check.setEnabled(true);
+
+            
assertThat(check.call(Map.of()).getState()).isEqualTo(HealthCheck.State.UP);
+            assertThat(query.get()).isEqualTo("bundles=true");
+        } finally {
+            server.stop(0);
+        }
+    }
+
+    @Test
+    void skipsTheServerProbeInWasmModeEvenWhenBundlesAreRequired() throws 
Exception {
+        OpaConfiguration configuration = new OpaConfiguration();
+        configuration.setEvaluationMode("wasm");
+        configuration.setHealthCheckBundles(true);
+        OpaEndpoint endpoint = new OpaEndpoint("opa:authz/wasm", new 
OpaComponent(context), configuration);
+        OpaProducer producer = new OpaProducer(endpoint);
+        int previousCount = registeredChecks().size();
+        try {
+            // Exercise the producer's registration independently from loading 
a compiled WASM fixture.
+            producer.start();
+
+            assertThat(registeredChecks()).hasSize(previousCount);
+        } finally {
+            producer.stop();
+        }
+    }
+
 }
diff --git 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaProducerHealthCheckTest.java
 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaProducerHealthCheckTest.java
index 7e0ee58d1cbb..cca01af3384a 100644
--- 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaProducerHealthCheckTest.java
+++ 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaProducerHealthCheckTest.java
@@ -19,9 +19,18 @@ package org.apache.camel.component.opa;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.InetSocketAddress;
+import java.security.KeyStore;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
 
 import com.sun.net.httpserver.HttpServer;
+import com.sun.net.httpserver.HttpsConfigurator;
+import com.sun.net.httpserver.HttpsServer;
 import org.apache.camel.health.HealthCheck;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
@@ -107,4 +116,70 @@ class OpaProducerHealthCheckTest {
         assertThat(result.getMessage()).get().asString().contains("Cannot 
reach the OPA server");
         assertThat(result.getError()).isPresent();
     }
+
+    @Test
+    void includesBundleActivationOnlyWhenEnabled() throws Exception {
+        AtomicBoolean activated = new AtomicBoolean();
+        AtomicReference<String> query = new AtomicReference<>();
+        AtomicReference<String> authorization = new AtomicReference<>();
+        server = HttpServer.create(new InetSocketAddress("localhost", 0), 0);
+        server.createContext("/health", exchange -> {
+            query.set(exchange.getRequestURI().getRawQuery());
+            
authorization.set(exchange.getRequestHeaders().getFirst("Authorization"));
+            int status = "bundles=true".equals(query.get()) && 
!activated.get() ? 500 : 200;
+            exchange.sendResponseHeaders(status, -1);
+            exchange.close();
+        });
+        server.start();
+        String serverUrl = "http://localhost:"; + server.getAddress().getPort();
+
+        assertThat(call(serverUrl).getState()).isEqualTo(HealthCheck.State.UP);
+        assertThat(query.get()).isNull();
+
+        OpaProducerHealthCheck bundleCheck = new OpaProducerHealthCheck(
+                serverUrl + "/", "test-token", "authz/allow", "bundles", null, 
true);
+        bundleCheck.setEnabled(true);
+        HealthCheck.Result notActivated = bundleCheck.call(Map.of());
+
+        assertThat(notActivated.getState()).isEqualTo(HealthCheck.State.DOWN);
+        
assertThat(notActivated.getDetails()).containsEntry("opa.healthCheckBundles", 
true);
+        assertThat(query.get()).isEqualTo("bundles=true");
+        assertThat(authorization.get()).isEqualTo("Bearer test-token");
+
+        activated.set(true);
+        
assertThat(bundleCheck.call(Map.of()).getState()).isEqualTo(HealthCheck.State.UP);
+    }
+
+    @Test
+    void preservesTlsConfigurationWhenCheckingBundles() throws Exception {
+        KeyStore fixture = KeyStore.getInstance("PKCS12");
+        try (var in = getClass().getResourceAsStream("/opa-server.p12")) {
+            fixture.load(in, "changeit".toCharArray());
+        }
+        KeyManagerFactory keys = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+        keys.init(fixture, "changeit".toCharArray());
+        SSLContext serverTls = SSLContext.getInstance("TLS");
+        serverTls.init(keys.getKeyManagers(), null, null);
+        TrustManagerFactory trust = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        trust.init(fixture);
+        SSLContext clientTls = SSLContext.getInstance("TLS");
+        clientTls.init(null, trust.getTrustManagers(), null);
+        HttpsServer https = HttpsServer.create(new 
InetSocketAddress("localhost", 0), 0);
+        https.setHttpsConfigurator(new HttpsConfigurator(serverTls));
+        server = https;
+        AtomicReference<String> query = new AtomicReference<>();
+        https.createContext("/health", exchange -> {
+            query.set(exchange.getRequestURI().getRawQuery());
+            exchange.sendResponseHeaders(200, -1);
+            exchange.close();
+        });
+        https.start();
+        OpaProducerHealthCheck check = new OpaProducerHealthCheck(
+                "https://localhost:"; + https.getAddress().getPort(), null, 
"authz/allow", "tls-bundles", clientTls, true);
+        check.setEnabled(true);
+
+        
assertThat(check.call(Map.of()).getState()).isEqualTo(HealthCheck.State.UP);
+        assertThat(query.get()).isEqualTo("bundles=true");
+    }
+
 }
diff --git 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyHealthCheckTest.java
 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyHealthCheckTest.java
index 5042ea75839c..7aa43f8c2234 100644
--- 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyHealthCheckTest.java
+++ 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyHealthCheckTest.java
@@ -21,6 +21,8 @@ import java.io.OutputStream;
 import java.net.InetSocketAddress;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 import com.styra.opa.OPAClient;
 import com.sun.net.httpserver.HttpServer;
@@ -45,6 +47,8 @@ public class OpaSecurityPolicyHealthCheckTest extends 
CamelTestSupport {
 
     private static HttpServer server;
     private static String serverUrl;
+    private static final AtomicBoolean bundlesActivated = new AtomicBoolean();
+    private static final AtomicReference<String> query = new 
AtomicReference<>();
 
     private final OpaSecurityPolicy policy = new OpaSecurityPolicy();
 
@@ -59,7 +63,9 @@ public class OpaSecurityPolicyHealthCheckTest extends 
CamelTestSupport {
     private static String startHealthyServer() throws IOException {
         server = HttpServer.create(new InetSocketAddress("localhost", 0), 0);
         server.createContext("/health", exchange -> {
-            exchange.sendResponseHeaders(200, -1);
+            query.set(exchange.getRequestURI().getRawQuery());
+            int status = "bundles=true".equals(query.get()) && 
!bundlesActivated.get() ? 500 : 200;
+            exchange.sendResponseHeaders(status, -1);
             try (OutputStream out = exchange.getResponseBody()) {
                 out.flush();
             }
@@ -70,6 +76,8 @@ public class OpaSecurityPolicyHealthCheckTest extends 
CamelTestSupport {
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
+        bundlesActivated.set(false);
+        query.set(null);
         serverUrl = startHealthyServer();
         policy.setPolicyPath("authz/allow");
         policy.setServerUrl(serverUrl);
@@ -172,4 +180,25 @@ public class OpaSecurityPolicyHealthCheckTest extends 
CamelTestSupport {
         // an injected client may point anywhere, so probing serverUrl would 
report on the wrong server
         assertThat(registered()).hasSize(1);
     }
+
+    @Test
+    void passesThePolicyBundleRequirementToItsRegisteredCheck() throws 
Exception {
+        OpaSecurityPolicy bundlePolicy = new OpaSecurityPolicy(serverUrl + 
"/", "authz/bundles");
+        bundlePolicy.setHealthCheckBundles(true);
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                
from("direct:bundles").policy(bundlePolicy).to("mock:bundleResult");
+            }
+        });
+        HealthCheck check = registered().stream()
+                .filter(hc -> hc.getId().contains("authz/bundles"))
+                .findFirst().orElseThrow();
+
+        
assertThat(check.call(Map.of()).getState()).isEqualTo(HealthCheck.State.DOWN);
+        assertThat(query.get()).isEqualTo("bundles=true");
+        bundlesActivated.set(true);
+        
assertThat(check.call(Map.of()).getState()).isEqualTo(HealthCheck.State.UP);
+    }
+
 }
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OpaComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OpaComponentBuilderFactory.java
index 44cec1caac9f..87e1e159cc36 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OpaComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OpaComponentBuilderFactory.java
@@ -355,6 +355,26 @@ public interface OpaComponentBuilderFactory {
             return this;
         }
     
+        
+        /**
+         * Whether the server readiness check also requires activation of OPA's
+         * configured bundles. Sends /health?bundles=true. Does not enable
+         * health checks, change policy evaluation or guarantee a particular
+         * policy revision. Not used in wasm mode or with an injected client.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: advanced
+         * 
+         * @param healthCheckBundles the value to set
+         * @return the dsl builder
+         */
+        default OpaComponentBuilder healthCheckBundles(boolean 
healthCheckBundles) {
+            doSetProperty("healthCheckBundles", healthCheckBundles);
+            return this;
+        }
+    
         /**
          * An existing OPAClient to use. When set, serverUrl and bearerToken 
are
          * ignored.
@@ -562,6 +582,7 @@ public interface OpaComponentBuilderFactory {
             case "autowiredEnabled": ((OpaComponent) 
component).setAutowiredEnabled((boolean) value); return true;
             case "borrowTimeout": getOrCreateConfiguration((OpaComponent) 
component).setBorrowTimeout((long) value); return true;
             case "connectionTimeout": getOrCreateConfiguration((OpaComponent) 
component).setConnectionTimeout((long) value); return true;
+            case "healthCheckBundles": getOrCreateConfiguration((OpaComponent) 
component).setHealthCheckBundles((boolean) value); return true;
             case "opaClient": getOrCreateConfiguration((OpaComponent) 
component).setOpaClient((com.styra.opa.OPAClient) value); return true;
             case "poolSize": getOrCreateConfiguration((OpaComponent) 
component).setPoolSize((int) value); return true;
             case "requestTimeout": getOrCreateConfiguration((OpaComponent) 
component).setRequestTimeout((long) value); return true;
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpaEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpaEndpointBuilderFactory.java
index 0f2697bd44aa..5a2e8f2ebf7b 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpaEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpaEndpointBuilderFactory.java
@@ -505,6 +505,42 @@ public interface OpaEndpointBuilderFactory {
             doSetProperty("connectionTimeout", connectionTimeout);
             return this;
         }
+        /**
+         * Whether the server readiness check also requires activation of OPA's
+         * configured bundles. Sends /health?bundles=true. Does not enable
+         * health checks, change policy evaluation or guarantee a particular
+         * policy revision. Not used in wasm mode or with an injected client.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: advanced
+         * 
+         * @param healthCheckBundles the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOpaEndpointBuilder healthCheckBundles(boolean 
healthCheckBundles) {
+            doSetProperty("healthCheckBundles", healthCheckBundles);
+            return this;
+        }
+        /**
+         * Whether the server readiness check also requires activation of OPA's
+         * configured bundles. Sends /health?bundles=true. Does not enable
+         * health checks, change policy evaluation or guarantee a particular
+         * policy revision. Not used in wasm mode or with an injected client.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: advanced
+         * 
+         * @param healthCheckBundles the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOpaEndpointBuilder healthCheckBundles(String 
healthCheckBundles) {
+            doSetProperty("healthCheckBundles", healthCheckBundles);
+            return this;
+        }
         /**
          * An existing OPAClient to use. When set, serverUrl and bearerToken 
are
          * ignored.

Reply via email to