Skip to content

Commit 3331ba5

Browse files
tkaymakclaude
andcommitted
Upgrade DebeziumIO to Debezium 3.5.2.Final
Debezium 3.5 builds against Kafka Connect 4.1.2, so the connect-api pin moves from 3.9.0 to 4.1.2 and kafka-clients is declared and forced to the same version. Connect 4.1 added an abstract pluginMetrics() to SourceTaskContext; BeamSourceTaskContext returns null, which is safe here because no Debezium 3.5.2 connector calls it. Debezium 3.5 split debezium-core into smaller modules, so debezium-config and debezium-connector-common are now declared explicitly. The expansion-service shadow jar was checked to still bundle the split classes and all five connectors. The Postgres connector needs JDBC driver 42.7.x, so 42.7.7 is forced in this module only, matching the upstream Debezium 3.5.2 pin. The Beam-wide 42.6.2 pin from 24f562d is deliberately left untouched. Test updates for 3.5 behaviour changes: connection failures now surface wrapped in a RetriableException, so the schema transform tests unwrap the cause chain, and the example-mysql image now names its binlog mysql-bin.000003 instead of binlog.000002. 3.6.0 was skipped for now because of open MySQL DDL parser regressions in that line. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent b493cbc commit 3331ba5

10 files changed

Lines changed: 53 additions & 26 deletions

File tree

sdks/go/test/integration/io/xlang/debezium/debezium.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func ReadPipeline(addr, username, password, dbname, host, port string, connector
3131
connectorClass, reflectx.String, debeziumio.MaxRecord(maxrecords),
3232
debeziumio.MaxTimeToRun(120000),
3333
debeziumio.ConnectionProperties(connectionProperties), debeziumio.ExpansionAddr(addr))
34-
expectedJson := `{"metadata":{"connector":"postgresql","version":"3.1.3.Final","name":"beam-debezium-connector","database":"inventory","schema":"inventory","table":"customers"},"before":null,"after":{"fields":{"last_name":"Thomas","id":1001,"first_name":"Sally","email":"sally.thomas@acme.com"}}}`
34+
expectedJson := `{"metadata":{"connector":"postgresql","version":"3.5.2.Final","name":"beam-debezium-connector","database":"inventory","schema":"inventory","table":"customers"},"before":null,"after":{"fields":{"last_name":"Thomas","id":1001,"first_name":"Sally","email":"sally.thomas@acme.com"}}}`
3535
expected := beam.Create(s, expectedJson)
3636
passert.Equals(s, result, expected)
3737
return p

sdks/go/test/integration/io/xlang/debezium/debezium_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import (
3333
)
3434

3535
const (
36-
debeziumImage = "quay.io/debezium/example-postgres:3.1.3.Final"
36+
debeziumImage = "quay.io/debezium/example-postgres:3.5.2.Final"
3737
debeziumPort = "5432/tcp"
3838
maxRetries = 5
3939
)

sdks/java/io/debezium/build.gradle

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ dependencies {
4646
permitUnusedDeclared library.java.jackson_dataformat_csv
4747

4848
// Kafka connect dependencies
49-
implementation "org.apache.kafka:connect-api:3.9.0"
49+
implementation "org.apache.kafka:connect-api:4.1.2"
50+
implementation "org.apache.kafka:kafka-clients:4.1.2"
5051

5152
// Debezium dependencies
52-
implementation group: 'io.debezium', name: 'debezium-core', version: '3.1.3.Final'
53+
implementation group: 'io.debezium', name: 'debezium-core', version: '3.5.2.Final'
54+
implementation group: 'io.debezium', name: 'debezium-config', version: '3.5.2.Final'
55+
implementation group: 'io.debezium', name: 'debezium-connector-common', version: '3.5.2.Final'
5356

5457
// Test dependencies
5558
testImplementation project(path: ":sdks:java:core", configuration: "shadowTest")
@@ -64,12 +67,12 @@ dependencies {
6467
testImplementation "org.testcontainers:kafka"
6568
testImplementation "org.testcontainers:mysql"
6669
testImplementation "org.testcontainers:postgresql"
67-
testImplementation "io.debezium:debezium-testing-testcontainers:3.1.3.Final"
70+
testImplementation "io.debezium:debezium-testing-testcontainers:3.5.2.Final"
6871
testImplementation 'com.zaxxer:HikariCP:5.1.0'
6972

7073
// Debezium connector implementations for testing
71-
testImplementation group: 'io.debezium', name: 'debezium-connector-mysql', version: '3.1.3.Final'
72-
testImplementation group: 'io.debezium', name: 'debezium-connector-postgres', version: '3.1.3.Final'
74+
testImplementation group: 'io.debezium', name: 'debezium-connector-mysql', version: '3.5.2.Final'
75+
testImplementation group: 'io.debezium', name: 'debezium-connector-postgres', version: '3.5.2.Final'
7376
}
7477

7578
// Pin the Antlr version to 4.10
@@ -83,7 +86,9 @@ configurations.all {
8386
'com.fasterxml.jackson.core:jackson-core:2.17.1',
8487
'com.fasterxml.jackson.core:jackson-annotations:2.17.1',
8588
'com.fasterxml.jackson.core:jackson-databind:2.17.1',
86-
'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1'
89+
'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1',
90+
'org.apache.kafka:kafka-clients:4.1.2',
91+
'org.postgresql:postgresql:42.7.7'
8792
}
8893
}
8994

sdks/java/io/debezium/expansion-service/build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ dependencies {
3939
runtimeOnly library.java.slf4j_jdk14
4040

4141
// Debezium runtime dependencies
42-
def debezium_version = '3.1.3.Final'
42+
def debezium_version = '3.5.2.Final'
4343
runtimeOnly group: 'io.debezium', name: 'debezium-connector-mysql', version: debezium_version
4444
runtimeOnly group: 'io.debezium', name: 'debezium-connector-postgres', version: debezium_version
4545
runtimeOnly group: 'io.debezium', name: 'debezium-connector-sqlserver', version: debezium_version
@@ -55,7 +55,9 @@ configurations.all {
5555
'com.fasterxml.jackson.core:jackson-core:2.17.1',
5656
'com.fasterxml.jackson.core:jackson-annotations:2.17.1',
5757
'com.fasterxml.jackson.core:jackson-databind:2.17.1',
58-
'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1'
58+
'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1',
59+
'org.apache.kafka:kafka-clients:4.1.2',
60+
'org.postgresql:postgresql:42.7.7'
5961
}
6062
}
6163

sdks/java/io/debezium/src/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ DebeziumIO is an Apache Beam connector that lets users connect their Events-Driv
2525

2626
### Getting Started
2727

28-
DebeziumIO uses [Debezium Connectors v3.1](https://debezium.io/documentation/reference/3.1/connectors/) to connect to Apache Beam. All you need to do is choose the Debezium Connector that suits your Debezium setup and pick a [Serializable Function](https://beam.apache.org/releases/javadoc/2.65.0/org/apache/beam/sdk/transforms/SerializableFunction.html), then you will be able to connect to Apache Beam and start building your own Pipelines.
28+
DebeziumIO uses [Debezium Connectors v3.5](https://debezium.io/documentation/reference/3.5/connectors/) to connect to Apache Beam. All you need to do is choose the Debezium Connector that suits your Debezium setup and pick a [Serializable Function](https://beam.apache.org/releases/javadoc/2.65.0/org/apache/beam/sdk/transforms/SerializableFunction.html), then you will be able to connect to Apache Beam and start building your own Pipelines.
2929

3030
These connectors have been successfully tested and are known to work fine:
3131
* MySQL Connector
@@ -65,7 +65,7 @@ You can also add more configuration, such as Connector-specific Properties with
6565
|Method|Params|Description|
6666
|-|-|-|
6767
|`.withConnectionProperty(propName, propValue)`|_String_, _String_|Adds a custom property to the connector.|
68-
> **Note:** For more information on custom properties, see your [Debezium Connector](https://debezium.io/documentation/reference/3.1/connectors/) specific documentation.
68+
> **Note:** For more information on custom properties, see your [Debezium Connector](https://debezium.io/documentation/reference/3.5/connectors/) specific documentation.
6969
7070
Example of a MySQL Debezium Connector setup:
7171
```
@@ -160,7 +160,7 @@ By default, DebeziumIO initializes it with the former, though user may choose th
160160
### Requirements and Supported versions
161161

162162
- JDK v17
163-
- Debezium Connectors v3.1
163+
- Debezium Connectors v3.5
164164
- Apache Beam 2.66
165165

166166
## Running Unit Tests

sdks/java/io/debezium/src/main/java/org/apache/beam/io/debezium/KafkaSourceConsumerFn.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,11 @@ public OffsetStorageReader offsetStorageReader() {
350350
LOG.debug("------------- Creating an offset storage reader");
351351
return new DebeziumSourceOffsetStorageReader(initialOffset);
352352
}
353+
354+
@Override
355+
public org.apache.kafka.common.metrics.PluginMetrics pluginMetrics() {
356+
return null;
357+
}
353358
}
354359

355360
private static class DebeziumSourceOffsetStorageReader implements OffsetStorageReader {

sdks/java/io/debezium/src/test/java/org/apache/beam/io/debezium/DebeziumIOMySqlConnectorIT.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public class DebeziumIOMySqlConnectorIT {
7474
@ClassRule
7575
public static final MySQLContainer<?> MY_SQL_CONTAINER =
7676
new MySQLContainer<>(
77-
DockerImageName.parse("quay.io/debezium/example-mysql:3.1.3.Final")
77+
DockerImageName.parse("quay.io/debezium/example-mysql:3.5.2.Final")
7878
.asCompatibleSubstituteFor("mysql"))
7979
.withPassword("debezium")
8080
.withUsername("mysqluser")
@@ -277,8 +277,8 @@ public void testDebeziumIOMySql() {
277277
.withMaxNumberOfRecords(30)
278278
.withCoder(StringUtf8Coder.of()));
279279
String expected =
280-
"{\"metadata\":{\"connector\":\"mysql\",\"version\":\"3.1.3.Final\",\"name\":\"beam-debezium-connector\","
281-
+ "\"database\":\"inventory\",\"schema\":\"binlog.000002\",\"table\":\"addresses\"},\"before\":null,"
280+
"{\"metadata\":{\"connector\":\"mysql\",\"version\":\"3.5.2.Final\",\"name\":\"beam-debezium-connector\","
281+
+ "\"database\":\"inventory\",\"schema\":\"mysql-bin.000003\",\"table\":\"addresses\"},\"before\":null,"
282282
+ "\"after\":{\"fields\":{\"zip\":\"76036\",\"city\":\"Euless\","
283283
+ "\"street\":\"3183 Moore Avenue\",\"id\":10,\"state\":\"Texas\",\"customer_id\":1001,"
284284
+ "\"type\":\"SHIPPING\"}}}";

sdks/java/io/debezium/src/test/java/org/apache/beam/io/debezium/DebeziumIOPostgresSqlConnectorIT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class DebeziumIOPostgresSqlConnectorIT {
5656
@ClassRule
5757
public static final PostgreSQLContainer<?> POSTGRES_SQL_CONTAINER =
5858
new PostgreSQLContainer<>(
59-
DockerImageName.parse("quay.io/debezium/example-postgres:3.1.3.Final")
59+
DockerImageName.parse("quay.io/debezium/example-postgres:3.5.2.Final")
6060
.asCompatibleSubstituteFor("postgres"))
6161
.withPassword("dbz")
6262
.withUsername("debezium")
@@ -180,7 +180,7 @@ public void testDebeziumIOPostgresSql() {
180180
.withMaxNumberOfRecords(30)
181181
.withCoder(StringUtf8Coder.of()));
182182
String expected =
183-
"{\"metadata\":{\"connector\":\"postgresql\",\"version\":\"3.1.3.Final\",\"name\":\"beam-debezium-connector\","
183+
"{\"metadata\":{\"connector\":\"postgresql\",\"version\":\"3.5.2.Final\",\"name\":\"beam-debezium-connector\","
184184
+ "\"database\":\"inventory\",\"schema\":\"inventory\",\"table\":\"customers\"},\"before\":null,"
185185
+ "\"after\":{\"fields\":{\"last_name\":\"Thomas\",\"id\":1001,\"first_name\":\"Sally\","
186186
+ "\"email\":\"sally.thomas@acme.com\"}}}";

sdks/java/io/debezium/src/test/java/org/apache/beam/io/debezium/DebeziumReadSchemaTransformTest.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.beam.io.debezium;
1919

2020
import static org.hamcrest.MatcherAssert.assertThat;
21+
import static org.junit.Assert.assertNotNull;
2122
import static org.junit.Assert.assertThrows;
2223

2324
import io.debezium.DebeziumException;
@@ -60,7 +61,7 @@ public class DebeziumReadSchemaTransformTest {
6061
@ClassRule
6162
public static final MySQLContainer<?> MY_SQL_CONTAINER =
6263
new MySQLContainer<>(
63-
DockerImageName.parse("debezium/example-mysql:1.4")
64+
DockerImageName.parse("quay.io/debezium/example-mysql:3.5.2.Final")
6465
.asCompatibleSubstituteFor("mysql"))
6566
.withPassword("debezium")
6667
.withUsername("mysqluser")
@@ -118,6 +119,17 @@ private PTransform<PCollectionRowTuple, PCollectionRowTuple> makePtransform(
118119
.build());
119120
}
120121

122+
// Since Debezium 3.5 connection failures surface as a RetriableException wrapping the
123+
// DebeziumException instead of a top-level DebeziumException.
124+
private static DebeziumException findDebeziumException(Throwable thrown) {
125+
Throwable cause = thrown;
126+
while (cause != null && !(cause instanceof DebeziumException)) {
127+
cause = cause.getCause();
128+
}
129+
assertNotNull("Expected DebeziumException in cause chain", cause);
130+
return (DebeziumException) cause;
131+
}
132+
121133
@Test
122134
public void testNoProblem() {
123135
Pipeline readPipeline = Pipeline.create();
@@ -142,9 +154,9 @@ public void testNoProblem() {
142154
@Test
143155
public void testWrongUser() {
144156
Pipeline readPipeline = Pipeline.create();
145-
DebeziumException ex =
157+
Exception thrown =
146158
assertThrows(
147-
DebeziumException.class,
159+
Exception.class,
148160
() -> {
149161
PCollectionRowTuple.empty(readPipeline)
150162
.apply(
@@ -156,16 +168,17 @@ public void testWrongUser() {
156168
"localhost"))
157169
.get("output");
158170
});
171+
DebeziumException ex = findDebeziumException(thrown);
159172
assertThat(ex.getCause().getMessage(), Matchers.containsString("password"));
160173
assertThat(ex.getCause().getMessage(), Matchers.containsString("wrongUser"));
161174
}
162175

163176
@Test
164177
public void testWrongPassword() {
165178
Pipeline readPipeline = Pipeline.create();
166-
DebeziumException ex =
179+
Exception thrown =
167180
assertThrows(
168-
DebeziumException.class,
181+
Exception.class,
169182
() -> {
170183
PCollectionRowTuple.empty(readPipeline)
171184
.apply(
@@ -177,21 +190,23 @@ public void testWrongPassword() {
177190
"localhost"))
178191
.get("output");
179192
});
193+
DebeziumException ex = findDebeziumException(thrown);
180194
assertThat(ex.getCause().getMessage(), Matchers.containsString("password"));
181195
assertThat(ex.getCause().getMessage(), Matchers.containsString(userName));
182196
}
183197

184198
@Test
185199
public void testWrongPort() {
186200
Pipeline readPipeline = Pipeline.create();
187-
DebeziumException ex =
201+
Exception thrown =
188202
assertThrows(
189-
DebeziumException.class,
203+
Exception.class,
190204
() -> {
191205
PCollectionRowTuple.empty(readPipeline)
192206
.apply(makePtransform(userName, password, database, 12345, "localhost"))
193207
.get("output");
194208
});
209+
DebeziumException ex = findDebeziumException(thrown);
195210
Throwable lowestCause = ex.getCause();
196211
while (lowestCause.getCause() != null) {
197212
lowestCause = lowestCause.getCause();

sdks/python/apache_beam/io/external/xlang_debeziumio_it_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def test_xlang_debezium_read(self):
8989
expected_response = [{
9090
"metadata": {
9191
"connector": "postgresql",
92-
"version": "3.1.3.Final",
92+
"version": "3.5.2.Final",
9393
"name": "beam-debezium-connector",
9494
"database": "inventory",
9595
"schema": "inventory",

0 commit comments

Comments
 (0)