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 64d78b0e8b1b CAMEL-26664: camel-dapr - use CamelDaprConfigKeys header
for configuration operation (#29563)
64d78b0e8b1b is described below
commit 64d78b0e8b1baa6f1f550cc2cca5caf289ffb205
Author: Jiří Ondrušek <[email protected]>
AuthorDate: Wed Nov 11 19:51:34 2026 +0100
CAMEL-26664: camel-dapr - use CamelDaprConfigKeys header for configuration
operation (#29563)
camel-dapr: the configuration operation now uses the CamelDaprConfigKeys
header it validates,
instead of ignoring it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
.../org/apache/camel/catalog/components/dapr.json | 2 +-
.../apache/camel/catalog/docs/dapr-component.adoc | 54 +++++++++++++++++++---
.../org/apache/camel/component/dapr/dapr.json | 2 +-
.../camel-dapr/src/main/docs/dapr-component.adoc | 54 +++++++++++++++++++---
.../dapr/DaprConfigurationOptionsProxy.java | 14 +++++-
.../apache/camel/component/dapr/DaprConstants.java | 4 +-
.../dapr/operations/DaprConfigurationTest.java | 44 ++++++++++++++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc | 6 +++
.../endpoint/dsl/DaprEndpointBuilderFactory.java | 3 +-
9 files changed, 164 insertions(+), 19 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dapr.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dapr.json
index 99c175b6f72f..b1a6022acf6a 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dapr.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dapr.json
@@ -100,7 +100,7 @@
"CamelDaprTraceState": { "index": 29, "kind": "header", "displayName": "",
"group": "consumer", "label": "consumer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "Gets additional vendor-specific trace context", "constantName":
"org.apache.camel.component.dapr.DaprConstants#TRACE_STATE" },
"CamelDaprBindingName": { "index": 30, "kind": "header", "displayName":
"", "group": "producer", "label": "producer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "The name of the Dapr binding to invoke", "constantName":
"org.apache.camel.component.dapr.DaprConstants#BINDING_NAME" },
"CamelDaprBindingOperation": { "index": 31, "kind": "header",
"displayName": "", "group": "producer", "label": "producer", "required": false,
"javaType": "String", "deprecated": false, "autowired": false, "secret": false,
"description": "The operation to perform on the binding", "constantName":
"org.apache.camel.component.dapr.DaprConstants#BINDING_OPERATION" },
- "CamelDaprConfigKeys": { "index": 32, "kind": "header", "displayName": "",
"group": "producer", "label": "producer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "List of keys for configuration operation", "constantName":
"org.apache.camel.component.dapr.DaprConstants#CONFIG_KEYS" },
+ "CamelDaprConfigKeys": { "index": 32, "kind": "header", "displayName": "",
"group": "producer", "label": "producer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "Keys for configuration operation, as a comma-separated String
or a Collection of keys", "constantName":
"org.apache.camel.component.dapr.DaprConstants#CONFIG_KEYS" },
"CamelDaprSubscriptionId": { "index": 33, "kind": "header", "displayName":
"", "group": "consumer", "label": "consumer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "The id for configuration change subscription", "constantName":
"org.apache.camel.component.dapr.DaprConstants#SUBSCRIPTION_ID" },
"CamelDaprRawConfigResponse": { "index": 34, "kind": "header",
"displayName": "", "group": "common", "label": "common", "required": false,
"javaType": "Map<String, io.dapr.client.domain.ConfigurationItem",
"deprecated": false, "autowired": false, "secret": false, "description": "The
raw configuration update response", "constantName":
"org.apache.camel.component.dapr.DaprConstants#RAW_CONFIG_RESPONSE" },
"CamelDaprLockOperation": { "index": 35, "kind": "header", "displayName":
"", "group": "producer", "label": "producer", "required": false, "javaType":
"LockOperation", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": "tryLock", "description": "The lock operation to perform on the
store. Required for DaprOperation.lock operation", "constantName":
"org.apache.camel.component.dapr.DaprConstants#LOCK_OPERATION" },
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/dapr-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/dapr-component.adoc
index 5d5899e99e45..786db40ca8a5 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/dapr-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/dapr-component.adoc
@@ -529,18 +529,58 @@ YAML::
- `configuration` -
-._Java-only: uses `List.of()` to set configuration key list_
+The `CamelDaprConfigKeys` header takes the place of the `configKeys` option.
It is a comma-separated String or a
+`Collection` of keys.
+
+[tabs]
+====
+Java::
++
[source,java]
----
from("direct:start")
- .process(exchange -> {
- exchange.getIn().setHeader("CamelDaprConfigKeys", List.of("k1", "k2"));
- })
- .to("dapr:configuration?configStore=myStore")
- .log("Received config updates from Dapr: ${body}")
- .to("mock:result");
+ .setHeader("CamelDaprConfigKeys", constant("k1,k2"))
+ .to("dapr:configuration?configStore=myStore")
+ .log("Received config updates from Dapr: ${body}")
+ .to("mock:result");
----
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="direct:start"/>
+ <setHeader name="CamelDaprConfigKeys">
+ <constant>k1,k2</constant>
+ </setHeader>
+ <to uri="dapr:configuration?configStore=myStore"/>
+ <log message="Received config updates from Dapr: ${body}"/>
+ <to uri="mock:result"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:start
+ steps:
+ - setHeader:
+ name: CamelDaprConfigKeys
+ constant: "k1,k2"
+ - to:
+ uri: dapr:configuration
+ parameters:
+ configStore: myStore
+ - log: "Received config updates from Dapr: ${body}"
+ - to:
+ uri: mock:result
+----
+====
+
- `lock: tryLock` -
[tabs]
diff --git
a/components/camel-dapr/src/generated/resources/META-INF/org/apache/camel/component/dapr/dapr.json
b/components/camel-dapr/src/generated/resources/META-INF/org/apache/camel/component/dapr/dapr.json
index 99c175b6f72f..b1a6022acf6a 100644
---
a/components/camel-dapr/src/generated/resources/META-INF/org/apache/camel/component/dapr/dapr.json
+++
b/components/camel-dapr/src/generated/resources/META-INF/org/apache/camel/component/dapr/dapr.json
@@ -100,7 +100,7 @@
"CamelDaprTraceState": { "index": 29, "kind": "header", "displayName": "",
"group": "consumer", "label": "consumer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "Gets additional vendor-specific trace context", "constantName":
"org.apache.camel.component.dapr.DaprConstants#TRACE_STATE" },
"CamelDaprBindingName": { "index": 30, "kind": "header", "displayName":
"", "group": "producer", "label": "producer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "The name of the Dapr binding to invoke", "constantName":
"org.apache.camel.component.dapr.DaprConstants#BINDING_NAME" },
"CamelDaprBindingOperation": { "index": 31, "kind": "header",
"displayName": "", "group": "producer", "label": "producer", "required": false,
"javaType": "String", "deprecated": false, "autowired": false, "secret": false,
"description": "The operation to perform on the binding", "constantName":
"org.apache.camel.component.dapr.DaprConstants#BINDING_OPERATION" },
- "CamelDaprConfigKeys": { "index": 32, "kind": "header", "displayName": "",
"group": "producer", "label": "producer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "List of keys for configuration operation", "constantName":
"org.apache.camel.component.dapr.DaprConstants#CONFIG_KEYS" },
+ "CamelDaprConfigKeys": { "index": 32, "kind": "header", "displayName": "",
"group": "producer", "label": "producer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "Keys for configuration operation, as a comma-separated String
or a Collection of keys", "constantName":
"org.apache.camel.component.dapr.DaprConstants#CONFIG_KEYS" },
"CamelDaprSubscriptionId": { "index": 33, "kind": "header", "displayName":
"", "group": "consumer", "label": "consumer", "required": false, "javaType":
"String", "deprecated": false, "autowired": false, "secret": false,
"description": "The id for configuration change subscription", "constantName":
"org.apache.camel.component.dapr.DaprConstants#SUBSCRIPTION_ID" },
"CamelDaprRawConfigResponse": { "index": 34, "kind": "header",
"displayName": "", "group": "common", "label": "common", "required": false,
"javaType": "Map<String, io.dapr.client.domain.ConfigurationItem",
"deprecated": false, "autowired": false, "secret": false, "description": "The
raw configuration update response", "constantName":
"org.apache.camel.component.dapr.DaprConstants#RAW_CONFIG_RESPONSE" },
"CamelDaprLockOperation": { "index": 35, "kind": "header", "displayName":
"", "group": "producer", "label": "producer", "required": false, "javaType":
"LockOperation", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": "tryLock", "description": "The lock operation to perform on the
store. Required for DaprOperation.lock operation", "constantName":
"org.apache.camel.component.dapr.DaprConstants#LOCK_OPERATION" },
diff --git a/components/camel-dapr/src/main/docs/dapr-component.adoc
b/components/camel-dapr/src/main/docs/dapr-component.adoc
index 5d5899e99e45..786db40ca8a5 100644
--- a/components/camel-dapr/src/main/docs/dapr-component.adoc
+++ b/components/camel-dapr/src/main/docs/dapr-component.adoc
@@ -529,18 +529,58 @@ YAML::
- `configuration` -
-._Java-only: uses `List.of()` to set configuration key list_
+The `CamelDaprConfigKeys` header takes the place of the `configKeys` option.
It is a comma-separated String or a
+`Collection` of keys.
+
+[tabs]
+====
+Java::
++
[source,java]
----
from("direct:start")
- .process(exchange -> {
- exchange.getIn().setHeader("CamelDaprConfigKeys", List.of("k1", "k2"));
- })
- .to("dapr:configuration?configStore=myStore")
- .log("Received config updates from Dapr: ${body}")
- .to("mock:result");
+ .setHeader("CamelDaprConfigKeys", constant("k1,k2"))
+ .to("dapr:configuration?configStore=myStore")
+ .log("Received config updates from Dapr: ${body}")
+ .to("mock:result");
----
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="direct:start"/>
+ <setHeader name="CamelDaprConfigKeys">
+ <constant>k1,k2</constant>
+ </setHeader>
+ <to uri="dapr:configuration?configStore=myStore"/>
+ <log message="Received config updates from Dapr: ${body}"/>
+ <to uri="mock:result"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:start
+ steps:
+ - setHeader:
+ name: CamelDaprConfigKeys
+ constant: "k1,k2"
+ - to:
+ uri: dapr:configuration
+ parameters:
+ configStore: myStore
+ - log: "Received config updates from Dapr: ${body}"
+ - to:
+ uri: mock:result
+----
+====
+
- `lock: tryLock` -
[tabs]
diff --git
a/components/camel-dapr/src/main/java/org/apache/camel/component/dapr/DaprConfigurationOptionsProxy.java
b/components/camel-dapr/src/main/java/org/apache/camel/component/dapr/DaprConfigurationOptionsProxy.java
index b8a1177720f5..9333f3be8329 100644
---
a/components/camel-dapr/src/main/java/org/apache/camel/component/dapr/DaprConfigurationOptionsProxy.java
+++
b/components/camel-dapr/src/main/java/org/apache/camel/component/dapr/DaprConfigurationOptionsProxy.java
@@ -18,10 +18,13 @@ package org.apache.camel.component.dapr;
import java.time.Duration;
import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
+import java.util.stream.Stream;
import io.dapr.client.domain.HttpExtension;
import io.dapr.client.domain.State;
@@ -166,7 +169,16 @@ public class DaprConfigurationOptionsProxy {
}
public List<String> getConfigKeysAsList(final Exchange exchange) {
- return configuration.getConfigKeysAsList();
+ // the header can be a Collection of keys or a comma-separated String
+ Object header = ObjectHelper.isEmpty(exchange) ? null :
exchange.getIn().getHeader(DaprConstants.CONFIG_KEYS);
+ Object configKeys = ObjectHelper.isEmpty(header) ?
configuration.getConfigKeys() : header;
+ if (configKeys == null) {
+ return null;
+ }
+ Stream<?> keys = configKeys instanceof Collection<?> collection
+ ? collection.stream()
+ : Arrays.stream(configKeys.toString().split(","));
+ return keys.map(key -> String.valueOf(key).trim()).filter(key ->
!key.isEmpty()).toList();
}
public LockOperation getLockOperation(final Exchange exchange) {
diff --git
a/components/camel-dapr/src/main/java/org/apache/camel/component/dapr/DaprConstants.java
b/components/camel-dapr/src/main/java/org/apache/camel/component/dapr/DaprConstants.java
index 193b2d003b5c..8d50fa7f698f 100644
---
a/components/camel-dapr/src/main/java/org/apache/camel/component/dapr/DaprConstants.java
+++
b/components/camel-dapr/src/main/java/org/apache/camel/component/dapr/DaprConstants.java
@@ -129,7 +129,9 @@ public class DaprConstants {
public static final String BINDING_NAME = HEADER_PREFIX + "BindingName";
@Metadata(label = "producer", description = "The operation to perform on
the binding", javaType = "String")
public static final String BINDING_OPERATION = HEADER_PREFIX +
"BindingOperation";
- @Metadata(label = "producer", description = "List of keys for
configuration operation", javaType = "String")
+ @Metadata(label = "producer",
+ description = "Keys for configuration operation, as a
comma-separated String or a Collection of keys",
+ javaType = "String")
public static final String CONFIG_KEYS = HEADER_PREFIX + "ConfigKeys";
@Metadata(label = "consumer", description = "The id for configuration
change subscription", javaType = "String")
public static final String SUBSCRIPTION_ID = HEADER_PREFIX +
"SubscriptionId";
diff --git
a/components/camel-dapr/src/test/java/org/apache/camel/component/dapr/operations/DaprConfigurationTest.java
b/components/camel-dapr/src/test/java/org/apache/camel/component/dapr/operations/DaprConfigurationTest.java
index 42f198319bf9..944a85074cab 100644
---
a/components/camel-dapr/src/test/java/org/apache/camel/component/dapr/operations/DaprConfigurationTest.java
+++
b/components/camel-dapr/src/test/java/org/apache/camel/component/dapr/operations/DaprConfigurationTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.component.dapr.operations;
+import java.util.List;
import java.util.Map;
import io.dapr.client.DaprClient;
@@ -31,6 +32,7 @@ import org.apache.camel.support.DefaultExchange;
import org.apache.camel.test.junit6.CamelTestSupport;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Mono;
@@ -40,6 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@@ -74,6 +77,47 @@ public class DaprConfigurationTest extends CamelTestSupport {
assertEquals(mockResponse,
operationResponse.getHeaders().get(DaprConstants.RAW_CONFIG_RESPONSE));
}
+ @Test
+ void testConfigKeysFromHeader() {
+ assertEquals(List.of("key1", "key2"), sentConfigKeys("endpointKey",
"key1,key2"));
+ }
+
+ @Test
+ void testConfigKeysFromListHeader() {
+ assertEquals(List.of("key1", "key2"), sentConfigKeys("endpointKey",
List.of("key1", " key2 ")));
+ }
+
+ @Test
+ void testConfigKeysFromHeaderAreTrimmed() {
+ assertEquals(List.of("key1", "key2"), sentConfigKeys("endpointKey", "
key1, ,key2 ,"));
+ }
+
+ @Test
+ void testConfigKeysFromEndpointWithoutHeader() {
+ assertEquals(List.of("k1", "k2"), sentConfigKeys("k1, k2", null));
+ }
+
+ private List<String> sentConfigKeys(String endpointKeys, Object header) {
+ when(endpoint.getClient()).thenReturn(client);
+
when(client.getConfiguration(any(GetConfigurationRequest.class))).thenReturn(Mono.just(Map.of()));
+
+ DaprConfiguration configuration = new DaprConfiguration();
+ configuration.setOperation(DaprOperation.configuration);
+ configuration.setConfigStore("myStore");
+ configuration.setConfigKeys(endpointKeys);
+ DaprConfigurationOptionsProxy configurationOptionsProxy = new
DaprConfigurationOptionsProxy(configuration);
+
+ final Exchange exchange = new DefaultExchange(context);
+ exchange.getMessage().setHeader(DaprConstants.CONFIG_KEYS, header);
+
+ final DaprConfigurationHandler operation = new
DaprConfigurationHandler(configurationOptionsProxy, endpoint);
+ operation.handle(exchange);
+
+ ArgumentCaptor<GetConfigurationRequest> captor =
ArgumentCaptor.forClass(GetConfigurationRequest.class);
+ verify(client).getConfiguration(captor.capture());
+ return captor.getValue().getKeys();
+ }
+
@Test
void testValidateConfiguration() {
DaprConfiguration configuration = new DaprConfiguration();
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index fbdd21a41b32..0de0af1acc7a 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -1346,6 +1346,12 @@ The other operations do not change: the `state`
operations still take the key fr
other operations still take the metadata from the `CamelDaprMetadata` header,
and the other `CamelDapr*` headers still
take the place of the options of the endpoint, as before.
+=== camel-dapr - the CamelDaprConfigKeys header takes the place of the
configKeys option
+
+The `configuration` operation of the `dapr` producer ignored the
`CamelDaprConfigKeys` header and always sent the keys
+of the `configKeys` option of the endpoint. It now sends the keys of the
header when it is set: a comma-separated String
+or a `Collection` of keys. A route that set this header, but relied on the
keys of the endpoint, must remove the header.
+
=== camel-consul - no Optional in the body, and the CamelConsulResult header
of every action
The `GET_SESSIONS` action of `consul:kv`, the `RENEW` action of
`consul:session` and the `GET` action of
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DaprEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DaprEndpointBuilderFactory.java
index 526d12215aaf..efba2571a82e 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DaprEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DaprEndpointBuilderFactory.java
@@ -1916,7 +1916,8 @@ public interface DaprEndpointBuilderFactory {
return "CamelDaprBindingOperation";
}
/**
- * List of keys for configuration operation.
+ * Keys for configuration operation, as a comma-separated String or a
+ * Collection of keys.
*
* The option is a: {@code String} type.
*