diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index 93b509bfa5a0..f7b6921c83df 100755 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -355,6 +355,11 @@ + + org.springframework.data + spring-data-geode + true + org.springframework.data spring-data-jpa diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfiguration.java new file mode 100644 index 000000000000..89e3872f18a3 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfiguration.java @@ -0,0 +1,64 @@ +/* + * 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.geode; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.client.ClientCache; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +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.gemfire.repository.GemfireRepository; +import org.springframework.data.gemfire.repository.config.GemfireRepositoryConfigurationExtension; +import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Geode Repositories. + *

+ * Activates when there is a bean of type {@link Cache} or {@link ClientCache} configured + * in the Spring context, the Spring Data Geode + * {@link org.springframework.data.gemfire.repository.GemfireRepository} + * type is on the classpath, and there is no other, existing + * {@link org.springframework.data.gemfire.repository.GemfireRepository} + * configured. + *

+ * Once in effect, the auto-configuration is the equivalent of enabling Geode Repositories + * using the + * {@link org.springframework.data.gemfire.repository.config.EnableGemfireRepositories} + * annotation. + * + * @author John Blum + * @since 1.5.0 + * @see org.springframework.boot.autoconfigure.data.geode.GeodeRepositoriesAutoConfigureRegistrar + * @see org.springframework.context.annotation.Configuration + * @see org.springframework.data.gemfire.repository.config.EnableGemfireRepositories + * @see org.apache.geode.cache.Cache + * @see org.apache.geode.cache.client.ClientCache + */ +@Configuration +@ConditionalOnBean({ Cache.class, ClientCache.class }) +@ConditionalOnClass(GemfireRepository.class) +@ConditionalOnMissingBean({ GemfireRepositoryConfigurationExtension.class, GemfireRepositoryFactoryBean.class }) +@ConditionalOnProperty(prefix = "spring.data.geode.repositories", name = "enabled", havingValue = "true", matchIfMissing = true) +@Import(GeodeRepositoriesAutoConfigureRegistrar.class) +public class GeodeRepositoriesAutoConfiguration { + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfigureRegistrar.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfigureRegistrar.java new file mode 100644 index 000000000000..559868b567d4 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfigureRegistrar.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011-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.geode; + +import java.lang.annotation.Annotation; + +import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories; +import org.springframework.data.gemfire.repository.config.GemfireRepositoryConfigurationExtension; +import org.springframework.data.repository.config.RepositoryConfigurationExtension; + +/** + * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Geode Repositories. + * + * @author John Blum + * @since 1.5.0 + * @see org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport + * @see org.springframework.data.gemfire.repository.config.EnableGemfireRepositories + * @see org.springframework.data.gemfire.repository.config.GemfireRepositoryConfigurationExtension + */ +public class GeodeRepositoriesAutoConfigureRegistrar + extends AbstractRepositoryConfigurationSourceSupport { + + @Override + protected Class getAnnotation() { + return EnableGemfireRepositories.class; + } + + @Override + protected Class getConfiguration() { + return EnableGeodeRepositoriesConfiguration.class; + } + + @Override + protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() { + return new GemfireRepositoryConfigurationExtension(); + } + + @EnableGemfireRepositories + private static class EnableGeodeRepositoriesConfiguration { + + } +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/package-info.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/package-info.java new file mode 100644 index 000000000000..e86484e2acc5 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/geode/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2011-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 Geode. + */ +package org.springframework.boot.autoconfigure.data.geode; diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index a453a0cd8ffc..122737df8e9b 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -28,6 +28,7 @@ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoC org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\ +org.springframework.boot.autoconfigure.data.geode.GeodeRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\ diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/geode/CityGeodeRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/geode/CityGeodeRepository.java new file mode 100644 index 000000000000..fef9e4e8e27b --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/geode/CityGeodeRepository.java @@ -0,0 +1,24 @@ +/* + * 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.geode; + +import org.springframework.boot.autoconfigure.data.geode.city.City; +import org.springframework.data.repository.Repository; + +public interface CityGeodeRepository extends Repository { + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfigurationTests.java new file mode 100644 index 000000000000..7d64dad6d821 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/GeodeRepositoriesAutoConfigurationTests.java @@ -0,0 +1,170 @@ +/* + * Copyright 2011-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.geode; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.GemFireCache; +import org.apache.geode.cache.RegionAttributes; +import org.apache.geode.cache.client.ClientRegionShortcut; + +import org.junit.After; +import org.junit.Test; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; +import org.springframework.boot.autoconfigure.data.alt.geode.CityGeodeRepository; +import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; +import org.springframework.boot.autoconfigure.data.geode.city.City; +import org.springframework.boot.autoconfigure.data.geode.city.CityRepository; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.gemfire.LocalRegionFactoryBean; +import org.springframework.data.gemfire.RegionAttributesFactoryBean; +import org.springframework.data.gemfire.client.ClientRegionFactoryBean; +import org.springframework.data.gemfire.config.annotation.ClientCacheApplication; +import org.springframework.data.gemfire.config.annotation.PeerCacheApplication; +import org.springframework.data.gemfire.repository.GemfireRepository; +import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for auto-configuring Spring Data Geode Repository with Spring Boot. + * + * @author John Blum + * @since 1.5.0 + */ +public class GeodeRepositoriesAutoConfigurationTests { + + private AnnotationConfigApplicationContext applicationContext; + + @After + public void tearDown() { + this.applicationContext.close(); + } + + @Test + public void clientCacheWithDefaultRepositoryConfigurationIsSuccessful() { + prepareApplicationContext(ClientCacheGemFireConfiguration.class); + + assertThat(this.applicationContext.getBean(CityRepository.class)).isNotNull(); + } + + @Test + public void peerCacheWithDefaultRepositoryConfigurationIsSuccessful() { + prepareApplicationContext(PeerCacheGemFireConfiguration.class); + + assertThat(this.applicationContext.getBean(CityRepository.class)).isNotNull(); + } + + @Test(expected = NoSuchBeanDefinitionException.class) + public void noRepositoryConfiguration() { + prepareApplicationContext(EmptyConfiguration.class, PeerCacheGemFireConfiguration.class); + + assertThat(this.applicationContext.getBean(Cache.class)).isNotNull(); + + this.applicationContext.getBean(GemfireRepository.class); + } + + @Test(expected = NoSuchBeanDefinitionException.class) + public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { + prepareApplicationContext(CustomizedConfiguration.class, PeerCacheGemFireConfiguration.class); + + assertThat(this.applicationContext.getBean(CityGeodeRepository.class)).isNotNull(); + + this.applicationContext.getBean(CityRepository.class); + } + + protected void prepareApplicationContext(Class... annotatedClasses) { + this.applicationContext = new AnnotationConfigApplicationContext(); + this.applicationContext.register(annotatedClasses); + this.applicationContext.register(GeodeRepositoriesAutoConfiguration.class); + this.applicationContext.refresh(); + } + + @SuppressWarnings("unused") + static abstract class AbstractBaseGemFireConfiguration { + + @Bean + @SuppressWarnings("unchecked") + RegionAttributesFactoryBean citiesRegionAttributes() { + RegionAttributesFactoryBean citiesRegionAttributes = + new RegionAttributesFactoryBean(); + + citiesRegionAttributes.setKeyConstraint(Long.class); + citiesRegionAttributes.setValueConstraint(City.class); + + return citiesRegionAttributes; + } + } + + @SuppressWarnings("unused") + @TestAutoConfigurationPackage(City.class) + @ClientCacheApplication(name = "GeodeClientCacheApplication", logLevel = "warning") + static class ClientCacheGemFireConfiguration extends AbstractBaseGemFireConfiguration { + + @Bean(name = "Cities") + ClientRegionFactoryBean citiesRegion(GemFireCache gemfireCache, + RegionAttributes citiesRegionAttributes) { + + ClientRegionFactoryBean citiesRegion = + new ClientRegionFactoryBean(); + + citiesRegion.setAttributes(citiesRegionAttributes); + citiesRegion.setCache(gemfireCache); + citiesRegion.setClose(false); + citiesRegion.setShortcut(ClientRegionShortcut.LOCAL); + + return citiesRegion; + } + } + + @SuppressWarnings("unused") + @TestAutoConfigurationPackage(City.class) + @PeerCacheApplication(name = "GeodePeerCacheApplication", logLevel = "warning") + static class PeerCacheGemFireConfiguration extends AbstractBaseGemFireConfiguration { + + @Bean(name = "Cities") + LocalRegionFactoryBean citiesRegion(GemFireCache gemfireCache, + RegionAttributes citiesRegionAttributes) { + + LocalRegionFactoryBean citiesRegion = + new LocalRegionFactoryBean(); + + citiesRegion.setAttributes(citiesRegionAttributes); + citiesRegion.setCache(gemfireCache); + citiesRegion.setClose(false); + citiesRegion.setPersistent(false); + + return citiesRegion; + } + } + + @Configuration + @TestAutoConfigurationPackage(EmptyDataPackage.class) + protected static class EmptyConfiguration { + + } + + @Configuration + @TestAutoConfigurationPackage(GeodeRepositoriesAutoConfigurationTests.class) + @EnableGemfireRepositories(basePackageClasses = CityGeodeRepository.class) + static class CustomizedConfiguration { + + } +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/city/City.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/city/City.java new file mode 100644 index 000000000000..f31addc3629c --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/city/City.java @@ -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.data.geode.city; + +import java.io.Serializable; + +import org.springframework.data.annotation.Id; +import org.springframework.data.gemfire.mapping.Region; + +@Region("Cities") +public class City implements Serializable { + + private static final long serialVersionUID = -398920762312328553L; + + @Id + private Long id; + + private String name; + + private String state; + + private String country; + + private String map; + + protected City() { + } + + public City(String name, String country) { + super(); + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/city/CityRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/city/CityRepository.java new file mode 100644 index 000000000000..6051ff007655 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/geode/city/CityRepository.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011-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.geode.city; + +import java.util.List; + +import org.springframework.data.repository.Repository; + +public interface CityRepository extends Repository { + + List findAll(); + + City findByNameAndCountry(String name, String country); + + List findByNameLikeAndCountryLike(String name, String country); + +} diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index 63594cb213ac..7b2b01d5f977 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -74,6 +74,7 @@ 2.4.1 8.2.0 3.0.0 + 1.0.0-incubating 2.9 2.4.7 2.7 @@ -147,6 +148,7 @@ 1.6.4.BUILD-SNAPSHOT 1.2.3.RELEASE 3.0.7.RELEASE + 1.0.0.INCUBATING-RELEASE Ingalls-M1 0.21.0.RELEASE 5.0.0.BUILD-SNAPSHOT @@ -1184,6 +1186,17 @@ commons-pool2 ${commons-pool2.version} + + org.apach.geode + geode-core + ${geode.version} + + + org.apache.shiro + shiro-core + + + org.apache.derby derby @@ -2002,6 +2015,11 @@ + + org.springframework.data + spring-data-geode + ${spring-data-geode.version} + org.springframework.data spring-data-releasetrain diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index a0a9a7b7df77..b2cca4348070 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -3442,17 +3442,227 @@ technologies, refer to their http://projects.spring.io/spring-data-neo4j/[refere documentation]. +[[boot-features-geode]] +=== Geode +http://geode.incubator.apache.org/[Apache Geode] is an In-Memory Data Grid (IMDG), +key-value store, with elastic compute and data management features, capable of +linear scale out in a shared nothing architecture for real-time, +low-latency/high-throughput data access. + +https://github.com/spring-projects/spring-data-gemfire[Spring Data Geode] uses the +powerful and consistent Spring programming model to provide a convenient and highly +familiar framework for accessing the +http://geode.incubator.apache.org/[Apache Geode] data management platform. + +Spring Boot provides a convenient '`Starter`' (`spring-boot-starter-data-geode`) +for collecting the necessary dependencies to easily build Spring-powered, Apache Geode +applications. In addition, there is also support for enabling Spring Data Geode +http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/#gemfire-repositories[Repositories] +using Spring Boot auto-configuration. + + +[[boot-features-connecting-to-geode]] +==== Connecting to Apache Geode using Spring Data Geode + +To use Spring Boot's auto-configuration support for Spring Data Geode's Repository +infrastructure extension, not only do you need Spring Data Geode and Apache Geode +on your classpath, in addition to your application-defined Repositories, but you +also need to define a Geode cache instance. There are 2 options for defining a +Geode cache depending on the Geode topology choice used in your application's +architecture. + +First, you might choose to embed a Geode cache in your application, participating +as a http://geode.docs.pivotal.io/docs/topologies_and_comm/p2p_configuration/chapter_overview.html[peer member] +in the Geode cluster. To do so, you must define a peer cache instance using +Spring Data Geode's `CacheFactoryBean`... -[[boot-features-gemfire]] -=== Gemfire -https://github.com/spring-projects/spring-data-gemfire[Spring Data Gemfire] provides -convenient Spring-friendly tools for accessing the -http://pivotal.io/big-data/pivotal-gemfire#details[Pivotal Gemfire] data management -platform. There is a `spring-boot-starter-data-gemfire` '`Starter`' for collecting the -dependencies in a convenient way. There is currently no auto-configuration support for -Gemfire, but you can enable Spring Data Repositories with a -https://github.com/spring-projects/spring-data-gemfire/blob/master/src/main/java/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.java[single annotation (`@EnableGemfireRepositories`)]. +[source,java,indent=0] +---- +@Configuration +class PeerCacheConfiguration { + + Properties geodeProperties() { + Properties geodeProperties = new Properties(); + + geodeProperties.setProperty("name", "PeerExample"); + geodeProperties.setProperty("mcast-port", "0"); + geodeProperties.setProperty("log-level", "config"); + + return geodeProperties; + } + + @Bean + CacheFactoryBean geodeCache() { + CacheFactoryBean geodeCache = new CacheFactoryBean(); + + geodeCache.setClose(true); + geodeCache.setProperties(geodeProperties()); + + return geodeCache; + } +} +---- + +You might also choose to use Geode's +http://geode.docs.pivotal.io/docs/topologies_and_comm/cs_configuration/chapter_overview.html[client/server topology] +to connect to a cluster of Geode Servers running elsewhere. If so, you must +configure your application as a Geode cache client using Spring Data Geode's +`ClientCacheFactoryBean`... + +[source,java,indent=0] +---- +@Configuration +class ClientCacheConfiguration { + + Properties geodeProperties() { + Properties geodeProperties = new Properties(); + + geodeProperties.setProperty("name", "ClientExample"); + geodeProperties.setProperty("log-level", "config"); + + return geodeProperties; + } + + @Bean + ClientCacheFactoryBean geodeCache() { + ClientCacheFactoryBean geodeCache = new ClientCacheFactoryBean(); + + geodeCache.setClose(true); + geodeCache.setProperties(geodeProperties()); + + return geodeCache; + } + + @Bean + PoolFactoryBean geodePool() { + PoolFactoryBean geodePool = new PoolFactoryBean(); + + geodePool.setPingInterval(5000); // 5 seconds + geodePool.setReadTimeout(15000); // 15 seconds + geodePool.setRetryAttempts(1); + geodePool.setSubscriptionEnabled(true); + geodePool.setServers(new ConnectionEndpoint("localhost", 40404)); + + return geodePool; + } +} +---- + +The Geode `Pool` is a pool of connections needed by a cache client to +communicate with the Geode servers in the cluster during Region +data access operations. + +[[boot-features-spring-data-geode-repositories]] +==== Spring Data Geode Repositories + +Regardless of the Geode topology used, either 'peer-to-peer' (P2P) or 'client/server', +you need to define Regions that will store your application data. + +Using a peer cache, you have a choice of different +http://geode.docs.pivotal.io/docs/developing/region_options/region_types.html[Region types] +corresponding to different data management policies and consistency options. You can choose +from `LOCAL`, `REPLICATE` and `PARTITION`. + +On the client, a developer can choose from one of several +http://geode.incubator.apache.org/releases/latest/javadoc/com/gemstone/gemfire/cache/client/ClientRegionShortcut.html[ClientRegionShortcuts]. + +When using Spring Data Geode, the developer only need define an appropriate SDG +`FactoryBean` based on the Region's type. For instance, in a peer cache application, +a developer could define either a `ReplicatedRegionFactoryBean` or +`PartitionedRegionFactoryBean`. As a cache client application, the developer just +defines a `ClientRegionFactoryBean` with an appropriate `ClientRegionShortcut`. + +Along with the Region, or Regions that hold the application data, a developer defines +application domain object/persistent entity types and annotates them with +Spring Data Geode's `@Region` annotation... + +[source,java,indent=0] +---- +@Region("Customers") +public class Customer { + + @Id private Long id; + + String firstName; + String lastName; + + ... + +} +---- + +Then, you define the corresponding Spring Data (Geode) Repository... + +[source,java,indent=0] +---- +public interface CustomerRepository extends GemfireRepository { + + Customer save(Customer); + + Customer findById(Long id); + + List findByLastNameLike(String lastName); + +} +---- + +Providing the `CustomerRepository` and persistent entity type, `Customer`, are found +on the application's classpath, Spring Boot will create and conveniently auto-configure +your application Repositories with Spring Data Geode. + +Do not forget to define the corresponding Region(s) in the Spring application context. +For example, in a peer cache application... + +[source,java,indent=0] +---- +class PeerCacheConfiguration { + + ... + + @Bean(name = "Customers") + PartitionedRegionFactoryBean customersRegion(GemFireCache geodeCache) { + + PartitionedRegionFactoryBean customersRegion = + new PartitionedRegionFactoryBean(); + + customersRegion.setCache(geodeCache); + customersRegion.setClose(false); + customersRegion.setPersistent(false); + + return customersRegion; + } +} +---- + +Or, in a client cache application... + +[source,java,indent=0] +---- +class ClientCacheConfiguration { + + ... + + @Bean(name = "Customers") + ClientRegionFactoryBean customersRegion(GemFireCache geodeCache) { + + ClientRegionFactoryBean customersRegion = + new ClientRegionFactoryBean(); + + customersRegion.setCache(geodeCache); + customersRegion.setClose(false); + customersRegion.setShortcut(ClientRegionShortcut.CACHING_PROXY); + + return customersRegion; + } +} +---- + +Make sure both the client and server cache Region names match. +For more information, refer to the +http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[Spring Data GemFire Reference Guide] +along with the +http://geode.incubator.apache.org/releases/latest/javadoc/com/gemstone/gemfire/cache/client/ClientRegionShortcut.html[Apache Geode User Guide]. [[boot-features-solr]]