Camel control bus is not working as expected - java

I have a scenario where when I call a rest endpoint which is custom defined and I am using camel-jetty for it, the other route should start executing but it is not working as expected.
Following are the routes:
RouteDefinition routeDefinition = getRouteBuilder().from("jetty:http://localhost:8090/valueA").routeId(routeId).to("controlbus:route?routeId=route2&action=start");
RouteDefinition routeDefinition2 = getRouteBuilder().from("paho://Properties").routeId("route2").noAutoStartup().log("DataSource content: ${body}");
But during executions it shows in logger as
[qtp1272744797-29] INFO org.apache.camel.component.controlbus.ControlBusProducer - ControlBus task done [start route route2] with result -> void
And if change the start to status then it says
[qtp1272744797-29] INFO org.apache.camel.component.controlbus.ControlBusProducer - ControlBus task done [status route route2] with result -> Stopped
It seems like it starts the route but I don't know why the content of the datasource is not getting displayed.
Please help as I got stuck here for so long.
Any help would be appreciated.

Related

Spring Webflux + Sleuth Zipkin: Proof of duplicate requests?

Small question regarding duplicates requests with Spring Webflux + Sleuth Zipkin server please.
I have a server, which code is super simple:
#PostMapping("/question")
public Mono<String> question() {
LOGGER.info("This has been called!");
return someService.getResponse();
}
Every hour, I expect only one client that I know to call this endpoint only once.
Therefore, every hour, I do see this in my log:
INFO [myservice,c3a25fb0fb7426b7,c3a25fb0fb7426b7] 10 --- [or-http-epoll-3] c.my.Controller : This has been called!
So far so good.
The issue is that several times, I did see in my logs:
INFO [myservice,5278cfd673fddc60,1582c3da8d01adaa] 10 --- [or-http-epoll-2] c.my.Controller : This has been called!
INFO [myservice,5278cfd673fddc60,c8a85b0275b6bfdd] 10 --- [or-http-epoll-3] c.my.Controller : This has been called!
Very naturally, I assume the only client I know, instead of calling me once as expected, called me twice.
However, the logs on client side shows only one http outbound request has been made.
May I ask, seeing same trace ID, but different Span ID is enough to prove, be hard evidence there is at least two requests sent?
Can the [or-http-epoll-2] and [or-http-epoll-3] help proving as well?
With the only information written here, is it possible to prove anything regarding the duplicates please?
Thank you
You can prove this by turning on access logs.
Having the same traceID for two different log events does not prove anything, it can happen that:
The client called you twice
The client called you once but you created another span
The client called you and another client which also called you
You can enable access logs which can prove this or you can use a rq/rs log library (like logbook) that does this for you. I recommend simply enabling the access logs.

camel delayer interceptor : works ambigously

I am having a camel route which reads from activemq and updates inventory and i am trying to add delayer to it as follows :
from("activemq:{{vs.inventory.queue.name}}")
.delay(200L)
.filter( body().isNotNull() )
But this doesn't work as expected(delay is not for 200 ms but is everytime an ambigous delay is being set).
I referrred to http://camel.apache.org/delayer.html for this but couldn't get a working way for it.
my question is am I using this in correct way or is their something being missed.

Camel pollEnrich only works second time

I have a direct Camel route triggered by a restful. The restful passes the name of a file (which needs to be processed) inside the Exchange body.
The route is very simple:
from("direct:myRoute")
.log("Reading file with name ${in.body}")
.pollEnrich().simple(inboundUri).timeout(5000)
.choice()
.when(body().isNull())
.log("Cannot read file. Body is null")
.otherwise()
.log("Processing file: ${in.headers.CamelFileAbsolutePath}")
...
where inboundUri is:
smb://DOMAIN;username:password#myLocation/myFolder/?include=${in.body}.csv&delay=5000&noop=true&idempotent=false&readLock=none&recursive=false&sortBy=reverse:file:modified
The first time I trigger this route I always get "Cannot read file. Body is null".
But if I trigger it again, it then works fine and the file gets processed.
Any idea why?
P.S. I've tried to set CAMEL in DEBUG mode, but I struggle to understand what it does. The first time I run it I get things like:
DefaultCamelContext : Using ComponentResolver: org.apache.camel.impl.DefaultComponentResolver#1016b44e to resolve component with name: smb
ResolverHelper : Lookup Component with name smb in registry. Found: null
ResolverHelper : Lookup Component with name smb-component in registry. Found: null
DefaultComponentResolver : Found component: smb via type: org.apacheextras.camel.component.jcifs.SmbComponent via: META-INF/services/org/apache/camel/component/smb
DefaultManagementAgent : Registered MBean with ObjectName: org.apache.camel:context=camel-1,type=components,name="smb"
...
PollEnricher : Consumer received no exchange
FilterProcessor : Filter matches: true for exchange: Exchange[ID-server-43626-1517937470434-0-2]
The second time the output is much shorter and the main differences seems to be:
ServiceHelper : Resuming service Consumer[smb://DOMAIN;username:password#myLocation/myFolder/?include=${in.body}.csv&delay=5000&noop=true&idempotent=false&readLock=none&recursive=false&sortBy=reverse:file:modified]
PollEnricher : Consumer received: Exchange[]
FilterProcessor : Filter matches: false for exchange: Exchange[ID-server-43626-1517937470434-0-4]
Set the delay value in your inbound uri to a lower value as it has a delay of 5000 which is the same as your timeout, so that does not allow enough time for it to run. Set it to 1000 or 500 or something.

Not able to exhibit backpressure with spring web reactive

I am trying to exhibit backpressure using spring-web-reactive just like the way it is shown here with akka - https://www.youtube.com/watch?v=oS9w3VenDW0
(Watch between 28:20 and 29:20).
To try it out I have used below sample project from github https://github.com/bclozel/spring-boot-web-reactive
Upon setup of the project I added an new endpoint in HomeController.java as shown below:
#RequestMapping(value = "/longflux",produces = "application/stream+json")
public Flux<Long> longFlux(){
return Flux.interval(Duration.ofMillis(10)).log();
}
Now, if I try to curl this endpoint and then suspend it using (CTRL+z), backpressure should have kicked in as soon as the tcp buffers are filled and server should stop emitting the events.
However, suspending the curl command after sometime throws below exception :
2017-02-16 08:49:48.480 ERROR 3500 --- [ timer-1] reactor.Flux.Interval.4 : onError(reactor.core.Exceptions$OverflowException: Could not emit value 2578 due to lack of requests)
2017-02-16 08:49:48.481 ERROR 3500 --- [ timer-1] reactor.Flux.Interval.4 :
reactor.core.Exceptions$OverflowException: Could not emit value 2578 due to lack of requests
at reactor.core.Exceptions.failWithOverflow(Exceptions.java:151) ~[reactor-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at reactor.core.publisher.FluxInterval$IntervalRunnable.run(FluxInterval.java:98) ~[reactor-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at reactor.core.scheduler.SingleTimedScheduler$TimedPeriodicScheduledRunnable.run(SingleTimedScheduler.java:394) ~[reactor-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_121]
I am not able to understand why the request terminated with exception in sometime after the curl command was suspended(In spring-web-reactive implementation), whereas in the akka example(as demonstrated in the youtube link) the server stopped publishing events once the tcp buffer was full.
Flux.interval is a special case, since it's a hot source and time is not buffered by Reactor; this means that if your request cycle is slow due to backpressure and your interval source is producing faster, Reactor will emit an Error signal.
You can update this sample with a .onBackpressureDrop() operator to drop interval in case of backpressure. This should behave as expected.
There are many ways to illustrate backpressure, including:
delaying the subscription with a delay operator
simulating multiple slow clients (bandwidth and latency)

Extract Route Statistics in Camel

On JConsole, We can see following route Statistics.
Minimum / Maximum / Mean Processing Time
First / last Message completion Time
Number of messages failed or re-delivered.
Total number of transaction processed
Requirement: I need to show above data on web page.
Below is my code:
public void process(Exchange exchange) throws Exception {
CamelContext context = exchange.getContext();
List<Route> routeObj = context.getRoutes();
for (Route routeId : routeObj) {
boolean started = context.getRouteStatus(strRouteId).isStarted();
boolean stopped = context.getRouteStatus(strRouteId).isStopped();
boolean suspended = context.getRouteStatus(strRouteId).isSuspended();
// TODO: find min/max/mean processing time, first/last message
// completion time, etc.
}
}
Thanks in advance.
Please suggest me how to get min/max/mean processing time, first/last message completion time, etc.
See for example the Camel Karaf commands that can dump statistics too. They use the JMX API to do that.
An example is the context-info command: https://github.com/apache/camel/blob/master/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInfo.java
Apache camel exposes these information using JMX.
A good starting point is the official JMX tutorial and the Apache Camel JMX Documentation
You can actually calculate the info you require, using org.apache.camel.management.PublishEventNotifier
One type of events will get notified of is concerning camel exchanges (like completion, failure...) of each route. The only piece of information you need after that is the processing time of a this exchange (last exchange) which is obtainable using JMX (LastProcessingTime).
Once you have the exchanges processing time for each route, all the information you require can be calculated in real-time.

Categories

Resources