Improve couchbase support

Expose an `auto-index` property that controls if views and indexes
should be created automatically.

Update the sample so that it uses this new property, lowering the manual
steps to make it working on a vanilla couchbase server.

See gh-3498
pull/4889/merge
Stephane Nicoll 9 years ago
parent ed04a5b12e
commit 64a5cad09a

@ -33,8 +33,9 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.config.CouchbaseBucketFactoryBean;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener;
import org.springframework.data.couchbase.repository.support.IndexManager;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
@ -45,7 +46,7 @@ import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbase
* @since 1.4.0
*/
@Configuration
@ConditionalOnClass({CouchbaseBucket.class, CouchbaseBucketFactoryBean.class})
@ConditionalOnClass({CouchbaseBucket.class, AbstractCouchbaseConfiguration.class})
@Conditional(CouchbaseAutoConfiguration.CouchbaseCondition.class)
@EnableConfigurationProperties(CouchbaseProperties.class)
public class CouchbaseAutoConfiguration {
@ -77,6 +78,26 @@ public class CouchbaseAutoConfiguration {
protected String getBucketPassword() {
return this.properties.getBucket().getPassword();
}
@Override
@ConditionalOnMissingBean(name = "couchbaseTemplate")
@Bean(name = "couchbaseTemplate")
public CouchbaseTemplate couchbaseTemplate() throws Exception {
return super.couchbaseTemplate();
}
@Override
@ConditionalOnMissingBean(name = "couchbaseIndexManager")
@Bean(name = "couchbaseIndexManager")
public IndexManager indexManager() {
if (this.properties.isAutoIndex()) {
return new IndexManager(true, true, true);
}
else {
return new IndexManager(false, false, false);
}
}
}
/**

@ -32,6 +32,12 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.data.couchbase")
public class CouchbaseProperties {
/**
* Automatically create views and indexes. Use the meta-data provided by "@ViewIndexed",
* "@N1qlPrimaryIndexed" and "@N1qlSecondaryIndexed".
*/
private boolean autoIndex;
/**
* Couchbase nodes (host or IP address) to bootstrap from.
*/
@ -39,6 +45,14 @@ public class CouchbaseProperties {
private final Bucket bucket = new Bucket();
public boolean isAutoIndex() {
return this.autoIndex;
}
public void setAutoIndex(boolean autoIndex) {
this.autoIndex = autoIndex;
}
public List<String> getBootstrapHosts() {
return this.bootstrapHosts;
}

@ -34,6 +34,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener;
import org.springframework.data.couchbase.repository.support.IndexManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@ -86,6 +87,33 @@ public class CouchbaseAutoConfigurationTests {
.isEqualTo(this.context.getBean(Validator.class));
}
@Test
public void autoIndexIsDisabledByDefault() {
load(CouchbaseTestConfiguration.class);
CouchbaseTestConfiguration configuration = this.context.getBean(CouchbaseTestConfiguration.class);
IndexManager indexManager = configuration.indexManager();
assertThat(indexManager.isIgnoreViews()).isTrue();
assertThat(indexManager.isIgnoreN1qlPrimary()).isTrue();
assertThat(indexManager.isIgnoreN1qlSecondary()).isTrue();
}
@Test
public void enableAutoIndex() {
load(CouchbaseTestConfiguration.class, "spring.data.couchbase.auto-index=true");
CouchbaseTestConfiguration configuration = this.context.getBean(CouchbaseTestConfiguration.class);
IndexManager indexManager = configuration.indexManager();
assertThat(indexManager.isIgnoreViews()).isFalse();
assertThat(indexManager.isIgnoreN1qlPrimary()).isFalse();
assertThat(indexManager.isIgnoreN1qlSecondary()).isFalse();
}
@Test
public void overrideCouchbaseOperations() {
load(CouchbaseTemplateConfiguration.class);
CouchbaseTemplateConfiguration configuration = this.context.getBean(CouchbaseTemplateConfiguration.class);
assertThat(this.context.getBean(CouchbaseTemplate.class)).isSameAs(configuration.myCouchbaseTemplate());
}
private void load(Class<?> config, String... environment) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(context, environment);
@ -109,4 +137,16 @@ public class CouchbaseAutoConfigurationTests {
}
@Configuration
@Import(CouchbaseTestConfiguration.class)
static class CouchbaseTemplateConfiguration {
@Bean(name = "couchbaseTemplate")
public CouchbaseTemplate myCouchbaseTemplate() {
return mock(CouchbaseTemplate.class);
}
}
}

@ -16,9 +16,6 @@
package org.springframework.boot.autoconfigure.couchbase;
import java.util.Collections;
import java.util.List;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseBucket;
@ -27,7 +24,6 @@ import com.couchbase.client.java.cluster.ClusterInfo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import static org.mockito.Mockito.mock;
@ -37,22 +33,7 @@ import static org.mockito.Mockito.mock;
* @author Stephane Nicoll
*/
@Configuration
public class CouchbaseTestConfiguration extends AbstractCouchbaseConfiguration {
@Override
protected List<String> getBootstrapHosts() {
return Collections.singletonList("localhost");
}
@Override
protected String getBucketName() {
return "my-bucket";
}
@Override
protected String getBucketPassword() {
return "my-password";
}
public class CouchbaseTestConfiguration extends CouchbaseAutoConfiguration.CouchbaseConfiguration {
@Override
public Cluster couchbaseCluster() throws Exception {

@ -22,10 +22,12 @@ import org.junit.Test;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties;
import org.springframework.boot.autoconfigure.couchbase.CouchbaseTestConfiguration;
import org.springframework.boot.autoconfigure.data.couchbase.city.City;
import org.springframework.boot.autoconfigure.data.couchbase.city.CityRepository;
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -65,6 +67,7 @@ public class CouchbaseRepositoriesAutoConfigurationTests {
@Configuration
@TestAutoConfigurationPackage(City.class)
@EnableConfigurationProperties(CouchbaseProperties.class)
@Import({ CouchbaseRepositoriesRegistrar.class, CouchbaseTestConfiguration.class })
static class TestConfiguration {

@ -489,6 +489,7 @@ content into your application; rather pick only the properties that you need.
spring.data.cassandra.username= # Login user of the server.
# COUCHBASE ({sc-spring-boot-autoconfigure}/couchbase/CouchbaseProperties.{sc-ext}[CouchbaseProperties])
spring.data.couchbase.auto-index=false # Automatically create views and indexes.
spring.data.couchbase.bootstrap-hosts=localhost # Couchbase nodes (host or IP address) to bootstrap from.
spring.data.couchbase.bucket.name= # Name of the bucket to connect to.
spring.data.couchbase.bucket.password= # Password of the bucket.

@ -2,13 +2,18 @@
This sample demonstrates how you can store a simple document using Spring Data Couchbase.
The sample expects couchbase to run on your machine with a bucket named `mybucket` and
`couchbase` for the password. You can customize these settings in `application.properties`.
The sample expects couchbase to run on your machine with a bucket named `default` and
no password. You can customize these settings in `application.properties`.
Before you use the sample, you need _at least_ to create an `all` view for the `User`: go
to the Couchbase servers admin console and visit the Views screen, then click `Create
Development View` and name it `all` with `user` as document name. On that view, you need
to change the code to:
This sample also configures the `auto-index` property and the `UserRepository` defines
the `all` view so you should be able to invoke `findAll` for this sample.
== Creating the view manually
If you don't want to rely on `auto-index` and better understand how this works behind the
scenes, you need to create an `all` view for the `User`. Go to the Couchbase servers
admin console and visit the Views screen, then click `Create Development View` and name
it `all` with `user` as document name. On that view, you need to change the code to:
```java
function (doc, meta) {

@ -35,18 +35,19 @@ public class SampleCouchbaseApplication implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
saveUsers();
this.userRepository.deleteAll();
User user = saveUser();
System.out.println(this.userRepository.findAll());
System.out.println(this.userRepository.findOne(user.getId()));
}
private void saveUsers() {
private User saveUser() {
User user = new User();
user.setId(UUID.randomUUID().toString());
user.setFirstName("Alice");
user.setLastName("Smith");
this.userRepository.save(user);
return this.userRepository.save(user);
}
}

@ -16,8 +16,10 @@
package sample.data.couchbase;
import org.springframework.data.couchbase.core.query.ViewIndexed;
import org.springframework.data.couchbase.repository.CouchbaseRepository;
@ViewIndexed(designDoc = "user", viewName = "all")
public interface UserRepository extends CouchbaseRepository<User, String> {
}

@ -1,2 +1,2 @@
spring.data.couchbase.bucket.name=mybucket
spring.data.couchbase.bucket.password=couchbase
spring.data.couchbase.auto-index=true
spring.data.couchbase.bucket.name=default
Loading…
Cancel
Save