I would like to make my Apache Camel application to be more resilient and start even when the MQTT broker is not reachable. We are using Camel on IoT devices with a possibly unstable internet connection and I want our application to start even without internet access.
An exemplary route looks like the following:
from("timer:heartbeat?period=5000")
.routeId("send heartbeat")
.setBody(simple("Hello World!"))
.to("paho:myhostnome/heartbeat?brokerUrl={{broker.url}}")
This works fine as long as the MQTT server is available. However when the server is not reachable, the context fails while warming up the PahoEndpoint.
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route send heartbeat: Route(send heartbeat)[[From[timer:heartbeat?period={{heartbe... because of Unable to connect to server
at org.apache.camel.impl.RouteService.warmUp(RouteService.java:147) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doWarmUpRoutes(DefaultCamelContext.java:3758) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3665) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3451) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3305) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:202) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3089) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3085) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:3108) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:3085) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:3022) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.spring.boot.RoutesCollector.maybeStart(RoutesCollector.java:242) ~[camel-spring-boot-2.19.3.jar:2.19.3]
at org.apache.camel.spring.boot.RoutesCollector.onApplicationEvent(RoutesCollector.java:217) ~[camel-spring-boot-2.19.3.jar:2.19.3]
... 13 common frames omitted
Caused by: org.eclipse.paho.client.mqttv3.MqttException: Unable to connect to server
at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:79) ~[org.eclipse.paho.client.mqttv3-1.1.0.jar:na]
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:650) ~[org.eclipse.paho.client.mqttv3-1.1.0.jar:na]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_121]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_121]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_121]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_121]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_121]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_121]
at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_121]
at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:70) ~[org.eclipse.paho.client.mqttv3-1.1.0.jar:na]
My first idea was to disable auto startup on all routes involving Paho and start them manually. This does not work as the PahoEndpoint is started even when the route itself is not started.
I'm now looking for an alternative approach to handle this problem.