http://camel.apache.org/direct.html
Direct Component
The direct: component provides direct, synchronous invocation of any consumers when a producer sends a message exchange.
This endpoint can be used to connect existing routes in the same camel context.
Asynchronous The SEDA component provides asynchronous invocation of any consumers when a producer sends a message exchange. |
Connection to other camel contexts The VM component provides connections between Camel contexts as long they run in the sameJVM. |
URI format
direct:someName[?options]
Where someName can be any string to uniquely identify the endpoint
Options
Name | Default Value | Description |
allowMultipleConsumers | true | @deprecated If set to false, then when a second consumer is started on the endpoint, anIllegalStateException is thrown. Will be removed in Camel 2.1: Direct endpoint does not support multiple consumers. |
You can append query options to the URI in the following format, ?option=value&option=value&...
Samples
In the route below we use the direct component to link the two routes together:
from("activemq:queue:order.in")
.to("bean:orderServer?method=validate")
.to("direct:processOrder");
from("direct:processOrder")
.to("bean:orderService?method=process")
.to("activemq:queue:order.out");
And the sample using spring DSL:
<route>
<from uri="activemq:queue:order.in"/>
<to uri="bean:orderService?method=validate"/>
<to uri="direct:processOrder"/>
</route>
<route>
<from uri="direct:processOrder"/>
<to uri="bean:orderService?method=process"/>
<to uri="activemq:queue:order.out"/>
</route>
See also samples from the SEDA component, how they can be used together.
Note:direct procuder(<to:/>) will use direct consumer<from:/>) 's processor to process its exchange.
===========
http://camel.apache.org/seda.html
SEDA Component
The seda: component provides asynchronous SEDA behavior, so that messages are exchanged on a BlockingQueue and consumers are invoked in a separate thread from the producer.
Note that queues are only visible within a single CamelContext. If you want to communicate across CamelContext instances (for example, communicating between Web applications), see theVM component.
This component does not implement any kind of persistence or recovery, if the VM terminates while messages are yet to be processed. If you need persistence, reliability or distributed SEDA, try using eitherJMS or ActiveMQ.
Synchronous The Direct component provides synchronous invocation of any consumers when a producer sends a message exchange. |
URI format
seda:someName[?options]
Where someName can be any string that uniquely identifies the endpoint within the currentCamelContext.
You can append query options to the URI in the following format: ?option=value&option=value&…
Options
Name | Since | Default | Description |
size | | | The maximum capacity of the SEDA queue (i.e., the number of messages it can hold). The default value in Camel 2.2 or older is1000. From Camel 2.3 onwards, the size is unbounded by default. |
concurrentConsumers | | 1 | Number of concurrent threads processing exchanges. |
waitForTaskToComplete | | IfReplyExpected | Option to specify whether the caller should wait for the async task to complete or not before continuing. The following three options are supported:Always, Never or IfReplyExpected. The first two values are self-explanatory. The last value,IfReplyExpected, will only wait if the message is Request Reply based. The default option is IfReplyExpected. See more information aboutAsync messaging. |
timeout | | 30000 | Timeout (in milliseconds) before a SEDA producer will stop waiting for an asynchronous task to complete. SeewaitForTaskToComplete and Async for more details. In Camel 2.2 you can now disable timeout by using 0 or a negative value. |
multipleConsumers | 2.2 | false | Specifies whether multiple consumers are allowed. If enabled, you can useSEDA forPublish-Subscribe messaging. That is, you can send a message to the SEDA queue and have each consumer receive a copy of the message. When enabled, this option should be specified on every consumer endpoint. |
limitConcurrentConsumers | 2.3 | true | Whether to limit the number of concurrentConsumers to the maximum of500. By default, an exception will be thrown if a SEDA endpoint is configured with a greater number. You can disable that check by turning this option off. |
blockWhenFull | 2.9 | false | Whether a thread that sends messages to a full SEDA queue will block until the queue's capacity is no longer exhausted. By default, an exception will be thrown stating that the queue is full. By enabling this option, the calling thread will instead block and wait until the message can be accepted. |
queueSize | 2.9 | | Component only: The maximum default size (capacity of the number of messages it can hold) of the SEDA queue. This option is used ifsize |
pollTimeout | 2.9.3 | 1000 | Consumer only – The timeout used when polling. When a timeout occurs, the consumer can check whether it is allowed to continue running. Setting a lower value allows the consumer to react more quickly upon shutdown. |
Use of Request Reply
The SEDA component supports usingRequest Reply, where the caller will wait for the Async route to complete. For instance:
from("mina:tcp://0.0.0.0:9876?textline=true&sync=true").to("seda:input");
from("seda:input").to("bean:processInput").to("bean:createResponse");
In the route above, we have a TCP listener on port 9876 that accepts incoming requests. The request is routed to theseda:input queue. As it is a Request Reply message, we wait for the response. When the consumer on the seda:input
until 2.2: Works only with 2 endpoints Using Request Reply over SEDA or VM only works with 2 endpoints. Youcannot chain endpoints by sending to A -> B -> C etc. Only between A -> B. The reason is the implementation logic is fairly simple. To support 3+ endpoints makes the logic much more complex to handle ordering and notification between the waiting threads properly. This has been improved in Camel 2.3 onwards, which allows you to chain as many endpoints as you like. |
Concurrent consumers
By default, the SEDA endpoint uses a single consumer thread, but you can configure it to use concurrent consumer threads. So instead of thread pools you can use:
from("seda:stageName?concurrentConsumers=5").process(...)
As for the difference between the two, note a thread pool can increase/shrink dynamically at runtime depending on load, whereas the number of concurrent consumers is always fixed.
Thread pools
Be aware that adding a thread pool to a SEDA endpoint by doing something like:
from("seda:stageName").thread(5).process(...)
Can wind up with two BlockQueues: one from the SEDA endpoint, and one from the workqueue of the thread pool, which may not be what you want. Instead, you might wish to configure aDirect endpoint with a thread pool, which can process messages both synchronously and asynchronously. For example:
from("direct:stageName").thread(5).process(...)
You can also directly configure number of threads that process messages on a SEDA endpoint using theconcurrentConsumers
Sample
In the route below we use the SEDA queue to send the request to this async queue to be able to send a fire-and-forget message for further processing in another thread, and return a constant reply in this thread to the original caller.
public void configure() throws Exception {
from("direct:start")
// send it to the seda queue that is async
.to("seda:next")
// return a constant response
.transform(constant("OK"));
from("seda:next").to("mock:result");
}
Here we send a Hello World message and expects the reply to be OK.
Object out = template.requestBody("direct:start", "Hello World");
assertEquals("OK", out);
The "Hello World" message will be consumed from the SEDA queue from another thread for further processing. Since this is from a unit test, it will be sent to amock
Using multipleConsumers
Available as of Camel 2.2
In this example we have defined two consumers and registered them as spring beans.
<!-- define the consumers as spring beans -->
<bean id="consumer1" class="org.apache.camel.spring.example.FooEventConsumer"/>
<bean id="consumer2" class="org.apache.camel.spring.example.AnotherFooEventConsumer"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<!-- define a shared endpoint which the consumers can refer to instead of using url -->
<endpoint id="foo" uri="seda:foo?multipleConsumers=true"/>
</camelContext>
Since we have specified multipleConsumers=true on the seda foo endpoint we can have those two consumers receive their own copy of the message as a kind of pub-sub style messaging.
As the beans are part of an unit test they simply send the message to a mock endpoint, but notice how we can use @Consume to consume from the seda queue.
public class FooEventConsumer {
@EndpointInject(uri = "mock:result")
private ProducerTemplate destination;
@Consume(ref = "foo")
public void doSomething(String body) {
destination.sendBody("foo" + body);
}
}
Extracting queue information.
If needed, information such as queue size, etc. can be obtained without using JMX in this fashion:
SedaEndpoint seda = context.getEndpoint("seda:xxxx");int
Note:seda producer will add exchanges to queue, then seda consumer will retrieve exchange then process.
===========
http://camel.apache.org/vm.html
VM Component
The vm: component provides asynchronous SEDA behavior, exchanging messages on a BlockingQueue and invoking consumers in a separate thread pool.
This component differs from the SEDA component in that VM supports communication across CamelContext instances - so you can use this mechanism to communicate across web applications (provided thatcamel-core.jar is on the system/boot
VM is an extension to the SEDA component.
URI format
vm:queueName[?options]
Where queueName can be any string to uniquely identify the endpoint within the JVM (or at least within the classloader that loaded camel-core.jar)
You can append query options to the URI in the following format: ?option=value&option=value&...
Before Camel 2.3 - Same URI must be used for both producer and consumer An exactly identical VM endpoint URI must be used for both the producer and the consumer endpoint. Otherwise, Camel will create a secondVM endpoint despite that thequeueName portion of the URI is identical. For example:
Notice that we have to use the full URI, including options in both the producer and consumer. In Camel 2.4 this has been fixed so that only the queue name must match. Using the queue namebar, we could rewrite the previous exmple as follows:
|
Options
See the SEDA component for options and other important usage details as the same rules apply to theVM component.
Samples
In the route below we send exchanges across CamelContext instances to a VM queue namedorder.email:
from("direct:in").bean(MyOrderBean.class).to("vm:order.email");
And then we receive exchanges in some other Camel context (such as deployed in another.war
from("vm:order.email").bean(MyOrderEmailSender.class);
Note:seda component's queues is not static, it's instance queues, so each camel context will differ, vm component's queues is static, so every seda component's instance will have same queues.
===============
http://camel.apache.org/timer.html
Timer Component
The timer: component is used to generate message exchanges when a timer fires You can only consume events from this endpoint.
URI format
timer:name[?options]
Where name is the name of the Timer object, which is created and shared across endpoints. So if you use the same name for all your timer endpoints, only one Timer
You can append query options to the URI in the following format, ?option=value&option=value&...
Note: The IN body of the generated exchange is null. So exchange.getIn().getBody() returns null.
Advanced Scheduler See also the Quartz component that supports much more advanced scheduling. |
Specify time in human friendly format In Camel 2.3 onwards you can specify the time in human friendly syntax. |
Options
Name | Default Value | Description |
time | null | A java.util.Date the first event should be generated. If using the URI, the pattern expected is: yyyy-MM-dd HH:mm:ss or yyyy-MM-dd'T'HH:mm:ss. |
pattern | null | Allows you to specify a custom Date |
period | 1000 | If greater than 0, generate periodic events every period |
delay | 0 / 1000 | The number of milliseconds to wait before the first event is generated. Should not be used in conjunction with the time option. The default value has been changed to 1000 from Camel 2.11 onwards. In older releases the default value is 0. |
fixedRate | false | Events take place at approximately regular intervals, separated by the specified period. |
daemon | true | Specifies whether or not the thread associated with the timer endpoint runs as a daemon. |
repeatCount | 0 | Camel 2.8: Specifies a maximum limit of number of fires. So if you set it to 1, the timer will only fire once. If you set it to 5, it will only fire five times. A value of zero or negative means fire forever. |
Exchange Properties
When the timer is fired, it adds the following information as properties to the Exchange:
Name | Type | Description |
Exchange.TIMER_NAME | String | The value of the name |
Exchange.TIMER_TIME | Date | The value of the time |
Exchange.TIMER_PERIOD | long | The value of the period |
Exchange.TIMER_FIRED_TIME | Date | The time when the consumer fired. |
Exchange.TIMER_COUNTER | Long | Camel 2.8: The current fire counter. Starts from 1. |
Message Headers
When the timer is fired, it adds the following information as headers to the IN message
Name | Type | Description |
Exchange.TIMER_FIRED_TIME | java.util.Date | The time when the consumer fired |
Sample
To set up a route that generates an event every 60 seconds:
from("timer://foo?fixedRate=true&period=60000").to("bean:myBean?method=someMethodName");
Instead of 60000 you can use period=60s which is more friendly to read. |
The above route will generate an event and then invoke the someMethodName method on the bean called myBean in the Registry such as JNDI or Spring.
And the route in Spring DSL:
<route>
<from uri="timer://foo?fixedRate=true&period=60000"/>
<to uri="bean:myBean?method=someMethodName"/>
</route>
Firing only once
Available as of Camel 2.8
You may want to fire a message in a Camel route only once, such as when starting the route. To do that you use the repeatCount option as shown:
<route> "timer://foo?repeatCount=1"/> "bean:myBean?method=someMethodName"/> </route>
==========
Log Component
The log: component logs message exchanges to the underlying logging mechanism.
Camel 2.7 or better uses sfl4j which allows you to configure logging via, among others:
Camel 2.6 or lower uses commons-logging which allows you to configure logging via, among others:
- Log4j
- JDK Util Logging logging
- SimpleLog - a simple provider in commons-logging
Refer to the commons-logging user guide for a more complete overview of how to use and configure commons-logging.
URI format
log:loggingCategory[?options]
Where loggingCategory is the name of the logging category to use. You can append query options to the URI in the following format, ?option=value&option=value&...
For example, a log endpoint typically specifies the logging level using the level
log:org.apache.camel.example?level=DEBUG
The default logger logs every exchange (regular logging). But Camel also ships with the Throughput logger, which is used whenever the groupSize
Also a log in the DSL In Camel 2.2 onwards there is a log directly in the DSL, but it has a different purpose. Its meant for lightweight and human logs. See more details at LogEIP. |
Options
Option | Default | Type | Description |
level | INFO | String | Logging level to use. Possible values: ERROR, WARN, INFO, DEBUG, TRACE, OFF |
marker | null | String | Camel 2.9: An optional Marker name to use. |
groupSize | null | Integer | An integer that specifies a group size for throughput logging. |
groupInterval | null | Integer | Camel 2.6: If specified will group message stats by this time interval (in millis) |
groupDelay | 0 | Integer | Camel 2.6: Set the initial delay for stats (in millis) |
groupActiveOnly | true | boolean | Camel 2.6: If true, will hide stats when no new messages have been received for a time interval, if false, show stats regardless of message traffic |
note: groupDelay and groupActiveOnly are only applicable when using groupInterval
Formatting
The log formats the execution of exchanges to log lines.
By default, the log uses LogFormatter to format the log output, where LogFormatter
Option | Default | Description |
showAll | false | Quick option for turning all options on. (multiline, maxChars has to be manually set if to be used) |
showExchangeId | false | Show the unique exchange ID. |
showExchangePattern | true | Camel 2.3: Shows the Message Exchange Pattern (or MEP for short). |
showProperties | false | Show the exchange properties. |
showHeaders | false | Show the In message headers. |
showBodyType | true | Show the In body Java type. |
showBody | true | Show the In body. |
showOut | false | If the exchange has an Out message, show the Out message. |
showException | false | If the exchange has an exception, show the exception message (no stack trace). |
showCaughtException | false | If the exchange has a caught exception, show the exception message (no stack trace). A caught exception is stored as a property on the exchange (using the key Exchange.EXCEPTION_CAUGHT) and for instance a doCatch can catch exceptions. See Try Catch Finally. |
showStackTrace | false | Show the stack trace, if an exchange has an exception. Only effective if one of showAll, showException or showCaughtException |
showFiles | false | Camel 2.9: Whether Camel should show file bodies or not (eg such as java.io.File). |
showFuture | false | Camel 2.1: Whether Camel should show java.util.concurrent.Future bodies or not. If enabled Camel could potentially wait until the Future |
showStreams | false | Camel 2.8: Whether Camel should show stream bodies or not (eg such as java.io.InputStream). Beware if you enable this option then you may not be able later to access the message body as the stream have already been read by this logger. To remedy this you will have to use Stream caching. |
multiline | false | If true, each piece of information is logged on a new line. |
maxChars | | Limits the number of characters logged per line. The default value is 10000 from Camel 2.9 onwards. |
Logging stream bodies For older versions of Camel that do not support the showFiles or showStreams properties above, you can set the following property instead on the CamelContext to log both stream and file bodies:
|
Regular logger sample
In the route below we log the incoming orders at DEBUG
from("activemq:orders").to("log:com.mycompany.order?level=DEBUG").to("bean:processOrder");
Or using Spring XML to define the route:
<route>
<from uri="activemq:orders"/>
<to uri="log:com.mycompany.order?level=DEBUG"/>
<to uri="bean:processOrder"/>
</route>
Regular logger with formatter sample
In the route below we log the incoming orders at INFO
from("activemq:orders").
to("log:com.mycompany.order?showAll=true&multiline=true").to("bean:processOrder");
Throughput logger with groupSize sample
In the route below we log the throughput of the incoming orders at DEBUG
from("activemq:orders").
to("log:com.mycompany.order?level=DEBUG&groupSize=10").to("bean:processOrder");
Throughput logger with groupInterval sample
This route will result in message stats logged every 10s, with an initial 60s delay and stats should be displayed even if there isn't any message traffic.
from("activemq:orders").
to("log:com.mycompany.order?level=DEBUG&groupInterval=10000&groupDelay=60000&groupActiveOnly=false").to("bean:processOrder");
The following will be logged:
"Received: 1000 new messages, with total 2000 so far. Last group took: 10000 millis which is: 100 messages per second. average: 100"
===================
Cache Component
Available as of Camel 2.1
The cache component enables you to perform caching operations using EHCache as the Cache Implementation. The cache itself is created on demand or if a cache of that name already exists then it is simply utilized with its original settings.
This component supports producer and event based consumer endpoints.
The Cache consumer is an event based consumer and can be used to listen and respond to specific cache activities. If you need to perform selections from a pre-existing cache, use the processors defined for the cache component.
Maven users will need to add the following dependency to their pom.xml
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cache</artifactId>
<version>x.x.x</version>
<!-- use the same version as your Camel core version -->
</dependency>
URI format
cache://cacheName[?options]
You can append query options to the URI in the following format, ?option=value&option=#beanRef&...
Options
Name | Default Value | Description |
maxElementsInMemory | 1000 | The number of elements that may be stored in the defined cache |
memoryStoreEvictionPolicy | MemoryStoreEvictionPolicy.LFU | The number of elements that may be stored in the defined cache. Options include
|
overflowToDisk | true | Specifies whether cache may overflow to disk |
eternal | false | Sets whether elements are eternal. If eternal, timeouts are ignored and the element never expires. |
timeToLiveSeconds | 300 | The maximum time between creation time and when an element expires. Is used only if the element is not eternal |
timeToIdleSeconds | 300 | The maximum amount of time between accesses before an element expires |
diskPersistent | false | Whether the disk store persists between restarts of the Virtual Machine. |
diskExpiryThreadIntervalSeconds | 120 | The number of seconds between runs of the disk expiry thread. |
cacheManagerFactory | null | Camel 2.8: If you want to use a custom factory which instantiates and creates the EHCache net.sf.ehcache.CacheManager. Type: abstract org.apache.camel.component.cache.CacheManagerFactory |
eventListenerRegistry | null | Camel 2.8: Sets a list of EHCache net.sf.ehcache.event.CacheEventListener for all new caches- no need to define it per cache in EHCache xml config anymore. Type: org.apache.camel.component.cache.CacheEventListenerRegistry |
cacheLoaderRegistry | null | Camel 2.8: Sets a list of org.apache.camel.component.cache.CacheLoaderWrapper that extends EHCache net.sf.ehcache.loader.CacheLoader for all new caches- no need to define it per cache in EHCache xml config anymore. Type: org.apache.camel.component.cache.CacheLoaderRegistry |
key | null | Camel 2.10: To configure using a cache key by default. If a key is provided in the message header, then the key from the header takes precedence. |
operation | null | Camel 2.10: To configure using an cache operation by default. If an operation in the message header, then the operation from the header takes precedence. |
Sending/Receiving Messages to/from the cache
Message Headers up to Camel 2.7
Header | Description |
CACHE_OPERATION | The operation to be performed on the cache. Valid options are
|
CACHE_KEY | The cache key used to store the Message in the cache. The cache key is optional if the CACHE_OPERATION is DELETEALL |
Message Headers Camel 2.8+
Header changes in Camel 2.8 The header names and supported values have changed to be prefixed with 'CamelCache' and use mixed case. This makes them easier to identify and keep separate from other headers. The CacheConstants variable names remain unchanged, just their values have been changed. Also, these headers are now removed from the exchange after the cache operation is performed. |
Header | Description |
CamelCacheOperation | The operation to be performed on the cache. The valid options are
|
CamelCacheKey | The cache key used to store the Message in the cache. The cache key is optional if the CamelCacheOperation is CamelCacheDeleteAll |
The CamelCacheAdd and CamelCacheUpdate
Header | Type | Description |
CamelCacheTimeToLive | Integer | Camel 2.11: Time to live in seconds. |
CamelCacheTimeToIdle | Integer | Camel 2.11: Time to idle in seconds. |
CamelCacheEternal | Boolean | Camel 2.11: Whether the content is eternal. |
Cache Producer
Sending data to the cache involves the ability to direct payloads in exchanges to be stored in a pre-existing or created-on-demand cache. The mechanics of doing this involve
- setting the Message Exchange Headers shown above.
- ensuring that the Message Exchange Body contains the message directed to the cache
Cache Consumer
Receiving data from the cache involves the ability of the CacheConsumer to listen on a pre-existing or created-on-demand Cache using an event Listener and receive automatic notifications when any cache activity take place (i.e CamelCacheGet/CamelCacheUpdate/CamelCacheDelete/CamelCacheDeleteAll). Upon such an activity taking place
- an exchange containing Message Exchange Headers and a Message Exchange Body containing the just added/updated payload is placed and sent.
- in case of a CamelCacheDeleteAll operation, the Message Exchange Header CamelCacheKey and the Message Exchange Body are not populated.
Cache Processors
There are a set of nice processors with the ability to perform cache lookups and selectively replace payload content at the
- body
- token
- xpath level
Cache Usage Samples
Example 1: Configuring the cache
from("cache://MyApplicationCache" +
"?maxElementsInMemory=1000" +
"&memoryStoreEvictionPolicy=" +
"MemoryStoreEvictionPolicy.LFU" +
"&overflowToDisk=true" +
"&eternal=true" +
"&timeToLiveSeconds=300" +
"&timeToIdleSeconds=true" +
"&diskPersistent=true" +
"&diskExpiryThreadIntervalSeconds=300")
Example 2: Adding keys to the cache
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("direct:start")
.setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD))
.setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson"))
.to("cache://TestCache1")
}
};
Example 2: Updating existing keys in a cache
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("direct:start")
.setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_UPDATE))
.setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson"))
.to("cache://TestCache1")
}
};
Example 3: Deleting existing keys in a cache
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("direct:start")
.setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_DELETE))
.setHeader(CacheConstants.CACHE_KEY", constant("Ralph_Waldo_Emerson"))
.to("cache://TestCache1")
}
};
Example 4: Deleting all existing keys in a cache
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("direct:start")
.setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_DELETEALL))
.to("cache://TestCache1");
}
};
Example 5: Notifying any changes registering in a Cache to Processors and other Producers
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("cache://TestCache1")
.process(new Processor() {
public void process(Exchange exchange)
throws Exception {
String operation = (String) exchange.getIn().getHeader(CacheConstants.CACHE_OPERATION);
String key = (String) exchange.getIn().getHeader(CacheConstants.CACHE_KEY);
Object body = exchange.getIn().getBody();
// Do something
}
})
}
};
Example 6: Using Processors to selectively replace payload with cache values
RouteBuilder builder = new RouteBuilder() {
public void configure() {
//Message Body Replacer
from("cache://TestCache1")
.filter(header(CacheConstants.CACHE_KEY).isEqualTo("greeting"))
.process(new CacheBasedMessageBodyReplacer("cache://TestCache1","farewell"))
.to("direct:next");
//Message Token replacer
from("cache://TestCache1")
.filter(header(CacheConstants.CACHE_KEY).isEqualTo("quote"))
.process(new CacheBasedTokenReplacer("cache://TestCache1","novel","#novel#"))
.process(new CacheBasedTokenReplacer("cache://TestCache1","author","#author#"))
.process(new CacheBasedTokenReplacer("cache://TestCache1","number","#number#"))
.to("direct:next");
//Message XPath replacer
from("cache://TestCache1").
.filter(header(CacheConstants.CACHE_KEY).isEqualTo("XML_FRAGMENT"))
.process(new CacheBasedXPathReplacer("cache://TestCache1","book1","/books/book1"))
.process (new CacheBasedXPathReplacer("cache://TestCache1","book2","/books/book2"))
.to("direct:next");
}
};
Example 7: Getting an entry from the Cache
from("direct:start")
// Prepare headers
.setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_GET))
.setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")).
.to("cache://TestCache1").
// Check if entry was not found
.choice().when(header(CacheConstants.CACHE_ELEMENT_WAS_FOUND).isNull()).
// If not found, get the payload and put it to cache
.to("cxf:bean:someHeavyweightOperation").
.setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD))
.setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson"))
.to("cache://TestCache1")
.end()
.to("direct:nextPhase");
Example 8: Checking for an entry in the Cache
Note: The CHECK command tests existence of an entry in the cache but doesn't place a message in the body.
from("direct:start")
// Prepare headers
.setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_CHECK))
.setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")).
.to("cache://TestCache1").
// Check if entry was not found
.choice().when(header(CacheConstants.CACHE_ELEMENT_WAS_FOUND).isNull()).
// If not found, get the payload and put it to cache
.to("cxf:bean:someHeavyweightOperation").
.setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD))
.setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson"))
.to("cache://TestCache1")
.end();
Management of EHCache
EHCache has its own statistics and management from JMX.
Here's a snippet on how to expose them via JMX in a Spring application context:
<bean id="ehCacheManagementService" class="net.sf.ehcache.management.ManagementService" init-method="init" lazy-init="false">
<constructor-arg>
<bean class="net.sf.ehcache.CacheManager" factory-method="getInstance"/>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.jmx.support.JmxUtils" factory-method="locateMBeanServer"/>
</constructor-arg>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
</bean>
Of course you can do the same thing in straight Java:
ManagementService.registerMBeans(CacheManager.getInstance(), mbeanServer, true, true, true, true);
You can get cache hits, misses, in-memory hits, disk hits, size stats this way. You can also change CacheConfiguration parameters on the fly.
Cache replication Camel 2.8+
The Camel Cache component is able to distribute a cache across server nodes using several different replication mechanisms including: RMI, JGroups, JMS and Cache Server.
There are two different ways to make it work:
1. You can configure ehcache.xml
OR
2. You can configure these three options:
- cacheManagerFactory
- eventListenerRegistry
- cacheLoaderRegistry
Configuring Camel Cache replication using the first option is a bit of hard work as you have to configure all caches separately. So in a situation when the all names of caches are not known, using ehcache.xml
The second option is much better when you want to use many different caches as you do not need to define options per cache. This is because replication options are set per CacheManager and per CacheEndpoint. Also it is the only way when cache names are not know at the development phase.
It might be useful to read the EHCache manual to get a better understanding of the Camel Cache replication mechanism. |
Example: JMS cache replication
JMS replication is the most powerful and secured replication method. Used together with Camel Cache replication makes it also rather simple.
An example is available on a separate page.
标签:Cache,Log,Camel,component,cache,Component,CacheConstants,message,CACHE From: https://blog.51cto.com/u_16174476/7779522