Camel Spring Boot

State Store

Perform key-value operations against a pluggable KeyValueRepository backend.

What’s inside

Please refer to the above links for usage and configuration details.

Maven coordinates

<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-state-store-starter</artifactId>
</dependency>

Usage

Choosing a backend

The State Store component supports Spring Cache and Camel KeyValueRepository backends.

Spring Cache

Set camel.state-store.spring-cache.enabled=true to register a StateStoreBackendFactory backed by Spring’s CacheManager. Each state-store name maps to a Spring cache with the same name, reusing the application’s spring.cache.* configuration.

The factory is registered when a single CacheManager candidate is available and no other StateStoreBackendFactory bean is defined. It does not register a global KeyValueRepository bean.

Camel KeyValueRepository

Alternatively, use a Camel KeyValueRepository implementation, such as camel-redis, camel-caffeine, camel-jcache, camel-sql, or camel-infinispan. Define the repository as a bean and leave camel.state-store.spring-cache.enabled disabled. The State Store component automatically discovers the repository.

These repositories can also be discovered by Camel features that support KeyValueRepository, including the Aggregate EIP, Idempotent Consumer, and Cache EIP.

Configuration examples

To use Spring Cache, configure a cache provider and enable the factory:

spring.cache.type=caffeine
spring.cache.cache-names=orders,users
camel.state-store.spring-cache.enabled=true

Spring Boot creates the CacheManager from spring.cache.* only when the application enables caching with @EnableCaching; otherwise, provide your own CacheManager bean. Without a single eligible CacheManager, the factory is not registered, and stores may fall back to the default in-memory repository. If spring.cache.cache-names specifies a fixed set of names, include every state-store name you use. A dynamic cache manager can create caches on demand.

To use a specific Camel repository, register it as a bean, for example under the name redisRepo, and select it on the endpoint:

from("direct:order")
    .setHeader("CamelStateStoreKey", simple("${header.orderId}"))
    .to("state-store:orders?backend=#redisRepo");

Using both backends

When the Spring Cache factory is enabled, it is the default backend for state-store endpoints unless an endpoint explicitly selects another backend or a component-level backend factory takes precedence.

You can therefore use Spring Cache for ordinary stores and explicitly select a Camel repository for stores that need its additional capabilities.

Limitations

Spring Cache

Spring Cache provides a common API, but some operations depend on the underlying cache provider.

  • Per-entry TTL: Spring Cache has no portable per-entry TTL API. A positive, non-zero TTL requested through the repository is not applied by the Spring adapter. Configure expiration using the underlying cache provider, for example with spring.cache.redis.time-to-live or a Caffeine specification.

  • Atomic operations: Spring Cache does not provide a portable atomic get-and-put operation. The adapter’s put and delete read the previous value and then write or evict separately, so the returned previous value is not atomic. putIfAbsent delegates to the provider’s Spring Cache implementation; its atomicity depends on that provider. Conditional replace and conditional delete may use non-atomic check-then-act operations.

  • Key enumeration and size: keys() and size() are supported only when Cache.getNativeCache() returns a ConcurrentMap, such as with the simple cache provider. They operate on a snapshot of current string keys. Other providers, including Caffeine, Redis, and JCache, do not support these operations through the Spring adapter.

Camel KeyValueRepository

Choose a Camel repository when you need capabilities beyond the portable Spring Cache API, such as per-entry TTL, atomic putIfAbsent or replace, conditional deletion, and key enumeration or size. Actual support and guarantees depend on the selected repository implementation.

Spring Boot Auto-Configuration

The starter supports 5 options, which are listed below.

Name Description Default Type

camel.component.state-store.autowired-enabled

Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which then gets configured on the component. This can be used for automatic configuring JDBC data sources, JMS connection factories, AWS Clients, etc.

true

Boolean

camel.component.state-store.backend-factory

Factory that creates a dedicated backend for each store name. When set, it takes precedence over registry auto-discovery for endpoints without an explicit backend. The option is a org.apache.camel.component.statestore.StateStoreBackendFactory type.

StateStoreBackendFactory

camel.component.state-store.enabled

Whether to enable auto configuration of the state-store component. This is enabled by default.

Boolean

camel.component.state-store.lazy-start-producer

Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel’s routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing.

false

Boolean

camel.state-store.spring-cache.enabled

Whether to register a StateStoreBackendFactory that creates a Spring Cache-backed KeyValueRepository for each state-store name. Disabled by default. Requires a single CacheManager bean and no user-defined StateStoreBackendFactory. Does not register a global KeyValueRepository.

false

Boolean