Skip to content

Commit 4b6a82c

Browse files
committed
JAVA-2833: Add clusterTime property to ChangeStreamDocument
MongoDB 4.0 adds a clusterTime field to every change stream document, so the driver now exposes it as a property to the statically typed ChangeStreamDocument class
1 parent 5d63fa7 commit 4b6a82c

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

driver-core/src/main/com/mongodb/client/model/changestream/ChangeStreamDocument.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
package com.mongodb.client.model.changestream;
1818

1919
import com.mongodb.MongoNamespace;
20+
import com.mongodb.lang.Nullable;
2021
import org.bson.BsonDocument;
22+
import org.bson.BsonTimestamp;
2123
import org.bson.codecs.Codec;
2224
import org.bson.codecs.configuration.CodecRegistry;
2325
import org.bson.codecs.pojo.annotations.BsonCreator;
@@ -41,6 +43,7 @@ public final class ChangeStreamDocument<TDocument> {
4143
private final MongoNamespace namespace;
4244
private final TDocument fullDocument;
4345
private final BsonDocument documentKey;
46+
private final BsonTimestamp clusterTime;
4447
private final OperationType operationType;
4548
private final UpdateDescription updateDescription;
4649

@@ -53,18 +56,43 @@ public final class ChangeStreamDocument<TDocument> {
5356
* @param fullDocument the fullDocument
5457
* @param operationType the operation type
5558
* @param updateDescription the update description
59+
* @deprecated Prefer {@link #ChangeStreamDocument(BsonDocument, MongoNamespace, Object, BsonDocument, BsonTimestamp, OperationType,
60+
* UpdateDescription)}
61+
*/
62+
@Deprecated
63+
public ChangeStreamDocument(@BsonProperty("resumeToken") final BsonDocument resumeToken,
64+
@BsonProperty("namespace") final MongoNamespace namespace,
65+
@BsonProperty("fullDocument") final TDocument fullDocument,
66+
@BsonProperty("documentKey") final BsonDocument documentKey,
67+
@BsonProperty("operationType") final OperationType operationType,
68+
@BsonProperty("updateDescription") final UpdateDescription updateDescription) {
69+
this(resumeToken, namespace, fullDocument, documentKey, null, operationType, updateDescription);
70+
}
71+
72+
/**
73+
* Creates a new instance
74+
*
75+
* @param resumeToken the resume token
76+
* @param namespace the namespace
77+
* @param documentKey a document containing the _id of the changed document
78+
* @param clusterTime the cluster time at which the change occurred
79+
* @param fullDocument the fullDocument
80+
* @param operationType the operation type
81+
* @param updateDescription the update description
5682
*/
5783
@BsonCreator
5884
public ChangeStreamDocument(@BsonProperty("resumeToken") final BsonDocument resumeToken,
5985
@BsonProperty("namespace") final MongoNamespace namespace,
6086
@BsonProperty("fullDocument") final TDocument fullDocument,
6187
@BsonProperty("documentKey") final BsonDocument documentKey,
88+
@Nullable @BsonProperty("clusterTime") final BsonTimestamp clusterTime,
6289
@BsonProperty("operationType") final OperationType operationType,
6390
@BsonProperty("updateDescription") final UpdateDescription updateDescription) {
6491
this.resumeToken = resumeToken;
6592
this.namespace = namespace;
6693
this.documentKey = documentKey;
6794
this.fullDocument = fullDocument;
95+
this.clusterTime = clusterTime;
6896
this.operationType = operationType;
6997
this.updateDescription = updateDescription;
7098
}
@@ -111,6 +139,18 @@ public BsonDocument getDocumentKey() {
111139
return documentKey;
112140
}
113141

142+
/**
143+
* Gets the cluster time at which the change occurred.
144+
*
145+
* @return the cluster time at which the change occurred
146+
* @since 3.8
147+
* @mongodb.server.release 4.0
148+
*/
149+
@Nullable
150+
public BsonTimestamp getClusterTime() {
151+
return clusterTime;
152+
}
153+
114154
/**
115155
* Returns the operationType
116156
*
@@ -165,6 +205,9 @@ public boolean equals(final Object o) {
165205
if (documentKey != null ? !documentKey.equals(that.documentKey) : that.documentKey != null) {
166206
return false;
167207
}
208+
if (clusterTime != null ? !clusterTime.equals(that.clusterTime) : that.clusterTime != null) {
209+
return false;
210+
}
168211
if (operationType != that.operationType) {
169212
return false;
170213
}
@@ -181,6 +224,7 @@ public int hashCode() {
181224
result = 31 * result + (namespace != null ? namespace.hashCode() : 0);
182225
result = 31 * result + (fullDocument != null ? fullDocument.hashCode() : 0);
183226
result = 31 * result + (documentKey != null ? documentKey.hashCode() : 0);
227+
result = 31 * result + (clusterTime != null ? clusterTime.hashCode() : 0);
184228
result = 31 * result + (operationType != null ? operationType.hashCode() : 0);
185229
result = 31 * result + (updateDescription != null ? updateDescription.hashCode() : 0);
186230
return result;
@@ -193,6 +237,7 @@ public String toString() {
193237
+ ", namespace=" + namespace
194238
+ ", fullDocument=" + fullDocument
195239
+ ", documentKey=" + documentKey
240+
+ ", clusterTime=" + clusterTime
196241
+ ", operationType=" + operationType
197242
+ ", updateDescription=" + updateDescription
198243
+ "}";

driver-core/src/main/com/mongodb/client/model/changestream/ChangeStreamDocumentCodec.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
import com.mongodb.MongoNamespace;
2020
import org.bson.BsonDocument;
2121
import org.bson.BsonReader;
22+
import org.bson.BsonTimestamp;
2223
import org.bson.BsonWriter;
2324
import org.bson.codecs.BsonDocumentCodec;
25+
import org.bson.codecs.BsonTimestampCodec;
2426
import org.bson.codecs.Codec;
2527
import org.bson.codecs.DecoderContext;
2628
import org.bson.codecs.EncoderContext;
@@ -44,6 +46,7 @@ final class ChangeStreamDocumentCodec<TResult> implements Codec<ChangeStreamDocu
4446
ChangeStreamDocumentCodec(final Class<TResult> fullDocumentClass, final CodecRegistry codecRegistry) {
4547

4648
ClassModelBuilder<ChangeStreamDocument> classModelBuilder = ClassModel.builder(ChangeStreamDocument.class);
49+
((PropertyModelBuilder<BsonTimestamp>) classModelBuilder.getProperty("clusterTime")).codec(new BsonTimestampCodec());
4750
((PropertyModelBuilder<BsonDocument>) classModelBuilder.getProperty("documentKey")).codec(BSON_DOCUMENT_CODEC);
4851
((PropertyModelBuilder<TResult>) classModelBuilder.getProperty("fullDocument")).codec(codecRegistry.get(fullDocumentClass));
4952
((PropertyModelBuilder<BsonDocument>) classModelBuilder.getProperty("resumeToken")).codec(BSON_DOCUMENT_CODEC);

driver-core/src/test/unit/com/mongodb/client/model/changestream/ChangeStreamDocumentCodecSpecification.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.bson.BsonDocumentReader
2222
import org.bson.BsonDocumentWriter
2323
import org.bson.BsonInt32
2424
import org.bson.BsonReader
25+
import org.bson.BsonTimestamp
2526
import org.bson.Document
2627
import org.bson.codecs.BsonValueCodecProvider
2728
import org.bson.codecs.DecoderContext
@@ -61,6 +62,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
6162
new MongoNamespace('databaseName.collectionName'),
6263
Document.parse('{key: "value for fullDocument"}'),
6364
new BsonDocument('_id', new BsonInt32(1)),
65+
new BsonTimestamp(1234, 2),
6466
OperationType.INSERT,
6567
null
6668
),
@@ -69,14 +71,15 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
6971
new MongoNamespace('databaseName.collectionName'),
7072
BsonDocument.parse('{key: "value for fullDocument"}'),
7173
new BsonDocument('_id', new BsonInt32(2)),
74+
null,
7275
OperationType.UPDATE,
7376
new UpdateDescription(['a', 'b'], BsonDocument.parse('{c: 1}'))
7477
)
7578
]
7679
clazz << [Document, BsonDocument]
7780
json << [
7881
'''{_id: {token: true}, ns: {db: "databaseName", coll: "collectionName"}, documentKey : {_id : 1},
79-
fullDocument: {key: "value for fullDocument"},
82+
fullDocument: {key: "value for fullDocument"}, clusterTime: { "$timestamp" : { "t" : 1234, "i" : 2 } }
8083
operationType: "insert"}''',
8184
'''{_id: {token: true}, ns: {db: "databaseName", coll: "collectionName"}, documentKey : {_id : 2},
8285
fullDocument: {key: "value for fullDocument"},

driver-core/src/test/unit/com/mongodb/client/model/changestream/ChangeStreamDocumentSpecification.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.mongodb.client.model.changestream
1818

1919
import com.mongodb.MongoNamespace
2020
import org.bson.BsonDocument
21+
import org.bson.BsonTimestamp
2122
import org.bson.RawBsonDocument
2223
import spock.lang.Specification
2324

@@ -29,17 +30,19 @@ class ChangeStreamDocumentSpecification extends Specification {
2930
def namespace = new MongoNamespace('databaseName.collectionName')
3031
def fullDocument = BsonDocument.parse('{key: "value for fullDocument"}')
3132
def documentKey = BsonDocument.parse('{_id : 1}')
33+
def clusterTime = new BsonTimestamp(1234, 2)
3234
def operationType = OperationType.UPDATE
3335
def updateDesc = new UpdateDescription(['a', 'b'], BsonDocument.parse('{c: 1}'))
3436

3537
when:
36-
def changeStreamDocument = new ChangeStreamDocument<BsonDocument>(resumeToken, namespace, fullDocument, documentKey,
38+
def changeStreamDocument = new ChangeStreamDocument<BsonDocument>(resumeToken, namespace, fullDocument, documentKey, clusterTime,
3739
operationType, updateDesc)
3840

3941
then:
4042
changeStreamDocument.getResumeToken() == resumeToken
4143
changeStreamDocument.getFullDocument() == fullDocument
4244
changeStreamDocument.getDocumentKey() == documentKey
45+
changeStreamDocument.getClusterTime() == clusterTime
4346
changeStreamDocument.getNamespace() == namespace
4447
changeStreamDocument.getOperationType() == operationType
4548
changeStreamDocument.getUpdateDescription() == updateDesc

0 commit comments

Comments
 (0)