You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by "oscerd (via GitHub)" <gi...@apache.org> on 2026/09/22 08:45:59 UTC
[PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
oscerd opened a new pull request, #26733:
URL: https://github.com/apache/camel/pull/26733
## What
`DebeziumEngine.create(Connect.class)` resolves through
`META-INF/services/io.debezium.engine.DebeziumEngine$BuilderFactory` to `ConvertingAsyncEngineBuilderFactory`,
so the consumer runs an `AsyncEmbeddedEngine`. That engine's `run()` wraps its whole body in its own
`catch (Throwable)`, logs the failure and reports it through the `CompletionCallback` — it never rethrows.
`DebeziumConsumer` registered no such callback, so:
* the `catch (Throwable)` around `dbzEngine.run()` could never fire — it was dead code;
* `getExceptionHandler()` was only ever called from `onEventListener`, i.e. for a failure of the **route**,
never for a failure of the **engine**;
* `ConsumerHealthCheck` only consults a consumer that implements `HealthCheckAware`, and this one did not.
A connector that cannot start — bad credentials, an unreachable database, a missing table, a failed
snapshot, an unreadable offset store — therefore left the route **started and healthy** while delivering
nothing, with no signal anywhere except a line in the Debezium logger.
The same root cause had a second symptom: once the engine has failed its state is `STOPPED`, and
`close()` throws on that state (`"Engine has been already shut down."`). `doStop()` called it unguarded,
so stopping such a route threw, the single-thread executor was never shut down and `super.doStop()` never ran.
## Changes
* `DebeziumConsumer` registers a `CompletionCallback`. On failure it hands the cause to
`getExceptionHandler()` and keeps it for the health check. A clean stop is logged at DEBUG.
* New `DebeziumConsumerHealthCheck` (same shape as `ScheduledPollConsumerHealthCheck`, `camel-api` types
only — no new dependency) reports `DOWN` with the engine error, `UP` otherwise. Registered from
`doBuild()` as `consumer:<routeId>`, the same idiom `ScheduledPollConsumer` uses.
* `doStop()` skips `close()` when the engine has already stopped, and catches the `IllegalStateException`
for the race where it stops in between.
* The `catch (Throwable)` around `run()` is kept, but now routes into the same failure path instead of
only logging — a safety net rather than dead code.
* The engine is still **not** restarted automatically; this change only makes the failure observable.
## Tests
`DebeziumConsumerEngineFailureTest` points the existing file-connector harness at an unreadable offset
store, which makes the engine fail with
`ConnectException: java.io.StreamCorruptedException: invalid stream header`, and asserts the failure
reaches the consumer exception handler and the health check goes `DOWN`.
`DebeziumConsumerTest` additionally asserts a consumer with a live engine stays `UP`.
Verified by reverting the fix and re-running: the new test then fails on
*"the engine failure should be handed to the consumer exception handler"*, i.e. it genuinely catches the
reported bug rather than passing by construction. Full module suite green (18 tests), full reactor
`mvn clean install -DskipTests -DskipITs` green.
## Docs
The "Note on handling failures" block in the six connector docs gains a paragraph, and there is an
upgrade-guide entry for 4.23 because a deployment with a dead engine now reports `DOWN` where it
previously reported `UP`.
_Claude Code on behalf of oscerd_
🤖 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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "oscerd (via GitHub)" <gi...@apache.org>.
oscerd commented on code in PR #26733:
URL: https://github.com/apache/camel/pull/26733#discussion_r4080047067
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumer.java:
##########
@@ -61,15 +76,23 @@ protected void doStart() throws Exception {
try {
dbzEngine.run();
} catch (Throwable e) {
- LOG.error("Debezium engine has failed: {}", e.getMessage(), e);
+ // the engine reports its own failures through the completion callback and is not
+ // expected to throw, so this is only a safety net
+ onEngineCompleted(false, e.getMessage(), e);
}
});
}
@Override
protected void doStop() throws Exception {
- if (dbzEngine != null) {
- dbzEngine.close();
+ if (dbzEngine != null && !engineStopped) {
+ try {
+ dbzEngine.close();
+ } catch (IllegalStateException e) {
+ // the engine refuses to be closed once it has stopped on its own, which happens when it
+ // failed between the check above and this call, and then there is nothing left to close
+ LOG.debug("Debezium engine was already stopped: {}", e.getMessage());
+ }
Review Comment:
Applied in ef9ab0c — you are right, and the comment was describing only one of the three states.
Confirmed against the `AsyncEmbeddedEngine.close()` bytecode: it throws `IllegalStateException` for `STARTING_TASKS` ("Cannot stop engine while tasks are starting, this may lead to leaked resource."), `STOPPING` ("Engine is already being shutting down.") and `STOPPED` ("Engine has been already shut down."). Only the last is benign, so the level is now keyed on `engineStopped` exactly as you suggested, and the comment says what the three states are.
_Claude Code on behalf of oscerd_
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumerHealthCheck.java:
##########
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.util.Map;
+
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckResultBuilder;
+import org.apache.camel.util.URISupport;
+
+/**
+ * {@link HealthCheck} reporting the state of the embedded Debezium engine that backs a {@link DebeziumConsumer}.
+ * <p>
+ * The engine runs on its own thread and does not restart itself, so once it has stopped with an error the route no
+ * longer receives change events even though it is still started. This check turns the route DOWN in that case.
+ */
+public class DebeziumConsumerHealthCheck implements HealthCheck {
+
+ private final DebeziumConsumer consumer;
+ private final String id;
+ private final String sanitizedUri;
+ private boolean enabled = true;
+
+ public DebeziumConsumerHealthCheck(DebeziumConsumer consumer, String id) {
+ this.consumer = consumer;
+ this.id = id;
+ this.sanitizedUri = URISupport.sanitizeUri(consumer.getEndpoint().getEndpointUri());
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public String getGroup() {
+ return "camel";
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public Result call(Map<String, Object> options) {
+ final HealthCheckResultBuilder builder = HealthCheckResultBuilder.on(this);
+
+ // ensure to sanitize uri, so we do not show sensitive information such as passwords
+ builder.detail(ENDPOINT_URI, sanitizedUri);
+
+ if (!isEnabled()) {
+ builder.message("Disabled");
+ builder.detail(CHECK_ENABLED, false);
+ return builder.unknown().build();
+ }
+
+ final Throwable failure = consumer.getEngineFailure();
Review Comment:
Agreed, and not adopting it for that reason. `ScheduledPollConsumerHealthCheck` can start from `DOWN` only because `consumer.isConsumerReady()` flips after the first successful poll; this consumer has no equivalent signal, so `builder.state(initialState)` on the `failure == null` path would leave the route `DOWN` forever wherever `initialState=DOWN` is configured — a regression, not a consistency win.
`ConnectorCallback.taskStarted()` is indeed the right hook if startup readiness is ever wanted. Noted for a follow-up rather than this PR.
_Claude Code on behalf of oscerd_
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet commented on PR #26733:
URL: https://github.com/apache/camel/pull/26733#issuecomment-5829571313
<!-- camel-backport-bot -->
### 🔄 Backport Bot
**Conflicts (🤖 agent dispatched to resolve):**
- ⚠️ `camel-4.22.x` — Cherry-pick conflict in: docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc, docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
ℹ️ If you push additional commits after `/port`, use `/port` again to update the port PRs.
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #26733:
URL: https://github.com/apache/camel/pull/26733#issuecomment-5773670158
:star2: Thank you for your contribution to the Apache Camel project! :star2:
:robot: CI automation will test this PR automatically.
:camel: Apache Camel Committers, please review the following items:
* First-time contributors **require MANUAL approval** for the GitHub Actions to run
* You can use the command `/component-test (camel-)component-name1 (camel-)component-name2..` to request a test from the test bot although they are normally detected and executed by CI.
* You can label PRs using `skip-tests` and `test-dependents` to fine-tune the checks executed by this PR.
* Build and test logs are available in the summary page. **Only** [Apache Camel committers](https://camel.apache.org/community/team/#committers) have access to the summary.
:warning: Be careful when sharing logs. Review their contents before sharing them publicly.
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "oscerd (via GitHub)" <gi...@apache.org>.
oscerd merged PR #26733:
URL: https://github.com/apache/camel/pull/26733
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "davsclaus (via GitHub)" <gi...@apache.org>.
davsclaus commented on code in PR #26733:
URL: https://github.com/apache/camel/pull/26733#discussion_r4070043068
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumer.java:
##########
@@ -61,15 +76,23 @@ protected void doStart() throws Exception {
try {
dbzEngine.run();
} catch (Throwable e) {
- LOG.error("Debezium engine has failed: {}", e.getMessage(), e);
+ // the engine reports its own failures through the completion callback and is not
+ // expected to throw, so this is only a safety net
+ onEngineCompleted(false, e.getMessage(), e);
}
});
}
@Override
protected void doStop() throws Exception {
- if (dbzEngine != null) {
- dbzEngine.close();
+ if (dbzEngine != null && !engineStopped) {
+ try {
+ dbzEngine.close();
+ } catch (IllegalStateException e) {
+ // the engine refuses to be closed once it has stopped on its own, which happens when it
+ // failed between the check above and this call, and then there is nothing left to close
+ LOG.debug("Debezium engine was already stopped: {}", e.getMessage());
+ }
Review Comment:
Question: this catch is broader than the comment describes. Debezium's `close()` throws `IllegalStateException` for three states, not one: `STOPPED` ("Engine has been already shut down.", the benign case), but also "Cannot stop engine while tasks are starting" and "Engine is already being shutting down".
In the tasks-starting case (route stopped during a slow snapshot start, or context shutdown right after startup) the engine has **not** stopped, yet this logs "already stopped" at DEBUG and `shutdownGraceful` then interrupts it. Before this PR that case threw out of `doStop()`, so at least it was visible.
Suggest keying the log level on `engineStopped`, so the genuinely-benign case stays quiet and the other two are visible:
```suggestion
} catch (IllegalStateException e) {
// the engine refuses to be closed once it has stopped on its own, which happens when it
// failed between the check above and this call, and then there is nothing left to close
if (engineStopped) {
LOG.debug("Debezium engine was already stopped: {}", e.getMessage());
} else {
LOG.warn("Debezium engine could not be closed: {}", e.getMessage());
}
}
```
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumerHealthCheck.java:
##########
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.util.Map;
+
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckResultBuilder;
+import org.apache.camel.util.URISupport;
+
+/**
+ * {@link HealthCheck} reporting the state of the embedded Debezium engine that backs a {@link DebeziumConsumer}.
+ * <p>
+ * The engine runs on its own thread and does not restart itself, so once it has stopped with an error the route no
+ * longer receives change events even though it is still started. This check turns the route DOWN in that case.
+ */
+public class DebeziumConsumerHealthCheck implements HealthCheck {
+
+ private final DebeziumConsumer consumer;
+ private final String id;
+ private final String sanitizedUri;
+ private boolean enabled = true;
+
+ public DebeziumConsumerHealthCheck(DebeziumConsumer consumer, String id) {
+ this.consumer = consumer;
+ this.id = id;
+ this.sanitizedUri = URISupport.sanitizeUri(consumer.getEndpoint().getEndpointUri());
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public String getGroup() {
+ return "camel";
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public Result call(Map<String, Object> options) {
+ final HealthCheckResultBuilder builder = HealthCheckResultBuilder.on(this);
+
+ // ensure to sanitize uri, so we do not show sensitive information such as passwords
+ builder.detail(ENDPOINT_URI, sanitizedUri);
+
+ if (!isEnabled()) {
+ builder.message("Disabled");
+ builder.detail(CHECK_ENABLED, false);
+ return builder.unknown().build();
+ }
+
+ final Throwable failure = consumer.getEngineFailure();
Review Comment:
A caution on the `initialState` idea raised in the earlier review, in case it gets picked up: `ScheduledPollConsumerHealthCheck` only gets away with `initialState=DOWN` because `consumer.isConsumerReady()` flips after the first successful poll. `DebeziumConsumer` has no equivalent "ready" signal, so returning `builder.state(initialState)` here when `failure == null` would keep the route `DOWN` forever under `initialState=DOWN`.
If startup readiness is ever wanted, Debezium's `ConnectorCallback.taskStarted()` is the natural hook to flip a ready flag. Not asking for it in this PR — the current `UP`-unless-failed semantics are consistent with the stated scope.
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/test/java/org/apache/camel/component/debezium/DebeziumConsumerEngineFailureTest.java:
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.debezium.util.IoUtil;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.debezium.configuration.FileConnectorEmbeddedDebeziumConfiguration;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.spi.ExceptionHandler;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The embedded engine runs on its own thread and reports a failure only through its completion callback, so without
+ * that callback a connector that cannot start leaves the route started, healthy and silent.
+ */
+public class DebeziumConsumerEngineFailureTest extends CamelTestSupport {
Review Comment:
CLAUDE.md test-visibility rule: new test classes must not be `public`.
```suggestion
class DebeziumConsumerEngineFailureTest extends CamelTestSupport {
```
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/test/java/org/apache/camel/component/debezium/DebeziumConsumerEngineFailureTest.java:
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.debezium.util.IoUtil;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.debezium.configuration.FileConnectorEmbeddedDebeziumConfiguration;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.spi.ExceptionHandler;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The embedded engine runs on its own thread and reports a failure only through its completion callback, so without
+ * that callback a connector that cannot start leaves the route started, healthy and silent.
+ */
+public class DebeziumConsumerEngineFailureTest extends CamelTestSupport {
+
+ private static final String ROUTE_ID = "debezium-failing-engine";
+ private static final Path TEST_FILE_PATH
+ = Paths.get("target/data", "camel-debezium-engine-failure-input.txt").toAbsolutePath();
+ private static final Path TEST_OFFSET_STORE_PATH
+ = Paths.get("target/data", "camel-debezium-engine-failure-offset-store.txt").toAbsolutePath();
+
+ @BeforeEach
+ public void beforeEach() throws IOException {
Review Comment:
Same rule applies to `@BeforeEach`/`@AfterEach` methods.
```suggestion
void beforeEach() throws IOException {
```
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/test/java/org/apache/camel/component/debezium/DebeziumConsumerEngineFailureTest.java:
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.debezium.util.IoUtil;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.debezium.configuration.FileConnectorEmbeddedDebeziumConfiguration;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.spi.ExceptionHandler;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The embedded engine runs on its own thread and reports a failure only through its completion callback, so without
+ * that callback a connector that cannot start leaves the route started, healthy and silent.
+ */
+public class DebeziumConsumerEngineFailureTest extends CamelTestSupport {
+
+ private static final String ROUTE_ID = "debezium-failing-engine";
+ private static final Path TEST_FILE_PATH
+ = Paths.get("target/data", "camel-debezium-engine-failure-input.txt").toAbsolutePath();
+ private static final Path TEST_OFFSET_STORE_PATH
+ = Paths.get("target/data", "camel-debezium-engine-failure-offset-store.txt").toAbsolutePath();
+
+ @BeforeEach
+ public void beforeEach() throws IOException {
+ IoUtil.createFile(TEST_FILE_PATH);
+ // an offset store the engine cannot read, which is what a corrupted offset file looks like; the
+ // content must be long enough not to be mistaken for an empty store
+ Files.write(IoUtil.createFile(TEST_OFFSET_STORE_PATH).toPath(),
+ "this is not a serialized offset store".getBytes(StandardCharsets.UTF_8));
+ }
+
+ @AfterEach
+ public void afterEach() throws IOException {
Review Comment:
```suggestion
void afterEach() throws IOException {
```
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "oscerd (via GitHub)" <gi...@apache.org>.
oscerd commented on code in PR #26733:
URL: https://github.com/apache/camel/pull/26733#discussion_r4080049232
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumerHealthCheck.java:
##########
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.util.Map;
+
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckResultBuilder;
+import org.apache.camel.util.URISupport;
+
+/**
+ * {@link HealthCheck} reporting the state of the embedded Debezium engine that backs a {@link DebeziumConsumer}.
+ * <p>
+ * The engine runs on its own thread and does not restart itself, so once it has stopped with an error the route no
+ * longer receives change events even though it is still started. This check turns the route DOWN in that case.
+ */
+public class DebeziumConsumerHealthCheck implements HealthCheck {
+
+ private final DebeziumConsumer consumer;
+ private final String id;
+ private final String sanitizedUri;
+ private boolean enabled = true;
Review Comment:
Thanks — flagging it was worth it, but I am deliberately not taking it, for the reason @davsclaus set out on the `call()` thread below.
`ScheduledPollConsumerHealthCheck` gets away with `initialState=DOWN` because `consumer.isConsumerReady()` flips after the first successful poll, so the check leaves `DOWN` on its own. `DebeziumConsumer` has no equivalent ready signal, so returning `builder.state(initialState)` on the `failure == null` path would pin the route `DOWN` for its whole life wherever `initialState=DOWN` is configured. That is a regression rather than an alignment.
Real startup readiness here needs a ready flag flipped from `ConnectorCallback.taskStarted()`, which is a separate change from failure detection — happy to do it as a follow-up.
On the backport: `port/camel-4.22.x` added, and the matching entry is now in `camel-4x-upgrade-guide-4_22.adoc` on `main`, since the per-release guides for every line live there.
_Claude Code on behalf of oscerd_
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/test/java/org/apache/camel/component/debezium/DebeziumConsumerEngineFailureTest.java:
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.debezium.util.IoUtil;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.debezium.configuration.FileConnectorEmbeddedDebeziumConfiguration;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.spi.ExceptionHandler;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The embedded engine runs on its own thread and reports a failure only through its completion callback, so without
+ * that callback a connector that cannot start leaves the route started, healthy and silent.
+ */
+public class DebeziumConsumerEngineFailureTest extends CamelTestSupport {
Review Comment:
I checked this before applying it and I think the premise is off, so I have left it as is — happy to flip it if you want it as a going-forward convention rather than an existing rule.
* There is no test-visibility rule in `CLAUDE.md` — I grepped the file; the only hit for "visibility" is in the GitHub-star section.
* The convention in this module points the other way: 7 of the 8 test classes under `camel-debezium` are `public` (`DebeziumConsumerTest`, `DebeziumComponentTest`, `DebeziumEndpointTest`, `DebeziumTypeConverterTest`, `ConnectorConfigGeneratorTest`, `ConnectorConfigFieldsFactoryTest`, `ConnectorConfigGeneratorUtilsTest`), with only `ConnectorConfigFieldTest` package-private.
* Repo-wide it is 8646 `public class *Test` against 973 package-private.
That is the same module-consistency argument you made on #26541 about JUnit vs AssertJ assertions, which is why I went with `public` here. If the preference is to move new tests to package-private, say so and I will change all three (class, `beforeEach`, `afterEach`) in one go — it is a one-line change either way.
_Claude Code on behalf of oscerd_
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/test/java/org/apache/camel/component/debezium/DebeziumConsumerEngineFailureTest.java:
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.debezium.util.IoUtil;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.debezium.configuration.FileConnectorEmbeddedDebeziumConfiguration;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.spi.ExceptionHandler;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The embedded engine runs on its own thread and reports a failure only through its completion callback, so without
+ * that callback a connector that cannot start leaves the route started, healthy and silent.
+ */
+public class DebeziumConsumerEngineFailureTest extends CamelTestSupport {
+
+ private static final String ROUTE_ID = "debezium-failing-engine";
+ private static final Path TEST_FILE_PATH
+ = Paths.get("target/data", "camel-debezium-engine-failure-input.txt").toAbsolutePath();
+ private static final Path TEST_OFFSET_STORE_PATH
+ = Paths.get("target/data", "camel-debezium-engine-failure-offset-store.txt").toAbsolutePath();
+
+ @BeforeEach
+ public void beforeEach() throws IOException {
Review Comment:
Same as the class-visibility thread above — not applied, with the numbers there. Will change it together with the class if you want package-private as the convention.
_Claude Code on behalf of oscerd_
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/test/java/org/apache/camel/component/debezium/DebeziumConsumerEngineFailureTest.java:
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.debezium.util.IoUtil;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.debezium.configuration.FileConnectorEmbeddedDebeziumConfiguration;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.spi.ExceptionHandler;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The embedded engine runs on its own thread and reports a failure only through its completion callback, so without
+ * that callback a connector that cannot start leaves the route started, healthy and silent.
+ */
+public class DebeziumConsumerEngineFailureTest extends CamelTestSupport {
+
+ private static final String ROUTE_ID = "debezium-failing-engine";
+ private static final Path TEST_FILE_PATH
+ = Paths.get("target/data", "camel-debezium-engine-failure-input.txt").toAbsolutePath();
+ private static final Path TEST_OFFSET_STORE_PATH
+ = Paths.get("target/data", "camel-debezium-engine-failure-offset-store.txt").toAbsolutePath();
+
+ @BeforeEach
+ public void beforeEach() throws IOException {
+ IoUtil.createFile(TEST_FILE_PATH);
+ // an offset store the engine cannot read, which is what a corrupted offset file looks like; the
+ // content must be long enough not to be mistaken for an empty store
+ Files.write(IoUtil.createFile(TEST_OFFSET_STORE_PATH).toPath(),
+ "this is not a serialized offset store".getBytes(StandardCharsets.UTF_8));
+ }
+
+ @AfterEach
+ public void afterEach() throws IOException {
Review Comment:
Same as above.
_Claude Code on behalf of oscerd_
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #26733:
URL: https://github.com/apache/camel/pull/26733#issuecomment-5774113107
<!-- ci-tested-modules -->
:test_tube: **CI tested the following changed modules:**
- `catalog/camel-catalog`
- `components/camel-debezium/camel-debezium-common/camel-debezium-common-component`
- `components/camel-debezium/camel-debezium-db2`
- `components/camel-debezium/camel-debezium-mongodb`
- `components/camel-debezium/camel-debezium-mysql`
- `components/camel-debezium/camel-debezium-oracle`
- `components/camel-debezium/camel-debezium-postgres`
- `components/camel-debezium/camel-debezium-sqlserver`
- `docs`
---
<details><summary>:microscope: Scalpel shadow comparison — Scalpel: 15 of 692 tested, 25 compile-only — current: 15 all tested</summary>
[Maveniverse Scalpel](https://github.com/maveniverse/scalpel) detected **42 affected modules** (current approach: 15).
**Skip-tests mode would test 15 modules** (9 direct + 8 downstream), **skip tests for 25** (generated code, meta-modules)
<details><summary>:warning: Modules only in Scalpel (27)</summary>
- `apache-camel`
- `camel-allcomponents`
- `camel-catalog`
- `camel-catalog-console`
- `camel-catalog-maven`
- `camel-catalog-suggest`
- `camel-componentdsl`
- `camel-endpointdsl`
- `camel-endpointdsl-support`
- `camel-itest`
- `camel-jbang-core`
- `camel-jbang-it`
- `camel-jbang-main`
- `camel-jbang-plugin-edit`
- `camel-jbang-plugin-generate`
- `camel-jbang-plugin-kubernetes`
- `camel-jbang-plugin-test`
- `camel-kamelet-main`
- `camel-launcher`
- `camel-report-maven-plugin`
- `camel-route-parser`
- `camel-yaml-dsl`
- `camel-yaml-dsl-deserializers`
- `camel-yaml-dsl-maven-plugin`
- `coverage`
- `docs`
- `dummy-component`
</details>
<details><summary>Modules Scalpel would test (15)</summary>
- `camel-catalog` ← catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/debezium-db2-component.adoc, catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/debezium-mongodb-component.adoc, catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/debezium-mysql-component.adoc, catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/debezium-oracle-component.adoc, catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/debezium-postgres-component.adoc, catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/debezium-sqlserver-component.adoc
- `camel-debezium-common` ← components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumer.java, components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumerHealthCheck.java, components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/test/java/org/apache/camel/component/debezium/DebeziumConsumerEngineFailureTest.java, components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/test/java/org/apache/camel/component/debezium/DebeziumConsumerTest.java
- `camel-debezium-db2` ← components/camel-debezium/camel-debezium-db2/src/main/docs/debezium-db2-component.adoc
- `camel-debezium-mongodb` ← components/camel-debezium/camel-debezium-mongodb/src/main/docs/debezium-mongodb-component.adoc
- `camel-debezium-mysql` ← components/camel-debezium/camel-debezium-mysql/src/main/docs/debezium-mysql-component.adoc
- `camel-debezium-oracle` ← components/camel-debezium/camel-debezium-oracle/src/main/docs/debezium-oracle-component.adoc
- `camel-debezium-postgres` ← components/camel-debezium/camel-debezium-postgres/src/main/docs/debezium-postgres-component.adoc
- `camel-debezium-sqlserver` ← components/camel-debezium/camel-debezium-sqlserver/src/main/docs/debezium-sqlserver-component.adoc
- `camel-jbang-mcp` ← downstream of org.apache.camel:camel-catalog
- `camel-jbang-plugin-mcp` ← downstream of org.apache.camel:camel-jbang-core
- `camel-jbang-plugin-route-parser` ← downstream of org.apache.camel:camel-route-parser
- `camel-jbang-plugin-tui` ← downstream of org.apache.camel:camel-catalog
- `camel-jbang-plugin-validate` ← downstream of org.apache.camel:camel-yaml-dsl-validator
- `camel-launcher-container` ← downstream of org.apache.camel:camel-launcher
- `camel-yaml-dsl-validator` ← downstream of org.apache.camel:camel-catalog
- `camel-yaml-dsl-validator-maven-plugin` ← downstream of org.apache.camel:camel-yaml-dsl-validator
- `docs` ← docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
</details>
<details><summary>Modules with tests skipped (25)</summary>
- `apache-camel`
- `camel-allcomponents`
- `camel-catalog-console`
- `camel-catalog-maven`
- `camel-catalog-suggest`
- `camel-componentdsl`
- `camel-endpointdsl`
- `camel-endpointdsl-support`
- `camel-itest`
- `camel-jbang-core`
- `camel-jbang-it`
- `camel-jbang-main`
- `camel-jbang-plugin-edit`
- `camel-jbang-plugin-generate`
- `camel-jbang-plugin-kubernetes`
- `camel-jbang-plugin-test`
- `camel-kamelet-main`
- `camel-launcher`
- `camel-report-maven-plugin`
- `camel-route-parser`
- `camel-yaml-dsl`
- `camel-yaml-dsl-deserializers`
- `camel-yaml-dsl-maven-plugin`
- `coverage`
- `dummy-component`
</details>
> :information_source: Shadow mode — Scalpel observes but does not affect test execution. [Learn more](https://github.com/maveniverse/scalpel)
</details>
<details><summary>All tested modules (42 modules, 5m 22s total)</summary>
**Total reactor time:** 5m 22s
| Module | Duration | Status |
| --- | --- | --- |
| Camel :: Launcher | 51.7s | SUCCESS |
| Camel :: JBang :: MCP | 39.0s | SUCCESS |
| Camel :: JBang :: Plugin :: TUI | 30.5s | SUCCESS |
| Camel :: Catalog :: Camel Catalog | 21.4s | SUCCESS |
| Camel :: Debezium :: Common | 19.2s | SUCCESS |
| Camel :: Component DSL | 18.9s | SUCCESS |
| Camel :: JBang :: Plugin :: Kubernetes | 14.4s | SUCCESS |
| Camel :: Docs | 14.3s | SUCCESS |
| Camel :: Kamelet Main | 10.0s | SUCCESS |
| Camel :: YAML DSL :: Validator | 8.8s | SUCCESS |
| Camel :: Catalog :: Camel Report Maven Plugin | 7.4s | SUCCESS |
| Camel :: JBang :: Plugin :: Testing | 7.2s | SUCCESS |
| Camel :: Catalog :: Camel Route Parser | 7.2s | SUCCESS |
| Camel :: Debezium :: Oracle | 6.8s | SUCCESS |
| Camel :: Debezium :: PostgreSQL | 6.0s | SUCCESS |
| Camel :: Debezium :: SQL Server | 5.9s | SUCCESS |
| Camel :: YAML DSL :: Deserializers | 5.0s | SUCCESS |
| Camel :: Debezium :: MongoDB | 4.9s | SUCCESS |
| Camel :: Debezium :: MySQL | 4.9s | SUCCESS |
| Camel :: JBang :: Plugin :: Validate | 4.7s | SUCCESS |
| Camel :: All Components Sync point | 4.5s | SUCCESS |
| Camel :: YAML DSL :: Validator Maven Plugin | 4.0s | SUCCESS |
| Camel :: Debezium :: DB2 | 3.7s | SUCCESS |
| Camel :: YAML DSL :: Maven Plugins | 3.4s | SUCCESS |
| Camel :: Catalog :: Maven | 2.6s | SUCCESS |
| Camel :: Catalog :: Suggest (deprecated) | 2.1s | SUCCESS |
| Camel :: Assembly | 1.9s | SUCCESS |
| Camel :: JBang :: Integration tests | 1.4s | SUCCESS |
| Camel :: Coverage | 1.4s | SUCCESS |
| Camel :: JBang :: Plugin :: Edit | 1.4s | SUCCESS |
| Camel :: Catalog :: Console | 1.2s | SUCCESS |
| Camel :: Endpoint DSL :: Support | 1.1s | SUCCESS |
| Camel :: JBang :: Main | 1.1s | SUCCESS |
| Camel :: JBang :: Plugin :: Generate | 1.0s | SUCCESS |
| Camel :: Catalog :: Dummy Component | 0.9s | SUCCESS |
| Camel :: JBang :: Plugin :: MCP | 0.8s | SUCCESS |
| Camel :: Launcher :: Container | 0.7s | SUCCESS |
| Camel :: JBang :: Plugin :: Route Parser | 0.5s | SUCCESS |
| Camel :: Endpoint DSL | n/a | |
| Camel :: Integration Tests | n/a | |
| Camel :: JBang :: Core | n/a | |
| Camel :: YAML DSL | n/a | |
**Top 20 slowest modules:**
- `Camel :: Launcher` (51.7s)
- `Camel :: JBang :: MCP` (39.0s)
- `Camel :: JBang :: Plugin :: TUI` (30.5s)
- `Camel :: Catalog :: Camel Catalog` (21.4s)
- `Camel :: Debezium :: Common` (19.2s)
- `Camel :: Component DSL` (18.9s)
- `Camel :: JBang :: Plugin :: Kubernetes` (14.4s)
- `Camel :: Docs` (14.3s)
- `Camel :: Kamelet Main` (10.0s)
- `Camel :: YAML DSL :: Validator` (8.8s)
- `Camel :: Catalog :: Camel Report Maven Plugin` (7.4s)
- `Camel :: JBang :: Plugin :: Testing` (7.2s)
- `Camel :: Catalog :: Camel Route Parser` (7.2s)
- `Camel :: Debezium :: Oracle` (6.8s)
- `Camel :: Debezium :: PostgreSQL` (6.0s)
- `Camel :: Debezium :: SQL Server` (5.9s)
- `Camel :: YAML DSL :: Deserializers` (5.0s)
- `Camel :: Debezium :: MongoDB` (4.9s)
- `Camel :: Debezium :: MySQL` (4.9s)
- `Camel :: JBang :: Plugin :: Validate` (4.7s)
</details>
---
:gear: [View full build and test results](https://github.com/apache/camel/actions/runs/35706598351)
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "oscerd (via GitHub)" <gi...@apache.org>.
oscerd commented on PR #26733:
URL: https://github.com/apache/camel/pull/26733#issuecomment-5810866985
Rebased onto current `main` (`3511ac6c`) — it had gone `CONFLICTING` again, this time against the `camel-seda` entry that landed at the end of `camel-4x-upgrade-guide-4_23.adoc`, plus the new `4.22.1 to 4.22.2` section in the 4.22 guide. Both resolved by keeping each side; the three reviewed source files are byte-identical to what was approved.
_Claude Code on behalf of oscerd_
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "gnodet-bot (via GitHub)" <gi...@apache.org>.
gnodet-bot commented on code in PR #26733:
URL: https://github.com/apache/camel/pull/26733#discussion_r4082468059
##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc:
##########
@@ -2580,3 +2580,14 @@ Routes that reference the constants (for example `setHeader(MustacheConstants.MU
are unaffected. Routes that set the header by its literal string name, or that use
`allowTemplateFromHeader=true` with the old header names, must switch to the new `Camel`-prefixed
names.
+=== camel-debezium - a failed embedded engine is now reported
Review Comment:
⚠️ **Missing blank line before section heading.** AsciiDoc requires a blank line before a `===` title or the title is rendered as a literal paragraph of text. Every other `===` section in this file is preceded by a blank line; this one isn't — the rebase inserted it flush against the preceding `names.` line.
```suggestion
=== camel-debezium - a failed embedded engine is now reported
```
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "oscerd (via GitHub)" <gi...@apache.org>.
oscerd commented on code in PR #26733:
URL: https://github.com/apache/camel/pull/26733#discussion_r4083098844
##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc:
##########
@@ -2580,3 +2580,14 @@ Routes that reference the constants (for example `setHeader(MustacheConstants.MU
are unaffected. Routes that set the header by its literal string name, or that use
`allowTemplateFromHeader=true` with the old header names, must switch to the new `Camel`-prefixed
names.
+=== camel-debezium - a failed embedded engine is now reported
Review Comment:
Correct, and my fault — the conflict resolution joined the two sides with a single newline and ate the blank line. Fixed in 0eb2056.
I also swept the whole file: three other `===` headings have the same problem — lines 741 (`camel-azure-eventgrid`), 1156 (`camel-langchain4j`) and 1200 (`camel-salesforce`) — and all three are pre-existing on `main`, so I left them alone rather than widen this PR. Worth a follow-up if the convention is being enforced.
Separately, the CI failure on the previous head was not this PR: `camel-jbang-core` failed to compile on `CatalogDocExamplesTest:100` (`cannot find symbol: variable m`). That was base breakage from CAMEL-24917, already fixed on `main` by fa8ab2a7a4b2, and the branch was behind it. This push is rebased onto current `main`, so it carries the fix.
_Claude Code on behalf of oscerd_
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "oscerd (via GitHub)" <gi...@apache.org>.
oscerd commented on PR #26733:
URL: https://github.com/apache/camel/pull/26733#issuecomment-5794788181
Rebased onto current `main` to clear a merge conflict in `camel-4x-upgrade-guide-4_23.adoc` — the `camel-mustache, camel-chunk` entry landed at the same end-of-file spot. Both entries are kept, mine after it; the three reviewed source files are byte-identical to what you approved.
Worth flagging for anyone else hitting this: the local clone here is shallow, so `git rebase origin/main` found **no merge base** and tried to replay unrelated history. Cherry-picking the two commits onto a fresh branch from `origin/main` was the way through.
_Claude Code on behalf of oscerd_
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "oscerd (via GitHub)" <gi...@apache.org>.
oscerd commented on code in PR #26733:
URL: https://github.com/apache/camel/pull/26733#discussion_r4080055166
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumerHealthCheck.java:
##########
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.util.Map;
+
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckResultBuilder;
+import org.apache.camel.util.URISupport;
+
+/**
+ * {@link HealthCheck} reporting the state of the embedded Debezium engine that backs a {@link DebeziumConsumer}.
+ * <p>
+ * The engine runs on its own thread and does not restart itself, so once it has stopped with an error the route no
+ * longer receives change events even though it is still started. This check turns the route DOWN in that case.
+ */
+public class DebeziumConsumerHealthCheck implements HealthCheck {
+
+ private final DebeziumConsumer consumer;
+ private final String id;
+ private final String sanitizedUri;
+ private boolean enabled = true;
Review Comment:
Follow-up filed as [CAMEL-24919](https://issues.apache.org/jira/browse/CAMEL-24919) (Improvement, unassigned) so the readiness idea is not lost: flip a ready flag from `DebeziumEngine.ConnectorCallback.pollingStarted()`, then the `failure == null` branch can honour `initialState` the way `ScheduledPollConsumerHealthCheck` does. Matters most for the connectors whose initial snapshot takes minutes.
_Claude Code on behalf of oscerd_
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-24889: camel-debezium - report a failed embedded engine [camel]
Posted by "gnodet-bot (via GitHub)" <gi...@apache.org>.
gnodet-bot commented on code in PR #26733:
URL: https://github.com/apache/camel/pull/26733#discussion_r4069950375
##########
components/camel-debezium/camel-debezium-common/camel-debezium-common-component/src/main/java/org/apache/camel/component/debezium/DebeziumConsumerHealthCheck.java:
##########
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.debezium;
+
+import java.util.Map;
+
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckResultBuilder;
+import org.apache.camel.util.URISupport;
+
+/**
+ * {@link HealthCheck} reporting the state of the embedded Debezium engine that backs a {@link DebeziumConsumer}.
+ * <p>
+ * The engine runs on its own thread and does not restart itself, so once it has stopped with an error the route no
+ * longer receives change events even though it is still started. This check turns the route DOWN in that case.
+ */
+public class DebeziumConsumerHealthCheck implements HealthCheck {
+
+ private final DebeziumConsumer consumer;
+ private final String id;
+ private final String sanitizedUri;
+ private boolean enabled = true;
Review Comment:
💡 **Optional consistency:** `ScheduledPollConsumerHealthCheck` uses `HealthCheckRegistry.getInitialState()` (typically `DOWN`) so that readiness probes stay `DOWN` until the consumer is confirmed healthy. The current field always initialises to `true` (UP), which means a readiness probe sees `UP` from the moment the route starts, before the engine has connected.
For Debezium this is largely benign — the engine fails fast on a bad offset store or unreachable DB — but if you want to match the `ScheduledPollConsumer` convention:
```suggestion
private boolean enabled = true;
private HealthCheck.State initialState = HealthCheck.State.UP;
```
And in the constructor, after `this.sanitizedUri = ...`:
```java
HealthCheckRegistry registry = HealthCheckRegistry.get(consumer.getEndpoint().getCamelContext());
if (registry != null) {
this.initialState = registry.getInitialState();
}
```
And in `call()`, replace `return builder.up().build()` with `return builder.state(initialState).build()`.
Not a blocker — raising for awareness.
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org