allthingssecurity opened a new pull request, #29045:
URL: https://github.com/apache/camel/pull/29045

   # Description
   
   [CAMEL-26419](https://issues.apache.org/jira/browse/CAMEL-26419)
   
   Follow-up of CAMEL-25861 (#28637), asked for in its review.
   
   Since CAMEL-25861 the cosmosdb consumer starts the change feed processor 
again, with a backoff of 1 to 30 seconds, until it starts or the consumer 
stops, when Cosmos DB is not reachable yet, the lease container does not exist 
yet or a role assignment has not propagated. During that time the route and the 
consumer report `Started` while no change is received; the only signals were 
the first failure on the consumer's `ExceptionHandler` and a WARN per attempt.
   
   ## The change
   
   - New `CosmosDbConsumerHealthCheck` (readiness only, as `HealthCheck` 
defaults to): the initial state of the health checks 
(`camel.health.initial-state`, DOWN by default, read from the registry as the 
Debezium consumer check does since CAMEL-24919) while the first attempt to 
start runs; DOWN while the change feed processor cannot start, with the message 
`The change feed processor has not started yet (<n> failed attempt(s))`, the 
failure of the last attempt as its error and the detail `failed.starts`; UP 
once it has started; UNKNOWN with the message `Disabled` when disabled (as 
`AbstractHealthCheck` of camel-health does). It does not follow what the change 
feed processor does after it started (the docs say so); a check of its state at 
runtime could be a follow-up.
   - `CosmosDbConsumer` sets it as its health check in `doStart` (once), as the 
Kafka consumer does (Debezium sets its check in `doBuild`), so the consumer 
check of the route (`consumer:<routeId>`, `ConsumerHealthCheck` of 
camel-health) reports it when the consumer health checks of Camel are enabled. 
It implements `HealthCheck` directly (camel-api), so the component needs no new 
runtime dependency (camel-health is added for the tests only). The component 
does not get the `healthCheckConsumerEnabled` option of `HealthCheckComponent` 
(it extends `DefaultComponent`; changing that would add component options and 
regenerate the component metadata): the check is left out with 
`camel.health.exclude-pattern=consumer:<routeId>` (or the global consumer 
health check settings).
   - The consumer keeps two volatile fields for it: the change feed processor 
of this start has started (set where the start is signalled, under the existing 
lock and only for the current generation), and the failure of the last attempt 
(recorded only for an attempt of the current generation, under the lock with 
the existing stale check). The count of failed attempts (which CAMEL-25861 
already kept for its INFO line) is now also set there, after the failure, 
instead of before the stale check, so a stale attempt does not change it and a 
DOWN of the check always has a count. `doStart` and `doStop` clear all three, 
so a restart begins in the initial state again. Package-private getters 
`isChangeFeedProcessorStarted()`, `getFailedStarts()`, `getLastStartFailure()` 
for the check.
   - Docs: a "Consumer health check" section under Usage on the component page 
(and its catalog copy).
   - Upgrade guide: two sentences folded into the 4.24 entry of CAMEL-25861: 
the readiness of such a consumer is now the initial state (DOWN by default) 
while the first attempt to start runs and DOWN while its change feed processor 
cannot start (it was UP), as the consumer health checks are on by default; the 
way back is `camel.health.exclude-pattern=consumer:<routeId>`.
   
   Not done: the optional cap on the start attempts that the JIRA mentions. It 
is a new option (component metadata to regenerate) and needs a decision on what 
a started consumer does when it gives up; I left it for a separate change if 
wanted.
   
   Backport: main only (a new check, and it builds on CAMEL-25861).
   
   ## Tests
   
   New `CosmosDbConsumerHealthCheckTest` (camel-azure-cosmosdb, JUnit 
assertions as in the module, 4 tests, with the mocked change feed processor of 
`CosmosDbConsumerFirstStartFailsTest`; waits with Awaitility, no sleeps):
   - the processor cannot start (the lease container "does not exist"): DOWN 
with the failure, `failed.starts` >= 1 and the message; once it can start: UP; 
after the stop: DOWN with no error and `failed.starts` 0;
   - the first start succeeds: UP with 0 failed attempts; after a stop and a 
new start: UP again (2 starts);
   - the change feed processor of the first start is still starting when the 
consumer is stopped and started again, and the one of the second start cannot 
start: when the first start ends, the check stays DOWN (the generation guard);
   - a disabled check is UNKNOWN.
   
   New `CosmosDbConsumerHealthCheckRegistryTest` (3 tests, camel-health's 
`DefaultHealthCheckRegistry` with the consumers repository, a route whose 
consumer uses a mocked change feed processor): the readiness check 
`consumer:<routeId>` is DOWN with the start failure and `failed.starts`, it is 
not DOWN in the liveness checks, and it is UP once the processor started; while 
the first attempt runs it is the configured initial state (DOWN and UP, 
parameterized), and DOWN once that attempt failed.
   
   Mutants (the tests use the new API, so main's consumer does not compile 
against them): the initial state ignored fails the UP case; the started flag 
never set fails 3 tests; set outside the generation guard fails 1 (the restart 
test); `doStop` not clearing the state fails 1; the failure not recorded fails 
6; the disabled check not honoured fails 1. Recording the count before the 
failure (a race window) is not caught by a test, as the tests wait on the 
failure.
   
   - The new classes, `CosmosDbConsumerFirstStartFailsTest` and 
`CosmosDbConsumerStopWhileStartingTest` 20 times in one JVM: 360 tests, 0 
failures.
   - camel-azure-cosmosdb, all tests of the module: 65, 0 failures, 22 skipped 
(the integration tests, which are skipped without Azure credentials).
   - Formatter and import-sort: no changes.
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL-26419) 
filed for the change (usually before you start working on it): 
[CAMEL-26419](https://issues.apache.org/jira/browse/CAMEL-26419).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
     (I built the core modules and camel-azure-cosmosdb and ran the tests 
above, including the formatter and import-sort plugins; the catalog copy of the 
page is identical to the page. I did not run the full root build.)
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
     This PR was prepared with Claude Code (Claude Opus 5.5). The commit 
carries a `Co-Authored-By` trailer.
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to