[JAVA] An introduction to Spring Boot + in-memory data grid

After studying the in-memory data grid, I was wondering what would happen if I actually incorporated it into the app, so I tried to get started.

What is an in-memory data grid?

--A mechanism for distributed management of data on multiple servers. --If all servers can have duplicate data (replication method), flexible data reliability can be ensured by managing duplicate data required only for a certain group of servers (partition method). Can. --Since disk I / O does not occur like DB, you can perform CRUD operations of data and P2P data synchronization at high speed. --Reliable and fast architecture. It seems.

Learn by referring to the following article -Recommended to get an overview -Specific architecture type

Let's make an app with SpringBoot + Apach GEODE

――Since I wanted to actually make it after zapping various articles, there is a project called SpringDataGeode in Spring's git repository, so I will try to experience the in-memory data grid with Spring Boot using it. --Created assuming a server application that performs user registration and search.

-spring-data-geode project

Create an app with Apache GEODE client / server model

-Create a client / server application template with Spring Initializer. --Select only Web and lombok. --This time, create a project with gradle.

Create client side application

--Added spring-data-geode to the dependency of build.gradle.

build.gradle


dependencies {
	implementation('org.springframework.boot:spring-boot-starter-web'){
      //log4j library is spring-data-Excluded because it conflicts with geode's dependent log4j library
	  exclude group: 'org.springframework.boot', module:'spring-boot-starter-logging'
	}
    //Add a project that handles domain model as a dependency
	compile project(':geodeCommon')
	compileOnly('org.projectlombok:lombok')
	compile(group: 'org.springframework.data', name: 'spring-data-geode', version: '2.1.3.RELEASE')
}

--Starting class code

GeodeClientApplication.java


package spring.geode.client.geodeClient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
import org.springframework.data.gemfire.config.annotation.EnablePdx;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

import spring.geode.client.geodeClient.repository.UserRepository;
import spring.geode.geodeCommon.model.User;

@SpringBootApplication
@ClientCacheApplication(name = "SpringGeodeClientApplication") //①
@EnableGemfireRepositories(basePackageClasses = UserRepository.class) //②
@EnableEntityDefinedRegions(basePackageClasses = User.class) //③
@EnablePdx //④
public class GeodeClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(GeodeClientApplication.class, args);
	}

}

--Explanation of annotation --①: Setting to start as client application in ʻApache GEODE -②: Setting to make the specified class function as a data accessor of ʻApache GEODE --③: Setting to automatically create the specified Region (table in RDB) -④: ʻApache GEODE`'s data serialization / deserialization settings (not required)

--Controller class

UserController.java


package spring.geode.client.geodeClient.controller;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import spring.geode.client.geodeClient.service.UserService;
import spring.geode.geodeCommon.model.User;
import spring.geode.geodeCommon.model.UserRequest;

@RestController
@RequiredArgsConstructor
public class UserController {
	private final UserService userService;
    //User search API by name
	@RequestMapping(path = "/find/user/{name}", method = RequestMethod.GET)
	public User findById(@PathVariable String name) {
		return userService.findByName(name);
	}
    //User all search API
	@RequestMapping("/findAll")
    public List<User> findAll() {
        return userService.findAll();
    }
    //New user registration API
	@RequestMapping(path = "/register/user", method = RequestMethod.POST)
	public String register(@RequestBody UserRequest request) {
		return userService.register(request).getName();
	}
}

--service class

UserService.java


package spring.geode.server.geodeServer.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import spring.geode.geodeCommon.model.User;
import spring.geode.geodeCommon.model.UserRequest;
import spring.geode.server.geodeServer.repository.UserRepository;

@RequiredArgsConstructor
@Service
public class UserService {
	private final UserRepository rep; 
	public User findByName(String name) {
		User user=rep.findByName(name).get(0);
		return user;
	}
	
	public User register(UserRequest request) {
		User commited = rep.save(new User(request));
		return commited;
	}
	
	public List<User> findAll(){
		List<User> users=new ArrayList<>();
		rep.findAll().forEach(user -> users.add(user));;
		return users;
	}
}

Repository class

UserRepository.java


package spring.geode.server.geodeServer.repository;

import java.util.List;

import org.springframework.data.gemfire.repository.GemfireRepository;

import spring.geode.geodeCommon.model.User;

public interface UserRepository extends GemfireRepository<User, Integer> {
	List<User> findByName(String name);
}

application.properties


spring.data.gemfire.pool.locators=localhost[40404]
server.port=9000

client Set the IP and port of the locator to which the application connects. This time, specify localhost to start locator with the server application settings.

ʻThe relationship between client, server and locator in Apache GEODE` is described in the following article. Overview of Apache GEODE

At this point, the client application has been implemented. Since it is necessary to use a common class for the client and server projects, the data objects (User class) to be handled will be aggregated in the Common project and created later.

Create server side application

Except for the startup class, you can bring the client application code into the server application project as it is.

--Startup class

GeodeServerApplication.java


package spring.geode.server.geodeServer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
import org.springframework.data.gemfire.config.annotation.EnableLocator;
import org.springframework.data.gemfire.config.annotation.EnableManager;
import org.springframework.data.gemfire.config.annotation.EnablePdx;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

import spring.geode.geodeCommon.model.User;
import spring.geode.server.geodeServer.repository.UserRepository;

@SpringBootApplication
@CacheServerApplication(locators = "localhost[40404]") //①
@EnableGemfireRepositories(basePackageClasses = UserRepository.class)
@EnableEntityDefinedRegions(basePackageClasses = User.class)
@EnablePdx
public class GeodeServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(GeodeServerApplication.class, args);
	}

	@Configuration
	@EnableLocator(port = 40404) //②
	@EnableManager(start = true) //③
	static class LocatorManagerConfiguration {
	}

}

--Explanation of annotation --①: ʻSetting to start as a server application in Apache GEODE. Set the connecting locator to be the 40404 port of localhost`. --②: Setting to start locator on 40404 port --③: Setting to start the service that monitors the client / server application

The implementation of the server application is completed up to this point.

Creating a data model

--Request model from client in web app (different from client in ʻApache GEODE`)

UserRequest.java


package spring.geode.geodeCommon.model;

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRequest implements Serializable{
	private static final long serialVersionUID = 1L;
	
	private String name;
	private int age;
}

--ʻDomain model persisted in Apache GEODE`

User.java


package spring.geode.geodeCommon.model;

import java.io.Serializable;
import java.util.UUID;

import org.springframework.data.gemfire.mapping.annotation.Region;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Region("Users") //①
public class User implements Serializable {
	private static final long serialVersionUID = 1L;

	private Integer id;
	private String name;
	private int age;
	
	public User(UserRequest request) {
		this.name=request.getName();
		this.age=request.getAge();
		this.id=UUID.randomUUID().hashCode();
	}
}

--Explanation of annotation --①: Set the Region to which this model is associated.

--Since the project that implements the data model depends on the project of the client and server application, the following contents are described in settings.gradle of the client and server application.

settings.gradle


//geodeCommon should be read as the project name you created
include ':geodeCommon'
project(':geodeCommon').projectDir = new File('../geodeCommon')

At this point, the implementation of the data model is complete.

Try to start

Since the client application connects to the locator at startup, it is necessary to start the server application first.

--Start server application (embedded Tomacat starts on port number 9090) スクリーンショット 2019-01-27 2.01.43.png

--client application launch (embedded tomcat launches on port number 9000) スクリーンショット 2019-01-27 2.02.58.png

If both applications can be started normally, the client, locator, and server should be connected.

Try registering the user in the client application

curl -H "Content-Type: application/json" -X POST -d '{"name":"John","age":23}' http://localhost:9000/register/user/;

curl -H "Content-Type: application/json" -X POST -d '{"name":"Bob","age":10}' http://localhost:9000/register/user/;

Try searching for a user from the server application

curl -i http://localhost:9090/findAll

It is OK if the user registered in the client application can be searched in the search results.

HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 26 Jan 2019 17:10:37 GMT

[{"id":-1174841827,"name":"Bob","age":10},{"id":-516984913,"name":"John","age":23}]

Just in case, also search by specifying name

curl -i http://localhost:9090/find/user/John;

HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 26 Jan 2019 17:12:33 GMT

{"id":-516984913,"name":"John","age":23}

I was able to confirm that the data was synchronized on the client and server. I implemented it with reference to the following official document. https://geode.apache.org/docs/

In the future, I will try to create applications with the peer model, application configuration on AWS, asynchronous persistence, and so on.

Recommended Posts

An introduction to Spring Boot + in-memory data grid
Introduction to SpringBoot + In-Memory Data Grid (Data Persistence)
Introduction to SpringBoot + In-Memory Data Grid (Event Handling)
Introduction to Spring Boot ① ~ DI ~
Introduction to Spring Boot ② ~ AOP ~
Introduction to Spring Boot Part 1
[Introduction to Spring Boot] Authentication function with Spring Security
[Introduction to Spring Boot] Submit a form using thymeleaf
Try Spring Boot from 0 to 100.
Introduction to Ratpack (7) --Guice & Spring
[Spring Boot] Send an email
Steps required to issue an asynchronous event for Spring Boot
Flow until output table data to view with Spring Boot
[How to install Spring Data Jpa]
How to set Spring Boot + PostgreSQL
How to use ModelMapper (Spring boot)
Upgrade spring boot from 1.5 series to 2.0 series
Introduction to Spring Boot x OpenAPI ~ OpenAPI made with Generation gap pattern ~
02. I made an API to connect to MySQL (MyBatis) from Spring Boot
Story when moving from Spring Boot 1.5 to 2.1
Changes when migrating from Spring Boot 1.5 to Spring Boot 2.0
Changes when migrating from Spring Boot 2.0 to Spring Boot 2.2
To write Response data directly in Spring
How to split Spring Boot message file
Add spring boot and gradle to eclipse
Introduction to Java development environment & Spring Boot application created with VS Code
When you want to notify an error somewhere when using graphql-spring-boot in Spring Boot
How to perform UT with Excel as test data with Spring Boot + JUnit5 + DBUnit
Sample to batch process data on DB with Apache Camel Spring Boot starters
From creating a Spring Boot project to running an application with VS Code
Book introduction: Spring Boot Recommended reference book for beginners!
Until data acquisition with Spring Boot + MyBatis + PostgreSQL
How to use built-in h2db with spring boot
How to make Spring Boot Docker Image smaller
How to use Spring Boot session attributes (@SessionAttributes)
The story of raising Spring Boot 1.5 series to 2.1 series
Try to implement login function with Spring Boot
Spring Data REST HAL Browser to check Spring REST operation
How to add a classpath in Spring Boot
How to bind to property file in Spring Boot
Try to automate migration with Spring Boot Flyway
[Java] Article to add validation with Spring Boot 2.3.1.
I wanted to gradle spring boot with multi-project
Apply Twitter Bootstrap 4 to Spring Boot 2 using Webjars
An introduction to Groovy for tedious Java engineers
[Spring Boot] How to refer to the property file
Spring Boot + Spring Data JPA About multiple table joins
Spring Boot --How to set session timeout time
[Spring Batch] Output table data to CSV file
Introduction to Ruby 2
Spring Fox ① Introduction
Introduction to SWING
Challenge Spring Boot
Introduction to Micronaut 1 ~ Introduction ~
[Java] Introduction to Java
Introduction to migration
Spring Boot Form
Introduction to java
Spring Boot Memorandum
gae + spring boot
Introduction to Doma