├── .circleci
└── config.yml
├── .gitignore
├── config
└── hazelcast.xml
├── employee-kubernetes-service
├── k8s
│ └── deployment.yaml
├── pom.xml
├── skaffold.yaml
└── src
│ └── main
│ └── java
│ └── pl
│ └── piomin
│ └── services
│ └── employee
│ ├── EmployeeApplication.java
│ ├── api
│ └── EmployeeController.java
│ ├── data
│ └── EmployeeRepository.java
│ └── model
│ └── Employee.java
├── employee-service
├── .gitignore
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── pl
│ │ │ └── piomin
│ │ │ └── services
│ │ │ └── datagrid
│ │ │ └── employee
│ │ │ ├── EmployeeApplication.java
│ │ │ ├── api
│ │ │ └── EmployeeController.java
│ │ │ ├── data
│ │ │ ├── EmployeeRepository.java
│ │ │ └── EmployeeSerializer.java
│ │ │ ├── model
│ │ │ └── Employee.java
│ │ │ └── service
│ │ │ └── EmployeeService.java
│ └── resources
│ │ └── application.yml
│ └── test
│ └── java
│ └── pl
│ └── piomin
│ └── services
│ └── datagrid
│ └── employee
│ ├── EmployeeApplicationTest.java
│ ├── MysqlContainerDevMode.java
│ └── data
│ └── AddEmployeeRepositoryTest.java
├── person-service
├── .gitignore
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── pl
│ │ │ └── piomin
│ │ │ └── services
│ │ │ └── datagrid
│ │ │ └── person
│ │ │ ├── PersonApplication.java
│ │ │ ├── api
│ │ │ └── PersonController.java
│ │ │ ├── data
│ │ │ └── PersonRepository.java
│ │ │ └── model
│ │ │ └── Person.java
│ └── resources
│ │ └── application.yml
│ └── test
│ └── java
│ └── pl
│ └── piomin
│ └── services
│ └── datagrid
│ └── person
│ ├── MysqlAndHazelcastContainersDevMode.java
│ ├── PersonDevModeApplication.java
│ └── data
│ └── AddPersonRepositoryTest.java
├── pom.xml
├── readme.md
└── renovate.json
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: '2.1'
2 |
3 | jobs:
4 | analyze:
5 | docker:
6 | - image: 'cimg/openjdk:21.0.6'
7 | steps:
8 | - checkout
9 | - run:
10 | name: Analyze on SonarCloud
11 | command: mvn verify sonar:sonar -DskipTests
12 | test:
13 | executor: machine_executor_amd64
14 | steps:
15 | - checkout
16 | - run:
17 | name: Install OpenJDK 21
18 | command: |
19 | java -version
20 | sudo apt-get update && sudo apt-get install openjdk-21-jdk
21 | sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java
22 | sudo update-alternatives --set javac /usr/lib/jvm/java-21-openjdk-amd64/bin/javac
23 | java -version
24 | export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
25 | - run:
26 | name: Maven Tests
27 | command: mvn test
28 |
29 | orbs:
30 | maven: circleci/maven@2.0.0
31 |
32 | executors:
33 | machine_executor_amd64:
34 | machine:
35 | image: ubuntu-2204:2023.10.1
36 | environment:
37 | architecture: "amd64"
38 | platform: "linux/amd64"
39 |
40 | workflows:
41 | maven_test:
42 | jobs:
43 | - test
44 | - analyze:
45 | context: SonarCloud
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.project
2 | /.settings/
3 |
--------------------------------------------------------------------------------
/config/hazelcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | dev
5 | dev-pass
6 |
7 | http://192.168.99.100:38080/mancenter
8 |
9 | 5701
10 | true
11 |
12 | 0
13 |
14 |
15 |
16 | 224.2.2.3
17 | 54327
18 | 2
19 | 32
20 |
21 |
22 |
23 | 127.0.0.1
24 | 127.0.0.1
25 |
26 |
27 |
28 | my-access-key
29 | my-secret-key
30 | us-west-1
31 | ec2.amazonaws.com
32 | hazelcast-sg
33 | type
34 | hz-nodes
35 |
36 |
37 |
38 |
39 | 10.10.1.*
40 |
41 |
42 |
43 |
44 | PBEWithMD5AndDES
45 | thesalt
46 | thepass
47 | 19
48 |
49 |
50 |
73 |
74 | true
75 | 2147483647
76 | 1
77 | 0
78 | -1
79 |
80 |
81 | 1
82 | 0
83 | true
84 | true
85 | SET
86 |
87 |
88 | true
89 | 2147483647
90 | 1
91 | 0
92 |
93 |
94 | true
95 | 2147483647
96 | 1
97 | 0
98 |
99 |
100 | 0
101 | 1
102 | 0
103 |
104 |
105 | 10000
106 | 0
107 | 1
108 | 0
109 | BINARY
110 |
111 |
112 |
113 | true
114 | 16
115 | 0
116 |
117 |
118 |
119 | 0
120 | false
121 | BIG_ENDIAN
122 | false
123 | true
124 | false
125 | true
126 |
127 |
128 | true
129 | 10
130 | BLOCK
131 |
132 |
133 |
134 |
135 | 16
136 | 4194304
137 | 12.5
138 |
139 |
140 |
141 | /opt/hazelcast/hot-restart
142 | 1
143 | 120
144 | 900
145 | FULL_RECOVERY_ONLY
146 |
147 |
--------------------------------------------------------------------------------
/employee-kubernetes-service/k8s/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: employee-service
5 | labels:
6 | app: employee-service
7 | spec:
8 | replicas: 3
9 | selector:
10 | matchLabels:
11 | app: employee-service
12 | template:
13 | metadata:
14 | labels:
15 | app: employee-service
16 | spec:
17 | containers:
18 | - name: employee-service
19 | image: piomin/employee-service
20 | ports:
21 | - name: http
22 | containerPort: 8080
23 | - name: multicast
24 | containerPort: 5701
25 | ---
26 | apiVersion: v1
27 | kind: Service
28 | metadata:
29 | name: employee-service
30 | labels:
31 | app: employee-service
32 | spec:
33 | ports:
34 | - port: 8080
35 | protocol: TCP
36 | selector:
37 | app: employee-service
38 | type: NodePort
39 | ---
40 | apiVersion: v1
41 | kind: Service
42 | metadata:
43 | name: hazelcast-service
44 | spec:
45 | selector:
46 | app: employee-service
47 | ports:
48 | - name: hazelcast
49 | port: 5701
50 | type: LoadBalancer
--------------------------------------------------------------------------------
/employee-kubernetes-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | pl.piomin.services
8 | sample-hazelcast-spring-datagrid
9 | 1.0-SNAPSHOT
10 |
11 | 4.0.0
12 |
13 | employee-kubernetes-service
14 |
15 |
16 | ${project.artifactId}
17 |
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 |
24 |
25 | com.hazelcast
26 | spring-data-hazelcast
27 | 2.4.0
28 |
29 |
30 | com.hazelcast
31 | hazelcast-spring
32 |
33 |
34 | com.hazelcast
35 | hazelcast-kubernetes
36 | 2.2.3
37 |
38 |
39 |
40 |
41 |
42 |
43 | org.springframework.boot
44 | spring-boot-maven-plugin
45 |
46 |
47 | com.google.cloud.tools
48 | jib-maven-plugin
49 | 3.4.5
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/employee-kubernetes-service/skaffold.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: skaffold/v2alpha1
2 | kind: Config
3 | build:
4 | artifacts:
5 | - image: piomin/employee-service
6 | jib: {}
7 | tagPolicy:
8 | gitCommit: {}
--------------------------------------------------------------------------------
/employee-kubernetes-service/src/main/java/pl/piomin/services/employee/EmployeeApplication.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.employee;
2 |
3 | import com.hazelcast.config.Config;
4 |
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.data.hazelcast.repository.config.EnableHazelcastRepositories;
9 |
10 | @SpringBootApplication
11 | @EnableHazelcastRepositories
12 | public class EmployeeApplication {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(EmployeeApplication.class, args);
16 | }
17 |
18 | @Bean
19 | Config config() {
20 | Config config = new Config();
21 | config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(false);
22 | config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
23 | config.getNetworkConfig().getJoin().getKubernetesConfig().setEnabled(true)
24 | .setProperty("namespace", "default")
25 | .setProperty("service-name", "hazelcast-service");
26 | return config;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/employee-kubernetes-service/src/main/java/pl/piomin/services/employee/api/EmployeeController.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.employee.api;
2 |
3 | import java.util.List;
4 |
5 | import pl.piomin.services.employee.data.EmployeeRepository;
6 | import pl.piomin.services.employee.model.Employee;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import org.springframework.web.bind.annotation.DeleteMapping;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.PathVariable;
13 | import org.springframework.web.bind.annotation.PostMapping;
14 | import org.springframework.web.bind.annotation.RequestBody;
15 | import org.springframework.web.bind.annotation.RequestMapping;
16 | import org.springframework.web.bind.annotation.RestController;
17 |
18 | @RestController
19 | @RequestMapping("/employees")
20 | public class EmployeeController {
21 |
22 | private static final Logger logger = LoggerFactory.getLogger(EmployeeController.class);
23 |
24 | private EmployeeRepository repository;
25 |
26 | EmployeeController(EmployeeRepository repository) {
27 | this.repository = repository;
28 | }
29 |
30 | @GetMapping("/person/{id}")
31 | public Employee findByPersonId(@PathVariable("id") Integer personId) {
32 | logger.info("findByPersonId({})", personId);
33 | return repository.findByPersonId(personId);
34 | }
35 |
36 | @GetMapping("/company/{company}")
37 | public List findByCompany(@PathVariable("company") String company) {
38 | logger.info(String.format("findByCompany({})", company));
39 | return repository.findByCompany(company);
40 | }
41 |
42 | @GetMapping("/company/{company}/position/{position}")
43 | public List findByCompanyAndPosition(@PathVariable("company") String company, @PathVariable("position") String position) {
44 | logger.info(String.format("findByCompany({}, {})", company, position));
45 | return repository.findByCompanyAndPosition(company, position);
46 | }
47 |
48 | @GetMapping("/{id}")
49 | public Employee findById(@PathVariable("id") Long id) {
50 | logger.info("findById({})", id);
51 | return repository.findById(id).get();
52 | }
53 |
54 | @GetMapping("/salary/{salary}")
55 | public List findBySalaryGreaterThan(@PathVariable("salary") int salary) {
56 | logger.info(String.format("findBySalaryGreaterThan({})", salary));
57 | return repository.findBySalaryGreaterThan(salary);
58 | }
59 |
60 | @PostMapping
61 | public Employee add(@RequestBody Employee emp) {
62 | logger.info("add({})", emp);
63 | return repository.save(emp);
64 | }
65 |
66 | @DeleteMapping("/{id}")
67 | public void delete(@PathVariable("id") Long id) {
68 | logger.info("delete({})", id);
69 | repository.deleteById(id);
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/employee-kubernetes-service/src/main/java/pl/piomin/services/employee/data/EmployeeRepository.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.employee.data;
2 |
3 |
4 | import java.util.List;
5 |
6 | import pl.piomin.services.employee.model.Employee;
7 |
8 | import org.springframework.data.hazelcast.repository.HazelcastRepository;
9 |
10 | public interface EmployeeRepository extends HazelcastRepository {
11 |
12 | Employee findByPersonId(Integer personId);
13 |
14 | List findByCompany(String company);
15 |
16 | List findByCompanyAndPosition(String company, String position);
17 |
18 | List findBySalaryGreaterThan(int salary);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/employee-kubernetes-service/src/main/java/pl/piomin/services/employee/model/Employee.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.employee.model;
2 |
3 | import org.springframework.data.annotation.Id;
4 |
5 | import java.io.Serializable;
6 | import java.util.Objects;
7 |
8 | public class Employee implements Serializable {
9 |
10 | @Id
11 | private Long id;
12 | private Integer personId;
13 | private String company;
14 | private String position;
15 | private int salary;
16 |
17 | public Long getId() {
18 | return id;
19 | }
20 |
21 | public void setId(Long id) {
22 | this.id = id;
23 | }
24 |
25 | public Integer getPersonId() {
26 | return personId;
27 | }
28 |
29 | public void setPersonId(Integer personId) {
30 | this.personId = personId;
31 | }
32 |
33 | public String getCompany() {
34 | return company;
35 | }
36 |
37 | public void setCompany(String company) {
38 | this.company = company;
39 | }
40 |
41 | public String getPosition() {
42 | return position;
43 | }
44 |
45 | public void setPosition(String position) {
46 | this.position = position;
47 | }
48 |
49 | public int getSalary() {
50 | return salary;
51 | }
52 |
53 | public void setSalary(int salary) {
54 | this.salary = salary;
55 | }
56 |
57 | @Override
58 | public String toString() {
59 | return "Employee{" +
60 | "id=" + id +
61 | ", personId=" + personId +
62 | ", company='" + company + '\'' +
63 | ", position='" + position + '\'' +
64 | ", salary=" + salary +
65 | '}';
66 | }
67 |
68 | @Override
69 | public boolean equals(Object o) {
70 | if (this == o) return true;
71 | if (o == null || getClass() != o.getClass()) return false;
72 |
73 | Employee employee = (Employee) o;
74 |
75 | return Objects.equals(id, employee.id);
76 | }
77 |
78 | @Override
79 | public int hashCode() {
80 | return id != null ? id.hashCode() : 0;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/employee-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | /.classpath
4 | /.project
5 |
--------------------------------------------------------------------------------
/employee-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | pl.piomin.services
6 | sample-hazelcast-spring-datagrid
7 | 1.0-SNAPSHOT
8 |
9 | employee-service
10 |
11 |
12 | ${project.artifactId}
13 |
14 |
15 |
16 |
17 | org.springframework.boot
18 | spring-boot-starter-data-jpa
19 |
20 |
21 | com.hazelcast
22 | hazelcast
23 |
24 |
25 | com.hazelcast
26 | hazelcast-spring
27 |
28 |
29 | org.testcontainers
30 | mysql
31 | 1.21.1
32 | test
33 |
34 |
35 | org.testcontainers
36 | junit-jupiter
37 | 1.21.1
38 | test
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-testcontainers
43 | test
44 |
45 |
46 |
--------------------------------------------------------------------------------
/employee-service/src/main/java/pl/piomin/services/datagrid/employee/EmployeeApplication.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee;
2 |
3 | import com.hazelcast.config.Config;
4 | import com.hazelcast.config.ManagementCenterConfig;
5 | import com.hazelcast.config.SerializerConfig;
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.context.annotation.Bean;
9 | import pl.piomin.services.datagrid.employee.data.EmployeeSerializer;
10 | import pl.piomin.services.datagrid.employee.model.Employee;
11 |
12 | @SpringBootApplication
13 | public class EmployeeApplication {
14 |
15 | public static void main(String[] args) {
16 | SpringApplication.run(EmployeeApplication.class, args);
17 | }
18 |
19 | @Bean
20 | Config config() {
21 | Config c = new Config();
22 | c.setInstanceName("cache-1");
23 | c.setClusterName("dev");
24 | ManagementCenterConfig mcc = new ManagementCenterConfig()
25 | .setConsoleEnabled(true);
26 | c.setManagementCenterConfig(mcc);
27 | SerializerConfig sc = new SerializerConfig()
28 | .setTypeClass(Employee.class)
29 | .setClass(EmployeeSerializer.class);
30 | c.getSerializationConfig().addSerializerConfig(sc);
31 | return c;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/employee-service/src/main/java/pl/piomin/services/datagrid/employee/api/EmployeeController.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee.api;
2 |
3 | import java.util.List;
4 | import java.util.logging.Logger;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.PathVariable;
9 | import org.springframework.web.bind.annotation.PostMapping;
10 | import org.springframework.web.bind.annotation.RequestBody;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | import pl.piomin.services.datagrid.employee.model.Employee;
14 | import pl.piomin.services.datagrid.employee.service.EmployeeService;
15 |
16 | @RestController
17 | public class EmployeeController {
18 |
19 | private Logger logger = Logger.getLogger(EmployeeController.class.getName());
20 |
21 | @Autowired
22 | EmployeeService service;
23 |
24 | @GetMapping("/employees/person/{id}")
25 | public Employee findByPersonId(@PathVariable("id") Integer personId) {
26 | logger.info(String.format("findByPersonId(%d)", personId));
27 | return service.findByPersonId(personId);
28 | }
29 |
30 | @GetMapping("/employees/company/{company}")
31 | public List findByCompany(@PathVariable("company") String company) {
32 | logger.info(String.format("findByCompany(%s)", company));
33 | return service.findByCompany(company);
34 | }
35 |
36 | @GetMapping("/employees/{id}")
37 | public Employee findById(@PathVariable("id") Integer id) {
38 | logger.info(String.format("findById(%d)", id));
39 | return service.findById(id);
40 | }
41 |
42 | @PostMapping("/employees")
43 | public Employee add(@RequestBody Employee emp) {
44 | logger.info(String.format("add(%s)", emp));
45 | return service.add(emp);
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/employee-service/src/main/java/pl/piomin/services/datagrid/employee/data/EmployeeRepository.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee.data;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.repository.CrudRepository;
6 |
7 | import pl.piomin.services.datagrid.employee.model.Employee;
8 |
9 | public interface EmployeeRepository extends CrudRepository {
10 |
11 | public Employee findByPersonId(Integer personId);
12 |
13 | public List findByCompany(String company);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/employee-service/src/main/java/pl/piomin/services/datagrid/employee/data/EmployeeSerializer.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee.data;
2 |
3 | import com.hazelcast.nio.ObjectDataInput;
4 | import com.hazelcast.nio.ObjectDataOutput;
5 | import com.hazelcast.nio.serialization.StreamSerializer;
6 | import pl.piomin.services.datagrid.employee.model.Employee;
7 |
8 | import java.io.IOException;
9 |
10 | public class EmployeeSerializer implements StreamSerializer {
11 |
12 | @Override
13 | public int getTypeId() {
14 | return 1;
15 | }
16 |
17 | @Override
18 | public void write(ObjectDataOutput out, Employee employee) throws IOException {
19 | out.writeInt(employee.getId());
20 | out.writeInt(employee.getPersonId());
21 | out.writeUTF(employee.getCompany());
22 | }
23 |
24 | @Override
25 | public Employee read(ObjectDataInput in) throws IOException {
26 | Employee e = new Employee();
27 | e.setId(in.readInt());
28 | e.setPersonId(in.readInt());
29 | e.setCompany(in.readUTF());
30 | return e;
31 | }
32 |
33 | @Override
34 | public void destroy() {
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/employee-service/src/main/java/pl/piomin/services/datagrid/employee/model/Employee.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee.model;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 |
7 | import java.io.Serializable;
8 |
9 | @Entity
10 | public class Employee implements Serializable {
11 |
12 | private static final long serialVersionUID = 3214253910554454648L;
13 |
14 | @Id
15 | @GeneratedValue
16 | private Integer id;
17 | private Integer personId;
18 | private String company;
19 |
20 | public Integer getId() {
21 | return id;
22 | }
23 |
24 | public void setId(Integer id) {
25 | this.id = id;
26 | }
27 |
28 | public Integer getPersonId() {
29 | return personId;
30 | }
31 |
32 | public void setPersonId(Integer personId) {
33 | this.personId = personId;
34 | }
35 |
36 | public String getCompany() {
37 | return company;
38 | }
39 |
40 | public void setCompany(String company) {
41 | this.company = company;
42 | }
43 |
44 | @Override
45 | public int hashCode() {
46 | final int prime = 31;
47 | int result = 1;
48 | result = prime * result + ((company == null) ? 0 : company.hashCode());
49 | result = prime * result + ((id == null) ? 0 : id.hashCode());
50 | result = prime * result + ((personId == null) ? 0 : personId.hashCode());
51 | return result;
52 | }
53 |
54 | @Override
55 | public boolean equals(Object obj) {
56 | if (this == obj)
57 | return true;
58 | if (obj == null)
59 | return false;
60 | if (getClass() != obj.getClass())
61 | return false;
62 | Employee other = (Employee) obj;
63 | if (company == null) {
64 | if (other.company != null)
65 | return false;
66 | } else if (!company.equals(other.company))
67 | return false;
68 | if (id == null) {
69 | if (other.id != null)
70 | return false;
71 | } else if (!id.equals(other.id))
72 | return false;
73 | if (personId == null) {
74 | if (other.personId != null)
75 | return false;
76 | } else if (!personId.equals(other.personId))
77 | return false;
78 | return true;
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | return "Employee [id=" + id + ", personId=" + personId + ", company=" + company + "]";
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/employee-service/src/main/java/pl/piomin/services/datagrid/employee/service/EmployeeService.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee.service;
2 |
3 | import com.hazelcast.config.IndexType;
4 | import com.hazelcast.core.HazelcastInstance;
5 | import com.hazelcast.map.IMap;
6 | import com.hazelcast.query.Predicate;
7 | import com.hazelcast.query.PredicateBuilder;
8 | import com.hazelcast.query.impl.PredicateBuilderImpl;
9 | import jakarta.annotation.PostConstruct;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Service;
12 | import pl.piomin.services.datagrid.employee.data.EmployeeRepository;
13 | import pl.piomin.services.datagrid.employee.model.Employee;
14 |
15 | import java.util.ArrayList;
16 | import java.util.Collection;
17 | import java.util.List;
18 | import java.util.Optional;
19 | import java.util.logging.Logger;
20 |
21 | @Service
22 | public class EmployeeService {
23 |
24 | private Logger logger = Logger.getLogger(EmployeeService.class.getName());
25 |
26 | @Autowired
27 | EmployeeRepository repository;
28 | @Autowired
29 | HazelcastInstance instance;
30 |
31 | IMap map;
32 |
33 | @PostConstruct
34 | public void init() {
35 | map = instance.getMap("employee");
36 | map.addIndex(IndexType.HASH, "company");
37 | logger.info("Employees cache: " + map.size());
38 | }
39 |
40 | @SuppressWarnings("rawtypes")
41 | public Employee findByPersonId(Integer personId) {
42 | PredicateBuilder.EntryObject eo = new PredicateBuilderImpl().getEntryObject();
43 | Predicate predicate = eo.get("personId").equal(personId);
44 | logger.info("Employee cache find");
45 | Collection ps = map.values(predicate);
46 | logger.info("Employee cached: " + ps);
47 | Optional e = ps.stream().findFirst();
48 | if (e.isPresent())
49 | return e.get();
50 | logger.info("Employee cache find");
51 | Employee emp = repository.findByPersonId(personId);
52 | logger.info("Employee: " + emp);
53 | map.put(emp.getId(), emp);
54 | return emp;
55 | }
56 |
57 | @SuppressWarnings("rawtypes")
58 | public List findByCompany(String company) {
59 | PredicateBuilder.EntryObject eo = new PredicateBuilderImpl().getEntryObject();
60 | Predicate predicate = eo.get("company").equal(company);
61 | logger.info("Employees cache find");
62 | Collection ps = map.values(predicate);
63 | logger.info("Employees cache size: " + ps.size());
64 | if (ps.size() > 0) {
65 | return new ArrayList<>(ps);
66 | }
67 | logger.info("Employees find");
68 | List e = repository.findByCompany(company);
69 | logger.info("Employees size: " + e.size());
70 | e.parallelStream().forEach(it -> {
71 | map.putIfAbsent(it.getId(), it);
72 | });
73 | return e;
74 | }
75 |
76 | public Employee findById(Integer id) {
77 | Employee e = map.get(id);
78 | if (e != null)
79 | return e;
80 | e = repository.findById(id).orElseThrow();
81 | map.put(id, e);
82 | return e;
83 | }
84 |
85 | public Employee add(Employee e) {
86 | e = repository.save(e);
87 | map.put(e.getId(), e);
88 | return e;
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/employee-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: ${PORT:2222}
3 |
4 | spring:
5 | application:
6 | name: employee-service
7 | datasource:
8 | url: jdbc:mysql://localhost:33306/datagrid?useSSL=false
9 | username: datagrid
10 | password: datagrid
11 | jpa:
12 | hibernate:
13 | ddl-auto: create
14 | # properties:
15 | # hibernate:
16 | # show_sql: true
17 | # cache:
18 | # use_query_cache: true
19 | # use_second_level_cache: true
20 | # hazelcast:
21 | # use_native_client: true
22 | # native_client_address: 192.168.99.100:5701
23 | # native_client_group: dev
24 | # native_client_password: dev-pass
25 | # region:
26 | # factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
27 |
28 | #logging:
29 | # level:
30 | # com.hazelcast: DEBUG
31 | # org.hibernate: DEBUG
--------------------------------------------------------------------------------
/employee-service/src/test/java/pl/piomin/services/datagrid/employee/EmployeeApplicationTest.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee;
2 |
3 | import org.springframework.boot.SpringApplication;
4 |
5 | public class EmployeeApplicationTest {
6 |
7 | public static void main(String[] args) {
8 | SpringApplication.from(EmployeeApplication::main)
9 | .with(MysqlContainerDevMode.class)
10 | .run(args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/employee-service/src/test/java/pl/piomin/services/datagrid/employee/MysqlContainerDevMode.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee;
2 |
3 | import org.springframework.boot.test.context.TestConfiguration;
4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
5 | import org.springframework.context.annotation.Bean;
6 | import org.testcontainers.containers.MySQLContainer;
7 |
8 | @TestConfiguration
9 | public class MysqlContainerDevMode {
10 |
11 | @Bean
12 | @ServiceConnection
13 | public MySQLContainer> mysql() {
14 | return new MySQLContainer<>("mysql:8.0")
15 | .withUsername("datagrid")
16 | .withPassword("datagrid");
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/employee-service/src/test/java/pl/piomin/services/datagrid/employee/data/AddEmployeeRepositoryTest.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.employee.data;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
7 | import org.springframework.test.context.DynamicPropertyRegistry;
8 | import org.springframework.test.context.DynamicPropertySource;
9 | import org.testcontainers.containers.MySQLContainer;
10 | import org.testcontainers.junit.jupiter.Container;
11 | import org.testcontainers.junit.jupiter.Testcontainers;
12 | import pl.piomin.services.datagrid.employee.model.Employee;
13 |
14 | import java.text.DecimalFormat;
15 | import java.util.Random;
16 | import java.util.logging.Logger;
17 |
18 |
19 | @SpringBootTest
20 | @Testcontainers
21 | public class AddEmployeeRepositoryTest {
22 |
23 | protected Logger logger = Logger.getLogger(AddEmployeeRepositoryTest.class.getName());
24 |
25 | @Autowired
26 | EmployeeRepository repository;
27 |
28 | @Container
29 | @ServiceConnection
30 | private static final MySQLContainer> MYSQL = new MySQLContainer<>("mysql:8.0")
31 | .withUsername("datagrid")
32 | .withPassword("datagrid");
33 |
34 | @Test
35 | void add() {
36 | for (int i = 0; i < 1000; i++) {
37 | int ix = new Random().nextInt(100);
38 | Employee e = new Employee();
39 | e.setPersonId(i);
40 | e.setCompany("TEST" + new DecimalFormat("000").format(ix));
41 | e = repository.save(e);
42 | logger.info("Add: " + e);
43 | }
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/person-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | /.classpath
4 | /.project
5 |
--------------------------------------------------------------------------------
/person-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | pl.piomin.services
6 | sample-hazelcast-spring-datagrid
7 | 1.0-SNAPSHOT
8 |
9 | person-service
10 |
11 |
12 | ${project.artifactId}
13 |
14 |
15 |
16 |
17 | org.springframework.boot
18 | spring-boot-starter-data-jpa
19 |
20 |
21 | com.hazelcast
22 | hazelcast
23 |
24 |
25 | com.hazelcast
26 | hazelcast-spring
27 |
28 |
29 | org.testcontainers
30 | mysql
31 | 1.21.1
32 | test
33 |
34 |
35 | org.testcontainers
36 | junit-jupiter
37 | 1.21.1
38 | test
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-testcontainers
43 | test
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/person-service/src/main/java/pl/piomin/services/datagrid/person/PersonApplication.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.person;
2 |
3 | import com.hazelcast.client.config.ClientConfig;
4 | import com.hazelcast.client.config.ClientConnectionStrategyConfig;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.annotation.Value;
8 | import org.springframework.boot.SpringApplication;
9 | import org.springframework.boot.autoconfigure.SpringBootApplication;
10 | import org.springframework.cache.annotation.EnableCaching;
11 | import org.springframework.context.annotation.Bean;
12 |
13 | @SpringBootApplication
14 | @EnableCaching
15 | public class PersonApplication {
16 |
17 | private static final Logger LOG = LoggerFactory.getLogger(PersonApplication.class);
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(PersonApplication.class, args);
21 | }
22 |
23 | @Value("${spring.hazelcast.url:localhost:5701}")
24 | private String hazelcastUrl;
25 |
26 | @Bean
27 | ClientConfig clientConfig() {
28 | LOG.info("Connecting Hazelcast: url={}", hazelcastUrl);
29 | ClientConfig config = new ClientConfig();
30 | config.getNetworkConfig().addAddress(hazelcastUrl);
31 | config.setInstanceName("cache-1");
32 |
33 | ClientConnectionStrategyConfig strategy = new ClientConnectionStrategyConfig();
34 | strategy.setAsyncStart(true);
35 | config.setConnectionStrategyConfig(strategy);
36 | return config;
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/person-service/src/main/java/pl/piomin/services/datagrid/person/api/PersonController.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.person.api;
2 |
3 | import java.util.List;
4 |
5 | import com.hazelcast.client.HazelcastClientOfflineException;
6 | import jakarta.annotation.PostConstruct;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.cache.CacheManager;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 | import org.springframework.web.bind.annotation.PathVariable;
14 | import org.springframework.web.bind.annotation.RestController;
15 |
16 | import pl.piomin.services.datagrid.person.data.PersonRepository;
17 | import pl.piomin.services.datagrid.person.model.Person;
18 |
19 | @RestController
20 | public class PersonController {
21 |
22 | protected Logger logger = LoggerFactory.getLogger(PersonController.class.getName());
23 |
24 | @Autowired
25 | PersonRepository repository;
26 | @Autowired
27 | CacheManager manager;
28 |
29 | @PostConstruct
30 | public void init() {
31 | try {
32 | logger.info("Cache manager: " + manager);
33 | logger.info("Cache manager names: " + manager.getCacheNames());
34 | } catch (HazelcastClientOfflineException e) {
35 | logger.error("No Hazelcast connection", e);
36 | }
37 | }
38 |
39 | @GetMapping("/persons/pesel/{pesel}")
40 | public List findByPesel(@PathVariable("pesel") String pesel) {
41 | return repository.findByPesel(pesel);
42 | }
43 |
44 | @GetMapping("/persons/{id}")
45 | public Person findById(@PathVariable("id") Integer id) {
46 | return repository.findById(id).orElseThrow();
47 | }
48 |
49 | @GetMapping("/persons")
50 | public List findAll() {
51 | return (List) repository.findAll();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/person-service/src/main/java/pl/piomin/services/datagrid/person/data/PersonRepository.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.person.data;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.cache.annotation.Cacheable;
6 | import org.springframework.data.repository.CrudRepository;
7 |
8 | import pl.piomin.services.datagrid.person.model.Person;
9 |
10 | public interface PersonRepository extends CrudRepository {
11 |
12 | @Cacheable("findByPesel")
13 | public List findByPesel(String pesel);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/person-service/src/main/java/pl/piomin/services/datagrid/person/model/Person.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.person.model;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import org.hibernate.annotations.Cache;
7 | import org.hibernate.annotations.CacheConcurrencyStrategy;
8 |
9 | import java.io.Serializable;
10 |
11 | @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
12 | @Entity
13 | public class Person implements Serializable {
14 |
15 | private static final long serialVersionUID = 3214253910554454648L;
16 |
17 | @Id
18 | @GeneratedValue
19 | private Integer id;
20 | private String firstName;
21 | private String lastName;
22 | private String pesel;
23 | private int age;
24 |
25 | public Integer getId() {
26 | return id;
27 | }
28 |
29 | public void setId(Integer id) {
30 | this.id = id;
31 | }
32 |
33 | public String getFirstName() {
34 | return firstName;
35 | }
36 |
37 | public void setFirstName(String firstName) {
38 | this.firstName = firstName;
39 | }
40 |
41 | public String getLastName() {
42 | return lastName;
43 | }
44 |
45 | public void setLastName(String lastName) {
46 | this.lastName = lastName;
47 | }
48 |
49 | public String getPesel() {
50 | return pesel;
51 | }
52 |
53 | public void setPesel(String pesel) {
54 | this.pesel = pesel;
55 | }
56 |
57 | public int getAge() {
58 | return age;
59 | }
60 |
61 | public void setAge(int age) {
62 | this.age = age;
63 | }
64 |
65 | @Override
66 | public String toString() {
67 | return "Person [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", pesel=" + pesel + "]";
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/person-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: ${PORT:2222}
3 |
4 | spring:
5 | application:
6 | name: person-service
7 | datasource:
8 | url: jdbc:mysql://localhost:33306/datagrid?useSSL=false
9 | username: datagrid
10 | password: datagrid
11 | hikari:
12 | connection-timeout: 2000
13 | initialization-fail-timeout: 0
14 | jpa:
15 | database-platform: org.hibernate.dialect.MySQL8Dialect
16 | # properties:
17 | # hibernate:
18 | # dialect: org.hibernate.dialect.MySQL8Dialect
19 | hibernate:
20 | # dialect: org.hibernate.dialect.MySQL8Dialect
21 | ddl-auto: create
22 |
23 | management:
24 | endpoint:
25 | caches:
26 | enabled: false
27 | #management.endpoints.web.exposure.include: 'health'
28 | #management.endpoint.health:
29 | # show-details: always
30 | # probes:
31 | # enabled: true
32 |
33 | # properties:
34 | # hibernate:
35 | # show_sql: true
36 | # cache:
37 | # use_query_cache: true
38 | # use_second_level_cache: true
39 | # hazelcast:
40 | # instance_name: cache-1
41 | # use_native_client: true
42 | # native_client_address: 192.168.99.100
43 | # native_client_group: dev
44 | # native_client_password: dev-pass
45 | # region:
46 | # factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
47 |
48 | testcontainers:
49 | beans:
50 | startup: parallel
51 | #logging:
52 | # level:
53 | # com.hazelcast: DEBUG
54 | # org.hibernate: DEBUG
--------------------------------------------------------------------------------
/person-service/src/test/java/pl/piomin/services/datagrid/person/MysqlAndHazelcastContainersDevMode.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.person;
2 |
3 | import org.springframework.boot.test.context.TestConfiguration;
4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.test.context.DynamicPropertyRegistry;
7 | import org.testcontainers.containers.GenericContainer;
8 | import org.testcontainers.containers.MySQLContainer;
9 | import org.testcontainers.utility.DockerImageName;
10 |
11 | @TestConfiguration(proxyBeanMethods = false)
12 | public class MysqlAndHazelcastContainersDevMode {
13 |
14 | @Bean
15 | @ServiceConnection
16 | public MySQLContainer> mysql() {
17 | return new MySQLContainer<>("mysql:8.0")
18 | .withUsername("datagrid")
19 | .withPassword("datagrid");
20 | }
21 |
22 | @Bean
23 | public GenericContainer> hazelcast(DynamicPropertyRegistry registry) {
24 | GenericContainer> hazelcast = new GenericContainer<>(DockerImageName.parse("hazelcast/hazelcast:5.1"))
25 | .withExposedPorts(5701);
26 | registry.add("spring.hazelcast.url", () -> hazelcast.getHost() + ":" + hazelcast.getFirstMappedPort());
27 | return hazelcast;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/person-service/src/test/java/pl/piomin/services/datagrid/person/PersonDevModeApplication.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.person;
2 |
3 | import org.springframework.boot.SpringApplication;
4 |
5 | public class PersonDevModeApplication {
6 |
7 | public static void main(String[] args) {
8 | SpringApplication.from(PersonApplication::main)
9 | .with(MysqlAndHazelcastContainersDevMode.class)
10 | .run(args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/person-service/src/test/java/pl/piomin/services/datagrid/person/data/AddPersonRepositoryTest.java:
--------------------------------------------------------------------------------
1 | package pl.piomin.services.datagrid.person.data;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
7 | import org.springframework.test.context.DynamicPropertyRegistry;
8 | import org.springframework.test.context.DynamicPropertySource;
9 | import org.testcontainers.containers.GenericContainer;
10 | import org.testcontainers.containers.MySQLContainer;
11 | import org.testcontainers.junit.jupiter.Container;
12 | import org.testcontainers.junit.jupiter.Testcontainers;
13 | import org.testcontainers.utility.DockerImageName;
14 | import pl.piomin.services.datagrid.person.model.Person;
15 |
16 | import java.text.DecimalFormat;
17 | import java.util.List;
18 | import java.util.Random;
19 | import java.util.logging.Logger;
20 |
21 | @SpringBootTest
22 | @Testcontainers
23 | public class AddPersonRepositoryTest {
24 |
25 | protected Logger logger = Logger.getLogger(AddPersonRepositoryTest.class.getName());
26 |
27 | @Autowired
28 | PersonRepository repository;
29 |
30 | @Container
31 | @ServiceConnection
32 | static final MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"))
33 | .withUsername("datagrid")
34 | .withPassword("datagrid");
35 |
36 | @Container
37 | // @ServiceConnection
38 | static final GenericContainer> hazelcast = new GenericContainer<>(DockerImageName.parse("hazelcast/hazelcast:5.1"))
39 | .withExposedPorts(5701);
40 |
41 | @DynamicPropertySource
42 | static void hazelcastProperties(DynamicPropertyRegistry registry) {
43 | String url = hazelcast.getHost() + ":" + hazelcast.getFirstMappedPort();
44 | registry.add("spring.hazelcast.url", () -> url);
45 | }
46 |
47 | @Test
48 | public void add() {
49 | for (int i = 0; i < 1000; i++) {
50 | int ix = new Random().nextInt(100000);
51 | Person p = new Person();
52 | p.setFirstName("Jan" + ix);
53 | p.setLastName("Testowy" + ix);
54 | p.setPesel(new DecimalFormat("0000000").format(ix) + new DecimalFormat("000").format(i%100));
55 | p.setAge(ix%100);
56 | p = repository.save(p);
57 | logger.info("Add: " + p);
58 | }
59 |
60 | }
61 |
62 | @Test
63 | void find() {
64 | logger.info("find()");
65 | List ps = repository.findByPesel("0034919066");
66 | logger.info("find(): " + ps);
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | pl.piomin.services
5 | sample-hazelcast-spring-datagrid
6 | 1.0-SNAPSHOT
7 | pom
8 |
9 |
10 | org.springframework.boot
11 | spring-boot-starter-parent
12 | 3.5.0
13 |
14 |
15 |
16 |
17 | UTF-8
18 | UTF-8
19 | 21
20 | piomin_sample-hazelcast-spring-datagrid
21 | piomin
22 | https://sonarcloud.io
23 |
24 |
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 |
32 |
33 |
34 |
35 | com.mysql
36 | mysql-connector-j
37 | runtime
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-starter-test
42 | test
43 |
44 |
45 |
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-maven-plugin
51 |
52 |
53 | org.jacoco
54 | jacoco-maven-plugin
55 | 0.8.13
56 |
57 |
58 |
59 | prepare-agent
60 |
61 |
62 |
63 | report
64 | test
65 |
66 | report
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | person-service
77 | employee-service
78 | employee-kubernetes-service
79 |
80 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Hazelcast With Spring Boot Demo Project [](https://twitter.com/piotr_minkowski)
2 |
3 | In this project I'm demonstrating you the most interesting features of [Hazelcast](https://hazelcast.com/) and its integration with Spring Boot and Spring Data to build cache or distributed in-memory data grid.
4 |
5 | ## Getting Started
6 | Currently you may find here some examples of application that integrates Hazelcast with Spring Boot and Spring Data. Some of them are divided into the branches and described in a separated articles on my blog. Here's a full list of available examples:
7 | 1. Using Hazelcast as 2nd level JPA Cache for **Hibernate** and **MySQL** database. The example is available in the branch [master](https://github.com/piomin/sample-hazelcast-spring-datagrid/tree/master). A detailed guide may be find in the following article: [JPA caching with Hazelcast, Hibernate and Spring Boot](https://piotrminkowski.com/2017/05/08/jpa-caching-with-hazelcast-hibernate-and-spring-boot/).
8 | 2. Using Hazelcast with [Striim](https://www.striim.com/) for enabling hot cache between **MySQL** database and in-memory data grid. The example is available in the branch [striim](https://github.com/piomin/sample-hazelcast-spring-datagrid/tree/striim). A detailed guide may be find in the following article: [Hazelcast Hot Cache with Striim](https://piotrminkowski.com/2017/08/09/hazelcast-hot-cache-with-striim/).
9 | 3. Using Hazelcast cluster on **Kubernetes** with Spring Boot. The example is available in the branch [master](https://github.com/piomin/sample-hazelcast-spring-datagrid/tree/master). A detailed guide may be find in the following article: [Hazelcast With Spring Boot on Kubernetes](https://piotrminkowski.com/2020/01/31/hazelcast-with-spring-boot-on-kubernetes/).
10 | 4. Using Hazelcast cluster with Spring Boot that programically stores data in the two sources: **MySQL** and Hazelcast. The example is available in the branch [master](https://github.com/piomin/sample-hazelcast-spring-datagrid/tree/master). A detailed guide may be find in the following article: [In-memory Data Grid with Hazelcast](https://piotrminkowski.com/2017/05/10/in-memory-data-grid-with-hazelcast/).
11 |
12 | ### Usage
13 |
14 | In the most cases you need to have Maven and JDK8+. In the third example with Kubernetes you will have to run **Minikube** on your machine. The best way to run the sample applications is with IDEs like IntelliJ IDEA or Eclipse.
15 |
16 | ## Architecture
17 |
18 | Our sample microservices-based system consists of the following modules:
19 | - **employee-service** - a module which is a simple Spring Boot application for storing `Employee` objects in Hazelcast and MySQL (optionally)
20 | - **person-service** - a module which is a simple Spring Boot application for storing `Person` objects in Hazelcast and MySQL (optionally)
21 | - **employee-service-kubernetes** - a module dedicated only for 3rd example based on Kubernetes.
22 |
23 | The following picture illustrates the architecture for running Hazelcast on Kubernetes (**Minikube**) (**Example 3**).
24 |
25 | 
26 |
27 | The following picture illustrates the architecture for running Hazelcast with **Striim** as a hot cache for MySQL database (**Example 2**).
28 |
29 | 
30 |
31 | The following picture illustrates the architecture for running Hazelcast with Spring Boot as in-memory data grid that programically stores data in two sources (**Example 4**).
32 |
33 | 
34 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base",":dependencyDashboard"
5 | ],
6 | "packageRules": [
7 | {
8 | "matchUpdateTypes": ["minor", "patch", "pin", "digest"],
9 | "automerge": true
10 | }
11 | ],
12 | "prCreation": "not-pending"
13 | }
--------------------------------------------------------------------------------