| = Ehcache Component | |
| :doctitle: Ehcache | |
| :shortname: ehcache | |
| :artifactid: camel-ehcache | |
| :description: Perform caching operations using Ehcache. | |
| :since: 2.18 | |
| :supportlevel: Stable | |
| :tabs-sync-option: | |
| :component-header: Both producer and consumer are supported | |
| *Since Camel {since}* | |
| *{component-header}* | |
| The Ehcache component enables you to perform caching operations using | |
| Ehcache 3 as the Cache Implementation. | |
| The Cache consumer is an event based consumer and can be used to listen | |
| and respond to specific cache activities. | |
| Maven users will need to add the following dependency to | |
| their `pom.xml` for this component: | |
| [source,xml] | |
| ---- | |
| <dependency> | |
| <groupId>org.apache.camel</groupId> | |
| <artifactId>camel-ehcache</artifactId> | |
| <version>x.x.x</version> | |
| <!-- use the same version as your Camel core version --> | |
| </dependency> | |
| ---- | |
| == URI format | |
| ---- | |
| ehcache://cacheName[?options] | |
| ---- | |
| // component options: START | |
| include::partial$component-configure-options.adoc[] | |
| include::partial$component-endpoint-options.adoc[] | |
| include::partial$component-endpoint-headers.adoc[] | |
| // component options: END | |
| == Examples | |
| === Using the cache in a route | |
| The producer runs the action of the `CamelEhcacheAction` header (or of the `action` option) with the key of the | |
| `CamelEhcacheKey` header. A PUT stores the message body. A GET sets the value as the message body, and the header | |
| `CamelEhcacheActionHasResult` tells whether the key was found: | |
| [source,yaml] | |
| ---- | |
| - route: | |
| from: | |
| uri: direct:save-order | |
| steps: | |
| - setHeader: | |
| name: CamelEhcacheAction | |
| expression: | |
| constant: | |
| expression: PUT | |
| - setHeader: | |
| name: CamelEhcacheKey | |
| expression: | |
| simple: | |
| expression: "${header.orderId}" | |
| - to: | |
| uri: ehcache:orders | |
| - route: | |
| from: | |
| uri: direct:find-order | |
| steps: | |
| - setHeader: | |
| name: CamelEhcacheAction | |
| expression: | |
| constant: | |
| expression: GET | |
| - setHeader: | |
| name: CamelEhcacheKey | |
| expression: | |
| simple: | |
| expression: "${header.orderId}" | |
| - to: | |
| uri: ehcache:orders | |
| - choice: | |
| when: | |
| - expression: | |
| simple: | |
| expression: "${header.CamelEhcacheActionHasResult}" | |
| steps: | |
| - log: | |
| message: "Order ${header.orderId} from the cache: ${body}" | |
| otherwise: | |
| steps: | |
| - log: | |
| message: "Order ${header.orderId} is not in the cache" | |
| ---- | |
| NOTE: Without a cache manager or a cache configuration, each endpoint creates its own cache. | |
| `ehcache:orders?action=PUT` and `ehcache:orders?action=GET` are then two different caches. | |
| Set the action in a header and use one endpoint, as above, or share a cache manager with `configurationUri`, | |
| `cacheManager` or `cacheManagerConfiguration`. | |
| The consumer receives cache events only when the cache comes from a configuration or a cache manager. | |
| The default cache of an endpoint has no events. In this example, both endpoints use the same `ehcache.xml`, | |
| so they share its cache manager: | |
| [source,yaml] | |
| ---- | |
| - route: | |
| from: | |
| uri: direct:save-order | |
| steps: | |
| - setHeader: | |
| name: CamelEhcacheKey | |
| expression: | |
| simple: | |
| expression: "${header.orderId}" | |
| - to: | |
| uri: ehcache:orders | |
| parameters: | |
| configurationUri: classpath:ehcache.xml | |
| action: PUT | |
| - route: | |
| from: | |
| uri: ehcache:orders | |
| parameters: | |
| configurationUri: classpath:ehcache.xml | |
| eventTypes: CREATED | |
| steps: | |
| - log: | |
| message: "New order ${header.CamelEhcacheKey}: ${body}" | |
| ---- | |
| The `ehcache.xml` file configures the cache: | |
| [source,xml] | |
| ---- | |
| <config xmlns="http://www.ehcache.org/v3"> | |
| <cache alias="orders"> | |
| <heap unit="entries">1000</heap> | |
| </cache> | |
| </config> | |
| ---- | |
| === Ehcache based idempotent repository example: | |
| ._Java-only: programmatic CacheManager and idempotent repository configuration_ | |
| [source,java] | |
| ---- | |
| CacheManager manager = CacheManagerBuilder.newCacheManager(new XmlConfiguration("ehcache.xml")); | |
| EhcacheIdempotentRepository repo = new EhcacheIdempotentRepository(manager, "idempotent-cache"); | |
| from("direct:in") | |
| .idempotentConsumer(header("messageId"), repo) | |
| .to("mock:out"); | |
| ---- | |
| === Ehcache based aggregation repository example: | |
| ._Java-only: full test class with aggregation repository configuration_ | |
| [source,java] | |
| ---- | |
| public class EhcacheAggregationRepositoryRoutesTest extends CamelTestSupport { | |
| private static final String ENDPOINT_MOCK = "mock:result"; | |
| private static final String ENDPOINT_DIRECT = "direct:one"; | |
| private static final int[] VALUES = generateRandomArrayOfInt(10, 0, 30); | |
| private static final int SUM = IntStream.of(VALUES).reduce(0, (a, b) -> a + b); | |
| private static final String CORRELATOR = "CORRELATOR"; | |
| @EndpointInject(ENDPOINT_MOCK) | |
| private MockEndpoint mock; | |
| @Produce(uri = ENDPOINT_DIRECT) | |
| private ProducerTemplate producer; | |
| @Test | |
| public void checkAggregationFromOneRoute() throws Exception { | |
| mock.expectedMessageCount(VALUES.length); | |
| mock.expectedBodiesReceived(SUM); | |
| IntStream.of(VALUES).forEach( | |
| i -> producer.sendBodyAndHeader(i, CORRELATOR, CORRELATOR) | |
| ); | |
| mock.assertIsSatisfied(); | |
| } | |
| private Exchange aggregate(Exchange oldExchange, Exchange newExchange) { | |
| if (oldExchange == null) { | |
| return newExchange; | |
| } else { | |
| Integer n = newExchange.getIn().getBody(Integer.class); | |
| Integer o = oldExchange.getIn().getBody(Integer.class); | |
| Integer v = (o == null ? 0 : o) + (n == null ? 0 : n); | |
| oldExchange.getIn().setBody(v, Integer.class); | |
| return oldExchange; | |
| } | |
| } | |
| @Override | |
| protected RoutesBuilder createRouteBuilder() throws Exception { | |
| return new RouteBuilder() { | |
| @Override | |
| public void configure() throws Exception { | |
| from(ENDPOINT_DIRECT) | |
| .routeId("AggregatingRouteOne") | |
| .aggregate(header(CORRELATOR)) | |
| .aggregationRepository(createAggregateRepository()) | |
| .aggregationStrategy(EhcacheAggregationRepositoryRoutesTest.this::aggregate) | |
| .completionSize(VALUES.length) | |
| .to("log:org.apache.camel.component.ehcache.processor.aggregate.level=INFO&showAll=true&mulltiline=true") | |
| .to(ENDPOINT_MOCK); | |
| } | |
| }; | |
| } | |
| protected EhcacheAggregationRepository createAggregateRepository() throws Exception { | |
| CacheManager cacheManager = CacheManagerBuilder.newCacheManager(new XmlConfiguration("ehcache.xml")); | |
| cacheManager.init(); | |
| EhcacheAggregationRepository repository = new EhcacheAggregationRepository(); | |
| repository.setCacheManager(cacheManager); | |
| repository.setCacheName("aggregate"); | |
| return repository; | |
| } | |
| } | |
| ---- |