[
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)