|
18 | 18 | package org.apache.flink.cdc.pipeline.tests.migration; |
19 | 19 |
|
20 | 20 | import org.apache.flink.api.common.JobID; |
| 21 | +import org.apache.flink.api.common.JobStatus; |
| 22 | +import org.apache.flink.cdc.common.test.utils.TestUtils; |
21 | 23 | import org.apache.flink.cdc.connectors.mysql.testutils.MySqlContainer; |
22 | 24 | import org.apache.flink.cdc.connectors.mysql.testutils.UniqueDatabase; |
23 | 25 | import org.apache.flink.cdc.pipeline.tests.utils.PipelineTestEnvironment; |
|
32 | 34 | import org.slf4j.Logger; |
33 | 35 | import org.slf4j.LoggerFactory; |
34 | 36 |
|
| 37 | +import java.nio.file.Path; |
35 | 38 | import java.sql.Connection; |
36 | 39 | import java.sql.DriverManager; |
37 | 40 | import java.sql.SQLException; |
@@ -276,6 +279,78 @@ void testStartingJobFromSavepointWithSchemaChange(TarballFetcher.CdcVersion migr |
276 | 279 | cancelJob(newJobID); |
277 | 280 | } |
278 | 281 |
|
| 282 | + @ParameterizedTest(name = "{0} -> SNAPSHOT") |
| 283 | + @EnumSource(names = {"SNAPSHOT"}) |
| 284 | + void testRestartingJobFromSavepointInSnapshotMode(TarballFetcher.CdcVersion migrateFromVersion) |
| 285 | + throws Exception { |
| 286 | + TarballFetcher.fetch(jobManager, migrateFromVersion); |
| 287 | + runInContainerAsRoot(jobManager, "chmod", "0777", "-R", "/tmp/cdc/"); |
| 288 | + Path udfJar = TestUtils.getResource("udf-examples.jar"); |
| 289 | + LOG.info("Successfully fetched CDC {}.", migrateFromVersion); |
| 290 | + String content = |
| 291 | + String.format( |
| 292 | + "source:\n" |
| 293 | + + " type: mysql\n" |
| 294 | + + " hostname: %s\n" |
| 295 | + + " port: %d\n" |
| 296 | + + " username: %s\n" |
| 297 | + + " password: %s\n" |
| 298 | + + " tables: %s.\\.*\n" |
| 299 | + + " server-id: 5400-5404\n" |
| 300 | + + " server-time-zone: UTC\n" |
| 301 | + + " scan.startup.mode: snapshot\n" |
| 302 | + + " scan.incremental.snapshot.chunk.size: 2\n" |
| 303 | + + "\n" |
| 304 | + + "sink:\n" |
| 305 | + + " type: values\n" |
| 306 | + + "\n" |
| 307 | + + "transform:\n" |
| 308 | + + " - source-table: %s.\\.*\n" |
| 309 | + + " projection: \\*, throttle(id, 10) AS throttled\n" |
| 310 | + + "\n" |
| 311 | + + "pipeline:\n" |
| 312 | + + " parallelism: %d\n" |
| 313 | + + " user-defined-function:\n" |
| 314 | + + " - name: throttle\n" |
| 315 | + + " classpath: org.apache.flink.cdc.udf.examples.java.ThrottlerFunctionClass\n", |
| 316 | + INTER_CONTAINER_MYSQL_ALIAS, |
| 317 | + MySqlContainer.MYSQL_PORT, |
| 318 | + MYSQL_TEST_USER, |
| 319 | + MYSQL_TEST_PASSWORD, |
| 320 | + mysqlInventoryDatabase.getDatabaseName(), |
| 321 | + mysqlInventoryDatabase.getDatabaseName(), |
| 322 | + parallelism); |
| 323 | + JobID jobID = submitPipelineJob(migrateFromVersion, content, udfJar); |
| 324 | + Assertions.assertThat(jobID).isNotNull(); |
| 325 | + LOG.info("Submitted Job ID is {} ", jobID); |
| 326 | + waitUntilJobState(Duration.ofSeconds(30), JobStatus.RUNNING); |
| 327 | + |
| 328 | + String savepointPath = stopJobWithSavepoint(jobID); |
| 329 | + LOG.info("Stopped Job {} and created a savepoint at {}.", jobID, savepointPath); |
| 330 | + |
| 331 | + JobID newJobID = submitPipelineJob(content, savepointPath, true, udfJar); |
| 332 | + LOG.info("Reincarnated Job {} has been submitted successfully.", newJobID); |
| 333 | + validateResult( |
| 334 | + dbNameFormatter, |
| 335 | + "CreateTableEvent{tableId=%s.customers, schema=columns={`id` INT NOT NULL,`name` VARCHAR(255) NOT NULL 'flink',`address` VARCHAR(1024),`phone_number` VARCHAR(512),`throttled` STRING}, primaryKeys=id, options=()}", |
| 336 | + "CreateTableEvent{tableId=%s.products, schema=columns={`id` INT NOT NULL,`name` VARCHAR(255) NOT NULL 'flink',`description` VARCHAR(512),`weight` FLOAT,`enum_c` STRING 'red',`json_c` STRING,`point_c` STRING,`throttled` STRING}, primaryKeys=id, options=()}", |
| 337 | + "DataChangeEvent{tableId=%s.customers, before=[], after=[101, user_1, Shanghai, 123567891234, throttled_101], op=INSERT, meta=()}", |
| 338 | + "DataChangeEvent{tableId=%s.customers, before=[], after=[102, user_2, Shanghai, 123567891234, throttled_102], op=INSERT, meta=()}", |
| 339 | + "DataChangeEvent{tableId=%s.customers, before=[], after=[103, user_3, Shanghai, 123567891234, throttled_103], op=INSERT, meta=()}", |
| 340 | + "DataChangeEvent{tableId=%s.customers, before=[], after=[104, user_4, Shanghai, 123567891234, throttled_104], op=INSERT, meta=()}", |
| 341 | + "DataChangeEvent{tableId=%s.products, before=[], after=[101, scooter, Small 2-wheel scooter, 3.14, red, {\"key1\": \"value1\"}, {\"coordinates\":[1,1],\"type\":\"Point\",\"srid\":0}, throttled_101], op=INSERT, meta=()}", |
| 342 | + "DataChangeEvent{tableId=%s.products, before=[], after=[102, car battery, 12V car battery, 8.1, white, {\"key2\": \"value2\"}, {\"coordinates\":[2,2],\"type\":\"Point\",\"srid\":0}, throttled_102], op=INSERT, meta=()}", |
| 343 | + "DataChangeEvent{tableId=%s.products, before=[], after=[103, 12-pack drill bits, 12-pack of drill bits with sizes ranging from #40 to #3, 0.8, red, {\"key3\": \"value3\"}, {\"coordinates\":[3,3],\"type\":\"Point\",\"srid\":0}, throttled_103], op=INSERT, meta=()}", |
| 344 | + "DataChangeEvent{tableId=%s.products, before=[], after=[104, hammer, 12oz carpenter's hammer, 0.75, white, {\"key4\": \"value4\"}, {\"coordinates\":[4,4],\"type\":\"Point\",\"srid\":0}, throttled_104], op=INSERT, meta=()}", |
| 345 | + "DataChangeEvent{tableId=%s.products, before=[], after=[105, hammer, 14oz carpenter's hammer, 0.875, red, {\"k1\": \"v1\", \"k2\": \"v2\"}, {\"coordinates\":[5,5],\"type\":\"Point\",\"srid\":0}, throttled_105], op=INSERT, meta=()}", |
| 346 | + "DataChangeEvent{tableId=%s.products, before=[], after=[106, hammer, 16oz carpenter's hammer, 1.0, null, null, null, throttled_106], op=INSERT, meta=()}", |
| 347 | + "DataChangeEvent{tableId=%s.products, before=[], after=[107, rocks, box of assorted rocks, 5.3, null, null, null, throttled_107], op=INSERT, meta=()}", |
| 348 | + "DataChangeEvent{tableId=%s.products, before=[], after=[108, jacket, water resistent black wind breaker, 0.1, null, null, null, throttled_108], op=INSERT, meta=()}", |
| 349 | + "DataChangeEvent{tableId=%s.products, before=[], after=[109, spare tire, 24 inch spare tire, 22.2, null, null, null, throttled_109], op=INSERT, meta=()}"); |
| 350 | + |
| 351 | + LOG.info("Snapshot stage finished successfully."); |
| 352 | + } |
| 353 | + |
279 | 354 | private void generateIncrementalEventsPhaseOne() { |
280 | 355 | executeMySqlStatements( |
281 | 356 | mysqlInventoryDatabase, |
|
0 commit comments