I developed a sample code to test the Topic and durable Topic on fuse and I faced an issue.
Sample code description
My sample code consists of 3 bundles, and each bundle has its own camel context, and its own route, so I have 3 routes in 3 bundles as the following:
bundle1 route : consume file from file system and send it to a queue
<route id="producer-route">
<from uri="file:D://camel_test"/>
<to uri="activemq:queue:service.queue"/>
</route>
bundle 2 route: consume message from the previous queue and send it to a topic
<route id="router-route">
<from uri="activemq:queue:service.queue"/>
<to uri="activemq:topic:router.topic"/>
</route>
bundle3 route: consume message from the previous topic and send it to the file system
<route id="consumer-route">
<from uri="activemq:topic:router.topic?clientId=consumer&durableSubscriptionName=bar"/>
<to uri="file:D://camel_test2"/>
When I put a file in the first folder "D://camel_test" , the sample code runs successfully in 95% of the cases and the file is disappeared from "D://camel_test" folder and moved to the second folder "D://camel_test2"
Issue Description
• Sometime, 5% of the cases, the file isn’t consumed by the second route, and when checking the consumers and queues on jconsole, I find
o a registered consumer for the queue as shown in the attached jconsole screen shot (2.png).
o The queue’s Enqueue count is increased while the queue’s Dequeue count is zero as shown in the attached jconsole screen shot (1.png).
• The issue appears in many cases but the most reproducible case is after restarting Fuse ESB.
• the issue doesn’t appear In every fuse restart, many times the sample code runs successfully without problems after fuse restart.
Important Note: Always the issue disappears after refreshing bundle2 and bundle3.
could you please advise?
Related
We have found that when we have 2 routes connected via direct-vm in a transaction, with MDC logging enabled, at the point when the second route returns to the first route after the direct-vm call, the routeId in the MDC is missing (everything else in the MDC is intact).
We are on version 2.24.3 and the routes are defined in JAVA DSL bootstrapped within a springboot application.
Debugging with Camel source code takes us to
this class
https://github.com/apache/camel/blob/camel-2.24.3/camel-core/src/main/java/org/apache/camel/impl/MDCUnitOfWork.java
and we can see that on line 112, that is where the routeId is removed
// not running in route, so clear (should ideally not happen)
MDC.remove(MDC_ROUTE_ID);
But I don't fully understand how route context fits into the picture, how a route context is being created in the first place.
There isn't much documentation I can find about route context except that it can be used as a way to group routes in separate XML files and imported into a camel context, which is irrelevant in our case.
Anyone can shed some lights would be much appreciated!
Thanks in advance.
As the UOW on the direct-vm call is done, the CamelInternalProcessor .UnitOfWorkProcessorAdvice.after(Exchange exchange, UnitOfWork uow) is called;
On line
https://github.com/apache/camel/blob/camel-2.24.x/camel-core/src/main/java/org/apache/camel/processor/CamelInternalProcessor.java#L685
the routeContextStack in the UOW object is cleared at
https://github.com/apache/camel/blob/camel-2.24.x/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java#L179
then on line
https://github.com/apache/camel/blob/camel-2.24.x/camel-core/src/main/java/org/apache/camel/processor/CamelInternalProcessor.java#L690
it's trying to get the route context object again from the stack
https://github.com/apache/camel/blob/camel-2.24.x/camel-core/src/main/java/org/apache/camel/impl/MDCUnitOfWork.java#L106
which would be always null as the stack has been cleared;
hence the routeId is removed from MDC as
https://github.com/apache/camel/blob/camel-2.24.x/camel-core/src/main/java/org/apache/camel/impl/MDCUnitOfWork.java#L112
We are on Camel 2.24.3 but the latest Camel master branch at this point seems to behave the same.
I have multiple routes deployed in a single camel bundle and what I'm trying to achieve is that once a single route starts execution, the other routes should not be executed until the route that got started is finished with execution.
I understand that it is possible to have the whole camelContext encompassing my routes be made single threaded but I see a drawback here in terms of performance.
Has someone had a similar use case and whats the best way to solve this? Since I'm using OSGi Blueprint DSL, any examples will be welcome.
You can use Camel's Control Bus if you need to control other routes selectively, such as starting and stopping them.
First, you need to prevent the routes you want from executing when your application is started. This is achieved with autoStartup=false in your route definition:
<route id="foo" autoStartup="false">
<from uri="activemq:queue:special"/>
<to uri="file://backup"/>
</route>
Then at the point in your running route where you want to start another route after doing stuff, simply:
<to uri="controlbus:route?routeId=foo&action=start"/>
You can also order the startup (and shutdown) of routes, explained in the Camel documentation here.
I need to work on some Camel routes which contain lot of CBR based on the headers:
<simple>${header.CamelFileName} regex '^.*xml$'</simple>
It would be very helpful to debug the content of the Headers of the Routes: do you recommend any component/processor ?
Thanks!
You can use Log component for that task (http://camel.apache.org/log.html)
<to uri="log:like-to-see-all?level=INFO&showAll=true&multiline=true"/>
This code will help you to see all message headers
I would recommend the DSL Log : http://camel.apache.org/logeip.html which is more confortable and comprehensible to use instead of a Log component (http://camel.apache.org/log.html) to debug headers.
<log message="CamelFileName : ${header.CamelFileName}; you can use simple langage" loggingLevel="FATAL" logName="com.mycompany.MyCoolRoute"/>
From the doc :
Difference between log in the DSL and [Log] component
The log DSL is
much lighter and meant for logging human logs such as Starting to do
... etc. It can only log a message based on the Simple language. On
the other hand Log component is a full fledged component which
involves using endpoints and etc. The Log component is meant for
logging the Message itself and you have many URI options to control
what you would like to be logged.
Hope
I have my camel bundle deployed in service mix and it runs well for some times and now after many runs the same bundle tells the below exception.
org.apache.camel.runtimeexception :java.lang.illegalstateexception: bundlecontext is no longer valid
The same scenario was working fine some runs and suddenly for some consecutive runs it throws the above errors.
Will restart of smx or uninstall of the bundle resolve the issue? this is the third time I am facing this issue and all the time a small restart solved it. Please suggest if this is some other problem.
After My Comment below
I have used in the code i have used like below code.
<choice>
<when>
<simple>some condition</simple>
</when>
<when>
<simple>some other condition</simple>
<stop/>
<when>
</choice>
<!--Still more code and logic exists-->
If I have used here and that is the problem here what should I do to exit when the second condition comes.
Is there any way I can stop the further execution here? that is what is the way to stop the execution for that particular request alone and not stop the route? In this scenario there are other requests which will not be affected by this stop and will work for other requests.
I think in the http://camel.apache.org/intercept.html link it says that to use to stop further execution but will it stop the route any way.
Will this cause the bundle no longer valid scenario. From this there arises a question where what will be the spring config equivalent of CamelContext.stop() ?
After My another Comment below which directs here.
Also we work in an environment where the camel has more customized bundles which ease our development. This has more specifically loading the routes dynamically. Will this be one reason where the routes may not be properly started when we give camelCOntext.Start() etc....?
From the camel route, I cann't tell anything is wrong.
As you just asked another question I just post my answer here:
stop element in the route only works for the exchange, which means the exchange which is routed to this point won't be processed any more. If you want to stop the route or camel context you need call the CamelContext.stop().
If can do it in Spring configuration by using camel-controlbus component.
I am currently building upon the camel-drools example found here: https://github.com/FuseByExample/camel-drools-example
The route is as follows:
<route trace="false" id="testRoute">
<description>Example route that will regularly create a Person with a random age and verify their age</description>
<from uri="timer:testRoute"/>
<bean method="createTestPerson" ref="personHelper"/>
<to uri="drools:node1/ksession1?action=insertBody" id="AgeVerification">
<description>valid 'action' values are:
'execute' that takes a 'Command' object (default)
'insertBody' that inserts the Exchange.in.body, and executes rules
'insertMessage' that inserts the Exchange.in (type org.apache.camel.Message), and executes rules
'insertExchange' that inserts the Exchange (type org.apache.camel.Exchange), and executes rules
</description>
</to>
<choice>
<when id="CanDrink">
<simple>${body.canDrink}</simple>
<log logName="Bar" message="Person ${body.name} can go to the bar"/>
</when>
<otherwise>
<log logName="Home" message="Person ${body.name} is staying home"/>
</otherwise>
</choice>
</route>
I have expanded on this example for my own project and have added more complicated rules and different Facts, which I would now like to debug, however I can't figure out how to get Drools debugging working in the camel / fuse environment.
I would ideally like to see all the various debugging views that the Drools IDE provides such as the agenda view, working memory view, etc (as per http://docs.jboss.org/drools/release/5.5.0.Final/drools-expert-docs/html/ch06.html#d0e8478). I have converted my Eclipse project to a Drools project. I have created a new 'Drools application' debug configuration, but have no idea what to put in the 'main class' section. I don't have my own main class since it's camel that invokes the firing of the rules and inserting facts into the working memory.
I've tried debugging the application as a normal Java application, so I set breakpoints before the drools part of the application is executed. I have followed the drools documentation that says that if you set normal breakpoints and click on the workingMemory variable that the drools 'Working memory' or 'Agenda' view should then populate, however I always see 'The selected working memory is empty', even though I know that it isn't. I've stepped through the code from start to finish clicking on all possible WorkingMemory variables but i still see 'the selected working memory is empty' error.
Has anyone been able to successfully debug drools when deployed using camel? If so, what steps did you take?
Cheers.
I use the KnowledgeRuntimeLogger to help debug my camel/drools app. It creates a log file that I view in the Audit view (you can drag it into the view in eclipse).
KnowledgeRuntimeLogger flogger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger(ksession,"c:/temp/wmlog");
If you need to do this in spring, you can create it as a bean with the two constructor arguments (or create you own little bean that creates the logger).
hth