in resilience4j configuration I have params for circuit breaker, bulkhead and thread timeout together. Once the fallback happens, I am unable to find out what caused the fallback.I am implementing the resilience4j configuration in camel route.
You can't mix onFallback and Exception, use doTry() and throwExceptionWhenHalfOpenOrOpenState(true) configuraton :
.doTry()
.circuitBreaker()
.resilience4jConfiguration()
.throwExceptionWhenHalfOpenOrOpenState(true)
.end()
.to("http://fooservice.com/faulty")
.end()
.endDoTry()
.doCatch(Exception.class)
.log("${exception.message}")
.end
Related
I have the following Apache Camel FTP file download Route:
from(downloadUri)
.routeId(routeId)
.aggregate(new CustomListAggregationStrategy())
.constant(true)
.completionFromBatchConsumer()
.to("direct:" + routeDestinationId);
I add this Route to a context and then request data with a ConsumerTemplate:
List<ResultType> result = consumerTemplate.receiveBody(CAMEL_DIRECT_OBJECT_PREFIX
+ routeId, List.class);
When a connection error occurs (e.g. unknown host, host not reachable), I want to shutdown the Route and throw an exception after the "receiveBody" line where I try to read the downloaded files.
How can I do this?
I tried an onException-handler for the Route where I added a process block to it and called exchange.getContext().stop(); in that processing block. But the application just keeps running.
Stopping a route during routing an existing message is a bit tricky. The reason for that is Camel will Graceful Shutdown the route you are stopping. And if you do that while a message is being routed the Graceful Shutdown will try to wait until that message has been processed.
You can find more info here : https://camel.apache.org/manual/faq/how-can-i-stop-a-route-from-a-route.html
I try to use the PahoEndpointBuilder
PahoEndpointBuilder endpoint = paho (topic).brokerUrl (brokerUrl);
but starting the route based on that endpoint always leads to an exception.
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: paho:myTestTopicMandant9?brokerUrl=tcp%3A%2F%2Flocalhost%3A1883 due to: There are 1 parameters that couldn't be set on the endpoint. Check the uri if the parameters are spelt correctly and that they are properties of the endpoint. Unknown parameters=[{brokerUrl=tcp://localhost:1883}]
at org.apache.camel.support.DefaultComponent.validateParameters(DefaultComponent.java:351)
at org.apache.camel.support.DefaultComponent.createEndpoint(DefaultComponent.java:169)
at org.apache.camel.impl.engine.AbstractCamelContext.doGetEndpoint(AbstractCamelContext.java:952)
Is this a bug?
Its a bug in Camel 3.2 that has been logged in JIRA: https://issues.apache.org/jira/browse/CAMEL-14921
My Spring boot camel application uses camel-corda component and failing to start when corda node (RPC connection) is not up and running
My current camel route is
#Component
class CordaOpsRouteBuilder() : RouteBuilder() {
override fun configure() {
from("timer://terminate?repeatCount=1&delay=20").autoStartup("{{corda.terminate.node}}")
.to("direct:terminate-node")
from("direct:terminate-node")
.log("Draining and shutting down node")
.to("corda://{{corda.rpc.username}}:{{corda.rpc.password}}#{{corda.rpc.host}}:{{corda.rpc.port}}?operation=TERMINATE")
.delay(10000).asyncDelayed()
.to("direct:shutdown")
from ("direct:shutdown")
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.to("http://localhost:{{server.port}}/actuator/shutdown")
}
}
Stack trace :
Caused by: org.apache.camel.RuntimeCamelException: net.corda.client.rpc.RPCException: Cannot connect to server(s). Tried with all available servers.
at org.apache.camel.RuntimeCamelException.wrapRuntimeCamelException(RuntimeCamelException.java:52) ~[camel-api-3.0.0-RC3.jar:3.0.0-RC3]
at org.apache.camel.support.ChildServiceSupport.start(ChildServiceSupport.java:63) ~[camel-support-3.0.0-RC3.jar:3.0.0-RC3]
How can handle above RuntimeCamelException during the startup?
Please use lazyStartProducer=true parameter on the corda endpoint to make sure the route starts even if corda is not available (a lazy start).
https://camel.apache.org/components/latest/corda-component.html
I observe, that errors in the route definition lead to a silent shutdown of the application, caused by Camel. How can I configure Camel to telling me what exactly it dislikes.
Simple example: Assigning duplicate route names
If I define two routes with different names [by using: .id ("route name")], then the application starts and reports readiness.
If I mistakenly use a name twice, the application fails to start completely and Camel announces:
Apache Camel 2.22.0 (CamelContext: camel-1) is shutting down
Apache Camel 2.22.0 (CamelContext: camel-1) uptime 0.332 seconds
Apache Camel 2.22.0 (CamelContext: camel-1) is shutdown in 0.017 seconds
Stopping service [Tomcat]
HikariPool-1 - Shutdown initiated ...
HikariPool-1 - Shutdown completed.
Process finished with exit code 0
The exit code 0 seems to suggest a non-exceptional shutdown.
The same early shutdown happened, when I added a CronScheduledRoutePolicy to a route. [e.g. with .routePolicy (policy)]
It shuts down if I add a default instance or if I make any settings to the policy.
I increased the log level and got significantly more background noise, but no new findings. [using application.yml: logging: level: ROOT: DEBUG]
A try catch around the route definition didn't help. No exception was caught at the time of the route definition.
I tried to set the CronScheduledRoutePolicy an exception handler. [E.g. with policy.setExceptionHandler (myCamelExceptionHandlerLoggingEverything)]
Nothing got logged. No breakpoint was hit.
I would be very grateful for your help or references to any solutions.
Ralf
There are multiple ways to print an exact error and it depends on how developer design app/class with the camel route. I have mentioned below example which will give exact error you are looking for.
public class CamelPrintingExample {
public static void main(String[] args) throws Exception {
CamelContext camelContext = new DefaultCamelContext();
try {
camelContext.addRoutes(new RouteBuilder() {
public void configure() {
from("file:C:\\input\\").routeId("demo")
.to("file:C:\\output\\").end();
from("file:C:\\input\\").routeId("demo")
.to("file:C:\\output\\").end();
}
});
camelContext.start();
Thread.sleep(300000);
camelContext.stop();
} catch (Exception camelException) {
camelException.printStackTrace();
}
}
}
By running this I got below error.
org.apache.camel.FailedToStartRouteException: Failed to start route demo because of duplicate id detected: demo. Please correct ids to be unique among all your routes.
You can try defining a custom shutdown strategy. Read here
Try to add this in your route and then start it:
getContext().setTracing(true);
P.S. a problem could also be in your error handler
I have a Apache Camel route publishing an AVRO message onto a Apache Kafka topic. I only got this to work when setting the producer property 'serializerClass=kafka.serializer.StringEncoder'. Otherwise I get
java.lang.ClassCastException: java.lang.String cannot be cast to [B
at kafka.serializer.DefaultEncoder.toBytes(Encoder.scala:34) at
kafka.producer.async.DefaultEventHandler$$anonfun$serialize$1.apply(DefaultEventHandler.scala:130)
at
kafka.producer.async.DefaultEventHandler$$anonfun$serialize$1.apply(DefaultEventHandler.scala:125)
at
scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
at
scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:34)
at
kafka.producer.async.DefaultEventHandler.serialize(DefaultEventHandler.scala:125)
at
kafka.producer.async.DefaultEventHandler.handle(DefaultEventHandler.scala:52)
at kafka.producer.Producer.send(Producer.scala:77) at
kafka.javaapi.producer.Producer.send(Producer.scala:33) at
org.apache.camel.component.kafka.KafkaProducer.process(KafkaProducer.java:84)
On the other end I have a second Apache Camel route supposed to consume from the above topic which failes with
java.io.IOException: Invalid long encoding at
org.apache.avro.io.BinaryDecoder.innerLongDecode(BinaryDecoder.java:217)
at org.apache.avro.io.BinaryDecoder.readLong(BinaryDecoder.java:176)
at
org.apache.avro.io.ResolvingDecoder.readLong(ResolvingDecoder.java:162)
at
org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:160)
at
org.apache.avro.generic.GenericDatumReader.readField(GenericDatumReader.java:193)
at
org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:183)
at
org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:151)
at
org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:142)
at
org.apache.camel.dataformat.avro.AvroDataFormat.unmarshal(AvroDataFormat.java:133)
at
org.apache.camel.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:67)
Here is the Apache Camel consumer code I use:
<route id="cassandra.publisher">
<from
uri="{{kafka.base.uri}}&topic=sensordata&groupId=Cassandra_ConsumerGroup&consumerId=CassandraConsumer_Instance_1&clientId=adapter2" />
<unmarshal>
<custom ref="avroSensorData" />
</unmarshal>
In order to solve this problem you have to provide the keyDeserializer and valueDeserializer for camel kafka consumer as follows:
&keyDeserializer=org.apache.kafka.common.serialization.StringDeserializer &valueDeserializer=org.apache.kafka.common.serialization.ByteArrayDeserializer
http://camel.465427.n5.nabble.com/Camel-Kafka-Component-td5749525.html#a5769561
describes that Apache Camel version 2.16.0/2.15.3 will support various datatype and not only String messages.
As promised this has been fixed with Apache Camel 2.15.3 and was fixed with CAMEL-8790 (https://issues.apache.org/jira/browse/CAMEL-8790).