QuarkusIntegrationTest does not allow two tests running sequentially: application closed in 2nd test by Camel SimpleMainShutdownStrategy - apache-camel

I have a strange error: I can only run one Quarkus integration test in my mvn verify step. When I have two integration tests, the second one runs but immediately stops the application so nothing is happening and building hangs forever.
The logs are different in two tests. For the 1st one, the logs are:
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup (total:8 started:8)
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route1 (activemq://queue:myqueue)
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route2 (activemq://queue:myqueue.online)
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started main (direct://main)
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started individual-endpoint (direct://individual-endpoint)
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started send-and-retry (direct://send-and-retry)
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started mapping-response (direct://mapping-response)
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started reply-queue (direct://reply-queue)
2023-01-04 15:43:04,560 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route3 (direct://receive.ack.response)
2023-01-04 15:43:04,561 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.14.1 (camel-1) started in 593ms (build:0ms init:206ms start:387ms)
2023-01-04 15:43:04,562 DEBUG [org.apa.cam.imp.DefaultCamelContext] (main) start() took 594 millis
2023-01-04 15:43:04,567 DEBUG [org.apa.cam.mai.SimpleMainShutdownStrategy] (camel-main) Await shutdown to complete
2023-01-04 15:43:04,583 INFO [com.example.MyLogger] (main) Application is up
2023-01-04 15:43:04,583 INFO [com.example.MyLogger] (main) Application is up
2023-01-04 15:43:04,767 INFO [com.example.ShutdownController] (main) Setting pre shutdown sleep time to 10 seconds.
2023-01-04 15:43:04,767 INFO [io.quarkus] (main) my-app 0.0.1-SNAPSHOT on JVM (powered by Quarkus 2.7.5.Final) started in 3.124s. Listening on: http://0.0.0.0:8081
2023-01-04 15:43:04,768 INFO [io.quarkus] (main) Profile integration activated.
...(application runs normally; sends a message to in memory AMQ broker and Camel starts consuming from the queue)
And the 2nd test runs with these logs:
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup (total:8 started:8)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route1 (activemq://queue:myqueue)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route2 (activemq://queue:myqueue.online)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started main (direct://main)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started individual-endpoint (direct://individual-endpoint)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started send-and-retry (direct://send-and-retry)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started mapping-response (direct://mapping-response)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started reply-queue (direct://reply-queue)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route3 (direct://receive.ack.response)
2023-01-04 15:43:59,606 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.14.1 (camel-1) started in 452ms (build:0ms init:202ms start:250ms)
2023-01-04 15:43:59,607 DEBUG [org.apa.cam.imp.DefaultCamelContext] (main) start() took 453 millis
2023-01-04 15:43:59,631 INFO [com.example.MyLogger] (main) Application is up
2023-01-04 15:43:59,631 INFO [com.example.MyLogger] (main) Application is up
2023-01-04 15:43:59,617 DEBUG [org.apa.cam.mai.SimpleMainShutdownStrategy] (camel-main) Await shutdown to complete
2023-01-04 15:43:59,756 INFO [com.example.MyLogger] (main) Application is down
2023-01-04 15:43:59,756 INFO [com.example.MyLogger] (main) Application is down
2023-01-04 15:43:59,757 DEBUG [org.apa.cam.mai.SimpleMainShutdownStrategy] (main) Shutdown called
2023-01-04 15:43:59,757 DEBUG [org.apa.cam.mai.MainLifecycleStrategy] (main) CamelContext: camel-1 is stopping, triggering shutdown of the JVM.
The class ShutdownController listens for Quarkus shutdown event.
public class ShutdownController implements ShutdownListener {
static final Logger LOGGER = LoggerFactory.getLogger(ShutdownController.class);
private final long preShutdownSleep;
public ShutdownController() {
this.preShutdownSleep = (Long)ConfigProvider.getConfig().getOptionalValue("com.example.shutdown-controller.pre-shutdown-sleep", Long.class).orElse(ProfileManager.getLaunchMode() == LaunchMode.TEST ? 0L : 10L);
LOGGER.info("Setting pre shutdown sleep time to {} seconds.", this.preShutdownSleep);
}
public ShutdownController(final int preShutdownSleep) {
this.preShutdownSleep = (long)preShutdownSleep;
}
public void preShutdown(final ShutdownNotification notification) {
LOGGER.info("Pre shutdown received. Waiting fully functionally for {} seconds.", this.preShutdownSleep);
this.sleep();
LOGGER.info("Continuing shutdown");
notification.done();
}
private void sleep() {
try {
TimeUnit.SECONDS.sleep(this.preShutdownSleep);
} catch (InterruptedException var2) {
Thread.currentThread().interrupt();
}
}
}
Notice that Camel SimpleMainShutdownStrategy is called but in the second test, it does not wait for 10s. Why?
I see this part in SimpleMainShutdownStrategy class:
#Override
public boolean isRunAllowed() {
return !completed.get();
}
#Override
public void addShutdownListener(ShutdownEventListener listener) {
listeners.add(listener);
}
#Override
public boolean shutdown() {
if (completed.compareAndSet(false, true)) {
LOG.debug("Shutdown called");
latch.countDown();
for (ShutdownEventListener l : listeners) {
try {
LOG.trace("ShutdownEventListener: {}", l);
l.onShutdown();
} catch (Throwable e) {
// ignore as we must continue
LOG.debug("Error during ShutdownEventListener: {}. This exception is ignored.", l, e);
}
}
return true;
}
return false;
}
#Override
public void await() throws InterruptedException {
LOG.debug("Await shutdown to complete");
latch.await();
}
So maybe it is because in the 1st case, ShutdownController has no instance so the constructor is called, and wait for 10s; but in the 2nd test, the instance is created so it does not call constructor. But why shutdown is called before the integration test runs?
In both cases, Quarkus app starts before Camel.
Both tests have similar structure:
#QuarkusIntegrationTest
#QuarkusTestResource(value = WiremockResource.class, restrictToAnnotatedClass = true)
#QuarkusTestResource(value = InMemoryAMQResource.class, restrictToAnnotatedClass = true)
#TestProfile(MyIntegrationTestProfile.class)
class MyOutboundMessageFormatIT extends MyIntegrationTestSupport { // the base class have a lot of fields like connetion, session, etc., which are used in #BeforeAll and #BeforeEach, etc.
private static final Logger LOG = Logger.getLogger(MyOutboundMessageFormatIT.class);
#InjectInMemoryAMQ
protected BrokerService brokerService;
#InjectWiremock
protected WireMockServer wireMockServer;
#Override
WireMockServer getWiremock() {
return wireMockServer;
}
#Override
BrokerService getBroker() {
return brokerService;
}
#BeforeAll
protected static void start() throws Exception {
LOG.debug("Connecting to AMQ");
connectToAMQ();
}
#AfterAll
protected static void stop() throws Exception {
LOG.debug("Stopping AMQ");
session.close();
connection.stop();
connection.close();
}
#BeforeEach
protected void stub() {
// global stubs
stubAllFieldsOK();
stubOauthOK();
}
#AfterEach
protected void clearWiremockRequestsJournal() throws JMSException {
// clear reply queue for next test
consumeOnlineReply();
assertEmptyNonOnlineReply();
waitTillTokenExpires();
wireMockServer.resetRequests();
}
...

At last, at the end of the log I see the cause:
2023-01-05 14:13:52,530 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.14.1 (camel-1) shutdown in 942ms (uptime:1s341ms)
2023-01-05 14:13:52,549 ERROR [io.qua.run.Application] (main) Port 8081 seems to be in use by another process. Quarkus may already be running or the port is used by another application.
2023-01-05 14:13:52,549 WARN [io.qua.run.Application] (main) Use 'netstat -anop | grep 8081' to identify the process occupying the port.
2023-01-05 14:13:52,549 WARN [io.qua.run.Application] (main) You can try to kill it with 'kill -9 <pid>'.
So actually there cannot be 2 integration tests running; seems Quarkus application can only start once and will occupy the port.
At last, I solved this by allowing duplicate message in my ActiveMQ in memory broker URL, and put all cases into one test.
The original issue is that I was reusing the JSON message body between tests, and somehow ActiveMQ is ignoring the message, so no message entered the queue, so 2nd test was not running; also, changing stubbing out of Wiremock resource class seems impossible(at first I let Wiremock return 200, but in the last test I want to simulate 404 case), that's why I wanted to separate the tests.
Now, I use an id to mark the stub I want to change, and in test I call wiremockServer.editStub() to change the stub, also I stop tests from running in parallel with #TestMethodOrder(value = MethodOrderer.MethodName.class), then things start to work. So no dividing into 2 test classes is needed now.

Related

Embedded ActiveMQ connection taking a long time to shutdown

I'm using Camel with embedded ActiveMQ for some functional tests. But after the tests have run, ActiveMQ is having trouble shutting down, and I see logs like this:
2022-01-31 19:12:34,873 [MQ ShutdownHook] INFO BrokerService - Apache ActiveMQ 5.15.9 (localhost, ID:8dc9dbba2775-37769-1643655318556-0:2) is shutting down
...
2022-01-31 19:12:34,875 [MQ ShutdownHook] INFO TransportConnector - Connector tcp://localhost:0 stopped
2022-01-31 19:12:35,052 [m://localhost#4] INFO PooledConnectionFactory - Expiring connection ActiveMQConnection {id=ID:8dc9dbba2775-37769-1643655318556-4:3,clientId=ID:8dc9dbba2775-37769-1643655318556-3:2,started=false} on IOException: peer (vm://localhost#5) stopped.
...
2022-01-31 19:12:35,053 [MQ ShutdownHook] INFO BrokerService - Apache ActiveMQ 5.15.9 (localhost, ID:8dc9dbba2775-37769-1643655318556-0:19) is shutdown
2022-01-31 19:12:40,052 [MQ ShutdownHook] INFO TransportConnection - The connection to 'vm://localhost#12' is taking a long time to shutdown.
2022-01-31 19:12:45,052 [MQ ShutdownHook] INFO TransportConnection - The connection to 'vm://localhost#12' is taking a long time to shutdown.
2022-01-31 19:12:50,053 [MQ ShutdownHook] INFO TransportConnection - The connection to 'vm://localhost#12' is taking a long time to shutdown.
A connection shutdown is failing and keeps repeating that last message.
The config is done programmatically for the tests :
private static void addActiveMqComponent()
{
if ( FunctionalTestFramework.framework().context().getComponent("activemq2") == null)
{
JmsConfiguration jmsConfig = new JmsConfiguration();
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost:61616?broker.persistent=false");
connectionFactory.setTrustAllPackages(true);
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setInitialRedeliveryDelay(1000);
redeliveryPolicy.setRedeliveryDelay(1000);
redeliveryPolicy.setBackOffMultiplier(3.5);
redeliveryPolicy.setUseExponentialBackOff(true);
redeliveryPolicy.setMaximumRedeliveries(-1);
connectionFactory.setRedeliveryPolicy(redeliveryPolicy);
jmsConfig.setConnectionFactory(connectionFactory );
transactionManager = new JmsTransactionManager();
transactionManager.setConnectionFactory(connectionFactory);
jmsConfig.setTransactionManager(transactionManager);
ActiveMQComponent activeMqComponent = new ActiveMQComponent();
activeMqComponent.setConfiguration(jmsConfig);
activeMqComponent.setTransacted(true);
activeMqComponent.setCacheLevelName("CACHE_CONSUMER");
FunctionalTestFramework.framework().context().addComponent("activemq2", activeMqComponent);
}
}
I've seen some other threads suggesting to set useShutdownHook="false" but it only applies when they're explicitly triggering shutdown (broker.stop()) which I'm not doing. And I'm not finding much else on this specific problem.
Any ideas on what the issue could be?

Why is CamelExchangesFailed_total metrics not increased?

I have a Apache Camel application which is monitored by Prometheus. Therefore, I added Micrometer to my POM (see Spring Boot Auto-Configuration) and MicrometerRoutePolicyFactory to my application (see Using Micrometer Route Policy Factory). But the metric CamelExchangesFailed_total doesn't change, althought a route failed.
Source
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
#Bean
public MicrometerRoutePolicyFactory micrometerRoutePolicyFactory() {
return new MicrometerRoutePolicyFactory();
}
#Bean
public EndpointRouteBuilder route() {
return new EndpointRouteBuilder() {
#Override
public void configure() throws Exception {
errorHandler(deadLetterChannel("log:dead"));
from(timer("testTimer").repeatCount(1)).throwException(new RuntimeException());
}
};
}
}
Logs
INFO 5060 --- [ restartedMain] o.a.c.i.e.InternalRouteStartupManager : Route: route1 started and consuming from: timer://testTimer
INFO 5060 --- [ restartedMain] o.a.c.impl.engine.AbstractCamelContext : Total 1 routes, of which 1 are started
INFO 5060 --- [ restartedMain] o.a.c.impl.engine.AbstractCamelContext : Apache Camel 3.5.0 (camel-1) started in 0.007 seconds
INFO 5060 --- [ restartedMain] test.TestApplication : Started TestApplication in 6.626 seconds (JVM running for 7.503)
INFO 5060 --- [on(3)-127.0.0.1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
INFO 5060 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
INFO 5060 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Completed initialization in 5 ms
INFO 5060 --- [mer://testTimer] dead : Exchange[ExchangePattern: InOnly, BodyType: null, Body: [Body is null]]
Metrics
# HELP CamelExchangesFailed_total
# TYPE CamelExchangesFailed_total counter
CamelExchangesFailed_total{application="test",camelContext="camel-1",routeId="route1",serviceName="MicrometerRoutePolicyService",} 0.0
# HELP CamelExchangesSucceeded_total
# TYPE CamelExchangesSucceeded_total counter
CamelExchangesSucceeded_total{application="test",camelContext="camel-1",routeId="route1",serviceName="MicrometerRoutePolicyService",} 1.0
Resaerch
If I remove the custom error handler, the metric CamelExchangesFailed_total is increased, but then the default error handler is used, which is not desired for some reasons.
Question
Why is CamelExchangesFailed_total metrics not increased? Is there any way to count all failed routes with a custom error handler?
Apache Camel LTS version 3.7.0 added a new metric CamelExchangesFailuresHandled_total, which is a counter of handled errors, see CAMEL-15908:
Similar to CAMEL-15255, there are some additional counter metrics we could add to the MicrometerRoutePolicy for:
Total exchanges processed
Number of failures handled
Number of external redeliveries
Metrics
# HELP CamelExchangesFailed_total
# TYPE CamelExchangesFailed_total counter
CamelExchangesFailed_total{application="test",camelContext="camel-1",routeId="route1",serviceName="MicrometerRoutePolicyService",} 0.0
# HELP CamelExchangesSucceeded_total
# TYPE CamelExchangesSucceeded_total counter
CamelExchangesSucceeded_total{application="test",camelContext="camel-1",routeId="route1",serviceName="MicrometerRoutePolicyService",} 1.0
# HELP CamelExchangesFailuresHandled_total
# TYPE CamelExchangesFailuresHandled_total counter
CamelExchangesFailuresHandled_total{application="test",camelContext="camel-1",routeId="route1",serviceName="MicrometerRoutePolicyService",} 1.0

concurrentConsumers not created right away from beginning

I am using Camel in a Spring-Boot application to route from AMQ-Queue. Messages from this queue will be sent to a REST-Webservice. It is already working with this code line:
from("amq:queue:MyQueue").process("jmsToHttpProcessor").to(uri);
My uri looks like this:
http4://localhost:28010/application/createCustomer
Now I have the requirement that the routing to the Webservice should be done parallely:
In order to achive that, I configured concurrentConsumers in JmsConfiguration as follows:
#Bean
public JmsComponent amq(#Qualifier("amqConnectionFactory") ConnectionFactory amqConnectionFactory, AMQProperties amqProperties) {
JmsConfiguration jmsConfiguration = new JmsConfiguration(amqConnectionFactory);
jmsConfiguration.setConcurrentConsumers(50);
jmsConfiguration.setMaxConcurrentConsumers(50);
return new JmsComponent(jmsConfiguration);
}
#Bean
public ConnectionFactory amqConnectionFactory(AMQProperties amqProperties) throws Exception {
ConnectionFactoryParser parser = new ConnectionFactoryParser();
ConnectionFactory returnValue = parser.newObject(parser.expandURI(amqProperties.getUrl()), "amqConnectionFactory");
return returnValue;
}
It is working as expected, BUT not right away from the beginning. I have the phenomenon:
I have 100 messages in the ActiveMQ queue
I start my Spring application
Camel creates only 1 thread consuming 1 message after the previous one gets response
I observe that the amount of messages in queue only decreasing slowly(99.... 98... 97... 96...)
I am filling the queue with new 100 messages
NOW the concurrent consumers are being created as I can observe that the messages decreasing rapidly.
Does someone have any idea, why the concurrentConsumers is not working right away from the beginning?
I tried the advices. Unfortunately they dont change the behaviour. I found out, that the problem is that Camel already starts consuming the messages from the queue before the Spring boot application is startet. I can observe this from the log:
2021-04-01T20:26:33,901 INFO (Camel (CamelBridgeContext) thread #592 - JmsConsumer[MyQueue]) [message]; ...
2021-04-01T20:26:33,902 INFO (Camel (CamelBridgeContext) thread #592 - JmsConsumer[MyQueue]) [message]; ...
2021-04-01T20:26:33,915 INFO (main) [AbstractConnector]; _; Started ServerConnector#5833f5cd{HTTP/1.1,[http/1.1]}{0.0.0.0:23500}
2021-04-01T20:26:33,920 INFO (main) [BridgeWsApplication]; _; Started BridgeWsApplication in 12.53 seconds (JVM running for 13.429)
In this case, only one consumer with thread #592 is consuming all the messages.
In fact, if I start my Spring application first, and then fill the queue with messages, then concurrentConsumers will be used:
2021-04-01T20:30:20,159 INFO (Camel (CamelBridgeContext) thread #594 - JmsConsumer[MyQueue])
2021-04-01T20:30:20,159 INFO (Camel (CamelBridgeContext) thread #599 - JmsConsumer[MyQueue])
2021-04-01T20:30:20,178 INFO (Camel (CamelBridgeContext) thread #593 - JmsConsumer[MyQueue])
2021-04-01T20:30:20,204 INFO (Camel (CamelBridgeContext) thread #564 - JmsConsumer[MyQueue])
In this case, messages are being consumed from concurrentConsumers parallely.
In order to solve the problem, I tried setting autoStartUp to false in my RouteBuilder component:
#Override
public void configure() {
CamelContext context = getContext();
context.setAutoStartup(false);
// My Route
}
In my naive thinking, I let Camel starting after the Spring boot is started and running:
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(BridgeWsApplication.class, args);
SpringCamelContext camel = (SpringCamelContext) context.getBean("camelContext");
camel.start();
try {
camel.startAllRoutes();
} catch (Exception e) {
e.printStackTrace();
}
}
Unfortunately, this does not change the behaviour. There must be a configuration to let Camel starts after Spring is started.

How to consume messages from a Topic ActiveMQ Artemis

I'm trying to work with topics on ActiveMQ Artemis.
I have created a Multicast Address and a Multicast Queue inside this Address.
Created 2 routes with Apache Camel to connect in this Topic, but when I post message only one Route consume the message and when I post another message, the secont Route that consume this message message.
Below the code and the output.
public class CamelRoutes {
public static void main(String[] args) throws Exception {
ActiveMQJMSConnectionFactory connection = new ActiveMQJMSConnectionFactory("tcp://localhost:61616", "admin", "admin");
CamelContext camel = new DefaultCamelContext();
camel.addComponent("amq", JmsComponent.jmsComponent(connection));
camel.addRoutes(new RouteBuilder(){
#Override
public void configure() throws Exception {
from("amq:TEST.TOPIC")
.routeId("Route1")
.log("ROUTE1: ${body}");
}
});
camel.addRoutes(new RouteBuilder(){
#Override
public void configure() throws Exception {
from("amq:TEST.TOPIC")
.routeId("Route2")
.log("ROUTE2: ${body}");
}
});
camel.start();
Thread.sleep(20000000);
}
}
2019-02-11 16:35:42 [Camel (camel-1) thread #1 - JmsConsumer[TEST.TOPIC]] INFO Route1:159 - ROUTE1: {"message":1}
2019-02-11 16:35:45 [Camel (camel-1) thread #2 - JmsConsumer[TEST.TOPIC]] INFO Route2:159 - ROUTE2: {"message":2}
2019-02-11 16:35:48 [Camel (camel-1) thread #1 - JmsConsumer[TEST.TOPIC]] INFO Route1:159 - ROUTE1: {"message":3}
2019-02-11 16:35:51 [Camel (camel-1) thread #2 - JmsConsumer[TEST.TOPIC]] INFO Route2:159 - ROUTE2: {"message":4}
2019-02-11 16:35:54 [Camel (camel-1) thread #1 - JmsConsumer[TEST.TOPIC]] INFO Route1:159 - ROUTE1: {"message":5}
You are consuming from the queue, not from the topic.
You need to correct your consumer's URI scheme.
Change your consumer to:
from("amq:topic:TEST.TOPIC");
This is how you can create queue consumer :
from("amq:queue:YOUR.QUEUE.NAME);
// or as queue is default value
from("amq:YOUR.QUEUE.NAME);
This is how you can create topic consumer :
from("amq:topic.YOUR.TOPIC.NAME);

Camel Stopping With No Apparent Reason

I have a bean producer and a bean consumer, used in a single route. The producer is spawned via a thread and listens for data on an hazelcast queue (it could be anything else, even randomly generated data locally I believe).
The data are sent to a seda endpoint, to ensure concurrency.
The consumer gets data and forwards it to another hazelcast queue. But again it could be anything else.
It works well but after a while, Camel shuts down and I can't find why.
Here are some of the messages I see:
Processing a lot of data...
[ main] MainSupport INFO Apache Camel 2.10.3 stopping
[ main] DefaultCamelContext INFO Apache Camel 2.10.3 (CamelContext: camel-1) is shutting down
[ main] DefaultShutdownStrategy INFO Starting to graceful shutdown 1 routes (timeout 300 seconds)
[el-1) thread #2 - ShutdownTask] DefaultShutdownStrategy INFO Waiting as there are still 1 inflight and pending exchanges to complete, timeout in 300 seconds.
then processing still during 300 seconds and stopping.
Here some of the code:
Producer:
public void run()
{
try
{
IRequest service = ProxyHelper.createProxy(context.getEndpoint("seda:echo"), IRequest.class);
BlockingQueue<Request> q = client.getQueue(MainApp.sQueueReceive);
while(true)
{
Request request;
request = q.take();
// no response awaited
service.request(request);
}
}
Consumer:
public void onMessage(Request request)
{
nb_forwarded++;
BlockingQueue<Request> q = MainApp.client.getQueue(MainApp.sQueueForward);
try
{
q.put(request);
}
catch (InterruptedException e)
{
exit(2); --> it does not happen
}
And finally, the route:
from("seda:echo")
.setExchangePattern(ExchangePattern.InOnly)
.bean(new HazelcastForwarder(), "onMessage");
It's in InOnly as no response is awaited from the producer, it is just a forward.
So why Camel is stopping. There is no message appart from those saying that it is stopping. Is there such a default behaviour in Camel. In which cases?
Thanks!
Enable DEBUG or Trace logging to reveil the true reason why camel is stopping. It can be that the enclosing container is stopping (if you are running camel inside something) or similar.
I was facing the similar issue, where Camel Context is closing immediately after starting the process. I am posting here so that it would also help others with similar issue.
In my case, I am using Spring for loading the Camel context using 'FileSystemXmlApplicationContext' and instantiating it with in try block,
try(AbstractXmlApplicationContext appContext = new FileSystemXmlApplicationContext(camelContextPath)) {
}
as my Eclipse was complaining about Resource leak. So, as soon as the call was coming out of the try/catch it was closing the Spring context, which again closing the Camel Context.
To fix the issue need to initialize Spring context out side the try block.
AbstractXmlApplicationContext appContext = null;
try {
appContext = new FileSystemXmlApplicationContext(camelContextPath);
}

Resources