Skip to content

Commit 9604193

Browse files
authored
Fix SimpleCouchbaseRepository not taking into account the default consistency. (#1256)
* Create a test repository dedicated to default consistency. * Test default consistency being used with CouchbaseRepository findAll. Related tickets #1243 * Take template default consistency into account when building the query scan consistency. Closes #1243 * Clean imports. * Query scan consistency is null unless specified. * Apply query scan consistency fix to reactive repository. * Reactive repository for default scan consistency tests. * Test reactive repository default scan consistency. * Avoid consistency default behavior duplication. * Tests request plus consistency now use deleteAll with request plus. This is to make sure other tests won't see documents from pending index mutations
1 parent 1c96427 commit 9604193

File tree

7 files changed

+226
-88
lines changed

7 files changed

+226
-88
lines changed

src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,7 @@
1616

1717
package org.springframework.data.couchbase.repository.support;
1818

19-
import static org.springframework.data.couchbase.repository.support.Util.hasNonZeroVersionProperty;
20-
21-
import java.util.Collection;
22-
import java.util.List;
23-
import java.util.Objects;
24-
import java.util.Optional;
25-
import java.util.stream.Collectors;
26-
19+
import com.couchbase.client.java.query.QueryScanConsistency;
2720
import org.springframework.data.couchbase.core.CouchbaseOperations;
2821
import org.springframework.data.couchbase.core.query.Query;
2922
import org.springframework.data.couchbase.repository.CouchbaseRepository;
@@ -36,14 +29,21 @@
3629
import org.springframework.data.util.Streamable;
3730
import org.springframework.util.Assert;
3831

39-
import com.couchbase.client.java.query.QueryScanConsistency;
32+
import java.util.Collection;
33+
import java.util.List;
34+
import java.util.Objects;
35+
import java.util.Optional;
36+
import java.util.stream.Collectors;
37+
38+
import static org.springframework.data.couchbase.repository.support.Util.hasNonZeroVersionProperty;
4039

4140
/**
4241
* Repository base implementation for Couchbase.
4342
*
4443
* @author Michael Nitschinger
4544
* @author Mark Paluch
4645
* @author Jens Schauder
46+
* @author Jonathan Massuchetti
4747
*/
4848
public class SimpleCouchbaseRepository<T, ID> implements CouchbaseRepository<T, ID> {
4949

@@ -190,7 +190,8 @@ private List<T> findAll(Query query) {
190190
}
191191

192192
private QueryScanConsistency buildQueryScanConsistency() {
193-
QueryScanConsistency scanConsistency = QueryScanConsistency.NOT_BOUNDED;
193+
QueryScanConsistency scanConsistency = null;
194+
194195
if (crudMethodMetadata.getScanConsistency() != null) {
195196
scanConsistency = crudMethodMetadata.getScanConsistency().query();
196197
}

src/main/java/org/springframework/data/couchbase/repository/support/SimpleReactiveCouchbaseRepository.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,7 @@
1616

1717
package org.springframework.data.couchbase.repository.support;
1818

19-
import static org.springframework.data.couchbase.repository.support.Util.hasNonZeroVersionProperty;
20-
21-
import reactor.core.publisher.Flux;
22-
import reactor.core.publisher.Mono;
23-
24-
import java.util.List;
25-
import java.util.Objects;
26-
import java.util.stream.Collectors;
27-
19+
import com.couchbase.client.java.query.QueryScanConsistency;
2820
import org.reactivestreams.Publisher;
2921
import org.springframework.data.couchbase.core.CouchbaseOperations;
3022
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
@@ -34,8 +26,14 @@
3426
import org.springframework.data.domain.Sort;
3527
import org.springframework.data.util.Streamable;
3628
import org.springframework.util.Assert;
29+
import reactor.core.publisher.Flux;
30+
import reactor.core.publisher.Mono;
3731

38-
import com.couchbase.client.java.query.QueryScanConsistency;
32+
import java.util.List;
33+
import java.util.Objects;
34+
import java.util.stream.Collectors;
35+
36+
import static org.springframework.data.couchbase.repository.support.Util.hasNonZeroVersionProperty;
3937

4038
/**
4139
* Reactive repository base implementation for Couchbase.
@@ -46,6 +44,7 @@
4644
* @author David Kelly
4745
* @author Douglas Six
4846
* @author Jens Schauder
47+
* @author Jonathan Massuchetti
4948
* @since 3.0
5049
*/
5150
public class SimpleReactiveCouchbaseRepository<T, ID> implements ReactiveCouchbaseRepository<T, ID> {
@@ -206,7 +205,8 @@ private Flux<T> findAll(Query query) {
206205
}
207206

208207
private QueryScanConsistency buildQueryScanConsistency() {
209-
QueryScanConsistency scanConsistency = QueryScanConsistency.NOT_BOUNDED;
208+
QueryScanConsistency scanConsistency = null;
209+
210210
if (crudMethodMetadata.getScanConsistency() != null) {
211211
scanConsistency = crudMethodMetadata.getScanConsistency().query();
212212
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2017-2021 the original author or authors.
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+
* https://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 org.springframework.data.couchbase.domain;
18+
19+
import org.springframework.data.couchbase.repository.CouchbaseRepository;
20+
import org.springframework.stereotype.Repository;
21+
22+
/**
23+
* Airport repository for testing default consistency<br>
24+
*
25+
* @author Jonathan Massuchetti
26+
*/
27+
@Repository
28+
public interface AirportDefaultConsistencyRepository extends CouchbaseRepository<Airport, String> {
29+
30+
Airport iata(String iata);
31+
32+
}

src/test/java/org/springframework/data/couchbase/domain/AirportRepository.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@
4343
@Repository
4444
public interface AirportRepository extends CouchbaseRepository<Airport, String> {
4545

46-
// NOT_BOUNDED to test ScanConsistency
47-
// @ScanConsistency(query = QueryScanConsistency.NOT_BOUNDED)
48-
Airport iata(String iata);
49-
5046
@Override
5147
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
5248
List<Airport> findAll();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2017-2021 the original author or authors.
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+
* https://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 org.springframework.data.couchbase.domain;
18+
19+
import com.couchbase.client.java.json.JsonArray;
20+
import com.couchbase.client.java.query.QueryScanConsistency;
21+
import org.springframework.data.couchbase.repository.Query;
22+
import org.springframework.data.couchbase.repository.ScanConsistency;
23+
import org.springframework.data.domain.Page;
24+
import org.springframework.data.domain.PageImpl;
25+
import org.springframework.data.domain.PageRequest;
26+
import org.springframework.data.domain.Pageable;
27+
import org.springframework.data.repository.reactive.ReactiveSortingRepository;
28+
import org.springframework.stereotype.Repository;
29+
import reactor.core.publisher.Flux;
30+
import reactor.core.publisher.Mono;
31+
32+
import java.util.ArrayList;
33+
34+
/**
35+
* template class for Reactive Couchbase operations
36+
*
37+
* @author Jonathan Massuchetti
38+
*/
39+
@Repository
40+
public interface ReactiveAirportDefaultConsistencyRepository extends ReactiveSortingRepository<Airport, String> {
41+
42+
}

src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,9 @@
1616

1717
package org.springframework.data.couchbase.repository;
1818

19-
import static com.couchbase.client.java.query.QueryScanConsistency.NOT_BOUNDED;
20-
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
21-
import static java.util.Arrays.asList;
22-
import static org.assertj.core.api.Assertions.assertThat;
23-
import static org.junit.jupiter.api.Assertions.assertEquals;
24-
import static org.junit.jupiter.api.Assertions.assertFalse;
25-
import static org.junit.jupiter.api.Assertions.assertNotNull;
26-
import static org.junit.jupiter.api.Assertions.assertNull;
27-
import static org.junit.jupiter.api.Assertions.assertThrows;
28-
import static org.junit.jupiter.api.Assertions.assertTrue;
29-
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE;
30-
31-
import java.lang.reflect.Method;
32-
import java.util.ArrayList;
33-
import java.util.Arrays;
34-
import java.util.List;
35-
import java.util.Locale;
36-
import java.util.Optional;
37-
import java.util.concurrent.Callable;
38-
import java.util.concurrent.ExecutorService;
39-
import java.util.concurrent.Executors;
40-
import java.util.concurrent.Future;
41-
import java.util.stream.Collectors;
42-
19+
import com.couchbase.client.core.error.CouchbaseException;
20+
import com.couchbase.client.core.error.IndexExistsException;
21+
import com.couchbase.client.java.query.QueryScanConsistency;
4322
import org.junit.jupiter.api.BeforeEach;
4423
import org.junit.jupiter.api.Test;
4524
import org.springframework.beans.factory.annotation.Autowired;
@@ -57,15 +36,7 @@
5736
import org.springframework.data.couchbase.core.query.N1QLExpression;
5837
import org.springframework.data.couchbase.core.query.Query;
5938
import org.springframework.data.couchbase.core.query.QueryCriteria;
60-
import org.springframework.data.couchbase.domain.Address;
61-
import org.springframework.data.couchbase.domain.Airport;
62-
import org.springframework.data.couchbase.domain.AirportRepository;
63-
import org.springframework.data.couchbase.domain.Iata;
64-
import org.springframework.data.couchbase.domain.NaiveAuditorAware;
65-
import org.springframework.data.couchbase.domain.Person;
66-
import org.springframework.data.couchbase.domain.PersonRepository;
67-
import org.springframework.data.couchbase.domain.User;
68-
import org.springframework.data.couchbase.domain.UserRepository;
39+
import org.springframework.data.couchbase.domain.*;
6940
import org.springframework.data.couchbase.domain.time.AuditingDateTimeProvider;
7041
import org.springframework.data.couchbase.repository.auditing.EnableCouchbaseAuditing;
7142
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
@@ -82,16 +53,32 @@
8253
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
8354
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
8455

85-
import com.couchbase.client.core.error.CouchbaseException;
86-
import com.couchbase.client.core.error.IndexExistsException;
87-
import com.couchbase.client.java.query.QueryScanConsistency;
56+
import java.lang.reflect.Method;
57+
import java.util.ArrayList;
58+
import java.util.Arrays;
59+
import java.util.List;
60+
import java.util.Locale;
61+
import java.util.Optional;
62+
import java.util.concurrent.Callable;
63+
import java.util.concurrent.ExecutorService;
64+
import java.util.concurrent.Executors;
65+
import java.util.concurrent.Future;
66+
import java.util.stream.Collectors;
67+
68+
import static com.couchbase.client.java.query.QueryScanConsistency.NOT_BOUNDED;
69+
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
70+
import static java.util.Arrays.asList;
71+
import static org.assertj.core.api.Assertions.assertThat;
72+
import static org.junit.jupiter.api.Assertions.*;
73+
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE;
8874

8975
/**
9076
* Repository tests
9177
*
9278
* @author Michael Nitschinger
9379
* @author Michael Reiche
9480
* @author Jens Schauder
81+
* @author Jonathan Massuchetti
9582
*/
9683
@SpringJUnitConfig(CouchbaseRepositoryQueryIntegrationTests.Config.class)
9784
@IgnoreWhen(missesCapabilities = Capabilities.QUERY, clusterTypes = ClusterType.MOCKED)
@@ -101,6 +88,9 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
10188

10289
@Autowired AirportRepository airportRepository;
10390

91+
@Autowired
92+
AirportDefaultConsistencyRepository airportDefaultConsistencyRepository;
93+
10494
@Autowired UserRepository userRepository;
10595

10696
@Autowired CouchbaseTemplate couchbaseTemplate;
@@ -212,9 +202,9 @@ public void saveNotBounded() {
212202
Airport airport2 = null;
213203
for (int i = 1; i <= 100; i++) {
214204
// set version == 0 so save() will be an upsert, not a replace
215-
Airport saved = airportRepository.save(vie.clearVersion());
205+
Airport saved = airportDefaultConsistencyRepository.save(vie.clearVersion());
216206
try {
217-
airport2 = airportRepository.iata(saved.getIata());
207+
airport2 = airportDefaultConsistencyRepository.iata(saved.getIata());
218208
if (airport2 == null) {
219209
break;
220210
}
@@ -227,14 +217,14 @@ public void saveNotBounded() {
227217
assertEquals(vie.getId(), removeResult.getId());
228218
assertTrue(removeResult.getCas() != 0);
229219
assertTrue(removeResult.getMutationToken().isPresent());
230-
Airport airport3 = airportRepository.iata(vie.getIata());
220+
Airport airport3 = airportDefaultConsistencyRepository.iata(vie.getIata());
231221
assertNull(airport3, "should have been removed");
232222
}
233223
}
234224
assertNull(airport2, "airport2 should have likely been null at least once");
235-
Airport saved = airportRepository.save(vie.clearVersion());
225+
Airport saved = airportDefaultConsistencyRepository.save(vie.clearVersion());
236226
couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).all();
237-
airport2 = airportRepository.iata(vie.getIata());
227+
airport2 = airportDefaultConsistencyRepository.iata(vie.getIata());
238228
RemoveResult removeResult = couchbaseTemplate.removeById().one(saved.getId());
239229
assertNotNull(airport2, "airport2 should have been found");
240230
}
@@ -244,7 +234,7 @@ public void saveNotBoundedRequestPlus() {
244234
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigRequestPlus.class);
245235
// the Config class has been modified, these need to be loaded again
246236
CouchbaseTemplate couchbaseTemplateRP = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
247-
AirportRepository airportRepositoryRP = (AirportRepository) ac.getBean("airportRepository");
237+
AirportDefaultConsistencyRepository airportRepositoryRP = (AirportDefaultConsistencyRepository) ac.getBean("airportDefaultConsistencyRepository");
248238

249239
// save() followed by query with NOT_BOUNDED will result in not finding the document
250240
Airport vie = new Airport("airports::vie", "vie", "low9");
@@ -277,6 +267,28 @@ public void saveNotBoundedRequestPlus() {
277267
assertFalse(!airports.isEmpty(), "airports should have been empty");
278268
}
279269

270+
@Test
271+
public void saveNotBoundedRequestPlusWithDefaultRepository() {
272+
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigRequestPlus.class);
273+
// the Config class has been modified, these need to be loaded again
274+
CouchbaseTemplate couchbaseTemplateRP = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
275+
AirportDefaultConsistencyRepository airportRepositoryRP = (AirportDefaultConsistencyRepository) ac.getBean("airportDefaultConsistencyRepository");
276+
277+
List<Airport> sizeBeforeTest = airportRepositoryRP.findAll();
278+
assertEquals(0, sizeBeforeTest.size());
279+
280+
for (int i = 1; i <= 100; i++) {
281+
Airport vie = new Airport("airports::vie" + i, "vie" + i, "low9");
282+
airportRepositoryRP.save(vie);
283+
}
284+
285+
List<Airport> allSaved = airportRepositoryRP.findAll();
286+
287+
airportRepository.deleteAll();
288+
289+
assertEquals(100, allSaved.size());
290+
}
291+
280292
@Test
281293
void findByTypeAlias() {
282294
Airport vie = null;

0 commit comments

Comments
 (0)