Skip to content

Commit 5caf9ba

Browse files
authored
Add namespace type support to ChangeStreamDocument. (#1736)
JAVA-5769
1 parent dfa4986 commit 5caf9ba

File tree

7 files changed

+237
-11
lines changed

7 files changed

+237
-11
lines changed

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

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public final class ChangeStreamDocument<TDocument> {
4646
@BsonId()
4747
private final BsonDocument resumeToken;
4848
private final BsonDocument namespaceDocument;
49+
50+
@BsonProperty("nsType")
51+
private final String namespaceTypeString;
52+
@BsonIgnore
53+
private final NamespaceType namespaceType;
4954
private final BsonDocument destinationNamespaceDocument;
5055
private final TDocument fullDocument;
5156
private final TDocument fullDocumentBeforeChange;
@@ -66,9 +71,10 @@ public final class ChangeStreamDocument<TDocument> {
6671
/**
6772
* Creates a new instance
6873
*
69-
* @param operationTypeString the operation type
74+
* @param operationType the operation type
7075
* @param resumeToken the resume token
7176
* @param namespaceDocument the BsonDocument representing the namespace
77+
* @param namespaceType the namespace type
7278
* @param destinationNamespaceDocument the BsonDocument representing the destinatation namespace
7379
* @param fullDocument the full document
7480
* @param fullDocumentBeforeChange the full document before change
@@ -85,9 +91,10 @@ public final class ChangeStreamDocument<TDocument> {
8591
*/
8692
@BsonCreator
8793
public ChangeStreamDocument(
88-
@Nullable @BsonProperty("operationType") final String operationTypeString,
94+
@Nullable @BsonProperty("operationType") final String operationType,
8995
@BsonProperty("resumeToken") final BsonDocument resumeToken,
9096
@Nullable @BsonProperty("ns") final BsonDocument namespaceDocument,
97+
@Nullable @BsonProperty("nsType") final String namespaceType,
9198
@Nullable @BsonProperty("to") final BsonDocument destinationNamespaceDocument,
9299
@Nullable @BsonProperty("fullDocument") final TDocument fullDocument,
93100
@Nullable @BsonProperty("fullDocumentBeforeChange") final TDocument fullDocumentBeforeChange,
@@ -101,12 +108,14 @@ public ChangeStreamDocument(
101108
@Nullable @BsonProperty final BsonDocument extraElements) {
102109
this.resumeToken = resumeToken;
103110
this.namespaceDocument = namespaceDocument;
111+
this.namespaceTypeString = namespaceType;
112+
this.namespaceType = namespaceTypeString == null ? null : NamespaceType.fromString(namespaceType);
104113
this.destinationNamespaceDocument = destinationNamespaceDocument;
105114
this.fullDocumentBeforeChange = fullDocumentBeforeChange;
106115
this.documentKey = documentKey;
107116
this.fullDocument = fullDocument;
108117
this.clusterTime = clusterTime;
109-
this.operationTypeString = operationTypeString;
118+
this.operationTypeString = operationType;
110119
this.operationType = operationTypeString == null ? null : OperationType.fromString(operationTypeString);
111120
this.updateDescription = updateDescription;
112121
this.txnNumber = txnNumber;
@@ -134,6 +143,8 @@ public BsonDocument getResumeToken() {
134143
*
135144
* @return the namespace. If the namespaceDocument is null or if it is missing either the 'db' or 'coll' keys,
136145
* then this will return null.
146+
* @see #getNamespaceType()
147+
* @see #getNamespaceTypeString()
137148
*/
138149
@BsonIgnore
139150
@Nullable
@@ -156,13 +167,49 @@ public MongoNamespace getNamespace() {
156167
*
157168
* @return the namespaceDocument
158169
* @since 3.8
170+
* @see #getNamespaceType()
171+
* @see #getNamespaceTypeString()
159172
*/
160173
@BsonProperty("ns")
161174
@Nullable
162175
public BsonDocument getNamespaceDocument() {
163176
return namespaceDocument;
164177
}
165178

179+
/**
180+
* Returns the type of the newly created namespace object as a String, derived from the "nsType" field in a change stream document.
181+
* <p>
182+
* This method is useful when using a driver release that has not yet been updated to include a newer namespace type in the
183+
* {@link NamespaceType} enum. In that case, {@link #getNamespaceType()} will return {@link NamespaceType#OTHER} and this method can
184+
* be used to retrieve the actual namespace type as a string value.
185+
* <p>
186+
* May return null only if <code>$changeStreamSplitLargeEvent</code> is used.
187+
*
188+
* @return the namespace type as a string
189+
* @since 5.6
190+
* @mongodb.server.release 8.1
191+
* @see #getNamespaceType()
192+
* @see #getNamespaceDocument()
193+
*/
194+
@Nullable
195+
public String getNamespaceTypeString() {
196+
return namespaceTypeString;
197+
}
198+
199+
/**
200+
* Returns the type of the newly created namespace object, derived from the "nsType" field in a change stream document.
201+
*
202+
* @return the namespace type.
203+
* @since 5.6
204+
* @mongodb.server.release 8.1
205+
* @see #getNamespaceTypeString()
206+
* @see #getNamespaceDocument()
207+
*/
208+
@Nullable
209+
public NamespaceType getNamespaceType() {
210+
return namespaceType;
211+
}
212+
166213
/**
167214
* Returns the destination namespace, derived from the "to" field in a change stream document.
168215
*
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mongodb.client.model.changestream;
18+
19+
import com.mongodb.lang.Nullable;
20+
21+
/**
22+
* Represents the type of the newly created namespace object in change stream events.
23+
* <p>
24+
* Only present for operations of type {@code create} and when the {@code showExpandedEvents}
25+
* change stream option is enabled.
26+
* </p>
27+
*
28+
* @since 5.6
29+
* @mongodb.server.release 8.1
30+
*/
31+
public enum NamespaceType {
32+
COLLECTION("collection"),
33+
TIMESERIES("timeseries"),
34+
VIEW("view"),
35+
/**
36+
* The other namespace type.
37+
*
38+
* <p>A placeholder for newer namespace types issued by the server.
39+
* Users encountering OTHER namespace types are advised to update the driver to get the actual namespace type.</p>
40+
*/
41+
OTHER("other");
42+
43+
private final String value;
44+
NamespaceType(final String namespaceTypeName) {
45+
this.value = namespaceTypeName;
46+
}
47+
48+
/**
49+
* @return the String representation of the namespace type
50+
*/
51+
public String getValue() {
52+
return value;
53+
}
54+
55+
/**
56+
* Returns the ChangeStreamNamespaceType from the string value.
57+
*
58+
* @param namespaceTypeName the string value.
59+
* @return the namespace type.
60+
*/
61+
public static NamespaceType fromString(@Nullable final String namespaceTypeName) {
62+
if (namespaceTypeName != null) {
63+
for (NamespaceType namespaceType : NamespaceType.values()) {
64+
if (namespaceTypeName.equals(namespaceType.value)) {
65+
return namespaceType;
66+
}
67+
}
68+
}
69+
return OTHER;
70+
}
71+
72+
@Override
73+
public String toString() {
74+
return "NamespaceType{"
75+
+ "value='" + value + "'"
76+
+ "}";
77+
}
78+
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.mongodb.client.model.changestream;
1818

19+
import com.mongodb.lang.Nullable;
20+
1921
/**
2022
* The {@code $changeStream} operation type.
2123
*
@@ -95,9 +97,9 @@ public String getValue() {
9597
* Returns the ChangeStreamOperationType from the string value.
9698
*
9799
* @param operationTypeName the string value.
98-
* @return the read concern
100+
* @return the operation type.
99101
*/
100-
public static OperationType fromString(final String operationTypeName) {
102+
public static OperationType fromString(@Nullable final String operationTypeName) {
101103
if (operationTypeName != null) {
102104
for (OperationType operationType : OperationType.values()) {
103105
if (operationTypeName.equals(operationType.value)) {

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
6161
new ChangeStreamDocument<Document>(OperationType.INSERT.value,
6262
BsonDocument.parse('{token: true}'),
6363
BsonDocument.parse('{db: "engineering", coll: "users"}'),
64+
NamespaceType.COLLECTION.value,
6465
null,
6566
Document.parse('{_id: 1, userName: "alice123", name: "Alice"}'),
6667
null,
@@ -73,6 +74,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
7374
new ChangeStreamDocument<Document>(OperationType.UPDATE.value,
7475
BsonDocument.parse('{token: true}'),
7576
BsonDocument.parse('{db: "engineering", coll: "users"}'),
77+
NamespaceType.COLLECTION.value,
7678
null,
7779
null,
7880
null,
@@ -84,6 +86,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
8486
new ChangeStreamDocument<Document>(OperationType.UPDATE.value,
8587
BsonDocument.parse('{token: true}'),
8688
BsonDocument.parse('{db: "engineering", coll: "users"}'),
89+
NamespaceType.COLLECTION.value,
8790
null,
8891
Document.parse('{_id: 1, userName: "alice123", name: "Alice"}'),
8992
Document.parse('{_id: 1, userName: "alice1234", name: "Alice"}'),
@@ -96,6 +99,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
9699
new ChangeStreamDocument<Document>(OperationType.REPLACE.value,
97100
BsonDocument.parse('{token: true}'),
98101
BsonDocument.parse('{db: "engineering", coll: "users"}'),
102+
NamespaceType.COLLECTION.value,
99103
null,
100104
Document.parse('{_id: 1, userName: "alice123", name: "Alice"}'),
101105
Document.parse('{_id: 1, userName: "alice1234", name: "Alice"}'),
@@ -106,6 +110,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
106110
new ChangeStreamDocument<Document>(OperationType.DELETE.value,
107111
BsonDocument.parse('{token: true}'),
108112
BsonDocument.parse('{db: "engineering", coll: "users"}'),
113+
NamespaceType.COLLECTION.value,
109114
null,
110115
null,
111116
Document.parse('{_id: 1, userName: "alice123", name: "Alice"}'),
@@ -116,6 +121,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
116121
new ChangeStreamDocument<Document>(OperationType.DROP.value,
117122
BsonDocument.parse('{token: true}'),
118123
BsonDocument.parse('{db: "engineering", coll: "users"}'),
124+
NamespaceType.COLLECTION.value,
119125
null,
120126
null,
121127
null,
@@ -126,6 +132,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
126132
new ChangeStreamDocument<Document>(OperationType.RENAME.value,
127133
BsonDocument.parse('{token: true}'),
128134
BsonDocument.parse('{db: "engineering", coll: "users"}'),
135+
NamespaceType.COLLECTION.value,
129136
BsonDocument.parse('{db: "engineering", coll: "people"}'),
130137
null,
131138
null,
@@ -140,6 +147,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
140147
null,
141148
null,
142149
null,
150+
null,
143151
new BsonTimestamp(1234, 2),
144152
null, null, null, null, null, null
145153
),
@@ -150,12 +158,14 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
150158
null,
151159
null,
152160
null,
161+
null,
153162
new BsonTimestamp(1234, 2),
154163
null, null, null, null, null, null
155164
),
156165
new ChangeStreamDocument<Document>(OperationType.INSERT.value,
157166
BsonDocument.parse('{token: true}'),
158167
BsonDocument.parse('{db: "engineering", coll: "users"}'),
168+
NamespaceType.COLLECTION.value,
159169
null,
160170
Document.parse('{_id: 1, userName: "alice123", name: "Alice"}'),
161171
null,
@@ -180,6 +190,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
180190
db: 'engineering',
181191
coll: 'users'
182192
},
193+
nsType: 'collection',
183194
documentKey: {
184195
userName: 'alice123',
185196
_id: 1
@@ -204,6 +215,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
204215
db: 'engineering',
205216
coll: 'users'
206217
},
218+
nsType: 'collection',
207219
documentKey: {
208220
_id: 1
209221
},
@@ -225,6 +237,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
225237
db: 'engineering',
226238
coll: 'users'
227239
},
240+
nsType: 'collection',
228241
documentKey: {
229242
_id: 1
230243
},
@@ -261,6 +274,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
261274
db: 'engineering',
262275
coll: 'users'
263276
},
277+
nsType: 'collection',
264278
documentKey: {
265279
_id: 1
266280
},
@@ -285,6 +299,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
285299
db: 'engineering',
286300
coll: 'users'
287301
},
302+
nsType: 'collection',
288303
documentKey: {
289304
_id: 1
290305
},
@@ -304,6 +319,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
304319
db: 'engineering',
305320
coll: 'users'
306321
}
322+
nsType: 'collection',
307323
}
308324
''',
309325
'''
@@ -315,6 +331,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
315331
db: 'engineering',
316332
coll: 'users'
317333
},
334+
nsType: 'collection',
318335
to: {
319336
db: 'engineering',
320337
coll: 'people'
@@ -347,6 +364,7 @@ class ChangeStreamDocumentCodecSpecification extends Specification {
347364
db: 'engineering',
348365
coll: 'users'
349366
},
367+
nsType: 'collection',
350368
documentKey: {
351369
userName: 'alice123',
352370
_id: 1

0 commit comments

Comments
 (0)