Skip to content

Commit bf54054

Browse files
christophstroblmp911de
authored andcommitted
Pass on FullDocumentBeforeChange option to change stream iterable/publisher.
This commit ensures to pass on a potentially set FullDocumentBeforeChange option to the change stream iterable/publisher. It also corrects false optional behavior within the change stream task which did some defaulting though the actual value is an optional one that must not be present. Original pull request: #4541 Closes #4495
1 parent 6928515 commit bf54054

File tree

5 files changed

+50
-10
lines changed

5 files changed

+50
-10
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupport.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ private ChangeStreamOptionsBuilder initOptionsBuilder() {
168168
}
169169
});
170170
options.getFullDocumentLookup().ifPresent(builder::fullDocumentLookup);
171+
options.getFullDocumentBeforeChangeLookup().ifPresent(builder::fullDocumentBeforeChangeLookup);
171172
options.getCollation().ifPresent(builder::collation);
172173

173174
if (options.isResumeAfter()) {

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,6 +2050,10 @@ public <T> Flux<ChangeStreamEvent<T>> changeStream(@Nullable String database, @N
20502050
publisher = options.getCollation().map(Collation::toMongoCollation).map(publisher::collation)
20512051
.orElse(publisher);
20522052
publisher = options.getResumeBsonTimestamp().map(publisher::startAtOperationTime).orElse(publisher);
2053+
2054+
if(options.getFullDocumentBeforeChangeLookup().isPresent()) {
2055+
publisher = publisher.fullDocumentBeforeChange(options.getFullDocumentBeforeChangeLookup().get());
2056+
}
20532057
return publisher.fullDocument(options.getFullDocumentLookup().orElse(fullDocument));
20542058
}) //
20552059
.flatMapMany(publisher -> Flux.from(publisher)

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTask.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
3838
import org.springframework.data.mongodb.core.convert.MongoConverter;
3939
import org.springframework.data.mongodb.core.convert.QueryMapper;
40-
import org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions;
4140
import org.springframework.data.mongodb.core.messaging.Message.MessageProperties;
4241
import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions;
4342
import org.springframework.lang.Nullable;
@@ -88,7 +87,7 @@ protected MongoCursor<ChangeStreamDocument<Document>> initCursor(MongoTemplate t
8887
Collation collation = null;
8988
FullDocument fullDocument = ClassUtils.isAssignable(Document.class, targetType) ? FullDocument.DEFAULT
9089
: FullDocument.UPDATE_LOOKUP;
91-
FullDocumentBeforeChange fullDocumentBeforeChange = FullDocumentBeforeChange.DEFAULT;
90+
FullDocumentBeforeChange fullDocumentBeforeChange = null;
9291
BsonTimestamp startAt = null;
9392
boolean resumeAfter = true;
9493

@@ -116,8 +115,9 @@ protected MongoCursor<ChangeStreamDocument<Document>> initCursor(MongoTemplate t
116115
.orElseGet(() -> ClassUtils.isAssignable(Document.class, targetType) ? FullDocument.DEFAULT
117116
: FullDocument.UPDATE_LOOKUP);
118117

119-
fullDocumentBeforeChange = changeStreamOptions.getFullDocumentBeforeChangeLookup()
120-
.orElse(FullDocumentBeforeChange.DEFAULT);
118+
if(changeStreamOptions.getFullDocumentBeforeChangeLookup().isPresent()) {
119+
fullDocumentBeforeChange = changeStreamOptions.getFullDocumentBeforeChangeLookup().get();
120+
}
121121

122122
startAt = changeStreamOptions.getResumeBsonTimestamp().orElse(null);
123123
}
@@ -158,7 +158,9 @@ protected MongoCursor<ChangeStreamDocument<Document>> initCursor(MongoTemplate t
158158
}
159159

160160
iterable = iterable.fullDocument(fullDocument);
161-
iterable = iterable.fullDocumentBeforeChange(fullDocumentBeforeChange);
161+
if(fullDocumentBeforeChange != null) {
162+
iterable = iterable.fullDocumentBeforeChange(fullDocumentBeforeChange);
163+
}
162164

163165
return iterable.iterator();
164166
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
2121
import static org.springframework.data.mongodb.test.util.Assertions.assertThat;
2222

23-
import com.mongodb.WriteConcern;
24-
import org.springframework.data.mongodb.core.MongoTemplateUnitTests.Sith;
2523
import reactor.core.publisher.Flux;
2624
import reactor.core.publisher.Mono;
2725
import reactor.test.StepVerifier;
@@ -101,6 +99,7 @@
10199
import com.mongodb.MongoClientSettings;
102100
import com.mongodb.ReadConcern;
103101
import com.mongodb.ReadPreference;
102+
import com.mongodb.WriteConcern;
104103
import com.mongodb.client.model.CountOptions;
105104
import com.mongodb.client.model.CreateCollectionOptions;
106105
import com.mongodb.client.model.DeleteOptions;
@@ -110,6 +109,7 @@
110109
import com.mongodb.client.model.ReplaceOptions;
111110
import com.mongodb.client.model.TimeSeriesGranularity;
112111
import com.mongodb.client.model.UpdateOptions;
112+
import com.mongodb.client.model.changestream.FullDocumentBeforeChange;
113113
import com.mongodb.client.result.DeleteResult;
114114
import com.mongodb.client.result.InsertManyResult;
115115
import com.mongodb.client.result.InsertOneResult;
@@ -1604,6 +1604,25 @@ void changeStreamOptionStartAftershouldApplied() {
16041604
verify(changeStreamPublisher).startAfter(eq(token));
16051605
}
16061606

1607+
@Test // GH-4495
1608+
void changeStreamOptionFullDocumentBeforeChangeShouldBeApplied() {
1609+
1610+
when(factory.getMongoDatabase(anyString())).thenReturn(Mono.just(db));
1611+
1612+
when(collection.watch(any(Class.class))).thenReturn(changeStreamPublisher);
1613+
when(changeStreamPublisher.batchSize(anyInt())).thenReturn(changeStreamPublisher);
1614+
when(changeStreamPublisher.startAfter(any())).thenReturn(changeStreamPublisher);
1615+
when(changeStreamPublisher.fullDocument(any())).thenReturn(changeStreamPublisher);
1616+
when(changeStreamPublisher.fullDocumentBeforeChange(any())).thenReturn(changeStreamPublisher);
1617+
1618+
template
1619+
.changeStream("database", "collection", ChangeStreamOptions.builder().fullDocumentBeforeChangeLookup(FullDocumentBeforeChange.REQUIRED).build(), Object.class)
1620+
.subscribe();
1621+
1622+
verify(changeStreamPublisher).fullDocumentBeforeChange(eq(FullDocumentBeforeChange.REQUIRED));
1623+
1624+
}
1625+
16071626
@Test // GH-4462
16081627
void replaceShouldUseCollationWhenPresent() {
16091628

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTaskUnitTests.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.junit.jupiter.api.extension.ExtendWith;
2828
import org.mockito.Mock;
2929
import org.mockito.junit.jupiter.MockitoExtension;
30-
3130
import org.springframework.data.mongodb.core.MongoTemplate;
3231
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
3332
import org.springframework.data.mongodb.core.convert.MongoConverter;
@@ -39,6 +38,7 @@
3938
import com.mongodb.client.MongoCursor;
4039
import com.mongodb.client.MongoDatabase;
4140
import com.mongodb.client.model.changestream.ChangeStreamDocument;
41+
import com.mongodb.client.model.changestream.FullDocumentBeforeChange;
4242

4343
/**
4444
* @author Christoph Strobl
@@ -68,8 +68,6 @@ void setUp() {
6868
when(mongoCollection.watch(eq(Document.class))).thenReturn(changeStreamIterable);
6969

7070
when(changeStreamIterable.fullDocument(any())).thenReturn(changeStreamIterable);
71-
72-
when(changeStreamIterable.fullDocumentBeforeChange(any())).thenReturn(changeStreamIterable);
7371
}
7472

7573
@Test // DATAMONGO-2258
@@ -125,6 +123,22 @@ void shouldApplyStartAfterToChangeStream() {
125123
verify(changeStreamIterable).startAfter(eq(resumeToken));
126124
}
127125

126+
@Test // GH-4495
127+
void shouldApplyFullDocumentBeforeChangeToChangeStream() {
128+
129+
when(changeStreamIterable.fullDocumentBeforeChange(any())).thenReturn(changeStreamIterable);
130+
131+
ChangeStreamRequest request = ChangeStreamRequest.builder() //
132+
.collection("start-wars") //
133+
.fullDocumentBeforeChangeLookup(FullDocumentBeforeChange.REQUIRED) //
134+
.publishTo(message -> {}) //
135+
.build();
136+
137+
initTask(request, Document.class);
138+
139+
verify(changeStreamIterable).fullDocumentBeforeChange(eq(FullDocumentBeforeChange.REQUIRED));
140+
}
141+
128142
private MongoCursor<ChangeStreamDocument<Document>> initTask(ChangeStreamRequest request, Class<?> targetType) {
129143

130144
ChangeStreamTask task = new ChangeStreamTask(template, request, targetType, er -> {});

0 commit comments

Comments
 (0)