DATACOUCH-148 - Allow to configure repository queries consistency globally.

The consistency to apply on generated view queries (Stale) and N1QL queries (ScanConsistency) can now be chosen via the configuration, through a more abstract Consistency enumeration.

It is accessed from the CouchbaseOperations interface but is used in the repository only. In xml, the consistency attribute is on the couchbase:template element (string value of the enum to be passed in).

Documentation has been amended to describe this feature.
This commit is contained in:
Simon Baslé
2015-07-27 17:17:21 +02:00
parent 508f190270
commit f543e2b037
15 changed files with 343 additions and 100 deletions

View File

@@ -13,61 +13,67 @@ import org.springframework.core.env.Environment;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.data.couchbase.core.WriteResultChecking;
import org.springframework.data.couchbase.core.view.Consistency;
@Configuration
public class IntegrationTestApplicationConfig extends AbstractCouchbaseConfiguration {
@Autowired
private Environment springEnv;
@Autowired
private Environment springEnv;
@Bean
public String couchbaseAdminUser() {
return springEnv.getProperty("couchbase.adminUser", "Administrator");
}
@Bean
public String couchbaseAdminUser() {
return springEnv.getProperty("couchbase.adminUser", "Administrator");
}
@Bean
public String couchbaseAdminPassword() {
return springEnv.getProperty("couchbase.adminUser", "password");
}
@Bean
public String couchbaseAdminPassword() {
return springEnv.getProperty("couchbase.adminUser", "password");
}
@Override
protected List<String> getBootstrapHosts() {
return Collections.singletonList(springEnv.getProperty("couchbase.host", "127.0.0.1"));
}
@Override
protected List<String> getBootstrapHosts() {
return Collections.singletonList(springEnv.getProperty("couchbase.host", "127.0.0.1"));
}
@Override
protected String getBucketName() {
return springEnv.getProperty("couchbase.bucket", "default");
}
@Override
protected String getBucketName() {
return springEnv.getProperty("couchbase.bucket", "default");
}
@Override
protected String getBucketPassword() {
return springEnv.getProperty("couchbase.password", "");
}
@Override
protected String getBucketPassword() {
return springEnv.getProperty("couchbase.password", "");
}
//TODO maybe create the bucket if doesn't exist
//TODO maybe create the bucket if doesn't exist
@Override
protected CouchbaseEnvironment getEnvironment() {
return DefaultCouchbaseEnvironment.builder()
.connectTimeout(10000)
.kvTimeout(10000)
.queryTimeout(10000)
.viewTimeout(10000)
.build();
}
@Override
protected CouchbaseEnvironment getEnvironment() {
return DefaultCouchbaseEnvironment.builder()
.connectTimeout(10000)
.kvTimeout(10000)
.queryTimeout(10000)
.viewTimeout(10000)
.build();
}
@Override
public CouchbaseTemplate couchbaseTemplate() throws Exception {
CouchbaseTemplate template = super.couchbaseTemplate();
template.setWriteResultChecking(WriteResultChecking.LOG);
return template;
}
@Override
public CouchbaseTemplate couchbaseTemplate() throws Exception {
CouchbaseTemplate template = super.couchbaseTemplate();
template.setWriteResultChecking(WriteResultChecking.LOG);
return template;
}
//change the name of the field that will hold type information
@Override
public String typeKey() {
return "javaClass";
}
@Override
public String typeKey() {
return "javaClass";
}
@Override
protected Consistency getDefaultConsistency() {
return Consistency.READ_YOUR_OWN_WRITES;
}
}

View File

@@ -30,65 +30,67 @@ import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
import org.springframework.data.couchbase.core.view.Consistency;
import org.springframework.data.couchbase.repository.User;
/**
* @author Michael Nitschinger
* @author Simon Baslé
*/
public class CouchbaseTemplateParserIntegrationTests {
DefaultListableBeanFactory factory;
BeanDefinitionReader reader;
DefaultListableBeanFactory factory;
BeanDefinitionReader reader;
@Before
public void setUp() {
factory = new DefaultListableBeanFactory();
reader = new XmlBeanDefinitionReader(factory);
}
@Before
public void setUp() {
factory = new DefaultListableBeanFactory();
reader = new XmlBeanDefinitionReader(factory);
}
@Test
public void readsCouchbaseTemplateAttributesCorrectly() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-template-bean.xml"));
@Test
public void readsCouchbaseTemplateAttributesCorrectly() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-template-bean.xml"));
BeanDefinition definition = factory.getBeanDefinition("couchbaseTemplate");
assertEquals(2, definition.getConstructorArgumentValues().getArgumentCount());
BeanDefinition definition = factory.getBeanDefinition("couchbaseTemplate");
assertEquals(2, definition.getConstructorArgumentValues().getArgumentCount());
factory.getBean("couchbaseTemplate");
}
factory.getBean("couchbaseTemplate");
}
@Test
public void readsCouchbaseTemplateWithTranslationServiceAttributesCorrectly() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-template-with-translation-service-bean.xml"));
@Test
public void readsCouchbaseTemplateWithTranslationServiceAttributesCorrectly() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-template-with-translation-service-bean.xml"));
BeanDefinition definition = factory.getBeanDefinition("couchbaseTemplate");
assertEquals(3, definition.getConstructorArgumentValues().getArgumentCount());
BeanDefinition definition = factory.getBeanDefinition("couchbaseTemplate");
assertEquals(3, definition.getConstructorArgumentValues().getArgumentCount());
factory.getBean("couchbaseTemplate");
}
factory.getBean("couchbaseTemplate");
}
/**
* Test case for DATACOUCH-47.
*/
@Test
public void allowsMultipleBuckets() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-multi-bucket-bean.xml"));
/**
* Test case for DATACOUCH-47.
*/
@Test
public void allowsMultipleBuckets() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-multi-bucket-bean.xml"));
factory.getBean("cb-template-first");
factory.getBean("cb-template-second");
}
factory.getBean("cb-template-first");
factory.getBean("cb-template-second");
}
/**
* Test case for DATACOUCH-134 in xml: field for storing type information can be renamed.
*/
@Test
public void testTypeFieldCanBeChosen() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-typekey.xml"));
CouchbaseTemplate template = factory.getBean("couchbaseTemplate", CouchbaseTemplate.class);
/**
* Test case for DATACOUCH-134 in xml: field for storing type information can be renamed.
*/
@Test
public void testTypeFieldCanBeChosen() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-typekey.xml"));
CouchbaseTemplate template = factory.getBean("couchbaseTemplate", CouchbaseTemplate.class);
assertTrue(template.getConverter() instanceof MappingCouchbaseConverter);
MappingCouchbaseConverter converter = ((MappingCouchbaseConverter) template.getConverter());
assertTrue(template.getConverter() instanceof MappingCouchbaseConverter);
MappingCouchbaseConverter converter = ((MappingCouchbaseConverter) template.getConverter());
assertEquals("javaXmlClass", converter.getTypeKey());
assertEquals("javaXmlClass", converter.getTypeKey());
User u = new User("specialSaveUser", "John Locke");
template.save(u);
@@ -99,5 +101,37 @@ public class CouchbaseTemplateParserIntegrationTests {
assertNull(uJson.get(MappingCouchbaseConverter.TYPEKEY_DEFAULT));
assertEquals("org.springframework.data.couchbase.repository.User", uJson.getString("javaXmlClass"));
assertEquals("John Locke", uJson.getString("username"));
}
}
/**
* Test case for DATACOUCH-148, choosing an alternative default for view/N1QL staleness.
*/
@Test
public void shouldParseCustomStaleness() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-consistency.xml"));
CouchbaseTemplate template = factory.getBean("template", CouchbaseTemplate.class);
assertEquals(Consistency.READ_YOUR_OWN_WRITES, template.getDefaultConsistency());
assertNotEquals(Consistency.DEFAULT_CONSISTENCY, template.getDefaultConsistency());
}
/**
* Test case for DATACOUCH-148, choosing an unknown value for view/N1QL staleness.
*/
@Test
public void shouldIgnoreBadCustomStaleness() {
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-consistency.xml"));
CouchbaseTemplate template = factory.getBean("templateBad", CouchbaseTemplate.class);
assertEquals(Consistency.DEFAULT_CONSISTENCY, template.getDefaultConsistency());
}
@Test
public void shouldHaveDefaultsForStaleness() {
//use another resource where staleness isn't customized
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-template-with-translation-service-bean.xml"));
CouchbaseTemplate template = factory.getBean("couchbaseTemplate", CouchbaseTemplate.class);
assertEquals(Consistency.DEFAULT_CONSISTENCY, template.getDefaultConsistency());
}
}