Reinstate the getDefaultConsistency() method in the Configuration. (#1249)

Closes #1243.
This commit is contained in:
Michael Reiche
2021-10-22 11:42:55 -07:00
committed by GitHub
parent f0221812e2
commit e1b0ea98d9
12 changed files with 230 additions and 31 deletions

View File

@@ -60,7 +60,6 @@ import com.couchbase.client.java.query.QueryScanConsistency;
// @ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
public interface AirportRepository extends CouchbaseRepository<Airport, String>, DynamicProxyable<AirportRepository> {
// override an annotate with REQUEST_PLUS
@Override
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
List<Airport> findAll();

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.couchbase.domain;
import org.springframework.data.couchbase.repository.CouchbaseRepository;
import org.springframework.stereotype.Repository;
/**
* Airport repository for testing <br>
*
* @author Michael Reiche
*/
@Repository
public interface AirportRepositoryScanConsistencyTest extends CouchbaseRepository<Airport, String> {
}

View File

@@ -18,12 +18,9 @@ package org.springframework.data.couchbase.domain;
import java.lang.reflect.InvocationTargetException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.auditing.DateTimeProvider;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.couchbase.CouchbaseClientFactory;
import org.springframework.data.couchbase.SimpleCouchbaseClientFactory;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
@@ -159,14 +156,16 @@ public class Config extends AbstractCouchbaseConfiguration {
// will be used instead of the result of this call (the client factory arg is different)
public ReactiveCouchbaseTemplate myReactiveCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
MappingCouchbaseConverter mappingCouchbaseConverter) {
return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter);
return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter,
new JacksonTranslationService(), getDefaultConsistency());
}
// do not use couchbaseTemplate for the name of this method, otherwise the value of that been
// will be used instead of the result from this call (the client factory arg is different)
public CouchbaseTemplate myCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
MappingCouchbaseConverter mappingCouchbaseConverter) {
return new CouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter);
return new CouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter, new JacksonTranslationService(),
getDefaultConsistency());
}
// do not use couchbaseClientFactory for the name of this method, otherwise the value of that bean will

View File

@@ -16,6 +16,8 @@
package org.springframework.data.couchbase.repository;
import static com.couchbase.client.java.query.QueryScanConsistency.NOT_BOUNDED;
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -25,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE;
import junit.framework.AssertionFailedError;
@@ -46,6 +49,8 @@ import javax.validation.ConstraintViolationException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.DataIntegrityViolationException;
@@ -63,6 +68,7 @@ import org.springframework.data.couchbase.domain.Address;
import org.springframework.data.couchbase.domain.Airport;
import org.springframework.data.couchbase.domain.AirportMini;
import org.springframework.data.couchbase.domain.AirportRepository;
import org.springframework.data.couchbase.domain.AirportRepositoryScanConsistencyTest;
import org.springframework.data.couchbase.domain.NaiveAuditorAware;
import org.springframework.data.couchbase.domain.Person;
import org.springframework.data.couchbase.domain.PersonRepository;
@@ -267,6 +273,80 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
}
}
@Test
public void saveNotBoundedRequestPlus() {
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigRequestPlus.class);
// the Config class has been modified, these need to be loaded again
CouchbaseTemplate couchbaseTemplateRP = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
AirportRepository airportRepositoryRP = (AirportRepository) ac.getBean("airportRepository");
// save() followed by query with NOT_BOUNDED will result in not finding the document
Airport vie = new Airport("airports::vie", "vie", "low9");
Airport airport2 = null;
for (int i = 1; i <= 100; i++) {
// set version == 0 so save() will be an upsert, not a replace
Airport saved = airportRepositoryRP.save(vie.clearVersion());
try {
airport2 = airportRepositoryRP.iata(saved.getIata());
if (airport2 == null) {
break;
}
} catch (DataRetrievalFailureException drfe) {
airport2 = null; //
} finally {
// airportRepository.delete(vie);
// instead of delete, use removeResult to test QueryOptions.consistentWith()
RemoveResult removeResult = couchbaseTemplateRP.removeById().one(vie.getId());
assertEquals(vie.getId(), removeResult.getId());
assertTrue(removeResult.getCas() != 0);
assertTrue(removeResult.getMutationToken().isPresent());
Airport airport3 = airportRepositoryRP.iata(vie.getIata());
assertNull(airport3, "should have been removed");
}
}
assertNotNull(airport2, "airport2 should have never been null");
Airport saved = airportRepositoryRP.save(vie.clearVersion());
List<Airport> airports = couchbaseTemplateRP.findByQuery(Airport.class).withConsistency(NOT_BOUNDED).all();
RemoveResult removeResult = couchbaseTemplateRP.removeById().one(saved.getId());
assertFalse(!airports.isEmpty(), "airports should have been empty");
}
@Test
public void saveNotBoundedWithDefaultRepository() {
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
// the Config class has been modified, these need to be loaded again
CouchbaseTemplate couchbaseTemplateRP = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
AirportRepositoryScanConsistencyTest airportRepositoryRP = (AirportRepositoryScanConsistencyTest) ac.getBean("airportRepositoryScanConsistencyTest");
List<Airport> sizeBeforeTest = airportRepositoryRP.findAll();
assertEquals(0, sizeBeforeTest.size());
Airport vie = new Airport("airports::vie", "vie" , "low9");
Airport saved = airportRepositoryRP.save(vie);
List<Airport> allSaved = airportRepositoryRP.findAll();
couchbaseTemplate.removeById(Airport.class).one(saved.getId());
assertNotEquals( 1, allSaved.size(),"should not have found 1 airport");
}
@Test
public void saveRequestPlusWithDefaultRepository() {
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigRequestPlus.class);
// the Config class has been modified, these need to be loaded again
AirportRepositoryScanConsistencyTest airportRepositoryRP = (AirportRepositoryScanConsistencyTest) ac.getBean("airportRepositoryScanConsistencyTest");
List<Airport> sizeBeforeTest = airportRepositoryRP.findAll();
assertEquals(0, sizeBeforeTest.size());
Airport vie = new Airport("airports::vie", "vie" , "low9");
Airport saved = airportRepositoryRP.save(vie);
List<Airport> allSaved = airportRepositoryRP.findAll();
couchbaseTemplate.removeById(Airport.class).one(saved.getId());
assertEquals( 1, allSaved.size(),"should have found 1 airport");
}
@Test
void findByTypeAlias() {
Airport vie = null;
@@ -386,9 +466,7 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
// set version == 0 so save() will be an upsert, not a replace
Airport saved = airportRepository.save(vie.clearVersion());
try {
airport2 = airportRepository
.withOptions(QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.NOT_BOUNDED))
.iata(saved.getIata());
airport2 = airportRepository.iata(saved.getIata());
if (airport2 == null) {
break;
}
@@ -401,14 +479,16 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
assertEquals(vie.getId(), removeResult.getId());
assertTrue(removeResult.getCas() != 0);
assertTrue(removeResult.getMutationToken().isPresent());
Airport airport3 = airportRepository
.withOptions(QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS)
.consistentWith(MutationState.from(removeResult.getMutationToken().get())))
.iata(vie.getIata());
Airport airport3 = airportRepository.iata(vie.getIata());
assertNull(airport3, "should have been removed");
}
}
assertNull(airport2, "airport2 should have likely been null at least once");
Airport saved = airportRepository.save(vie.clearVersion());
couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).all();
airport2 = airportRepository.iata(vie.getIata());
RemoveResult removeResult = couchbaseTemplate.removeById().one(saved.getId());
assertNotNull(airport2, "airport2 should have been found");
}
@Test
@@ -474,7 +554,7 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
airportRepository.saveAll(
Arrays.stream(iatas).map((iata) -> new Airport("airports::" + iata, iata, iata.toLowerCase(Locale.ROOT)))
.collect(Collectors.toSet()));
couchbaseTemplate.findByQuery(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).all();
Long count = airportRepository.countFancyExpression(asList("JFK"), asList("jfk"), false);
assertEquals(1, count);
@@ -677,7 +757,7 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
void couchbaseRepositoryQuery() throws Exception {
User user = new User("1", "Dave", "Wilson");
userRepository.save(user);
couchbaseTemplate.findByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS)
couchbaseTemplate.findByQuery(User.class).withConsistency(REQUEST_PLUS)
.matching(QueryCriteria.where("firstname").is("Dave").and("`1`").is("`1`")).all();
String input = "findByFirstname";
Method method = UserRepository.class.getMethod(input, String.class);
@@ -809,4 +889,45 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
return new ValidatingCouchbaseEventListener(validator());
}
}
@Configuration
@EnableCouchbaseRepositories("org.springframework.data.couchbase")
@EnableCouchbaseAuditing(auditorAwareRef = "auditorAwareRef", dateTimeProviderRef = "dateTimeProviderRef")
static class ConfigRequestPlus extends AbstractCouchbaseConfiguration {
@Override
public String getConnectionString() {
return connectionString();
}
@Override
public String getUserName() {
return config().adminUsername();
}
@Override
public String getPassword() {
return config().adminPassword();
}
@Override
public String getBucketName() {
return bucketName();
}
@Bean(name = "auditorAwareRef")
public NaiveAuditorAware testAuditorAware() {
return new NaiveAuditorAware();
}
@Bean(name = "dateTimeProviderRef")
public DateTimeProvider testDateTimeProvider() {
return new AuditingDateTimeProvider();
}
@Override
public QueryScanConsistency getDefaultConsistency() {
return REQUEST_PLUS;
}
}
}