package camelinaction; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.hazelcast.HazelcastConstants; /** * Route used by both foo and bar server. * <p/> * This route will expose a HTTP server on localhost port 8080 or 9090 and then update a counter value * on the clustered hazelcast data-grid. The HTTP server returns the current counter value. * <p/> * The use-case for atomic counter is better implemented as in {@link AtomicCounterRoute} because this * implementation is not thread-safe as the foo server may read a value as 16 and then update the value to 17 * and at the same time the bar server also reads the value as 16 and therefore you can end up with "lost updates". * The map is better for storing other kind of shared data in the cluster. */ public class CounterRoute extends RouteBuilder { private String name; private int port; public CounterRoute(String name, int port) { this.name = name; this.port = port; } @Override public void configure() throws Exception { // HTTP service fromF("jetty:http://localhost:" + port) // get the counter from the hazelcast cache .setHeader(HazelcastConstants.OBJECT_ID, constant("myCounter")) .to("hazelcast:map:myCache?hazelcastInstance=#hz&defaultOperation=get") // update the counter using java code .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { Integer counter = exchange.getIn().getBody(Integer.class); if (counter == null) { counter = 0; } counter++; exchange.getIn().setBody(counter); } }) // update the counter in the hazelcast cache .setHeader(HazelcastConstants.OBJECT_ID, constant("myCounter")) .to("hazelcast:map:myCache?hazelcastInstance=#hz&defaultOperation=put") // prepare http response .log(name + ": counter is now ${body}") .setHeader(Exchange.CONTENT_TYPE, constant("text/plain")) .transform().simple("Counter is now ${body}\n"); } }