diff --git a/pom.xml b/pom.xml
index 5c85e94546..e0295e5c72 100644
--- a/pom.xml
+++ b/pom.xml
@@ -211,7 +211,8 @@
rabbitmq
vertx
-
+ spring-data-gemfire
+
diff --git a/spring-data-gemfire/pom.xml b/spring-data-gemfire/pom.xml
new file mode 100644
index 0000000000..f387b04651
--- /dev/null
+++ b/spring-data-gemfire/pom.xml
@@ -0,0 +1,97 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ spring-data-gemfire
+ 1.0.0-SNAPSHOT
+ jar
+
+ 2.19.1
+ 1.7.4.RELEASE
+ 7.0.1
+ 1.0
+ 4.12
+ 1.3
+ 4.3.0.RELEASE
+ 4.3.0.RELEASE
+
+
+
+
+ org.springframework.data
+ spring-data-gemfire
+ ${spring-data-gemfire-version}
+
+
+
+ com.gemstone.gemfire
+ gemfire
+ ${gemfire-version}
+
+
+
+ com.google.collections
+ google-collections
+ ${google-collections-version}
+
+
+
+ junit
+ junit
+ ${junit-version}
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+ org.hamcrest
+ hamcrest-library
+ ${hamcrest-library-version}
+ test
+
+
+ org.springframework
+ spring-context
+ ${spring-context-version}
+
+
+ org.springframework
+ spring-test
+ ${spring-test-version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ http://repo.spring.io/libs-snapshot
+
+ true
+
+
+
+ gemstone
+ http://dist.gemstone.com.s3.amazonaws.com/maven/release/
+
+
+
+
\ No newline at end of file
diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionExecution.java b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionExecution.java
new file mode 100644
index 0000000000..a3ddf32414
--- /dev/null
+++ b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionExecution.java
@@ -0,0 +1,16 @@
+package com.baeldung.spring.data.gemfire.function;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.gemfire.function.annotation.FunctionId;
+import org.springframework.data.gemfire.function.annotation.OnRegion;
+import org.springframework.data.gemfire.function.annotation.RegionData;
+
+import java.util.Map;
+import java.util.Set;
+
+@OnRegion(region="employee")
+public interface FunctionExecution {
+ @FunctionId("greeting")
+ public void execute(String message);
+
+}
diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionImpl.java b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionImpl.java
new file mode 100644
index 0000000000..9fc6a2155d
--- /dev/null
+++ b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionImpl.java
@@ -0,0 +1,18 @@
+package com.baeldung.spring.data.gemfire.function;
+
+import org.springframework.data.gemfire.function.annotation.GemfireFunction;
+import org.springframework.stereotype.Component;
+
+@Component
+public class FunctionImpl {
+
+ @GemfireFunction
+ public void greeting(String message){
+ System.out.println("Message "+message);
+ }
+
+ @GemfireFunction
+ public String sayHello(String message){
+ return "Hello "+message;
+ }
+}
diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/GemfireConfiguration.java b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/GemfireConfiguration.java
new file mode 100644
index 0000000000..0049f82ddc
--- /dev/null
+++ b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/GemfireConfiguration.java
@@ -0,0 +1,65 @@
+package com.baeldung.spring.data.gemfire.function;
+
+import com.baeldung.spring.data.gemfire.model.Employee;
+import com.baeldung.spring.data.gemfire.repository.EmployeeRepository;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.GemFireCache;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.gemfire.CacheFactoryBean;
+import org.springframework.data.gemfire.LocalRegionFactoryBean;
+import org.springframework.data.gemfire.function.config.EnableGemfireFunctionExecutions;
+import org.springframework.data.gemfire.function.config.EnableGemfireFunctions;
+import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;
+import java.util.Properties;
+
+@Configuration
+@ComponentScan
+@EnableGemfireRepositories(basePackages = "com.baeldung.spring.data.gemfire.repository")
+@EnableGemfireFunctions
+@EnableGemfireFunctionExecutions(basePackages = "com.baeldung.spring.data.gemfire.function")
+public class GemfireConfiguration {
+
+ @Autowired
+ EmployeeRepository employeeRepository;
+
+ @Autowired
+ FunctionExecution functionExecution;
+
+
+ @Bean
+ Properties gemfireProperties() {
+ Properties gemfireProperties = new Properties();
+ gemfireProperties.setProperty("name", "SpringDataGemFireApplication");
+ gemfireProperties.setProperty("mcast-port", "0");
+ gemfireProperties.setProperty("log-level", "config");
+ return gemfireProperties;
+ }
+
+ @Bean
+ @Autowired
+ CacheFactoryBean gemfireCache() {
+ CacheFactoryBean gemfireCache = new CacheFactoryBean();
+ gemfireCache.setClose(true);
+ gemfireCache.setProperties(gemfireProperties());
+ return gemfireCache;
+ }
+
+
+ @Bean(name="employee")
+ @Autowired
+ LocalRegionFactoryBean getEmployee(final GemFireCache cache) {
+ LocalRegionFactoryBean employeeRegion = new LocalRegionFactoryBean();
+ employeeRegion.setCache(cache);
+ employeeRegion.setClose(false);
+ employeeRegion.setName("employee");
+ employeeRegion.setPersistent(false);
+ employeeRegion.setDataPolicy(DataPolicy.PRELOADED);
+ return employeeRegion;
+ }
+
+
+}
+
diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/model/Employee.java b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/model/Employee.java
new file mode 100644
index 0000000000..9c29b28dca
--- /dev/null
+++ b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/model/Employee.java
@@ -0,0 +1,41 @@
+package com.baeldung.spring.data.gemfire.model;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.PersistenceConstructor;
+import org.springframework.data.gemfire.mapping.Region;
+
+
+@Region("employee")
+public class Employee {
+
+ @Id
+ public String name;
+ public double salary;
+
+ @PersistenceConstructor
+ public Employee(String name, double salary) {
+ this.name = name;
+ this.salary = salary;
+ }
+
+ @Override
+ public String toString() {
+ return name + " is " + salary + " years old.";
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public double getSalary() {
+ return salary;
+ }
+
+ public void setSalary(int salary) {
+ this.salary = salary;
+ }
+}
\ No newline at end of file
diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepository.java b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepository.java
new file mode 100644
index 0000000000..30799a2b99
--- /dev/null
+++ b/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepository.java
@@ -0,0 +1,17 @@
+package com.baeldung.spring.data.gemfire.repository;
+
+import com.baeldung.spring.data.gemfire.model.Employee;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface EmployeeRepository extends CrudRepository {
+
+ Employee findByName(String name);
+
+ Iterable findBySalaryGreaterThan(double salary);
+
+ Iterable findBySalaryLessThan(double salary);
+
+ Iterable findBySalaryGreaterThanAndSalaryLessThan(double salary1, double salary2);
+}
diff --git a/spring-data-gemfire/src/main/resources/application-context.xml b/spring-data-gemfire/src/main/resources/application-context.xml
new file mode 100644
index 0000000000..e618719b30
--- /dev/null
+++ b/spring-data-gemfire/src/main/resources/application-context.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-data-gemfire/src/test/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepositoryTest.java b/spring-data-gemfire/src/test/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepositoryTest.java
new file mode 100644
index 0000000000..8714ad2d81
--- /dev/null
+++ b/spring-data-gemfire/src/test/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepositoryTest.java
@@ -0,0 +1,98 @@
+package com.baeldung.spring.data.gemfire.repository;
+
+import com.baeldung.spring.data.gemfire.function.FunctionExecution;
+import com.baeldung.spring.data.gemfire.function.GemfireConfiguration;
+import com.baeldung.spring.data.gemfire.model.Employee;
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes=GemfireConfiguration.class, loader=AnnotationConfigContextLoader.class)
+public class EmployeeRepositoryTest {
+
+ @Autowired
+ EmployeeRepository employeeRepository;
+
+ @Autowired
+ FunctionExecution execution;
+
+ @Test
+ public void whenEmployeeIsSaved_ThenAbleToRead(){
+ Employee employee=new Employee("John Davidson",4550.00);
+ employeeRepository.save(employee);
+
+ List employees= Lists.newArrayList(employeeRepository.findAll());
+
+ assertEquals(1, employees.size());
+ }
+
+ @Test
+ public void whenSalaryGreaterThan_ThenEmployeeFound(){
+
+ Employee employee=new Employee("John Davidson",4550.00);
+ Employee employee1=new Employee("Adam Davidson",3500.00);
+ Employee employee2=new Employee("Chris Davidson",5600.00);
+
+ employeeRepository.save(employee);
+ employeeRepository.save(employee1);
+ employeeRepository.save(employee2);
+
+ List employees= Lists.newArrayList(employeeRepository.findBySalaryGreaterThan(4000.00));
+
+ assertEquals(2,employees.size());
+
+ }
+
+ @Test
+ public void whenSalaryLessThan_ThenEmployeeFound(){
+
+ Employee employee=new Employee("John Davidson",4550.00);
+ Employee employee1=new Employee("Adam Davidson",3500.00);
+ Employee employee2=new Employee("Chris Davidson",5600.00);
+
+ employeeRepository.save(employee);
+ employeeRepository.save(employee1);
+ employeeRepository.save(employee2);
+
+ List employees= Lists.newArrayList(employeeRepository.findBySalaryLessThan(4000));
+
+ assertEquals(1,employees.size());
+
+ }
+ @Test
+ public void whenSalaryBetween_ThenEmployeeFound(){
+
+ Employee employee=new Employee("John Davidson",4550.00);
+ Employee employee1=new Employee("Adam Davidson",3500.00);
+ Employee employee2=new Employee("Chris Davidson",5600.00);
+
+ employeeRepository.save(employee);
+ employeeRepository.save(employee1);
+ employeeRepository.save(employee2);
+
+ List employees= Lists.newArrayList(employeeRepository.findBySalaryGreaterThanAndSalaryLessThan(3500,5000));
+
+ assertEquals(1,employees.size());
+
+ }
+
+ @Test
+ public void whenFunctionExecutedFromClient_ThenFunctionExecutedOnServer(){
+ execution.execute("Hello World");
+ }
+
+ @After
+ public void cleanup(){
+ employeeRepository.deleteAll();
+ }
+}