Skip to content

Commit 019e199

Browse files
committed
Add support for "to" field in ChangeStreamDocument
JAVA-3261
1 parent 5c4ba48 commit 019e199

File tree

4 files changed

+340
-45
lines changed

4 files changed

+340
-45
lines changed

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

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public final class ChangeStreamDocument<TDocument> {
4343
@BsonId()
4444
private final BsonDocument resumeToken;
4545
private final BsonDocument namespaceDocument;
46+
private final BsonDocument destinationNamespaceDocument;
4647
private final TDocument fullDocument;
4748
private final BsonDocument documentKey;
4849
private final BsonTimestamp clusterTime;
@@ -58,8 +59,8 @@ public final class ChangeStreamDocument<TDocument> {
5859
* @param fullDocument the fullDocument
5960
* @param operationType the operation type
6061
* @param updateDescription the update description
61-
* @deprecated Prefer {@link #ChangeStreamDocument(BsonDocument, MongoNamespace, Object, BsonDocument, BsonTimestamp, OperationType,
62-
* UpdateDescription)}
62+
* @deprecated Prefer {@link #ChangeStreamDocument(OperationType, BsonDocument, BsonDocument, BsonDocument, Object, BsonDocument,
63+
* BsonTimestamp, UpdateDescription)}
6364
*/
6465
@Deprecated
6566
public ChangeStreamDocument(final BsonDocument resumeToken,
@@ -81,6 +82,8 @@ public ChangeStreamDocument(final BsonDocument resumeToken,
8182
* @param fullDocument the fullDocument
8283
* @param operationType the operation type
8384
* @param updateDescription the update description
85+
* @deprecated Prefer {@link #ChangeStreamDocument(OperationType, BsonDocument, BsonDocument, BsonDocument, Object, BsonDocument,
86+
* BsonTimestamp, UpdateDescription)}
8487
*/
8588
@Deprecated
8689
public ChangeStreamDocument(final BsonDocument resumeToken,
@@ -90,8 +93,7 @@ public ChangeStreamDocument(final BsonDocument resumeToken,
9093
@Nullable final BsonTimestamp clusterTime,
9194
final OperationType operationType,
9295
final UpdateDescription updateDescription) {
93-
this(resumeToken, namespaceToDocument(namespace), fullDocument, documentKey,
94-
clusterTime, operationType, updateDescription);
96+
this(resumeToken, namespaceToDocument(namespace), fullDocument, documentKey, clusterTime, operationType, updateDescription);
9597
}
9698

9799
/**
@@ -107,16 +109,44 @@ public ChangeStreamDocument(final BsonDocument resumeToken,
107109
*
108110
* @since 3.8
109111
*/
110-
@BsonCreator
112+
@Deprecated
111113
public ChangeStreamDocument(@BsonProperty("resumeToken") final BsonDocument resumeToken,
112114
@BsonProperty("ns") final BsonDocument namespaceDocument,
113115
@BsonProperty("fullDocument") final TDocument fullDocument,
114116
@BsonProperty("documentKey") final BsonDocument documentKey,
115117
@Nullable @BsonProperty("clusterTime") final BsonTimestamp clusterTime,
116118
@BsonProperty("operationType") final OperationType operationType,
117119
@BsonProperty("updateDescription") final UpdateDescription updateDescription) {
120+
this(operationType, resumeToken, namespaceDocument, null, fullDocument, documentKey, clusterTime,
121+
updateDescription);
122+
}
123+
124+
/**
125+
* Creates a new instance
126+
*
127+
* @param operationType the operation type
128+
* @param resumeToken the resume token
129+
* @param namespaceDocument the BsonDocument representing the namespace
130+
* @param destinationNamespaceDocument the BsonDocument representing the destinatation namespace
131+
* @param fullDocument the full document
132+
* @param documentKey a document containing the _id of the changed document
133+
* @param clusterTime the cluster time at which the change occured
134+
* @param updateDescription the update description
135+
*
136+
* @since 3.11
137+
*/
138+
@BsonCreator
139+
public ChangeStreamDocument(@BsonProperty("operationType") final OperationType operationType,
140+
@BsonProperty("resumeToken") final BsonDocument resumeToken,
141+
@Nullable @BsonProperty("ns") final BsonDocument namespaceDocument,
142+
@Nullable @BsonProperty("to") final BsonDocument destinationNamespaceDocument,
143+
@Nullable @BsonProperty("fullDocument") final TDocument fullDocument,
144+
@Nullable @BsonProperty("documentKey") final BsonDocument documentKey,
145+
@Nullable @BsonProperty("clusterTime") final BsonTimestamp clusterTime,
146+
@Nullable @BsonProperty("updateDescription") final UpdateDescription updateDescription) {
118147
this.resumeToken = resumeToken;
119148
this.namespaceDocument = namespaceDocument;
149+
this.destinationNamespaceDocument = destinationNamespaceDocument;
120150
this.documentKey = documentKey;
121151
this.fullDocument = fullDocument;
122152
this.clusterTime = clusterTime;
@@ -140,7 +170,7 @@ public BsonDocument getResumeToken() {
140170
}
141171

142172
/**
143-
* Returns the namespace
173+
* Returns the namespace, derived from the "ns" field in a change stream document.
144174
*
145175
* The invalidate operation type does include a MongoNamespace in the ChangeStreamDocument response. The
146176
* dropDatabase operation type includes a MongoNamespace, but does not include a collection name as part
@@ -149,7 +179,8 @@ public BsonDocument getResumeToken() {
149179
* @return the namespace. If the namespaceDocument is null or if it is missing either the 'db' or 'coll' keys,
150180
* then this will return null.
151181
*/
152-
@BsonIgnore @Nullable
182+
@BsonIgnore
183+
@Nullable
153184
public MongoNamespace getNamespace() {
154185
if (namespaceDocument == null) {
155186
return null;
@@ -162,27 +193,67 @@ public MongoNamespace getNamespace() {
162193
}
163194

164195
/**
165-
* Returns the namespaceDocument
196+
* Returns the namespace cocument, derived from the "ns" field in a change stream document.
166197
*
167-
* The namespaceDocument is a BsonDocument containing the values associated with a MongoNamespace. The
198+
* The namespace document is a BsonDocument containing the values associated with a MongoNamespace. The
168199
* 'db' key refers to the database name and the 'coll' key refers to the collection name.
169200
*
170201
* @return the namespaceDocument
171202
* @since 3.8
172203
*/
173204
@BsonProperty("ns")
205+
@Nullable
174206
public BsonDocument getNamespaceDocument() {
175207
return namespaceDocument;
176208
}
177209

210+
/**
211+
* Returns the destination namespace, derived from the "to" field in a change stream document.
212+
*
213+
* <p>
214+
* The destination namespace is used to indicate the destination of a collection rename event.
215+
* </p>
216+
*
217+
* @return the namespace. If the "to" document is null or absent, then this will return null.
218+
* @see OperationType#RENAME
219+
* @since 3.11
220+
*/
221+
@BsonIgnore
222+
@Nullable
223+
public MongoNamespace getDestinationNamespace() {
224+
if (destinationNamespaceDocument == null) {
225+
return null;
226+
}
227+
228+
return new MongoNamespace(destinationNamespaceDocument.getString("db").getValue(),
229+
destinationNamespaceDocument.getString("coll").getValue());
230+
}
231+
232+
/**
233+
* Returns the destination namespace document, derived from the "to" field in a change stream document.
234+
*
235+
* <p>
236+
* The destination namespace document is a BsonDocument containing the values associated with a MongoNamespace. The
237+
* 'db' key refers to the database name and the 'coll' key refers to the collection name.
238+
* </p>
239+
* @return the destinationNamespaceDocument
240+
* @since 3.11
241+
*/
242+
@BsonProperty("to")
243+
@Nullable
244+
public BsonDocument getDestinationNamespaceDocument() {
245+
return destinationNamespaceDocument;
246+
}
247+
178248
/**
179249
* Returns the database name
180250
*
181251
* @return the databaseName. If the namespaceDocument is null or if it is missing the 'db' key, then this will
182252
* return null.
183253
* @since 3.8
184254
*/
185-
@BsonIgnore @Nullable
255+
@BsonIgnore
256+
@Nullable
186257
public String getDatabaseName() {
187258
if (namespaceDocument == null) {
188259
return null;
@@ -212,8 +283,9 @@ public TDocument getFullDocument() {
212283
* followed by the _id if the _id isn’t part of the shard key.
213284
* </p>
214285
*
215-
* @return the document key
286+
* @return the document key, or null if the event is not associated with a single document (e.g. a collection rename event)
216287
*/
288+
@Nullable
217289
public BsonDocument getDocumentKey() {
218290
return documentKey;
219291
}
@@ -242,8 +314,9 @@ public OperationType getOperationType() {
242314
/**
243315
* Returns the updateDescription
244316
*
245-
* @return the updateDescription
317+
* @return the updateDescription, or null if the event is not associated with a single document (e.g. a collection rename event)
246318
*/
319+
@Nullable
247320
public UpdateDescription getUpdateDescription() {
248321
return updateDescription;
249322
}
@@ -278,6 +351,11 @@ public boolean equals(final Object o) {
278351
if (namespaceDocument != null ? !namespaceDocument.equals(that.namespaceDocument) : that.namespaceDocument != null) {
279352
return false;
280353
}
354+
if (destinationNamespaceDocument != null
355+
? !destinationNamespaceDocument.equals(that.destinationNamespaceDocument)
356+
: that.destinationNamespaceDocument != null) {
357+
return false;
358+
}
281359
if (fullDocument != null ? !fullDocument.equals(that.fullDocument) : that.fullDocument != null) {
282360
return false;
283361
}
@@ -301,6 +379,7 @@ public boolean equals(final Object o) {
301379
public int hashCode() {
302380
int result = resumeToken != null ? resumeToken.hashCode() : 0;
303381
result = 31 * result + (namespaceDocument != null ? namespaceDocument.hashCode() : 0);
382+
result = 31 * result + (destinationNamespaceDocument != null ? destinationNamespaceDocument.hashCode() : 0);
304383
result = 31 * result + (fullDocument != null ? fullDocument.hashCode() : 0);
305384
result = 31 * result + (documentKey != null ? documentKey.hashCode() : 0);
306385
result = 31 * result + (clusterTime != null ? clusterTime.hashCode() : 0);
@@ -312,12 +391,13 @@ public int hashCode() {
312391
@Override
313392
public String toString() {
314393
return "ChangeStreamDocument{"
315-
+ "resumeToken=" + resumeToken
394+
+ " operationType=" + operationType
395+
+ ", resumeToken=" + resumeToken
316396
+ ", namespace=" + getNamespace()
397+
+ ", destinationNamespace=" + getDestinationNamespace()
317398
+ ", fullDocument=" + fullDocument
318399
+ ", documentKey=" + documentKey
319400
+ ", clusterTime=" + clusterTime
320-
+ ", operationType=" + operationType
321401
+ ", updateDescription=" + updateDescription
322402
+ "}";
323403
}

driver-core/src/test/functional/com/mongodb/operation/ChangeStreamOperationSpecification.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ class ChangeStreamOperationSpecification extends OperationFunctionalSpecificatio
380380
def helper = getHelper()
381381

382382
def pipeline = [BsonDocument.parse('{$match: {operationType: "rename"}}')]
383-
def operation = new ChangeStreamOperation<BsonDocument>(helper.getNamespace(), FullDocument.UPDATE_LOOKUP, pipeline,
383+
def operation = new ChangeStreamOperation<ChangeStreamDocument>(helper.getNamespace(), FullDocument.UPDATE_LOOKUP, pipeline,
384384
ChangeStreamDocument.createCodec(BsonDocument, fromProviders(new BsonValueCodecProvider(), new ValueCodecProvider())))
385385
def newNamespace = new MongoNamespace('JavaDriverTest', 'newCollectionName')
386386
helper.insertDocuments(BsonDocument.parse('{ _id : 2, x : 2, y : 3 }'))
@@ -395,6 +395,7 @@ class ChangeStreamOperationSpecification extends OperationFunctionalSpecificatio
395395
next.getDocumentKey() == null
396396
next.getFullDocument() == null
397397
next.getNamespace() == helper.getNamespace()
398+
next.getDestinationNamespace() == newNamespace
398399
next.getOperationType() == OperationType.RENAME
399400
next.getUpdateDescription() == null
400401

0 commit comments

Comments
 (0)