You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@camel.apache.org by "Claus Ibsen (JIRA)" <ji...@apache.org> on 2009/09/13 10:13:12 UTC

[jira] Commented: (CAMEL-1868) Created a new Camel Cache component (based on ehCache) with an ability to put messages and receive notifications from a Cache.

    [ https://issues.apache.org/activemq/browse/CAMEL-1868?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=54177#action_54177 ] 

Claus Ibsen commented on CAMEL-1868:
------------------------------------

Comments on patch
================

1)
Are the dependencies in pom.xml all needed? It has JSCH and commons net as mandatory? Maybe they are optional or for testing only?

2)
Could we reduce the INFO level logging to DEBUG. Especially in process methods that can be assumed to be invoked a lot. 

3)
Remove todo comments such as
/ TODO Auto-generated method stub

4)
Constants used to add to headers. CACHE_KEY etc. Is that a special ehache name? If not please use CamelCacheKey as this is the syntax we have agree upon in Camel.

5)
Program against interfaces
Instead of using DefaultExchange use Exchange and the same for Message, in such code as:

  DefaultExchange exchange = new DefaultExchange(this.getCamelContext(), getExchangePattern());
  DefaultMessage message = new DefaultMessage();

6)
Wrong error handling

+        try {
+            cacheConsumer.getProcessor().process(exchange);
+        } catch (Exception e) {
+            throw new CacheException("Error in consumer while dispatching exchange containing Key " + (String) element.getObjectKey() + " for further processing  ", e);
+        }

It should just set the exception on the exchange
exchange.setException(e);

7)
Why does it use clone?

+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }

8)
No need to log when starting and stopping if no special is done as Camel does this by default at DEBUG level

+    @Override
+    protected void doStart() throws Exception {
+        LOG.info("In CacheProducer.start()");
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        LOG.info("In CacheProducer.stop()");
+        super.doStop();
+    }
+

9)
A lot of the INFO logging should be TRACE and a some of them DEBUG.

10)
Use Camel type converter to convert to a byte[]

+        // Read InputStream into a byte[] buffer
+        byte[] buffer = new byte[is.available()];
+        int n = is.available();
+        for (int j = 0; j < n; j++) {
+            buffer[j] = (byte)is.read();
+        }

11)
Use IllegalArgumentException for invalid configuration instead of CacheException

12)
Maybe use .convertMandatoryTo(InputStream.class) if the input stream *must* be not null

13)
And use the camel type converter features instead of all that manual type converting.



> Created a new Camel Cache component (based on ehCache)  with an ability to put messages and receive notifications from a Cache. 
> --------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-1868
>                 URL: https://issues.apache.org/activemq/browse/CAMEL-1868
>             Project: Apache Camel
>          Issue Type: New Feature
>         Environment: All UNIX and windows based environments...
>            Reporter: Ashwin Karpe
>            Assignee: Willem Jiang
>             Fix For: 2.1.0
>
>         Attachments: camel-cache-with-processors.patch, camel-cache-with-processors.zip, camel-cache.patch, camel-cache.zip
>
>
> I have developed a Camel Caching component based on ehCache. I am submitting this new feature for your review and consideration for releasing this capability into the Camel mainstream.  
> The Camel Caching component has the following abilities
>     a> In Producer mode, the component provides the ability to direct payloads in exchanges to a  stored in a pre-existing or created-on-demand Cache. The producer mode supports operations to ADD/UPDATE/DELETE/DELETEALL elements in a cache. (Examples goven below)
>     b> In Consumer mode, the component provides the ability 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 ADD/UPDATE/DELETE/DELETEALL). Upon such an activity takng place, an exchange containing header elements describing the operation and cachekey and a body containing the just added/updated payload is placed and sent. In case of a DELETEALL operation the body of the exchanage is not populated.
> The cache itself may be created on demand or if a cache of that name already exists then it is simply utilized with its original settings. The URL itself may take the following form
> from ("cache://MyApplicationCache?maxElementsInMemory=1000&memoryStoreEvictionPolicy=MemoryStoreEvictionPolicy.LFU&overflowToDisk=true&eternal=true&timeToLiveSeconds=300&timeToIdleSeconds=true&diskPersistent=true&diskExpiryThreadIntervalSeconds=300")  
> Note that all the attributes of the above URL are standard ehCache settings that may be set at Cache creation.
> Given below are examples of how to create/set routes:
> Producer Example 1: Adding keys to the cache with a body received from direct:start
> ----------------------------------------------------------------------------------------------------
>         context.addRoutes(new RouteBuilder() {
>             public void configure() {
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("ADD")).
>                     setHeader("CACHE_KEY", constant("Ralph_Waldo_Emerson")).
>                     to("cache://TestCache1");
>             }
>         });
>         context.start();
> Producer Example 2: Updating existing keys in a cache with a body received from direct:start
> ----------------------------------------------------------------------------------------------------
>   
>          context.addRoutes(new RouteBuilder() {
>             public void configure() {
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("UPDATE")).
>                     setHeader("CACHE_KEY", constant("Ralph_Waldo_Emerson")).
>                     to("cache://TestCache1");
>             }
>         });
>         context.start();
>  
> Producer Example 3: Deleting existing keys in a cache with a body received from direct:start
> ----------------------------------------------------------------------------------------------------
>  
>         context.addRoutes(new RouteBuilder() {
>             public void configure() {
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("DELETE")).
>                     setHeader("CACHE_KEY", constant("Ralph_Waldo_Emerson")).
>                     to("cache://TestCache1");
>             }
>         });
>         context.start();
> Producer Example 4: Deleting all keys in a cache with a body received from direct:start
> ----------------------------------------------------------------------------------------------------
>  
>         context.addRoutes(new RouteBuilder() {
>             public void configure() {
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("ADD")).
>                     setHeader("CACHE_KEY", constant("Ralph_Waldo_Emerson")).
>                     to("cache://TestCache1");
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("ADD")).
>                     setHeader("CACHE_KEY", constant("Ralph_Waldo_Emerson2")).
>                     to("cache://TestCache1");
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("DELETEALL")).
>                     to("cache://TestCache1");
>             }
>         });
>         context.start();
> Consumer Example 1: Notifying any changes registering in a Cache to Processors and other Producers
> ---------------------------------------------------------------------------------------------------------------------------------------------
> Note: in this example the consumer is created first and then 3 routes send different message as Cache Producers
>  
>         // Cache Notification Consumer
>         context.addRoutes(new RouteBuilder() {
>             public void configure() {
>                 from("cache://TestCache1").
>                     process(new Processor() {
>                         public void process(Exchange exchange) throws Exception {
>                             String operation = (String) exchange.getIn().getHeader("CACHE_OPERATION");
>                             String key = (String) exchange.getIn().getHeader("CACHE_KEY");
>                             Object body = exchange.getIn().getBody();
>                             // Do something
>                         }
>                         
>                     });
>                 // Cache Producer1
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("ADD")).
>                     setHeader("CACHE_KEY", constant("Ralph_Waldo_Emerson")).
>                     to("cache://TestCache1");
>                 
>                 // Cache Producer2
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("UPDATE")).
>                     setHeader("CACHE_KEY", constant("Ralph_Waldo_Emerson")).
>                     to("cache://TestCache1");
>                 
>                 // Cache Producer3 
>                 from("direct:start").
>                     setHeader("CACHE_OPERATION", constant("DELETE")).
>                     setHeader("CACHE_KEY", constant("Ralph_Waldo_Emerson")).
>                     to("cache://TestCache1");
>             }
>         });
>         context.start();

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.