Add Couchbase support

Closes gh-3498
This commit is contained in:
Eddú Meléndez
2015-07-30 02:49:50 -05:00
committed by Stephane Nicoll
parent ecf11e0230
commit 76f1ca4188
30 changed files with 1006 additions and 2 deletions

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.couchbase;
import java.util.Arrays;
import java.util.List;
import javax.validation.Validator;
import com.couchbase.client.java.CouchbaseBucket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
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.mapping.event.ValidatingCouchbaseEventListener;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-Configuration} for Couchbase.
*
* @author Eddú Meléndez
* @since 1.4.0
*/
@Configuration
@ConditionalOnClass({ CouchbaseBucket.class, CouchbaseBucketFactoryBean.class })
@EnableConfigurationProperties(CouchbaseProperties.class)
public class CouchbaseAutoConfiguration {
@Bean
@ConditionalOnBean(Validator.class)
public ValidatingCouchbaseEventListener validationEventListener(Validator validator) {
return new ValidatingCouchbaseEventListener(validator);
}
@Configuration
static class CouchbaseConfiguration extends AbstractCouchbaseConfiguration {
@Autowired
private CouchbaseProperties properties;
@Override
protected List<String> getBootstrapHosts() {
return Arrays.asList(this.properties.getHosts());
}
@Override
protected String getBucketName() {
return this.properties.getBucketName();
}
@Override
protected String getBucketPassword() {
return this.properties.getBucketPassword();
}
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.couchbase;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Configuration properties for Couchbase.
*
* @author Eddú Meléndez
* @since 1.4.0
*/
@ConfigurationProperties(prefix = "spring.data.couchbase")
public class CouchbaseProperties {
/**
* Couchabase server hosts.
*/
private String[] hosts;
/**
* Couchbase bucket name.
*/
private String bucketName;
/**
* Couchbase bucket password.
*/
private String bucketPassword;
public String[] getHosts() {
return this.hosts;
}
public void setHosts(String[] hosts) {
this.hosts = hosts;
}
public String getBucketName() {
return this.bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public String getBucketPassword() {
return this.bucketPassword;
}
public void setBucketPassword(String bucketPassword) {
this.bucketPassword = bucketPassword;
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2012-2016 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
*
* http://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.
*/
/**
* Auto-configuration for Couchbase.
*/
package org.springframework.boot.autoconfigure.couchbase;

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.data.couchbase;
import com.couchbase.client.java.Bucket;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.couchbase.repository.CouchbaseRepository;
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactoryBean;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Couchbase
* Repositories.
*
* @author Eddú Meléndez
* @since 1.4.0
*/
@Configuration
@ConditionalOnClass({ Bucket.class, CouchbaseRepository.class })
@ConditionalOnProperty(prefix = "spring.data.couchbase.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnMissingBean(CouchbaseRepositoryFactoryBean.class)
@Import(CouchbaseRepositoriesRegistrar.class)
public class CouchbaseRepositoriesAutoConfiguration {
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.data.couchbase;
import java.lang.annotation.Annotation;
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.couchbase.repository.config.CouchbaseRepositoryConfigurationExtension;
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
/**
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Couchbase
* Repositories.
*
* @author Eddú Meléndez
* @since 1.4.0
*/
public class CouchbaseRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableCouchbaseRepositories.class;
}
@Override
protected Class<?> getConfiguration() {
return EnableCouchbaseRepositoriesConfiguration.class;
}
@Override
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
return new CouchbaseRepositoryConfigurationExtension();
}
@EnableCouchbaseRepositories
private static class EnableCouchbaseRepositoriesConfiguration {
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2012-2016 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
*
* http://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.
*/
/**
* Auto-configuration for Spring Data Couchbase.
*/
package org.springframework.boot.autoconfigure.data.couchbase;

View File

@@ -19,9 +19,11 @@ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.couchbase;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Tests for {@link CouchbaseAutoConfiguration}
*
* @author Eddú Meléndez
*/
public class CouchbaseAutoConfigurationTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private AnnotationConfigApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void validateProperties() {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"spring.data.couchbase.hosts=localhost",
"spring.data.couchbase.bucket-name=test",
"spring.data.couchbase.bucket-password=test");
this.context.register(PropertyPlaceholderAutoConfiguration.class,
CouchbaseAutoConfiguration.class);
this.thrown.expect(BeanCreationException.class);
this.thrown.expectMessage("Connection refused");
this.context.refresh();
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.data.alt.couchbase;
import org.springframework.boot.autoconfigure.data.couchbase.city.City;
import org.springframework.data.repository.Repository;
/**
* @author Eddú Meléndez
*/
public interface CityCouchbaseRepository extends Repository<City, Long> {
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.data.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;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.cluster.ClusterInfo;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
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.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.WriteResultChecking;
import org.springframework.data.couchbase.core.query.Consistency;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* @author Eddú Meléndez
*/
public class CouchbaseRepositoriesAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@After
public void close() {
this.context.close();
}
@Test
public void testDefaultRepositoryConfiguration() throws Exception {
this.context = new AnnotationConfigApplicationContext();
addCouchbaseProperties(this.context);
this.context.register(TestConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertThat(this.context.getBean(CityRepository.class)).isNotNull();
assertThat(this.context.getBean(Bucket.class)).isNotNull();
}
@Test
public void testNoRepositoryConfiguration() throws Exception {
this.context = new AnnotationConfigApplicationContext();
addCouchbaseProperties(this.context);
this.context.register(EmptyConfiguration.class, TestConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertThat(this.context.getBean(Bucket.class)).isNotNull();
}
@Test
public void templateExists() {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"spring.data.couchbase.hosts=localhost",
"spring.data.couchbase.bucket-name=test",
"spring.data.couchbase.bucket-password=test");
this.context.register(PropertyPlaceholderAutoConfiguration.class,
TestConfiguration.class);
this.context.refresh();
assertThat(this.context.getBeanNamesForType(CouchbaseTemplate.class).length).isEqualTo(1);
}
private void addCouchbaseProperties(AnnotationConfigApplicationContext context) {
EnvironmentTestUtils.addEnvironment(context,
"spring.data.couchbase.hosts=localhost",
"spring.data.couchbase.bucket-name=test",
"spring.data.couchbase.bucket-password=test");
}
@Configuration
@TestAutoConfigurationPackage(City.class)
@Import(CouchbaseRepositoriesRegistrar.class)
static class TestConfiguration extends AbstractCouchbaseConfiguration {
@Override
protected List<String> getBootstrapHosts() {
return Collections.singletonList("192.1.2.3");
}
@Override
protected String getBucketName() {
return "someBucket";
}
@Override
protected String getBucketPassword() {
return "someBucketPassword";
}
@Override
public Cluster couchbaseCluster() throws Exception {
return mock(CouchbaseCluster.class);
}
@Bean
public ClusterInfo couchbaseClusterInfo() {
return mock(ClusterInfo.class);
}
@Override
public Bucket couchbaseClient() throws Exception {
return mock(CouchbaseBucket.class);
}
@Override
public CouchbaseTemplate couchbaseTemplate() throws Exception {
CouchbaseTemplate template = super.couchbaseTemplate();
template.setWriteResultChecking(WriteResultChecking.LOG);
return template;
}
@Override
protected Consistency getDefaultConsistency() {
return Consistency.READ_YOUR_OWN_WRITES;
}
}
@Configuration
@TestAutoConfigurationPackage(EmptyDataPackage.class)
protected static class EmptyConfiguration {
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.data.couchbase.city;
import com.couchbase.client.java.repository.annotation.Field;
import com.couchbase.client.java.repository.annotation.Id;
import org.springframework.data.couchbase.core.mapping.Document;
@Document
public class City {
@Id
private String id;
@Field
private String name;
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2012-2016 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
*
* http://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.boot.autoconfigure.data.couchbase.city;
import org.springframework.data.repository.Repository;
public interface CityRepository extends Repository<City, Long> {
}