Skip to content

Commit 5a4d36d

Browse files
committed
Add auto-configuration support for Spring Data Geode Repositories
Closes gh-6952
1 parent d0eedd2 commit 5a4d36d

File tree

11 files changed

+673
-9
lines changed

11 files changed

+673
-9
lines changed

spring-boot-autoconfigure/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@
360360
</exclusion>
361361
</exclusions>
362362
</dependency>
363+
<dependency>
364+
<groupId>org.springframework.data</groupId>
365+
<artifactId>spring-data-geode</artifactId>
366+
<optional>true</optional>
367+
</dependency>
363368
<dependency>
364369
<groupId>org.springframework.data</groupId>
365370
<artifactId>spring-data-jpa</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.data.geode;
18+
19+
import org.apache.geode.cache.Cache;
20+
import org.apache.geode.cache.client.ClientCache;
21+
22+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
25+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.context.annotation.Import;
29+
import org.springframework.data.gemfire.repository.GemfireRepository;
30+
import org.springframework.data.gemfire.repository.config.GemfireRepositoryConfigurationExtension;
31+
import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean;
32+
33+
/**
34+
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Geode Repositories.
35+
* <p>
36+
* Activates when there is a bean of type {@link Cache} or {@link ClientCache} configured
37+
* in the Spring context, the Spring Data Geode
38+
* {@link org.springframework.data.gemfire.repository.GemfireRepository}
39+
* type is on the classpath, and there is no other, existing
40+
* {@link org.springframework.data.gemfire.repository.GemfireRepository}
41+
* configured.
42+
* <p>
43+
* Once in effect, the auto-configuration is the equivalent of enabling Geode Repositories
44+
* using the
45+
* {@link org.springframework.data.gemfire.repository.config.EnableGemfireRepositories}
46+
* annotation.
47+
*
48+
* @author John Blum
49+
* @since 1.5.0
50+
* @see org.springframework.boot.autoconfigure.data.geode.GeodeRepositoriesAutoConfigureRegistrar
51+
* @see org.springframework.context.annotation.Configuration
52+
* @see org.springframework.data.gemfire.repository.config.EnableGemfireRepositories
53+
* @see org.apache.geode.cache.Cache
54+
* @see org.apache.geode.cache.client.ClientCache
55+
*/
56+
@Configuration
57+
@ConditionalOnBean({ Cache.class, ClientCache.class })
58+
@ConditionalOnClass(GemfireRepository.class)
59+
@ConditionalOnMissingBean({ GemfireRepositoryConfigurationExtension.class, GemfireRepositoryFactoryBean.class })
60+
@ConditionalOnProperty(prefix = "spring.data.geode.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
61+
@Import(GeodeRepositoriesAutoConfigureRegistrar.class)
62+
public class GeodeRepositoriesAutoConfiguration {
63+
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2011-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.data.geode;
18+
19+
import java.lang.annotation.Annotation;
20+
21+
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
22+
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
23+
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;
24+
import org.springframework.data.gemfire.repository.config.GemfireRepositoryConfigurationExtension;
25+
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
26+
27+
/**
28+
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Geode Repositories.
29+
*
30+
* @author John Blum
31+
* @since 1.5.0
32+
* @see org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport
33+
* @see org.springframework.data.gemfire.repository.config.EnableGemfireRepositories
34+
* @see org.springframework.data.gemfire.repository.config.GemfireRepositoryConfigurationExtension
35+
*/
36+
public class GeodeRepositoriesAutoConfigureRegistrar
37+
extends AbstractRepositoryConfigurationSourceSupport {
38+
39+
@Override
40+
protected Class<? extends Annotation> getAnnotation() {
41+
return EnableGemfireRepositories.class;
42+
}
43+
44+
@Override
45+
protected Class<?> getConfiguration() {
46+
return EnableGeodeRepositoriesConfiguration.class;
47+
}
48+
49+
@Override
50+
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
51+
return new GemfireRepositoryConfigurationExtension();
52+
}
53+
54+
@EnableGemfireRepositories
55+
private static class EnableGeodeRepositoriesConfiguration {
56+
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2011-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Auto-configuration for Spring Data Geode.
19+
*/
20+
package org.springframework.boot.autoconfigure.data.geode;

spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoC
2828
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
2929
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
3030
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
31+
org.springframework.boot.autoconfigure.data.geode.GeodeRepositoriesAutoConfiguration,\
3132
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
3233
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
3334
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.data.alt.geode;
18+
19+
import org.springframework.boot.autoconfigure.data.geode.city.City;
20+
import org.springframework.data.repository.Repository;
21+
22+
public interface CityGeodeRepository extends Repository<City, Long> {
23+
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
* Copyright 2011-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.data.geode;
18+
19+
import org.apache.geode.cache.Cache;
20+
import org.apache.geode.cache.GemFireCache;
21+
import org.apache.geode.cache.RegionAttributes;
22+
import org.apache.geode.cache.client.ClientRegionShortcut;
23+
24+
import org.junit.After;
25+
import org.junit.Test;
26+
27+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
28+
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
29+
import org.springframework.boot.autoconfigure.data.alt.geode.CityGeodeRepository;
30+
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
31+
import org.springframework.boot.autoconfigure.data.geode.city.City;
32+
import org.springframework.boot.autoconfigure.data.geode.city.CityRepository;
33+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
34+
import org.springframework.context.annotation.Bean;
35+
import org.springframework.context.annotation.Configuration;
36+
import org.springframework.data.gemfire.LocalRegionFactoryBean;
37+
import org.springframework.data.gemfire.RegionAttributesFactoryBean;
38+
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
39+
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
40+
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
41+
import org.springframework.data.gemfire.repository.GemfireRepository;
42+
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;
43+
44+
import static org.assertj.core.api.Assertions.assertThat;
45+
46+
/**
47+
* Integration test for auto-configuring Spring Data Geode Repository with Spring Boot.
48+
*
49+
* @author John Blum
50+
* @since 1.5.0
51+
*/
52+
public class GeodeRepositoriesAutoConfigurationTests {
53+
54+
private AnnotationConfigApplicationContext applicationContext;
55+
56+
@After
57+
public void tearDown() {
58+
this.applicationContext.close();
59+
}
60+
61+
@Test
62+
public void clientCacheWithDefaultRepositoryConfigurationIsSuccessful() {
63+
prepareApplicationContext(ClientCacheGemFireConfiguration.class);
64+
65+
assertThat(this.applicationContext.getBean(CityRepository.class)).isNotNull();
66+
}
67+
68+
@Test
69+
public void peerCacheWithDefaultRepositoryConfigurationIsSuccessful() {
70+
prepareApplicationContext(PeerCacheGemFireConfiguration.class);
71+
72+
assertThat(this.applicationContext.getBean(CityRepository.class)).isNotNull();
73+
}
74+
75+
@Test(expected = NoSuchBeanDefinitionException.class)
76+
public void noRepositoryConfiguration() {
77+
prepareApplicationContext(EmptyConfiguration.class, PeerCacheGemFireConfiguration.class);
78+
79+
assertThat(this.applicationContext.getBean(Cache.class)).isNotNull();
80+
81+
this.applicationContext.getBean(GemfireRepository.class);
82+
}
83+
84+
@Test(expected = NoSuchBeanDefinitionException.class)
85+
public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
86+
prepareApplicationContext(CustomizedConfiguration.class, PeerCacheGemFireConfiguration.class);
87+
88+
assertThat(this.applicationContext.getBean(CityGeodeRepository.class)).isNotNull();
89+
90+
this.applicationContext.getBean(CityRepository.class);
91+
}
92+
93+
protected void prepareApplicationContext(Class<?>... annotatedClasses) {
94+
this.applicationContext = new AnnotationConfigApplicationContext();
95+
this.applicationContext.register(annotatedClasses);
96+
this.applicationContext.register(GeodeRepositoriesAutoConfiguration.class);
97+
this.applicationContext.refresh();
98+
}
99+
100+
@SuppressWarnings("unused")
101+
static abstract class AbstractBaseGemFireConfiguration {
102+
103+
@Bean
104+
@SuppressWarnings("unchecked")
105+
RegionAttributesFactoryBean citiesRegionAttributes() {
106+
RegionAttributesFactoryBean citiesRegionAttributes =
107+
new RegionAttributesFactoryBean();
108+
109+
citiesRegionAttributes.setKeyConstraint(Long.class);
110+
citiesRegionAttributes.setValueConstraint(City.class);
111+
112+
return citiesRegionAttributes;
113+
}
114+
}
115+
116+
@SuppressWarnings("unused")
117+
@TestAutoConfigurationPackage(City.class)
118+
@ClientCacheApplication(name = "GeodeClientCacheApplication", logLevel = "warning")
119+
static class ClientCacheGemFireConfiguration extends AbstractBaseGemFireConfiguration {
120+
121+
@Bean(name = "Cities")
122+
ClientRegionFactoryBean<Long, City> citiesRegion(GemFireCache gemfireCache,
123+
RegionAttributes<Long, City> citiesRegionAttributes) {
124+
125+
ClientRegionFactoryBean<Long, City> citiesRegion =
126+
new ClientRegionFactoryBean<Long, City>();
127+
128+
citiesRegion.setAttributes(citiesRegionAttributes);
129+
citiesRegion.setCache(gemfireCache);
130+
citiesRegion.setClose(false);
131+
citiesRegion.setShortcut(ClientRegionShortcut.LOCAL);
132+
133+
return citiesRegion;
134+
}
135+
}
136+
137+
@SuppressWarnings("unused")
138+
@TestAutoConfigurationPackage(City.class)
139+
@PeerCacheApplication(name = "GeodePeerCacheApplication", logLevel = "warning")
140+
static class PeerCacheGemFireConfiguration extends AbstractBaseGemFireConfiguration {
141+
142+
@Bean(name = "Cities")
143+
LocalRegionFactoryBean<Long, City> citiesRegion(GemFireCache gemfireCache,
144+
RegionAttributes<Long, City> citiesRegionAttributes) {
145+
146+
LocalRegionFactoryBean<Long, City> citiesRegion =
147+
new LocalRegionFactoryBean<Long, City>();
148+
149+
citiesRegion.setAttributes(citiesRegionAttributes);
150+
citiesRegion.setCache(gemfireCache);
151+
citiesRegion.setClose(false);
152+
citiesRegion.setPersistent(false);
153+
154+
return citiesRegion;
155+
}
156+
}
157+
158+
@Configuration
159+
@TestAutoConfigurationPackage(EmptyDataPackage.class)
160+
protected static class EmptyConfiguration {
161+
162+
}
163+
164+
@Configuration
165+
@TestAutoConfigurationPackage(GeodeRepositoriesAutoConfigurationTests.class)
166+
@EnableGemfireRepositories(basePackageClasses = CityGeodeRepository.class)
167+
static class CustomizedConfiguration {
168+
169+
}
170+
}

0 commit comments

Comments
 (0)