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
This commit is contained in:
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.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
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.core.mapping.event.ValidatingCouchbaseEventListener;
|
||||||
|
import org.springframework.data.couchbase.repository.support.IndexManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||||
|
|
@ -45,7 +46,7 @@ import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbase
|
||||||
* @since 1.4.0
|
* @since 1.4.0
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass({CouchbaseBucket.class, CouchbaseBucketFactoryBean.class})
|
@ConditionalOnClass({CouchbaseBucket.class, AbstractCouchbaseConfiguration.class})
|
||||||
@Conditional(CouchbaseAutoConfiguration.CouchbaseCondition.class)
|
@Conditional(CouchbaseAutoConfiguration.CouchbaseCondition.class)
|
||||||
@EnableConfigurationProperties(CouchbaseProperties.class)
|
@EnableConfigurationProperties(CouchbaseProperties.class)
|
||||||
public class CouchbaseAutoConfiguration {
|
public class CouchbaseAutoConfiguration {
|
||||||
|
|
@ -77,6 +78,26 @@ public class CouchbaseAutoConfiguration {
|
||||||
protected String getBucketPassword() {
|
protected String getBucketPassword() {
|
||||||
return this.properties.getBucket().getPassword();
|
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")
|
@ConfigurationProperties(prefix = "spring.data.couchbase")
|
||||||
public class CouchbaseProperties {
|
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.
|
* Couchbase nodes (host or IP address) to bootstrap from.
|
||||||
*/
|
*/
|
||||||
|
|
@ -39,6 +45,14 @@ public class CouchbaseProperties {
|
||||||
|
|
||||||
private final Bucket bucket = new Bucket();
|
private final Bucket bucket = new Bucket();
|
||||||
|
|
||||||
|
public boolean isAutoIndex() {
|
||||||
|
return this.autoIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoIndex(boolean autoIndex) {
|
||||||
|
this.autoIndex = autoIndex;
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getBootstrapHosts() {
|
public List<String> getBootstrapHosts() {
|
||||||
return this.bootstrapHosts;
|
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.config.AbstractCouchbaseConfiguration;
|
||||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||||
import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener;
|
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.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
@ -86,6 +87,33 @@ public class CouchbaseAutoConfigurationTests {
|
||||||
.isEqualTo(this.context.getBean(Validator.class));
|
.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) {
|
private void load(Class<?> config, String... environment) {
|
||||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||||
EnvironmentTestUtils.addEnvironment(context, environment);
|
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;
|
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.Bucket;
|
||||||
import com.couchbase.client.java.Cluster;
|
import com.couchbase.client.java.Cluster;
|
||||||
import com.couchbase.client.java.CouchbaseBucket;
|
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.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
|
@ -37,22 +33,7 @@ import static org.mockito.Mockito.mock;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class CouchbaseTestConfiguration extends AbstractCouchbaseConfiguration {
|
public class CouchbaseTestConfiguration extends CouchbaseAutoConfiguration.CouchbaseConfiguration {
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<String> getBootstrapHosts() {
|
|
||||||
return Collections.singletonList("localhost");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getBucketName() {
|
|
||||||
return "my-bucket";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getBucketPassword() {
|
|
||||||
return "my-password";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cluster couchbaseCluster() throws Exception {
|
public Cluster couchbaseCluster() throws Exception {
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,12 @@ import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
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.couchbase.CouchbaseTestConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.data.couchbase.city.City;
|
import org.springframework.boot.autoconfigure.data.couchbase.city.City;
|
||||||
import org.springframework.boot.autoconfigure.data.couchbase.city.CityRepository;
|
import org.springframework.boot.autoconfigure.data.couchbase.city.CityRepository;
|
||||||
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
|
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.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
@ -65,6 +67,7 @@ public class CouchbaseRepositoriesAutoConfigurationTests {
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@TestAutoConfigurationPackage(City.class)
|
@TestAutoConfigurationPackage(City.class)
|
||||||
|
@EnableConfigurationProperties(CouchbaseProperties.class)
|
||||||
@Import({ CouchbaseRepositoriesRegistrar.class, CouchbaseTestConfiguration.class })
|
@Import({ CouchbaseRepositoriesRegistrar.class, CouchbaseTestConfiguration.class })
|
||||||
static class TestConfiguration {
|
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.
|
spring.data.cassandra.username= # Login user of the server.
|
||||||
|
|
||||||
# COUCHBASE ({sc-spring-boot-autoconfigure}/couchbase/CouchbaseProperties.{sc-ext}[CouchbaseProperties])
|
# 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.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.name= # Name of the bucket to connect to.
|
||||||
spring.data.couchbase.bucket.password= # Password of the bucket.
|
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.
|
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
|
The sample expects couchbase to run on your machine with a bucket named `default` and
|
||||||
`couchbase` for the password. You can customize these settings in `application.properties`.
|
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
|
This sample also configures the `auto-index` property and the `UserRepository` defines
|
||||||
to the Couchbase server’s admin console and visit the Views screen, then click `Create
|
the `all` view so you should be able to invoke `findAll` for this sample.
|
||||||
Development View` and name it `all` with `user` as document name. On that view, you need
|
|
||||||
to change the code to:
|
== 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 server’s
|
||||||
|
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
|
```java
|
||||||
function (doc, meta) {
|
function (doc, meta) {
|
||||||
|
|
|
||||||
|
|
@ -35,18 +35,19 @@ public class SampleCouchbaseApplication implements CommandLineRunner {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(String... args) throws Exception {
|
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 user = new User();
|
||||||
user.setId(UUID.randomUUID().toString());
|
user.setId(UUID.randomUUID().toString());
|
||||||
user.setFirstName("Alice");
|
user.setFirstName("Alice");
|
||||||
user.setLastName("Smith");
|
user.setLastName("Smith");
|
||||||
|
|
||||||
this.userRepository.save(user);
|
return this.userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,10 @@
|
||||||
|
|
||||||
package sample.data.couchbase;
|
package sample.data.couchbase;
|
||||||
|
|
||||||
|
import org.springframework.data.couchbase.core.query.ViewIndexed;
|
||||||
import org.springframework.data.couchbase.repository.CouchbaseRepository;
|
import org.springframework.data.couchbase.repository.CouchbaseRepository;
|
||||||
|
|
||||||
|
@ViewIndexed(designDoc = "user", viewName = "all")
|
||||||
public interface UserRepository extends CouchbaseRepository<User, String> {
|
public interface UserRepository extends CouchbaseRepository<User, String> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
spring.data.couchbase.bucket.name=mybucket
|
spring.data.couchbase.auto-index=true
|
||||||
spring.data.couchbase.bucket.password=couchbase
|
spring.data.couchbase.bucket.name=default
|
||||||
Loading…
Reference in New Issue