|
32 | 32 | import static org.junit.jupiter.api.Assertions.assertNotNull; |
33 | 33 | import static org.junit.jupiter.api.Assertions.assertNull; |
34 | 34 | import static org.junit.jupiter.api.Assertions.assertThrows; |
| 35 | +import static org.junit.jupiter.api.Assertions.assertTrue; |
35 | 36 |
|
36 | 37 | import org.apache.kafka.connect.data.Schema; |
37 | 38 | import org.apache.kafka.connect.errors.DataException; |
|
46 | 47 | import com.mongodb.MongoNamespace; |
47 | 48 | import com.mongodb.client.model.ReplaceOneModel; |
48 | 49 | import com.mongodb.client.model.ReplaceOptions; |
| 50 | +import com.mongodb.client.model.UpdateOneModel; |
49 | 51 |
|
50 | 52 | import com.mongodb.kafka.connect.sink.cdc.debezium.mongodb.MongoDbHandler; |
51 | 53 | import com.mongodb.kafka.connect.sink.namespace.mapping.FieldPathNamespaceMapper; |
@@ -197,6 +199,52 @@ INVALID_SINK_RECORD, createSinkConfig(ERRORS_TOLERANCE_CONFIG, "all")) |
197 | 199 | FIELD_NAMESPACE_MAPPER_ERROR_IF_INVALID_CONFIG))))); |
198 | 200 | } |
199 | 201 |
|
| 202 | + @Test |
| 203 | + @DisplayName("Rename _id handling") |
| 204 | + void testRenameIdHandling() { |
| 205 | + SinkRecord sinkRecord = |
| 206 | + new SinkRecord( |
| 207 | + TEST_TOPIC, |
| 208 | + 0, |
| 209 | + Schema.STRING_SCHEMA, |
| 210 | + "{_id: 1}", |
| 211 | + Schema.STRING_SCHEMA, |
| 212 | + "{a: 'a', b: 'b', c: 'c', d: 'd'}", |
| 213 | + 1); |
| 214 | + |
| 215 | + String topicConfig = |
| 216 | + "{" |
| 217 | + + "'writemodel.strategy': 'com.mongodb.kafka.connect.sink.writemodel.strategy.UpdateOneBusinessKeyTimestampStrategy'," |
| 218 | + + "'post.processor.chain': 'com.mongodb.kafka.connect.sink.processor.field.renaming.RenameByMapping, " |
| 219 | + + "com.mongodb.kafka.connect.sink.processor.DocumentIdAdder'," |
| 220 | + + "'field.renamer.mapping': '[{oldName: \"value.c\", newName: \"_id\"}]'," |
| 221 | + + "'document.id.strategy': 'com.mongodb.kafka.connect.sink.processor.id.strategy.PartialValueStrategy'," |
| 222 | + + "'document.id.strategy.overwrite.existing': 'true'," |
| 223 | + + "'document.id.strategy.partial.value.projection.type': 'allowlist'," |
| 224 | + + "'document.id.strategy.partial.value.projection.list': 'a, b, _id'" |
| 225 | + + "}"; |
| 226 | + |
| 227 | + MongoProcessedSinkRecordData processedData = |
| 228 | + new MongoProcessedSinkRecordData(sinkRecord, createSinkConfig(topicConfig)); |
| 229 | + assertNull(processedData.getException()); |
| 230 | + UpdateOneModel<BsonDocument> writeModel = |
| 231 | + (UpdateOneModel<BsonDocument>) processedData.getWriteModel(); |
| 232 | + assertTrue(writeModel.getOptions().isUpsert()); |
| 233 | + assertEquals(BsonDocument.parse("{'a': 'a', 'b': 'b', '_id': 'c'}"), writeModel.getFilter()); |
| 234 | + |
| 235 | + BsonDocument update = (BsonDocument) writeModel.getUpdate(); |
| 236 | + assertNotNull(update); |
| 237 | + BsonDocument setDocument = update.getDocument("$set", new BsonDocument()); |
| 238 | + assertTrue(setDocument.containsKey("_modifiedTS")); |
| 239 | + setDocument.remove("_modifiedTS"); |
| 240 | + assertEquals(BsonDocument.parse("{'a': 'a', 'b': 'b', 'd': 'd'}"), setDocument); |
| 241 | + |
| 242 | + BsonDocument setOnInsertDocument = update.getDocument("$setOnInsert", new BsonDocument()); |
| 243 | + assertTrue(setOnInsertDocument.containsKey("_insertedTS")); |
| 244 | + setOnInsertDocument.remove("_insertedTS"); |
| 245 | + assertTrue(setOnInsertDocument.isEmpty()); |
| 246 | + } |
| 247 | + |
200 | 248 | void assertWriteModel(final MongoProcessedSinkRecordData processedData) { |
201 | 249 | assertWriteModel(processedData, EXPECTED_WRITE_MODEL); |
202 | 250 | } |
|
0 commit comments