diff --git a/hazelcast/README.md b/hazelcast/README.md
new file mode 100644
index 0000000..ac8b7a6
--- /dev/null
+++ b/hazelcast/README.md
@@ -0,0 +1,24 @@
+# Sample for running using Hazelcast.
+
+- http://localhost:8080 -> Spring Boot Main Application
+- http://localhost:8090 -> Spring Boot Replica Application
+
+
+
+## Prerequisites
+
+- Java
+- Maven
+- Docker and Docker Compose
+
+## Run Everything
+You can run the whole build and start all apps in docker containers with the following script
+```bash
+chmod u+x buildAndRunAll.sh
+./buildAndRunAll.sh
+```
+
+## Stop Everything
+```bash
+docker compose down -v
+```
\ No newline at end of file
diff --git a/hazelcast/apps/hello-world/.gitignore b/hazelcast/apps/hello-world/.gitignore
new file mode 100644
index 0000000..b18abdf
--- /dev/null
+++ b/hazelcast/apps/hello-world/.gitignore
@@ -0,0 +1,5 @@
+target
+.idea
+*.iml
+*.log
+*.gz
diff --git a/hazelcast/apps/hello-world/Dockerfile b/hazelcast/apps/hello-world/Dockerfile
new file mode 100644
index 0000000..7940f0a
--- /dev/null
+++ b/hazelcast/apps/hello-world/Dockerfile
@@ -0,0 +1,8 @@
+# https://hub.docker.com/_/eclipse-temurin/
+FROM eclipse-temurin:21
+
+VOLUME /tmp
+
+COPY target/app.jar /opt/app/app.jar
+
+CMD ["bash", "-c", "java $JAVA_OPTS -jar /opt/app/app.jar"]
diff --git a/hazelcast/apps/hello-world/build.sh b/hazelcast/apps/hello-world/build.sh
new file mode 100755
index 0000000..9b23c00
--- /dev/null
+++ b/hazelcast/apps/hello-world/build.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Build App
+mvn package
+# Build Docker Image
+docker build --tag hello-world-hazelcast .
diff --git a/hazelcast/apps/hello-world/pom.xml b/hazelcast/apps/hello-world/pom.xml
new file mode 100644
index 0000000..80ea01a
--- /dev/null
+++ b/hazelcast/apps/hello-world/pom.xml
@@ -0,0 +1,73 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.5.6
+
+
+ de.codecentric
+ hello-world-hazelcast
+ 1.0.0-SNAPSHOT
+ Hello World
+
+
+ 17
+ 3.5.5
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ de.codecentric
+ spring-boot-admin-starter-client
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ de.codecentric
+ spring-boot-admin-dependencies
+ ${spring-boot-admin.version}
+ pom
+ import
+
+
+
+
+
+ app
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ repackage
+
+ repackage
+
+ build-info
+
+
+
+
+
+
+
+
diff --git a/hazelcast/apps/hello-world/src/main/java/de/codecentric/helloworld/hazelcast/HelloWorld.java b/hazelcast/apps/hello-world/src/main/java/de/codecentric/helloworld/hazelcast/HelloWorld.java
new file mode 100644
index 0000000..af0b7df
--- /dev/null
+++ b/hazelcast/apps/hello-world/src/main/java/de/codecentric/helloworld/hazelcast/HelloWorld.java
@@ -0,0 +1,14 @@
+package de.codecentric.helloworld.hazelcast;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloWorld {
+
+ @GetMapping("/")
+ public String hello() {
+ return "Hello World!";
+ }
+
+}
diff --git a/hazelcast/apps/hello-world/src/main/java/de/codecentric/helloworld/hazelcast/HelloWorldHazelcastApplication.java b/hazelcast/apps/hello-world/src/main/java/de/codecentric/helloworld/hazelcast/HelloWorldHazelcastApplication.java
new file mode 100644
index 0000000..c492cff
--- /dev/null
+++ b/hazelcast/apps/hello-world/src/main/java/de/codecentric/helloworld/hazelcast/HelloWorldHazelcastApplication.java
@@ -0,0 +1,13 @@
+package de.codecentric.helloworld.hazelcast;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class HelloWorldHazelcastApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(HelloWorldHazelcastApplication.class, args);
+ }
+
+}
diff --git a/hazelcast/apps/hello-world/src/main/resources/application.yml b/hazelcast/apps/hello-world/src/main/resources/application.yml
new file mode 100644
index 0000000..fd7af28
--- /dev/null
+++ b/hazelcast/apps/hello-world/src/main/resources/application.yml
@@ -0,0 +1,47 @@
+server:
+ port: 8081
+spring:
+ application: # Application-Info for the Info-Actuator
+ name: "@pom.artifactId@"
+ boot:
+ admin:
+ client:
+ url: "http://spring-boot-admin-member-1:8080" # use docker compose internal service name to access sba server
+ instance:
+ # if admin server should talk to hello through proxy, the following properties could be used,
+ # see https://docs.spring-boot-admin.com/current/client.html#spring-boot-admin-client
+ #health-url: "http://host.docker.internal:8888/hello/actuator/health"
+ #management-url: "http://host.docker.internal:8888/hello/actuator"
+ #management-base-url: "http://host.docker.internal:8888/hello"
+ #service-url: "http://host.docker.internal:8888/hello"
+management: # Actuator Configuration
+ endpoints:
+ web:
+ exposure:
+ include: "*"
+ endpoint: # Health-Actuator
+ health:
+ show-details: always
+ info: # Info-Actuator
+ java:
+ enabled: true
+ os:
+ enabled: true
+ build:
+ enabled: true
+ env:
+ enabled: true
+info: # Application-Info for the Info-Actuator
+ group: "@pom.groupId@"
+ artifact: "@pom.artifactId@"
+ description: "@pom.description@"
+ version: "@pom.version@"
+ spring-boot: "@pom.parent.version@"
+ # Tags for the Spring Boot Admin UI
+ tags:
+ spring-boot: "@pom.parent.version@"
+logging: # Logging-File for the Logfile-Actuator
+ file:
+ name: "hello-world.log"
+ level:
+ ROOT: debug
diff --git a/hazelcast/apps/hello-world/src/test/java/de/codecentric/helloworld/hazelcast/HelloWorldHazelcastApplicationTests.java b/hazelcast/apps/hello-world/src/test/java/de/codecentric/helloworld/hazelcast/HelloWorldHazelcastApplicationTests.java
new file mode 100644
index 0000000..dc0a420
--- /dev/null
+++ b/hazelcast/apps/hello-world/src/test/java/de/codecentric/helloworld/hazelcast/HelloWorldHazelcastApplicationTests.java
@@ -0,0 +1,13 @@
+package de.codecentric.helloworld.hazelcast;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class HelloWorldHazelcastApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/hazelcast/apps/spring-boot-admin/.gitignore b/hazelcast/apps/spring-boot-admin/.gitignore
new file mode 100644
index 0000000..b18abdf
--- /dev/null
+++ b/hazelcast/apps/spring-boot-admin/.gitignore
@@ -0,0 +1,5 @@
+target
+.idea
+*.iml
+*.log
+*.gz
diff --git a/hazelcast/apps/spring-boot-admin/Dockerfile b/hazelcast/apps/spring-boot-admin/Dockerfile
new file mode 100644
index 0000000..7940f0a
--- /dev/null
+++ b/hazelcast/apps/spring-boot-admin/Dockerfile
@@ -0,0 +1,8 @@
+# https://hub.docker.com/_/eclipse-temurin/
+FROM eclipse-temurin:21
+
+VOLUME /tmp
+
+COPY target/app.jar /opt/app/app.jar
+
+CMD ["bash", "-c", "java $JAVA_OPTS -jar /opt/app/app.jar"]
diff --git a/hazelcast/apps/spring-boot-admin/build.sh b/hazelcast/apps/spring-boot-admin/build.sh
new file mode 100755
index 0000000..4d4d3ab
--- /dev/null
+++ b/hazelcast/apps/spring-boot-admin/build.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Build App
+mvn package
+# Build Docker Image
+docker build --tag spring-boot-admin-hazelcast .
diff --git a/hazelcast/apps/spring-boot-admin/pom.xml b/hazelcast/apps/spring-boot-admin/pom.xml
new file mode 100644
index 0000000..b2b158f
--- /dev/null
+++ b/hazelcast/apps/spring-boot-admin/pom.xml
@@ -0,0 +1,81 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.5.6
+
+
+ de.codecentric
+ spring-boot-admin-hazelcast
+ 1.0.0-SNAPSHOT
+ spring-boot-admin-hazelcast
+ spring-boot-admin using hazelcast as cluster
+
+
+ 17
+ 3.5.5
+ 2025.0.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.cloud
+ spring-cloud-starter
+
+
+ de.codecentric
+ spring-boot-admin-starter-server
+
+
+
+ com.hazelcast
+ hazelcast
+
+
+
+
+
+ de.codecentric
+ spring-boot-admin-dependencies
+ ${spring-boot-admin.version}
+ pom
+ import
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+ app
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ repackage
+
+ repackage
+
+ build-info
+
+
+
+
+
+
+
+
diff --git a/hazelcast/apps/spring-boot-admin/src/main/java/de/codecentric/springbootadmin/hazelcast/SpringBootAdminHazelcastApplication.java b/hazelcast/apps/spring-boot-admin/src/main/java/de/codecentric/springbootadmin/hazelcast/SpringBootAdminHazelcastApplication.java
new file mode 100644
index 0000000..d5c47fb
--- /dev/null
+++ b/hazelcast/apps/spring-boot-admin/src/main/java/de/codecentric/springbootadmin/hazelcast/SpringBootAdminHazelcastApplication.java
@@ -0,0 +1,56 @@
+package de.codecentric.springbootadmin.hazelcast;
+
+import com.hazelcast.config.*;
+import com.hazelcast.spi.merge.PutIfAbsentMergePolicy;
+import de.codecentric.boot.admin.server.config.EnableAdminServer;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+
+import static de.codecentric.boot.admin.server.config.AdminServerHazelcastAutoConfiguration.DEFAULT_NAME_EVENT_STORE_MAP;
+import static de.codecentric.boot.admin.server.config.AdminServerHazelcastAutoConfiguration.DEFAULT_NAME_SENT_NOTIFICATIONS_MAP;
+import static java.util.Collections.singletonList;
+
+@SpringBootApplication
+@EnableAdminServer
+public class SpringBootAdminHazelcastApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootAdminHazelcastApplication.class, args);
+ }
+
+ @Bean
+ public Config hazelcastConfig() {
+ // This map is used to store the events.
+ // It should be configured to reliably hold all the data,
+ // Spring Boot Admin will compact the events, if there are too many
+ MapConfig eventStoreMap = new MapConfig(DEFAULT_NAME_EVENT_STORE_MAP).setInMemoryFormat(InMemoryFormat.OBJECT)
+ .setBackupCount(1)
+ .setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMergePolicy.class.getName(), 100));
+ // This map is used to deduplicate the notifications.
+ // If data in this map gets lost it should not be a big issue as it will atmost
+ // lead to
+ // the same notification to be sent by multiple instances
+ MapConfig sentNotificationsMap = new MapConfig(DEFAULT_NAME_SENT_NOTIFICATIONS_MAP)
+ .setInMemoryFormat(InMemoryFormat.OBJECT)
+ .setBackupCount(1)
+ .setEvictionConfig(
+ new EvictionConfig().setEvictionPolicy(EvictionPolicy.LRU).setMaxSizePolicy(MaxSizePolicy.PER_NODE))
+ .setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMergePolicy.class.getName(), 100));
+
+ Config config = new Config();
+ config.addMapConfig(eventStoreMap);
+ config.addMapConfig(sentNotificationsMap);
+ config.setProperty("hazelcast.jmx", "true");
+
+ // network and join configuration (simple defaults good for local/dev)
+ NetworkConfig network = config.getNetworkConfig();
+ network.setPort(5701).setPortAutoIncrement(true);
+
+ JoinConfig join = network.getJoin();
+ join.getMulticastConfig().setEnabled(true);
+
+ return config;
+ }
+
+}
diff --git a/hazelcast/apps/spring-boot-admin/src/main/resources/application.yml b/hazelcast/apps/spring-boot-admin/src/main/resources/application.yml
new file mode 100644
index 0000000..7667dfa
--- /dev/null
+++ b/hazelcast/apps/spring-boot-admin/src/main/resources/application.yml
@@ -0,0 +1,40 @@
+spring:
+ application: # Application-Info for the Info-Actuator
+ name: "@pom.artifactId@"
+ cloud:
+ discovery:
+ client:
+ simple:
+ instances:
+ hello-world:
+ - uri: http://hello-world-hazelcast:8081
+
+management: # Actuator Configuration
+ endpoints:
+ web:
+ exposure:
+ include: "*"
+ endpoint: # Health-Actuator
+ health:
+ show-details: always
+ info: # Info-Actuator
+ java:
+ enabled: true
+ os:
+ enabled: true
+ build:
+ enabled: true
+ env:
+ enabled: true
+info: # Application-Info for the Info-Actuator
+ group: "@pom.groupId@"
+ artifact: "@pom.artifactId@"
+ description: "@pom.description@"
+ version: "@pom.version@"
+ spring-boot: "@pom.parent.version@"
+ # Tags for the Spring Boot Admin UI
+ tags:
+ spring-boot: "@pom.parent.version@"
+logging: # Logging-File for the Logfile-Actuator
+ file:
+ name: "hello-world.log"
diff --git a/hazelcast/architecture.png b/hazelcast/architecture.png
new file mode 100644
index 0000000..25f390e
Binary files /dev/null and b/hazelcast/architecture.png differ
diff --git a/hazelcast/buildAndRunAll.sh b/hazelcast/buildAndRunAll.sh
new file mode 100755
index 0000000..df59a3e
--- /dev/null
+++ b/hazelcast/buildAndRunAll.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+cd apps/spring-boot-admin
+./build.sh
+cd ../..
+
+cd apps/hello-world
+./build.sh
+cd ../..
+
+docker compose up -d
diff --git a/hazelcast/docker-compose.yml b/hazelcast/docker-compose.yml
new file mode 100644
index 0000000..c733a02
--- /dev/null
+++ b/hazelcast/docker-compose.yml
@@ -0,0 +1,18 @@
+services:
+ hello-world:
+ container_name: hello-world-hazelcast
+ image: hello-world-hazelcast
+
+ spring-boot-admin-member-1:
+ container_name: spring-boot-admin-hazelcast-member-1
+ image: spring-boot-admin-hazelcast
+ ports:
+ - "8080:8080"
+ environment:
+ SPRING_BOOT_ADMIN_UI_PUBLICURL: http://localhost:8080
+
+ spring-boot-admin-member-2:
+ container_name: spring-boot-admin-hazelcast-member-2
+ image: spring-boot-admin-hazelcast
+ ports:
+ - "8090:8080"