[ 
https://issues.apache.org/jira/browse/CAMEL-24757?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18115566#comment-18115566
 ] 

Federico Mariani commented on CAMEL-24757:
------------------------------------------

Hi [~gnodet] do you think this is worth implementing in camel spring boot? it 
is an integration of the camel state store, with the spring cache APIs

> camel-spring-boot: Spring Cache-backed KeyValueRepository adapter for the 
> State Store component
> -----------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24757
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24757
>             Project: Camel
>          Issue Type: New Feature
>          Components: camel-spring-boot
>            Reporter: Federico Mariani
>            Priority: Major
>
> h2. Background
> The State Store component (camel-state-store, since 4.23) provides a unified 
> key-value API (put/get/putIfAbsent/delete/contains/keys/size/clear) backed by 
> the pluggable {{KeyValueRepository}} SPI from camel-api. When no backend bean 
> is configured, it falls back to the in-memory {{MemoryKeyValueRepository}}; 
> for anything persistent/distributed, camel-api already ships implementations 
> for Caffeine, Cassandra, Ehcache, Hazelcast, Infinispan, JCache, JDBC, JPA, 
> Kafka and Redis.
> h2. Problem
> Those implementations don't line up with what Spring Boot users already have 
> auto-configured:
> * {{RedisKeyValueRepository}} (camel-redis) is built on *Redisson* 
> ({{RedissonClient}}), not Spring Data Redis (Lettuce/{{RedisTemplate}}), 
> which is what {{spring-boot-starter-data-redis}} actually auto-configures. A 
> Spring Boot user has to add Redisson separately and hand-wire a 
> {{RedissonClient}} bean just to get a {{KeyValueRepository}}.
> * The same friction applies to Caffeine/Ehcache/Hazelcast: Camel's 
> implementations expect Camel-flavored construction, not the {{CacheManager}} 
> bean that {{spring-boot-starter-cache}} already auto-configures from 
> {{spring.cache.type}}.
> So in a Spring Boot application, using the State Store component with a real 
> backend currently means adding a second, Camel-specific client/dependency and 
> manually wiring a bean, even when Spring Boot already manages an equivalent 
> cache/client for you.
> h2. Proposal
> Add a {{KeyValueRepository}} implementation in *camel-spring-boot* (core 
> auto-configuration module, not the generated starter) backed by Spring's 
> cache abstraction ({{org.springframework.cache.Cache}} / {{CacheManager}}). 
> Auto-configure it with {{@ConditionalOnBean(CacheManager.class)}} and 
> {{@ConditionalOnMissingBean(KeyValueRepository.class)}}, so it only kicks in 
> when the application already has a Spring-managed {{CacheManager}} and no 
> explicit Camel {{KeyValueRepository}} bean.
> One adapter then covers every backend Spring Boot's cache abstraction already 
> supports (Caffeine, Redis via Lettuce, Ehcache, Hazelcast, JCache, Couchbase, 
> etc.) via the standard {{spring.cache.*}} properties, with no extra 
> Camel-specific dependency or bean.
> The State Store endpoint's {{storeName}} would map 1:1 to the Spring 
> {{Cache}} name looked up via {{CacheManager.getCache(storeName)}}.
> h2. Example usage
> Caffeine, using only spring-boot-starter-cache (no camel-caffeine dependency 
> needed):
> {code:yaml}
> spring:
>   cache:
>     type: caffeine
>     cache-names: myStore
>     caffeine:
>       spec: maximumSize=10000,expireAfterWrite=600s
> {code}
> {code:java}
> from("direct:store")
>     .setHeader("CamelStateStoreKey", constant("myKey"))
>     .to("state-store:myStore?operation=put");
> from("direct:retrieve")
>     .setHeader("CamelStateStoreKey", constant("myKey"))
>     .to("state-store:myStore?operation=get");
> {code}
> Redis via Spring Data Redis/Lettuce (no camel-redis/Redisson dependency 
> needed):
> {code:yaml}
> spring:
>   cache:
>     type: redis
>     cache-names: myStore
>   data:
>     redis:
>       host: localhost
>       port: 6379
> {code}
> Same route code as above - only the Spring Boot configuration changes to 
> switch backend.
> h2. Limitations
> * *No {{keys()}} support* - Spring's {{Cache}} SPI has no portable key 
> enumeration across backends, so the adapter would throw 
> {{UnsupportedOperationException}} for the {{keys}} operation.
> * *No {{size()}} support* - same reason as above; {{size}} would also throw 
> {{UnsupportedOperationException}}.
> * *No per-entry TTL* - Spring's {{Cache.put}} has no TTL parameter; TTL is 
> fixed per cache/CacheManager configuration (e.g. the Caffeine spec or Redis 
> entry-ttl config), not per message. The State Store {{ttl}} endpoint option 
> and {{CamelStateStoreTtl}} header would have no effect against this backend; 
> the adapter should log a WARN if a TTL is supplied so the mismatch isn't 
> silent.
> * *Spring Boot only* - this lives in camel-spring-boot, not camel-api/core, 
> so it is not available to other runtimes (Quarkus, camel-main, etc.); those 
> keep using the existing backend-specific KeyValueRepository implementations.
> * *Cache pre-declaration* - some {{CacheManager}} implementations require 
> cache names to be pre-declared (e.g. via {{spring.cache.cache-names}}); a 
> {{storeName}} without a matching configured cache would fail to resolve, 
> unlike the always-available in-memory default.
> _Claude Code on behalf of Federico Mariani_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to