|
9 | 9 | import com.mongodb.MongoCommandException;
|
10 | 10 | import com.mongodb.client.ChangeStreamIterable;
|
11 | 11 | import com.mongodb.client.MongoClient;
|
| 12 | +import com.mongodb.client.model.Aggregates; |
| 13 | +import com.mongodb.client.model.Filters; |
12 | 14 | import io.airbyte.cdk.integrations.debezium.internals.AirbyteFileOffsetBackingStore;
|
13 | 15 | import io.airbyte.cdk.integrations.debezium.internals.DebeziumPropertiesManager;
|
14 | 16 | import io.airbyte.cdk.integrations.debezium.internals.DebeziumStateUtil;
|
|
23 | 25 | import io.debezium.connector.mongodb.ReplicaSets;
|
24 | 26 | import io.debezium.connector.mongodb.ResumeTokens;
|
25 | 27 | import java.util.Collection;
|
| 28 | +import java.util.Collections; |
26 | 29 | import java.util.LinkedHashMap;
|
27 | 30 | import java.util.LinkedList;
|
28 | 31 | import java.util.List;
|
|
35 | 38 | import org.bson.BsonDocument;
|
36 | 39 | import org.bson.BsonString;
|
37 | 40 | import org.bson.BsonTimestamp;
|
| 41 | +import org.bson.conversions.Bson; |
38 | 42 | import org.slf4j.Logger;
|
39 | 43 | import org.slf4j.LoggerFactory;
|
40 | 44 |
|
@@ -103,25 +107,38 @@ public static String getReplicaSetName(final MongoClient mongoClient) {
|
103 | 107 | *
|
104 | 108 | * @param savedOffset The resume token from the saved offset.
|
105 | 109 | * @param mongoClient The {@link MongoClient} used to validate the saved offset.
|
| 110 | + * |
106 | 111 | * @return {@code true} if the saved offset value is valid Otherwise, {@code false} is returned to
|
107 | 112 | * indicate that an initial snapshot should be performed.
|
108 | 113 | */
|
109 |
| - public boolean isValidResumeToken(final BsonDocument savedOffset, final MongoClient mongoClient) { |
| 114 | + public boolean isValidResumeToken(final BsonDocument savedOffset, |
| 115 | + final MongoClient mongoClient, |
| 116 | + final String databaseName, |
| 117 | + final ConfiguredAirbyteCatalog catalog) { |
110 | 118 | if (Objects.isNull(savedOffset) || savedOffset.isEmpty()) {
|
111 | 119 | return true;
|
112 | 120 | }
|
113 | 121 |
|
114 |
| - final ChangeStreamIterable<BsonDocument> stream = mongoClient.watch(BsonDocument.class); |
115 |
| - stream.resumeAfter(savedOffset); |
116 |
| - try (final var ignored = stream.cursor()) { |
| 122 | + // Scope the change stream to the collections & database of interest - this mirrors the logic while |
| 123 | + // getting the most recent resume token. |
| 124 | + final List<String> collectionsList = catalog.getStreams().stream() |
| 125 | + .map(s -> s.getStream().getName()) |
| 126 | + .toList(); |
| 127 | + final List<Bson> pipeline = Collections.singletonList(Aggregates.match( |
| 128 | + Filters.in("ns.coll", collectionsList))); |
| 129 | + final ChangeStreamIterable<BsonDocument> eventStream = mongoClient.getDatabase(databaseName).watch(pipeline, BsonDocument.class); |
| 130 | + |
| 131 | + // Attempt to start the stream after the saved offset. |
| 132 | + eventStream.resumeAfter(savedOffset); |
| 133 | + try (final var ignored = eventStream.cursor()) { |
117 | 134 | LOGGER.info("Valid resume token '{}' present, corresponding to timestamp (seconds after epoch) : {}. Incremental sync will be performed for "
|
118 | 135 | + "up-to-date streams.",
|
119 | 136 | ResumeTokens.getData(savedOffset).asString().getValue(), ResumeTokens.getTimestamp(savedOffset).getTime());
|
120 | 137 | return true;
|
121 | 138 | } catch (final MongoCommandException | MongoChangeStreamException e) {
|
122 |
| - LOGGER.info("Invalid resume token '{}' present, corresponding to timestamp (seconds after epoch) : {}. Initial snapshot will be performed for " |
123 |
| - + "all streams.", |
124 |
| - ResumeTokens.getData(savedOffset).asString().getValue(), ResumeTokens.getTimestamp(savedOffset).getTime()); |
| 139 | + LOGGER.info("Exception : {}", e.getMessage()); |
| 140 | + LOGGER.info("Invalid resume token '{}' present, corresponding to timestamp (seconds after epoch) : {}, due to reason {}", |
| 141 | + ResumeTokens.getData(savedOffset).asString().getValue(), ResumeTokens.getTimestamp(savedOffset).getTime(), e.getMessage()); |
125 | 142 | return false;
|
126 | 143 | }
|
127 | 144 | }
|
|
0 commit comments