Guillaume Nodet created CAMEL-24463:
---------------------------------------
Summary: Introduce KeyValueRepository SPI to unify state store,
idempotent, aggregation and cache repositories
Key: CAMEL-24463
URL: https://issues.apache.org/jira/browse/CAMEL-24463
Project: Camel
Issue Type: New Feature
Components: camel-core
Reporter: Guillaume Nodet
h2. Motivation
Camel currently has four similar key-value store abstractions that are
implemented independently for every backend (Caffeine, Redis, Infinispan, JDBC,
etc.):
||SPI||Location||Key methods||Backends||
|{{IdempotentRepository}}|{{camel-api}}|add, contains, remove, confirm,
clear|13+|
|{{AggregationRepository}}|{{camel-api}}|add, get, remove, confirm, getKeys|12+|
|{{StateStoreBackend}}|{{camel-state-store}} (PR #22158)|put, get, delete,
contains, keys, clear|4|
|{{CacheRepository}} (proposed)|CAMEL-11114|get, put, contains, clear|n/a|
Every backend reimplements each SPI separately. Adding a new backend (MapDB,
RocksDB, etcd) means writing 2-4 separate implementations.
h2. Proposal
Introduce a single {{KeyValueRepository}} interface in {{camel-api}} that
captures the common denominator:
{code:java}
public interface KeyValueRepository extends Service {
Object get(String key);
void put(String key, Object value, long ttlMillis);
Object delete(String key);
boolean contains(String key);
Set<String> keys();
void clear();
default Object putIfAbsent(String key, Object value, long ttlMillis) { ... }
default int size() { return keys().size(); }
}
{code}
Then provide generic adapters in core that give every backend all EIP
integrations for free:
* {{KeyValueIdempotentRepository}} - wraps contains/put/delete with marker
values
* {{KeyValueAggregationRepository}} - serializes/deserializes Exchange via
DefaultExchangeHolder
These adapters are auto-discovered by the EIPs: if no explicit
{{IdempotentRepository}} or {{AggregationRepository}} is configured, the EIP
looks up a {{KeyValueRepository}} from the registry and wraps it transparently.
h2. User Experience
Configure ONE backend, use everywhere - zero wiring:
{code:properties}
# Configure one backend
camel.beans.kvStore =
#class:org.apache.camel.component.statestore.redis.RedisStateStoreBackend
camel.beans.kvStore.redisUrl = redis://localhost:6379
{code}
{code:yaml}
# Idempotent consumer - auto-discovers KeyValueRepository
- idempotentConsumer:
header: orderId
steps:
- to: direct:process
# Aggregate - same backend, zero config
- aggregate:
correlationExpression:
header: groupId
steps:
- to: direct:result
# State store endpoint - same backend
- to:
uri: state-store:myStore?operation=put
{code}
One backend, four EIP integrations, zero wiring. For users needing separation
(different DBs, TTL policies), explicit refs still work.
h2. Scope
# Define {{KeyValueRepository}} interface in {{camel-api}}
# Create {{MemoryKeyValueRepository}} default in {{camel-support}}
# Create {{KeyValueIdempotentRepository}} adapter
# Create {{KeyValueAggregationRepository}} adapter
# Add auto-discovery to {{IdempotentConsumer}} and {{AggregateProcessor}}: if
no explicit repository configured, look up {{KeyValueRepository}} from registry
# Update {{StateStoreBackend}} (CAMEL-23239) to extend {{KeyValueRepository}}
# Unit tests for all adapters
# Documentation
h2. Related
* CAMEL-23239 - camel-state-store component (PR #22158)
* CAMEL-11114 - Cache EIP (follow-up, would add CacheRepository adapter)
* [Raymond's feedback on
CAMEL-23239|https://issues.apache.org/jira/browse/CAMEL-23239?focusedCommentId=18103595]
- unified SPI vision from a real-world user
--
This message was sent by Atlassian Jira
(v8.20.10#820010)