This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.18.x by this push:
new a1132971f3d6 CAMEL-24576: dynamic-router - gate control message
predicate (#26019)
a1132971f3d6 is described below
commit a1132971f3d64fd4d1dc748c3bfa87c49130ac9b
Author: Andrea Cosentino <[email protected]>
AuthorDate: Wed Sep 2 09:23:24 2026 +0200
CAMEL-24576: dynamic-router - gate control message predicate (#26019)
Backport of #25992 onto camel-4.18.x, reduced to the control endpoint gate.
This branch has no security marker attributes on @UriParam, no SecurityUtils
insecure-options registry, and no RecipientList.setAllowedSchemes, so the
insecure:dev marker and the allowedSchemes option are left out.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_013xhhhvd8YPrPXuXxL1ULdt
Signed-off-by: Andrea Cosentino <[email protected]>
---
.../catalog/components/dynamic-router-control.json | 3 +-
.../DynamicRouterControlEndpointConfigurer.java | 6 +
.../DynamicRouterControlEndpointUriFactory.java | 3 +-
.../control/dynamic-router-control.json | 3 +-
.../src/main/docs/dynamic-router-component.adoc | 15 ++-
.../docs/dynamic-router-control-component.adoc | 31 +++++
...ynamicRouterControlChannelSendDynamicAware.java | 9 ++
.../control/DynamicRouterControlConfiguration.java | 33 ++++++
.../control/DynamicRouterControlConstants.java | 16 +++
.../control/DynamicRouterControlProducer.java | 70 +++++++++---
...icRouterControlChannelSendDynamicAwareTest.java | 11 ++
.../control/DynamicRouterControlProducerTest.java | 126 +++++++++++++++++++++
.../DynamicRouterBasicSynchronousIT.java | 8 +-
.../DynamicRouterSendDynamicAwareIT.java | 3 +-
...DynamicRouterControlEndpointBuilderFactory.java | 42 +++++++
15 files changed, 353 insertions(+), 26 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dynamic-router-control.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dynamic-router-control.json
index 9f70a1e7523d..d8c4f25b440f 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dynamic-router-control.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dynamic-router-control.json
@@ -46,6 +46,7 @@
"predicateBean": { "index": 5, "kind": "parameter", "displayName":
"Predicate Bean", "group": "control", "label": "control", "required": false,
"type": "object", "javaType": "org.apache.camel.Predicate", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "A Predicate instance in
the registry." },
"priority": { "index": 6, "kind": "parameter", "displayName": "Priority",
"group": "control", "label": "control", "required": false, "type": "integer",
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "The subscription
priority." },
"subscribeChannel": { "index": 7, "kind": "parameter", "displayName":
"Subscribe Channel", "group": "control", "label": "control", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "The channel to
subscribe to" },
- "subscriptionId": { "index": 8, "kind": "parameter", "displayName":
"Subscription Id", "group": "control", "label": "control", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "The subscription ID; if
unspecified, one will be assigned and returned." }
+ "subscriptionId": { "index": 8, "kind": "parameter", "displayName":
"Subscription Id", "group": "control", "label": "control", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "The subscription ID; if
unspecified, one will be assigned and returned." },
+ "allowPredicateFromMessage": { "index": 9, "kind": "parameter",
"displayName": "Allow Predicate From Message", "group": "security", "label":
"control,security", "required": false, "type": "boolean", "javaType":
"boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "Whether the subscripti
[...]
}
}
diff --git
a/components/camel-dynamic-router/src/generated/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlEndpointConfigurer.java
b/components/camel-dynamic-router/src/generated/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlEndpointConfigurer.java
index 65978aadf7f5..6eaaebe11bff 100644
---
a/components/camel-dynamic-router/src/generated/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlEndpointConfigurer.java
+++
b/components/camel-dynamic-router/src/generated/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlEndpointConfigurer.java
@@ -23,6 +23,8 @@ public class DynamicRouterControlEndpointConfigurer extends
PropertyConfigurerSu
public boolean configure(CamelContext camelContext, Object obj, String
name, Object value, boolean ignoreCase) {
DynamicRouterControlEndpoint target = (DynamicRouterControlEndpoint)
obj;
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "allowpredicatefrommessage":
+ case "allowPredicateFromMessage":
target.getConfiguration().setAllowPredicateFromMessage(property(camelContext,
boolean.class, value)); return true;
case "destinationuri":
case "destinationUri":
target.getConfiguration().setDestinationUri(property(camelContext,
java.lang.String.class, value)); return true;
case "expressionlanguage":
@@ -44,6 +46,8 @@ public class DynamicRouterControlEndpointConfigurer extends
PropertyConfigurerSu
@Override
public Class<?> getOptionType(String name, boolean ignoreCase) {
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "allowpredicatefrommessage":
+ case "allowPredicateFromMessage": return boolean.class;
case "destinationuri":
case "destinationUri": return java.lang.String.class;
case "expressionlanguage":
@@ -66,6 +70,8 @@ public class DynamicRouterControlEndpointConfigurer extends
PropertyConfigurerSu
public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
DynamicRouterControlEndpoint target = (DynamicRouterControlEndpoint)
obj;
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "allowpredicatefrommessage":
+ case "allowPredicateFromMessage": return
target.getConfiguration().isAllowPredicateFromMessage();
case "destinationuri":
case "destinationUri": return
target.getConfiguration().getDestinationUri();
case "expressionlanguage":
diff --git
a/components/camel-dynamic-router/src/generated/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlEndpointUriFactory.java
b/components/camel-dynamic-router/src/generated/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlEndpointUriFactory.java
index 3b2f543db380..542a7017607e 100644
---
a/components/camel-dynamic-router/src/generated/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlEndpointUriFactory.java
+++
b/components/camel-dynamic-router/src/generated/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlEndpointUriFactory.java
@@ -23,7 +23,8 @@ public class DynamicRouterControlEndpointUriFactory extends
org.apache.camel.sup
private static final Set<String> SECRET_PROPERTY_NAMES;
private static final Map<String, String> MULTI_VALUE_PREFIXES;
static {
- Set<String> props = new HashSet<>(9);
+ Set<String> props = new HashSet<>(10);
+ props.add("allowPredicateFromMessage");
props.add("controlAction");
props.add("destinationUri");
props.add("expressionLanguage");
diff --git
a/components/camel-dynamic-router/src/generated/resources/META-INF/org/apache/camel/component/dynamicrouter/control/dynamic-router-control.json
b/components/camel-dynamic-router/src/generated/resources/META-INF/org/apache/camel/component/dynamicrouter/control/dynamic-router-control.json
index 9f70a1e7523d..d8c4f25b440f 100644
---
a/components/camel-dynamic-router/src/generated/resources/META-INF/org/apache/camel/component/dynamicrouter/control/dynamic-router-control.json
+++
b/components/camel-dynamic-router/src/generated/resources/META-INF/org/apache/camel/component/dynamicrouter/control/dynamic-router-control.json
@@ -46,6 +46,7 @@
"predicateBean": { "index": 5, "kind": "parameter", "displayName":
"Predicate Bean", "group": "control", "label": "control", "required": false,
"type": "object", "javaType": "org.apache.camel.Predicate", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "A Predicate instance in
the registry." },
"priority": { "index": 6, "kind": "parameter", "displayName": "Priority",
"group": "control", "label": "control", "required": false, "type": "integer",
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "The subscription
priority." },
"subscribeChannel": { "index": 7, "kind": "parameter", "displayName":
"Subscribe Channel", "group": "control", "label": "control", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "The channel to
subscribe to" },
- "subscriptionId": { "index": 8, "kind": "parameter", "displayName":
"Subscription Id", "group": "control", "label": "control", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "The subscription ID; if
unspecified, one will be assigned and returned." }
+ "subscriptionId": { "index": 8, "kind": "parameter", "displayName":
"Subscription Id", "group": "control", "label": "control", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "The subscription ID; if
unspecified, one will be assigned and returned." },
+ "allowPredicateFromMessage": { "index": 9, "kind": "parameter",
"displayName": "Allow Predicate From Message", "group": "security", "label":
"control,security", "required": false, "type": "boolean", "javaType":
"boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": false, "configurationClass":
"org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConfiguration",
"configurationField": "configuration", "description": "Whether the subscripti
[...]
}
}
diff --git
a/components/camel-dynamic-router/src/main/docs/dynamic-router-component.adoc
b/components/camel-dynamic-router/src/main/docs/dynamic-router-component.adoc
index 32935b5b00b8..3ebae76f0796 100644
---
a/components/camel-dynamic-router/src/main/docs/dynamic-router-component.adoc
+++
b/components/camel-dynamic-router/src/main/docs/dynamic-router-component.adoc
@@ -265,7 +265,18 @@ producerTemplate.sendBody("kafka://subscriptions",
mapper.writeValueAsString(con
----
In another module, additional routing will serve as a bridge to get the
message from Kafka to the control channel of the
-Dynamic Router:
+Dynamic Router. The subscriptions above carry their predicate in the control
message, so the bridge has to opt in with
+`allowPredicateFromMessage=true`.
+
+[WARNING]
+====
+`allowPredicateFromMessage` lets whoever puts a message on the bridged
transport choose both the expression language and
+the expression that the Dynamic Router compiles and evaluates, which means it
decides what runs inside the Camel
+process. Only enable it when the transport that feeds the control channel is
trusted. When it is not, have the
+participants subscribe with `predicateBean`, which selects a `Predicate` that
the route author bound in the registry,
+and leave the flag at its default of `false`. See
+xref:dynamic-router-control-component.adoc[the control component
documentation] for the alternatives.
+====
.Bridge from Kafka to the Dynamic Router control channel
[source,java]
@@ -276,7 +287,7 @@ RouteBuilder subscriptionRouter() {
public void configure() {
from("kafka:subscriptions")
.unmarshal().json(DynamicRouterControlMessage.class)
- .to("dynamic-router-control:subscribe");
+
.to("dynamic-router-control:subscribe?allowPredicateFromMessage=true");
}
};
}
diff --git
a/components/camel-dynamic-router/src/main/docs/dynamic-router-control-component.adoc
b/components/camel-dynamic-router/src/main/docs/dynamic-router-control-component.adoc
index 154439314a0a..a2012ee09438 100644
---
a/components/camel-dynamic-router/src/main/docs/dynamic-router-control-component.adoc
+++
b/components/camel-dynamic-router/src/main/docs/dynamic-router-control-component.adoc
@@ -32,6 +32,37 @@ include::partial$component-endpoint-options.adoc[]
include::partial$component-endpoint-headers.adoc[]
// component options: END
+== Supplying the subscription predicate
+
+A subscription needs a predicate that decides which exchanges the participant
receives. There are three ways to supply
+one, and they differ in who chooses it:
+
+* `predicateBean` -- the name of a `Predicate` bound in the registry. The
route author decides which predicates exist,
+and the control message only selects one of them by name.
+* `predicate` and `expressionLanguage` as control endpoint URI parameters --
the route author writes the expression, and
+every subscription made through that endpoint uses it.
+* `predicate` and `expressionLanguage` carried in the control message, in its
body or its headers -- the sender of the
+control message chooses both the expression language and the expression.
+
+The third form is disabled by default. The predicate is compiled and then
evaluated against every exchange on the
+channel, so letting the control message choose both the language and the
expression means the sender of that message
+decides what runs inside the Camel process. Set
`allowPredicateFromMessage=true` on the control endpoint to enable it,
+and only do so when control messages can only come from a trusted source:
+
+[source,java]
+----
+from("kafka:subscriptions")
+ .unmarshal().json(DynamicRouterControlMessage.class)
+ .to("dynamic-router-control:subscribe?allowPredicateFromMessage=true");
+----
+
+When `allowPredicateFromMessage` is `false`, which is the default, a control
message that supplies a `predicate` or an
+`expressionLanguage` is rejected with an `IllegalArgumentException`. Prefer
`predicateBean`, or configure the predicate
+on the endpoint, when control messages arrive from outside the application.
+
+Subscription parameters that the control message does not carry fall back to
the values configured on the control
+endpoint, so a participant can send only the parameters that identify it and
let the endpoint supply the rest.
+
== Subscribing
Subscribing can be achieved by using query parameters in the control endpoint
URI, or by sending a
diff --git
a/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlChannelSendDynamicAware.java
b/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlChannelSendDynamicAware.java
index 13662241b271..3e5d0a79731d 100644
---
a/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlChannelSendDynamicAware.java
+++
b/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlChannelSendDynamicAware.java
@@ -28,6 +28,7 @@ import org.apache.camel.spi.annotations.SendDynamic;
import org.apache.camel.support.component.SendDynamicAwareSupport;
import org.apache.camel.util.URISupport;
+import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.ALLOW_PREDICATE_FROM_MESSAGE_PROPERTY;
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.COMPONENT_SCHEME_CONTROL;
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.CONTROL_ACTION_PROPERTY;
@@ -95,6 +96,14 @@ public class DynamicRouterControlChannelSendDynamicAware
extends SendDynamicAwar
String uri = entry.getUri();
if (DynamicRouterControlConstants.SHOULD_OPTIMIZE.test(uri)) {
optimizedUri = URISupport.stripQuery(uri);
+ // The subscription parameters are carried as headers, but
"allowPredicateFromMessage" decides whether a
+ // control message may supply the predicate at all, so it has to
stay on the endpoint, where only the
+ // route author can set it. Stripping it here would make the
endpoint fall back to the default of false.
+ Object allowPredicateFromMessage =
entry.getProperties().get(ALLOW_PREDICATE_FROM_MESSAGE_PROPERTY);
+ if (allowPredicateFromMessage != null) {
+ optimizedUri = optimizedUri + "?" +
ALLOW_PREDICATE_FROM_MESSAGE_PROPERTY + "="
+ + allowPredicateFromMessage;
+ }
}
return optimizedUri;
}
diff --git
a/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlConfiguration.java
b/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlConfiguration.java
index 27a02fbe1684..03bb28d97ef1 100644
---
a/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlConfiguration.java
+++
b/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlConfiguration.java
@@ -80,6 +80,19 @@ public class DynamicRouterControlConfiguration {
@UriParam(label = "control", defaultValue = "simple", description = "The
subscription predicate language.")
private String expressionLanguage = "simple";
+ /**
+ * Whether the subscription predicate, and the language used to compile
it, may be taken from the incoming control
+ * message.
+ */
+ @UriParam(label = "control,security", defaultValue = "false",
+ description = "Whether the subscription predicate, and the
language used to compile it, may be taken"
+ + " from the incoming control message. When
disabled, the predicate and expressionLanguage"
+ + " configured on this endpoint are used instead.
Enabling this lets the sender of a"
+ + " control message choose both the expression
language and the expression that the"
+ + " Dynamic Router compiles into a live predicate,
so only enable it when control messages"
+ + " come from a trusted source.")
+ private boolean allowPredicateFromMessage;
+
/**
* The control action (subscribe or unsubscribe).
*
@@ -237,6 +250,26 @@ public class DynamicRouterControlConfiguration {
this.expressionLanguage = expressionLanguage;
}
+ /**
+ * Whether the subscription predicate, and the language used to compile
it, may be taken from the incoming control
+ * message.
+ *
+ * @return true if the control message may supply the predicate
+ */
+ public boolean isAllowPredicateFromMessage() {
+ return allowPredicateFromMessage;
+ }
+
+ /**
+ * Whether the subscription predicate, and the language used to compile
it, may be taken from the incoming control
+ * message.
+ *
+ * @param allowPredicateFromMessage true if the control message may supply
the predicate
+ */
+ public void setAllowPredicateFromMessage(final boolean
allowPredicateFromMessage) {
+ this.allowPredicateFromMessage = allowPredicateFromMessage;
+ }
+
public DynamicRouterControlConfiguration() {
// Default constructor is empty because we need an instance, and
// then things can be populated through mutator methods.
diff --git
a/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlConstants.java
b/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlConstants.java
index c5516973453d..196cb80f8174 100644
---
a/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlConstants.java
+++
b/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlConstants.java
@@ -124,6 +124,15 @@ public final class DynamicRouterControlConstants {
*/
public static final String ERROR_NO_PREDICATE_BEAN_FOUND = "Predicate bean
could not be found";
+ /**
+ * Error when a control message supplies a predicate expression, or the
language to compile it with, but the control
+ * endpoint does not allow those to be taken from a control message.
+ */
+ public static final String ERROR_PREDICATE_FROM_MESSAGE_NOT_ALLOWED
+ = "The subscription predicate expression, and the language used to
compile it, cannot be taken from a "
+ + "control message. Configure 'predicate' and
'expressionLanguage' on the dynamic-router-control "
+ + "endpoint, or set 'allowPredicateFromMessage=true' to let the
control message supply them.";
+
/**
* The configuration property for the control channel action.
*/
@@ -164,6 +173,13 @@ public final class DynamicRouterControlConstants {
*/
public static final String EXPRESSION_LANGUAGE_PROPERTY =
"expressionLanguage";
+ /**
+ * The configuration property that controls whether the predicate may be
taken from a control message. Unlike the
+ * other properties, this one is deliberately absent from {@link
#URI_PARAMS_TO_HEADER_NAMES}: it must stay on the
+ * endpoint, where only the route author can set it, and must never be
settable from a message.
+ */
+ public static final String ALLOW_PREDICATE_FROM_MESSAGE_PROPERTY =
"allowPredicateFromMessage";
+
/**
* Header name for the control action.
*/
diff --git
a/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlProducer.java
b/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlProducer.java
index 178cd0903390..658969e6af3d 100644
---
a/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlProducer.java
+++
b/components/camel-dynamic-router/src/main/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlProducer.java
@@ -42,6 +42,7 @@ import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterCont
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.CONTROL_SUBSCRIBE_CHANNEL;
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.CONTROL_SUBSCRIPTION_ID;
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.ERROR_NO_PREDICATE_BEAN_FOUND;
+import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.ERROR_PREDICATE_FROM_MESSAGE_NOT_ALLOWED;
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.SIMPLE_LANGUAGE;
/**
@@ -74,29 +75,57 @@ public class DynamicRouterControlProducer extends
HeaderSelectorProducer {
this.configuration = configuration;
}
+ /**
+ * Returns the value to use for a predicate parameter that a control
message may try to supply. Unless the endpoint
+ * explicitly allows the predicate to come from the message, a
message-supplied value is rejected, and the value
+ * configured on the endpoint is used instead. Without this, the sender of
a control message would choose both the
+ * expression language and the expression that the Dynamic Router compiles
into a live predicate.
+ *
+ * @param allowFromMessage whether the endpoint allows the predicate to
come from the control message
+ * @param messageValue the value found in the control message, if any
+ * @param configValue the value configured on the endpoint
+ * @return the value to use
+ */
+ static String predicateValueToUse(
+ final boolean allowFromMessage, final String messageValue, final
String configValue) {
+ if (allowFromMessage) {
+ return messageValue;
+ }
+ if (ObjectHelper.isNotEmpty(messageValue)) {
+ throw new
IllegalArgumentException(ERROR_PREDICATE_FROM_MESSAGE_NOT_ALLOWED);
+ }
+ return configValue;
+ }
+
/**
* Create a filter from parameters in the message body.
*
* @param dynamicRouterControlService the {@link
DynamicRouterControlService}
+ * @param configuration the configuration for the Dynamic
Router Control
* @param message the message, where the body
contains a control message
* @param update whether to update an existing
filter (true) or add a new one (false)
* @return the ID of the added filter
*/
static String subscribeFromMessage(
final DynamicRouterControlService dynamicRouterControlService,
+ final DynamicRouterControlConfiguration configuration,
final Message message, final boolean update) {
DynamicRouterControlMessage messageBody =
message.getBody(DynamicRouterControlMessage.class);
String subscriptionId = messageBody.getSubscriptionId();
String subscribeChannel = messageBody.getSubscribeChannel();
String destinationUri = messageBody.getDestinationUri();
String priority = String.valueOf(messageBody.getPriority());
- String predicate = messageBody.getPredicate();
String predicateBean = messageBody.getPredicateBean();
- String expressionLanguage = messageBody.getExpressionLanguage();
if (ObjectHelper.isNotEmpty(predicateBean)) {
return
dynamicRouterControlService.subscribeWithPredicateBean(subscribeChannel,
subscriptionId,
destinationUri, Integer.parseInt(priority), predicateBean,
update);
- } else if (ObjectHelper.isNotEmpty(predicate) &&
ObjectHelper.isNotEmpty(expressionLanguage)) {
+ }
+ boolean allowFromMessage = configuration.isAllowPredicateFromMessage();
+ String predicate = predicateValueToUse(allowFromMessage,
messageBody.getPredicate(),
+ configuration.getPredicate());
+ String expressionLanguage = predicateValueToUse(allowFromMessage,
messageBody.getExpressionLanguage(),
+ configuration.getExpressionLanguage());
+ if (ObjectHelper.isNotEmpty(predicate) &&
ObjectHelper.isNotEmpty(expressionLanguage)) {
return
dynamicRouterControlService.subscribeWithPredicateExpression(subscribeChannel,
subscriptionId,
destinationUri, Integer.parseInt(priority), predicate,
expressionLanguage, update);
} else {
@@ -105,29 +134,38 @@ public class DynamicRouterControlProducer extends
HeaderSelectorProducer {
}
/**
- * Create a filter from parameters in message headers.
+ * Create a filter from parameters in message headers, falling back to the
values configured on the endpoint for any
+ * parameter that the message does not carry.
*
* @param dynamicRouterControlService the {@link
DynamicRouterControlService}
+ * @param configuration the configuration for the Dynamic
Router Control
* @param message the message, where the headers
contain subscription params
* @param update whether to update an existing
filter (true) or add a new one (false)
* @return the ID of the added filter
*/
static String subscribeFromHeaders(
final DynamicRouterControlService dynamicRouterControlService,
+ final DynamicRouterControlConfiguration configuration,
final Message message, final boolean update) {
Map<String, Object> headers = message.getHeaders();
- String subscriptionId = (String) headers.get(CONTROL_SUBSCRIPTION_ID);
- String subscribeChannel = (String)
headers.get(CONTROL_SUBSCRIBE_CHANNEL);
- String destinationUri = (String) headers.get(CONTROL_DESTINATION_URI);
- String priority = String.valueOf(headers.get(CONTROL_PRIORITY));
- String predicate = (String) headers.get(CONTROL_PREDICATE);
+ String subscriptionId = (String)
headers.getOrDefault(CONTROL_SUBSCRIPTION_ID,
configuration.getSubscriptionId());
+ String subscribeChannel
+ = (String) headers.getOrDefault(CONTROL_SUBSCRIBE_CHANNEL,
configuration.getSubscribeChannel());
+ String destinationUri = (String)
headers.getOrDefault(CONTROL_DESTINATION_URI,
configuration.getDestinationUri());
+ String priority =
String.valueOf(headers.getOrDefault(CONTROL_PRIORITY,
configuration.getPriority()));
String predicateBean = (String) headers.get(CONTROL_PREDICATE_BEAN);
- String expressionLanguage = Optional.ofNullable((String)
headers.get(CONTROL_EXPRESSION_LANGUAGE))
- .orElse(SIMPLE_LANGUAGE);
if (ObjectHelper.isNotEmpty(predicateBean)) {
return
dynamicRouterControlService.subscribeWithPredicateBean(subscribeChannel,
subscriptionId,
destinationUri, Integer.parseInt(priority), predicateBean,
update);
- } else if (ObjectHelper.isNotEmpty(predicate) &&
ObjectHelper.isNotEmpty(expressionLanguage)) {
+ }
+ boolean allowFromMessage = configuration.isAllowPredicateFromMessage();
+ String predicate = predicateValueToUse(allowFromMessage, (String)
headers.get(CONTROL_PREDICATE),
+ configuration.getPredicate());
+ String expressionLanguage = Optional
+ .ofNullable(predicateValueToUse(allowFromMessage, (String)
headers.get(CONTROL_EXPRESSION_LANGUAGE),
+ configuration.getExpressionLanguage()))
+ .orElse(SIMPLE_LANGUAGE);
+ if (ObjectHelper.isNotEmpty(predicate) &&
ObjectHelper.isNotEmpty(expressionLanguage)) {
return
dynamicRouterControlService.subscribeWithPredicateExpression(subscribeChannel,
subscriptionId,
destinationUri, Integer.parseInt(priority), predicate,
expressionLanguage, update);
} else {
@@ -147,9 +185,9 @@ public class DynamicRouterControlProducer extends
HeaderSelectorProducer {
public void performSubscribe(final Message message, AsyncCallback
callback) {
String filterId;
if (message.getBody() instanceof DynamicRouterControlMessage) {
- filterId = subscribeFromMessage(dynamicRouterControlService,
message, false);
+ filterId = subscribeFromMessage(dynamicRouterControlService,
configuration, message, false);
} else {
- filterId = subscribeFromHeaders(dynamicRouterControlService,
message, false);
+ filterId = subscribeFromHeaders(dynamicRouterControlService,
configuration, message, false);
}
message.setBody(filterId);
callback.done(false);
@@ -190,9 +228,9 @@ public class DynamicRouterControlProducer extends
HeaderSelectorProducer {
public void performUpdate(final Message message, AsyncCallback callback) {
String filterId;
if (message.getBody() instanceof DynamicRouterControlMessage) {
- filterId = subscribeFromMessage(dynamicRouterControlService,
message, true);
+ filterId = subscribeFromMessage(dynamicRouterControlService,
configuration, message, true);
} else {
- filterId = subscribeFromHeaders(dynamicRouterControlService,
message, true);
+ filterId = subscribeFromHeaders(dynamicRouterControlService,
configuration, message, true);
}
message.setBody(filterId);
callback.done(false);
diff --git
a/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlChannelSendDynamicAwareTest.java
b/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlChannelSendDynamicAwareTest.java
index 634d942297b5..deb7e48b812d 100644
---
a/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlChannelSendDynamicAwareTest.java
+++
b/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlChannelSendDynamicAwareTest.java
@@ -68,6 +68,17 @@ class DynamicRouterControlChannelSendDynamicAwareTest {
}
}
+ @Test
+ void resolveStaticUriRetainsAllowPredicateFromMessage() throws Exception {
+ String originalUri =
"dynamic-router-control:subscribe?subscriptionId=testSub1&allowPredicateFromMessage=true";
+ String uri =
"dynamic-router-control://subscribe?subscriptionId=testSub1&allowPredicateFromMessage=true";
+ try (DynamicRouterControlChannelSendDynamicAware testSubject = new
DynamicRouterControlChannelSendDynamicAware()) {
+ SendDynamicAware.DynamicAwareEntry entry =
testSubject.prepare(exchange, uri, originalUri);
+ String result = testSubject.resolveStaticUri(exchange, entry);
+
assertEquals("dynamic-router-control://subscribe?allowPredicateFromMessage=true",
result);
+ }
+ }
+
@Test
void resolveStaticUriShouldNotOptimize() throws Exception {
String originalUri =
"dynamic-router-ctrl:subscribe?subscriptionId=testSub1";
diff --git
a/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlProducerTest.java
b/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlProducerTest.java
index f86a48d55575..fad05c24c670 100644
---
a/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlProducerTest.java
+++
b/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/control/DynamicRouterControlProducerTest.java
@@ -48,6 +48,7 @@ import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterCont
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.CONTROL_PRIORITY;
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.CONTROL_SUBSCRIBE_CHANNEL;
import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.CONTROL_SUBSCRIPTION_ID;
+import static
org.apache.camel.component.dynamicrouter.control.DynamicRouterControlConstants.ERROR_PREDICATE_FROM_MESSAGE_NOT_ALLOWED;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
@@ -89,6 +90,7 @@ class DynamicRouterControlProducerTest {
@Test
void performSubscribeAction() {
+ when(configuration.isAllowPredicateFromMessage()).thenReturn(true);
String subscribeChannel = "testChannel";
Map<String, Object> headers = Map.of(
CONTROL_ACTION_HEADER, CONTROL_ACTION_SUBSCRIBE,
@@ -107,6 +109,7 @@ class DynamicRouterControlProducerTest {
@Test
void performSubscribeActionWithEmptyExpressionLanguage() {
+ when(configuration.isAllowPredicateFromMessage()).thenReturn(true);
String subscribeChannel = "testChannel";
Map<String, Object> headers = Map.of(
CONTROL_ACTION_HEADER, CONTROL_ACTION_SUBSCRIBE,
@@ -155,6 +158,7 @@ class DynamicRouterControlProducerTest {
@Test
void performUpdateAction() {
+ when(configuration.isAllowPredicateFromMessage()).thenReturn(true);
// First, perform initial subscription
String subscribeChannel = "testChannel";
Map<String, Object> headers = Map.of(
@@ -229,6 +233,7 @@ class DynamicRouterControlProducerTest {
@Test
void performSubscribeActionWithMessageInBody() {
+ when(configuration.isAllowPredicateFromMessage()).thenReturn(true);
String subscribeChannel = "testChannel";
DynamicRouterControlMessage subMsg =
DynamicRouterControlMessage.Builder.newBuilder()
.subscribeChannel(subscribeChannel)
@@ -249,6 +254,7 @@ class DynamicRouterControlProducerTest {
@Test
void performSubscribeActionWithMessageInBodyWithEmptyExpressionLanguage() {
+ when(configuration.isAllowPredicateFromMessage()).thenReturn(true);
String subscribeChannel = "testChannel";
DynamicRouterControlMessage subMsg =
DynamicRouterControlMessage.Builder.newBuilder()
.subscribeChannel(subscribeChannel)
@@ -266,6 +272,7 @@ class DynamicRouterControlProducerTest {
@Test
void performSubscribeActionWithMessageInBodyWithEmptyExpression() {
+ when(configuration.isAllowPredicateFromMessage()).thenReturn(true);
String subscribeChannel = "testChannel";
DynamicRouterControlMessage subMsg =
DynamicRouterControlMessage.Builder.newBuilder()
.subscribeChannel(subscribeChannel)
@@ -302,6 +309,7 @@ class DynamicRouterControlProducerTest {
@Test
void performUpdateActionWithMessageInBody() {
+ when(configuration.isAllowPredicateFromMessage()).thenReturn(true);
String subscribeChannel = "testChannel";
DynamicRouterControlMessage subMsg =
DynamicRouterControlMessage.Builder.newBuilder()
.subscribeChannel(subscribeChannel)
@@ -320,6 +328,124 @@ class DynamicRouterControlProducerTest {
subscribeChannel, "testId", "mock://test", 10, "true",
"simple", true);
}
+ @Test
+ void performSubscribeActionRejectsPredicateFromHeadersByDefault() {
+ Map<String, Object> headers = Map.of(
+ CONTROL_ACTION_HEADER, CONTROL_ACTION_SUBSCRIBE,
+ CONTROL_SUBSCRIBE_CHANNEL, "testChannel",
+ CONTROL_SUBSCRIPTION_ID, "testId",
+ CONTROL_DESTINATION_URI, "mock://test",
+ CONTROL_PREDICATE, "true",
+ CONTROL_EXPRESSION_LANGUAGE, "simple",
+ CONTROL_PRIORITY, 10);
+ when(message.getHeaders()).thenReturn(headers);
+ Exception ex = assertThrows(IllegalArgumentException.class, () ->
producer.performSubscribe(message, callback));
+ assertEquals(ERROR_PREDICATE_FROM_MESSAGE_NOT_ALLOWED,
ex.getMessage());
+ Mockito.verifyNoInteractions(controlService);
+ }
+
+ @Test
+ void performSubscribeActionRejectsExpressionLanguageFromHeadersByDefault()
{
+ Map<String, Object> headers = Map.of(
+ CONTROL_ACTION_HEADER, CONTROL_ACTION_SUBSCRIBE,
+ CONTROL_SUBSCRIBE_CHANNEL, "testChannel",
+ CONTROL_SUBSCRIPTION_ID, "testId",
+ CONTROL_DESTINATION_URI, "mock://test",
+ CONTROL_EXPRESSION_LANGUAGE, "simple",
+ CONTROL_PRIORITY, 10);
+ when(message.getHeaders()).thenReturn(headers);
+ Exception ex = assertThrows(IllegalArgumentException.class, () ->
producer.performSubscribe(message, callback));
+ assertEquals(ERROR_PREDICATE_FROM_MESSAGE_NOT_ALLOWED,
ex.getMessage());
+ Mockito.verifyNoInteractions(controlService);
+ }
+
+ @Test
+ void performSubscribeActionRejectsPredicateFromMessageBodyByDefault() {
+ DynamicRouterControlMessage subMsg =
DynamicRouterControlMessage.Builder.newBuilder()
+ .subscribeChannel("testChannel")
+ .subscriptionId("testId")
+ .destinationUri("mock://test")
+ .priority(10)
+ .predicate("true")
+ .expressionLanguage("simple")
+ .build();
+ when(message.getBody()).thenReturn(subMsg);
+
when(message.getBody(DynamicRouterControlMessage.class)).thenReturn(subMsg);
+ Exception ex = assertThrows(IllegalArgumentException.class, () ->
producer.performSubscribe(message, callback));
+ assertEquals(ERROR_PREDICATE_FROM_MESSAGE_NOT_ALLOWED,
ex.getMessage());
+ Mockito.verifyNoInteractions(controlService);
+ }
+
+ @Test
+ void performUpdateActionRejectsPredicateFromMessageBodyByDefault() {
+ DynamicRouterControlMessage subMsg =
DynamicRouterControlMessage.Builder.newBuilder()
+ .subscribeChannel("testChannel")
+ .subscriptionId("testId")
+ .destinationUri("mock://test")
+ .priority(10)
+ .predicate("true")
+ .expressionLanguage("simple")
+ .build();
+ when(message.getBody()).thenReturn(subMsg);
+
when(message.getBody(DynamicRouterControlMessage.class)).thenReturn(subMsg);
+ Exception ex = assertThrows(IllegalArgumentException.class, () ->
producer.performUpdate(message, callback));
+ assertEquals(ERROR_PREDICATE_FROM_MESSAGE_NOT_ALLOWED,
ex.getMessage());
+ Mockito.verifyNoInteractions(controlService);
+ }
+
+ @Test
+ void performSubscribeActionUsesEndpointPredicateWhenMessageSuppliesNone() {
+ String subscribeChannel = "testChannel";
+ Map<String, Object> headers = Map.of(
+ CONTROL_ACTION_HEADER, CONTROL_ACTION_SUBSCRIBE,
+ CONTROL_SUBSCRIBE_CHANNEL, subscribeChannel,
+ CONTROL_SUBSCRIPTION_ID, "testId",
+ CONTROL_DESTINATION_URI, "mock://test",
+ CONTROL_PRIORITY, 10);
+ when(message.getHeaders()).thenReturn(headers);
+ when(configuration.getPredicate()).thenReturn("true");
+ when(configuration.getExpressionLanguage()).thenReturn("simple");
+ Mockito.doNothing().when(callback).done(false);
+ producer.performSubscribe(message, callback);
+ Mockito.verify(controlService,
Mockito.times(1)).subscribeWithPredicateExpression(
+ subscribeChannel, "testId", "mock://test", 10, "true",
"simple", false);
+ }
+
+ @Test
+ void
performSubscribeActionFallsBackToEndpointParametersWhenHeadersAreAbsent() {
+ Map<String, Object> headers = Map.of(CONTROL_ACTION_HEADER,
CONTROL_ACTION_SUBSCRIBE);
+ when(message.getHeaders()).thenReturn(headers);
+ when(configuration.getSubscribeChannel()).thenReturn("testChannel");
+ when(configuration.getSubscriptionId()).thenReturn("testId");
+ when(configuration.getDestinationUri()).thenReturn("mock://test");
+ when(configuration.getPriority()).thenReturn(10);
+ when(configuration.getPredicate()).thenReturn("true");
+ when(configuration.getExpressionLanguage()).thenReturn("simple");
+ Mockito.doNothing().when(callback).done(false);
+ producer.performSubscribe(message, callback);
+ Mockito.verify(controlService,
Mockito.times(1)).subscribeWithPredicateExpression(
+ "testChannel", "testId", "mock://test", 10, "true", "simple",
false);
+ }
+
+ @Test
+ void performSubscribeActionWithPredicateBeanIsUnaffectedByTheGate() {
+ String subscribeChannel = "testChannel";
+ Map<String, Object> headers = Map.of(
+ CONTROL_ACTION_HEADER, CONTROL_ACTION_SUBSCRIBE,
+ CONTROL_SUBSCRIBE_CHANNEL, subscribeChannel,
+ CONTROL_SUBSCRIPTION_ID, "testId",
+ CONTROL_DESTINATION_URI, "mock://test",
+ CONTROL_PREDICATE, "true",
+ CONTROL_EXPRESSION_LANGUAGE, "simple",
+ CONTROL_PRIORITY, 10,
+ CONTROL_PREDICATE_BEAN, "testPredicate");
+ when(message.getHeaders()).thenReturn(headers);
+ Mockito.doNothing().when(callback).done(false);
+ producer.performSubscribe(message, callback);
+ Mockito.verify(controlService,
Mockito.times(1)).subscribeWithPredicateBean(
+ subscribeChannel, "testId", "mock://test", 10,
"testPredicate", false);
+ }
+
@Test
void testPerformListAction() {
String subscribeChannel = "testChannel";
diff --git
a/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/integration/DynamicRouterBasicSynchronousIT.java
b/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/integration/DynamicRouterBasicSynchronousIT.java
index da957ccdc46c..8b21c21b624d 100644
---
a/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/integration/DynamicRouterBasicSynchronousIT.java
+++
b/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/integration/DynamicRouterBasicSynchronousIT.java
@@ -176,7 +176,7 @@ public class DynamicRouterBasicSynchronousIT {
.expressionLanguage("spel")
.build();
- template.sendBody("dynamic-router-control:subscribe", controlMessage);
+
template.sendBody("dynamic-router-control:subscribe?allowPredicateFromMessage=true",
controlMessage);
// Trigger events to subscribers
template.sendBodyAndHeader("direct:start", "testMessage", "test",
"testValue");
@@ -239,7 +239,7 @@ public class DynamicRouterBasicSynchronousIT {
.predicate("#{headers.test == 'testValue1'}")
.expressionLanguage("spel")
.build();
- template.sendBody("dynamic-router-control:subscribe", controlMessage1);
+
template.sendBody("dynamic-router-control:subscribe?allowPredicateFromMessage=true",
controlMessage1);
DynamicRouterControlMessage controlMessage2 =
DynamicRouterControlMessage.Builder.newBuilder()
.subscribeChannel("test")
@@ -249,7 +249,7 @@ public class DynamicRouterBasicSynchronousIT {
.predicate("#{headers.test == 'testValue2'}")
.expressionLanguage("spel")
.build();
- template.sendBody("dynamic-router-control:subscribe", controlMessage2);
+
template.sendBody("dynamic-router-control:subscribe?allowPredicateFromMessage=true",
controlMessage2);
DynamicRouterControlMessage controlMessage3 =
DynamicRouterControlMessage.Builder.newBuilder()
.subscribeChannel("test")
@@ -259,7 +259,7 @@ public class DynamicRouterBasicSynchronousIT {
.predicate("#{headers.test == 'testValue3'}")
.expressionLanguage("spel")
.build();
- template.sendBody("dynamic-router-control:subscribe", controlMessage3);
+
template.sendBody("dynamic-router-control:subscribe?allowPredicateFromMessage=true",
controlMessage3);
String filtersJson = template.requestBodyAndHeader("direct:list", "",
"subscribeChannel", "test", String.class);
Assertions.assertEquals(
diff --git
a/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/integration/DynamicRouterSendDynamicAwareIT.java
b/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/integration/DynamicRouterSendDynamicAwareIT.java
index dfcc58352080..aae5c2e1d694 100644
---
a/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/integration/DynamicRouterSendDynamicAwareIT.java
+++
b/components/camel-dynamic-router/src/test/java/org/apache/camel/component/dynamicrouter/integration/DynamicRouterSendDynamicAwareIT.java
@@ -62,7 +62,8 @@ public class DynamicRouterSendDynamicAwareIT {
"&subscriptionId=${header.subscriptionId}" +
"&destinationUri=${header.destinationUri}" +
"&priority=${header.priority}" +
- "&predicate=${header.predicate}");
+ "&predicate=${header.predicate}" +
+ "&allowPredicateFromMessage=true");
}
});
}
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DynamicRouterControlEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DynamicRouterControlEndpointBuilderFactory.java
index 9b9d0c56d7c3..e6bae5bd2a7b 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DynamicRouterControlEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DynamicRouterControlEndpointBuilderFactory.java
@@ -176,6 +176,48 @@ public interface
DynamicRouterControlEndpointBuilderFactory {
doSetProperty("subscriptionId", subscriptionId);
return this;
}
+ /**
+ * Whether the subscription predicate, and the language used to compile
+ * it, may be taken from the incoming control message. When disabled,
+ * the predicate and expressionLanguage configured on this endpoint are
+ * used instead. Enabling this lets the sender of a control message
+ * choose both the expression language and the expression that the
+ * Dynamic Router compiles into a live predicate, so only enable it
when
+ * control messages come from a trusted source.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: false
+ * Group: security
+ *
+ * @param allowPredicateFromMessage the value to set
+ * @return the dsl builder
+ */
+ default DynamicRouterControlEndpointBuilder
allowPredicateFromMessage(boolean allowPredicateFromMessage) {
+ doSetProperty("allowPredicateFromMessage",
allowPredicateFromMessage);
+ return this;
+ }
+ /**
+ * Whether the subscription predicate, and the language used to compile
+ * it, may be taken from the incoming control message. When disabled,
+ * the predicate and expressionLanguage configured on this endpoint are
+ * used instead. Enabling this lets the sender of a control message
+ * choose both the expression language and the expression that the
+ * Dynamic Router compiles into a live predicate, so only enable it
when
+ * control messages come from a trusted source.
+ *
+ * The option will be converted to a <code>boolean</code> type.
+ *
+ * Default: false
+ * Group: security
+ *
+ * @param allowPredicateFromMessage the value to set
+ * @return the dsl builder
+ */
+ default DynamicRouterControlEndpointBuilder
allowPredicateFromMessage(String allowPredicateFromMessage) {
+ doSetProperty("allowPredicateFromMessage",
allowPredicateFromMessage);
+ return this;
+ }
}
/**