JCachePolicy in Camel 2 - apache-camel

I want to implement some content-caching on my Camel 2.23.2 routes. While researching I came across Camel's JCache component which, according to the documentation, should have a JCachePolicy that would:
"The JCachePolicy is an interceptor around a route that caches the "result of the route" - the message body - after the route is completed. If next time the route is called with a "similar" Exchange, the cached value is used on the Exchange instead of executing the route."
Which is basically exactly what I'm looking for. However, as it turns out this policy is only available in Camel 3.x and higher.
So my question is, how might I recreate this functionality in Camel 2.23.2?

The solution was quite simple. In the Camel 3.x branch the policy package is available and in it are only two files. The actual policy and the processor.
As it turns out, pending more testing, these files work very well with little adjustment.
On the policy you need to change the method definition for the "wrap" and "beforeWrap" methods. These require the routeContext, not the Route. But moving from the RouteContext to the route is simple enough.
On the processor, the main change is using the correct package for "DelegateAsyncProcessor" it extends.
With those changes everything seemingly works as documented. I used the ehcache spring boot starter in my pom without any further change to have it work with ehcache as it's cachemanager.
One other remark, when you want to use this, the model you want to cache needs to be serializable.

Related

What is the CamelContext in apache?

I searched in web but did not find any explanation that what is the exactly CamelContext? where and how to use ?
I gone through below links also but not satisfied with explanation.
https://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/CamelContext.html
https://dzone.com/articles/apache-camel-tutorial-eip
There are many comparision for CamelContext with others, but what I am looking for is the what is it? I want some conceptual explanation.
Please help me to understand this.
It's roughly an instance of a Camel environment, or at least it's a reference to it. Most apps would only have one CamelContext, but you can have several if needed. Looking at the referenced document, it shows how the context has a lifecycle.
In most cases, the context will start and stop along with the application.
After seeing the videos in YouTube, I knew about the Apache camel framework,
and from that I got the answer that camelcontext is nothing but context of the 'apache camel framework' framework.
As many framework have context like Spring have an applicationcontext, Ninja have a context, same the 'Apache camel framework' have a context and that is called 'camelcontext'.
So, it is the run-time system of Apache Camel (framework) and it connects its different concepts such as routes, components or endpoints.
Reference :
Basic Apache Camel Tutorial

Stop Apache Camel from starting LevelDB until the route using it is started

I have an Apache Camel Route that uses LevelDB as the aggregation repository. My problem is that when the Camel Context is started the LevelDBAggregationRepository is automatically started by Camel even if the Camel Route it is used in is off and not started.
Is there a way of preventing this?
Why is this important for me? I want my application to be highly available, so I want to share the same LevelDB between nodes. But the LevelDBAggregationRepository unfortunately does not support using multiple processes at a time, and I have no SQL DB available for the JDBC Aggregation Repository.
So, my current solution attempt is to use a route policy that ensures that only one node at a time has the Camel Route enabled (determined by leader election with Zookeeper). However, when I start a second node with the route turned off, its Camel Context tries to launch the LevelDB anyway and then all hell breaks loose.

Can I use Camel and WMQ without JMS?

I am currently learning Camel, and have a specific project in mind that requires a Websphere MQ back-end, but I can't use JMS components, since I need a lot of non-jms headers, like MQIIH.
I found the camel-wmq project.
Is it the recommended solution ? Is it any good ?
You don't need to use jms. WMQ has a client API. Just download the wmq client jars and put them in your project and use them together with your Camel routes. You will probably put the wmq client code in a processor class or something similar. Off course best to test to put a message on a queue manually via RFHUTIL or something similar as a client so you are sure the environment setup is correct.
The suggested way of working with WMQ has always been through the JMS component since it enables you to painlessly switch to other providers if the need arises.
However, if you need to use some WMQ-specific function then my suggestion would be to extend the camel-wmq library - it contains only a subset of features supported by WMQ and does not support MQIIH headers that you need. Adding functionality to a component would probably involve more work than the solution Souciance Eqdam Rashti suggested but it would be a cleaner solution and more in line with Camel's philosophy. Also, you'd be giving back to the community and thus help make Camel a better tool for everyone :)
I would also suggest you go through the IBM MQ discussions on the Camel's official user group mailing list and see if you can salvage anything.

Camel app on Liberty - JAXB Marshalling

I'm running a Camel application on Liberty Profile server. I'm taking a message from a queue, unmarshalling, mapping then marshalling. This was working fine but now I'm getting an error that JAXBDataBinding method getContextualNamespaceMap is not found.
I think this is because there is an older version of the jar in the server libs but I don't know why it started using it.
IBM Jar: com.ibm.ws.org.apache.cxf-rt-databinding-jaxb.2.6.2_1.0.12
The issue is resolved if I switch to parent last class loading but its a very hacky way to fix it and is not a great option. Any other ideas? I'm thinking some feature or other dependency in my build may have pulled this jar in.
So it does look like getContextualNamespaceMap is only available in newer versions of the org.apache.cxf-rt-databinding-jaxb JAR than what is available in Liberty.
It might be that parentLast is the best option then. (You already know how to do this but it's documented (here). If it leads to some other issues then do follow-up with another question.
I suppose it's conceivable you might be able to look at whatever is packaged within your application and try removing a set of things and picking them up from the Liberty runtime, to avoid running in parentLast mode. E.g. if you are only referencing getContextualNamespaceMap because you have other code in your app but there is some alternative path you could have gone down entirely in the Liberty-provided modules, then in theory you could be OK.
I'm not familiar enough with the code paths in the modules in the CXF or Camel "stack" to guess whether that's a real-world likelihood though.
The javaee7 feature contained a jaxsw version that clashed with the server version. Removing the javaee7 feature has resolved this issue. Remains to be seen whether or not I will to add it back in.

Configuring logging for ActiveMQ 5.5 on Tomcat 6 with web app using SLF4j and logback

I would like my web app to log using SLF4j and logback. However, I am using ActiveMQ - which then requires that some if its jars go in /usr/share/tomcat6/lib (this is because the queues are defined outside of the web app so the classes to support them must be at container level).
ActiveMQ 5.5+ requires SLF4j-api so that jar has to go in to. Because SLF4j is now starting it needs to have a logging library added or it will simply nop. Thus, logback-core and logback-classic go in too.
After quite some frustration I got this working well enough that I can tidy it up shortly. I needed to configure logback to use a JNDI lookup to get the context. Then it can lookup logback-kenobi.xml in my web app and have a separate configuration there.
However, I'm wondering if this is the best way to do this. For one, the context handling appears not to support the groovy format. I did have a logback.groovy in my web app that logged to console when I was developing locally (which means that Eclipse WTP works nicely) but logs to file and to Splunk Storm when everywhere else. I'm going to want to do something similar with this setup but I'm not sure if I should do that by overwriting the logback-kenobi.xml or some other method.
Note that I don't, currently, need Tomcat itself to log with slf4j although I am planning to do that. Nor do I really need ActiveMQ to log with slf4j but I did need it to stop spewing debug messages every 30s as it was doing. I am aware of tomcat-slf4j-logbak but I don't believe it is directly useful as it is ActiveMQ requiring logging which is the issue.
However, I'm wondering if this is the best way to do this.
Best is an opinion, working is a fact.

Resources