shashank created CAMEL-25848:
--------------------------------
Summary: camel-quartz - CronScheduledRoutePolicy /
SimpleScheduledRoutePolicy: a consumer that cannot be suspended (netty, mina,
mllp, paho, ...) is stopped by the scheduled suspend and never started again by
the scheduled resume
Key: CAMEL-25848
URL: https://issues.apache.org/jira/browse/CAMEL-25848
Project: Camel
Issue Type: Bug
Components: camel-quartz
Reporter: shashank
Assignee: shashank
{{ScheduledRoutePolicy.onJobExecute}} (camel-quartz, main 20cdb309f7d0, lines
64-99) is shared by {{CronScheduledRoutePolicy}} and
{{SimpleScheduledRoutePolicy}}. The scheduled suspend calls
{{suspendOrStopConsumer(route.getConsumer())}}, which suspends a
{{Suspendable}} consumer and *stops* any other consumer
({{ServiceHelper.suspendService}}). The route itself stays {{Started}}.
The scheduled resume and start only look for a suspended consumer:
{code:java}
} else if (action == Action.RESUME) {
if (routeStatus == ServiceStatus.Started) {
if (ServiceHelper.isSuspended(route.getConsumer())) {
resumeOrStartConsumer(route.getConsumer());
} else {
LOG.warn("The Consumer {} is not suspended and cannot be resumed.",
route.getConsumer());
}
{code}
The START action of a {{Started}} route has the same {{isSuspended}} check. A
stopped consumer is not suspended, so after the first scheduled suspend a
consumer that is not {{Suspendable}} is never started again: every scheduled
resume logs the WARN above, and the route stays {{Started}} without a consumer
until someone restarts the route or the application.
Consumers that are not {{Suspendable}} on main include those of camel-netty
(TCP/UDP), camel-mina, camel-mllp, camel-paho, camel-paho-mqtt5, camel-grpc,
camel-azure-servicebus, camel-azure-eventhubs, camel-google-pubsub,
camel-aws2-kinesis (KCL), camel-debezium and camel-mongodb (tailable cursor,
change streams). The page of the policy describes exactly this use: suspension
stops the consumer "from listening on a given port" and resumption makes the
route accept requests again. For example a nightly maintenance window
({{routeSuspendTime}} / {{routeResumeTime}}) on a netty or MLLP listener leaves
the port closed for good after the first night.
{{resumeOrStartConsumer}} itself already starts a stopped consumer that is not
{{Suspendable}} (the throttling route policies rely on it); only the guard in
front of it is too narrow.
*Fix*: a scheduled resume, and a scheduled start of a {{Started}} route, resume
or start the consumer when it is suspended *or stopped*. Nothing else changes:
a stopped route is still started with {{startRoute}}, and a running consumer
still gets the WARN on resume.
*Tests*: new {{ScheduledRoutePolicyNonSuspendableConsumerTest}} (2 tests) with
a test endpoint whose consumer is a plain {{DefaultConsumer}} (not
{{Suspendable}}). {{scheduledResumeStartsConsumerThatWasStoppedBySuspend}} uses
a {{SimpleScheduledRoutePolicy}} with a suspend date and a resume date and real
Quartz triggers; on main the suspend stops the consumer and the resume never
starts it ({{ConditionTimeoutException ... consumer should be started again ==>
expected: <true> but was: <false> within 5 seconds}}).
{{scheduledStartStartsConsumerThatWasStoppedBySuspend}} runs the SUSPEND and
START actions of a {{CronScheduledRoutePolicy}} as the scheduler would; on main
it fails with {{consumer should be started again ==> expected: <true> but was:
<false>}}. Both pass with the fix. camel-quartz unit tests with the fix: 110
run, 0 failures.
*How it was found*: a review of the route policies that suspend a consumer,
comparing how each one undoes {{suspendOrStopConsumer}} (the throttling
policies call {{resumeOrStartConsumer}} directly; the scheduled policies guard
it with {{isSuspended}}). The JUnit tests above are the evidence; it was not
run with a netty or MLLP route.
*Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x and camel-4.14.x
(the same {{isSuspended}} checks in {{ScheduledRoutePolicy}}, lines 72 and 90,
and {{NettyConsumer}} is not {{Suspendable}} on each; read, not run). The check
on the START action came with CAMEL-5555 (start of a suspended route).
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)