Using Spring Boot Data Geode
Spring Boot Data Geode is a new project aimed at simplifying the use of Geode/Gemfire/PivotalCloudCache. Its primary goal is to extend Spring Boot with auto-configuration support as well as streamline the programmer's experience while working in the spring ecosystem.
The project has the following primary goals.
-
Auto Configure the ClientCache automatically when the project's starter is on the classpath.
1<dependency> 2 <groupId>org.springframework.geode</groupId> 3 <artifactId>spring-gemfire-starter</artifactId> 4 <version>1.0.0.M4</version> 5</dependency>
or
1<dependency> 2 <groupId>org.springframework.geode</groupId> 3 <artifactId>spring-geode-starter</artifactId> 4 <version>1.0.0.M4</version> 5</dependency>
-
Auto Configure Spring's Cache Abstraction
1@Cacheable({"books", "isbns"}) 2public Book findBook(ISBN isbn) {...}
-
Provide automatic connectivity to a cache when the application is deployed to Pivotal Cloud Foundry and bound to a Pivotal Cloud Cache.
Getting Started
All code for this article can be found on Github
The easiest way to get started is to use Docker to start a local cache on your laptop.
1docker run -ti -p 40404:40404 -p 10334:10334 apachegeode/geode:1.6.0 bash
Running this command will drop you into a GFSH shell that you can use to start the locator, server and create some regions.
1start locator --name locator
2start server --name server1
3create region --name /restrictionRegion --type=REPLICATE
Since the ClientCache
is already registered by spring boot, all you need to do is define a ClientRegionFactoryBean
in your configuration.
1@Bean("restrictionRegion")
2public ClientRegionFactoryBean<String, Boolean> restrictionRegion(GemFireCache cache) {
3 ClientRegionFactoryBean<String, Boolean> region = new ClientRegionFactoryBean<>();
4 region.setCache(cache);
5 region.setShortcut(ClientRegionShortcut.PROXY);
6 return region;
7}
You can then inject this region into your code and do Cache Get/Put Operations.
1@Resource(name = "restrictionRegion")
2Region<String,Boolean> restrictionRegion;
3
4public boolean checkRestriction(String key){
5 return restrictionRegion.get(key);
6}
7
Upon starting the app, Spring Boot will automatically connect to the Cache cluster running on your machine. It will use the locator address of localhost[10334]. If you wish to connect to a different Cache, you can use the following spring properties.
1 #Comma-delimited list of Locator endpoints formatted as: locator1[port1],...,locatorN[portN]
2 spring.data.gemfire.locators=localhost[10334]
3
4 #Configures the username used to authenticate with the servers.
5 spring.data.gemfire.security.username
6
7 #Configures the user password used to authenticate with the servers.
8 spring.data.gemfire.security.password
Testing
Testing can be done in two ways.
-
Unit Testing with Mockito Mocks
-
Integration Tests using a real server.
Mocks
By far the easiest way to test Gemfire code is with mocks. The Gemfire region can easily be mocked using Mockito.
1private Region restrictionRegion;
2
3 @InjectMocks
4 private RestrictionService restrictionService;
5
6 @Test
7 public void checkRestricted(){
8 when(restrictionRegion.get("restricted")).thenReturn(true);
9
10 assertTrue((restrictionService.checkRestriction("restricted")));
11 }
Integration Testing
There is a new project called Spring Geode Test
This project makes it trivial to spin up a test Locator and Server for use during an integration test.
Extend ForkingClientServerIntegrationTestsSupport
Add a Spring boot configuration class to bootstrap a server and configure your test regions.
To start, add the following dependency to your project.
1<dependency>
2 <groupId>org.springframework.data</groupId>
3 <artifactId>spring-data-gemfire-test</artifactId>
4 <version>0.0.1.RC1</version>
5 <scope>test</scope>
6</dependency>
7
8<repositories>
9 <repository>
10 <id>spring-snapshot</id>
11 <url>https://repo.spring.io/libs-snapshot</url>
12 </repository>
13</repositories>
Implement a @CacheServerAppliction
to bootstrap the test server.
1@CacheServerApplication(name = "AutoConfiguredIntegrationTests", logLevel = GEMFIRE_LOG_LEVEL)
2@EnablePdx
3@EnableLocator
4public static class GemFireServerConfiguration {
5 public static void main(String[] args) {
6 AnnotationConfigApplicationContext applicationContext =
7 new AnnotationConfigApplicationContext(GemFireServerConfiguration.class);
8
9 applicationContext.registerShutdownHook();
10
11
12 }
13
14 @Bean("restrictionRegion")
15 public PartitionedRegionFactoryBean<String, Boolean> restrictionRegion(GemFireCache gemfireCache) {
16
17
18 PartitionedRegionFactoryBean<String, Boolean> restrictionsRegion =
19 new PartitionedRegionFactoryBean<>();
20
21 restrictionsRegion.setCache(gemfireCache);
22 restrictionsRegion.setClose(false);
23 restrictionsRegion.setPersistent(false);
24 return restrictionsRegion;
25 }
26
27}
you can then run your service code as required.
1@Autowired
2 private RestrictionService restrictionService;
3
4 @Test
5 public void checkRestricted(){
6
7 assertTrue((restrictionService.checkRestriction("restricted")));
8 }
9
10 @Test
11 public void checkNotRestricted(){
12
13 assertFalse((restrictionService.checkRestriction("notrestricted")));
14 }`</pre>
The full test code can be found here.