Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions hazelcast/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Sample for running using Hazelcast.

- http://localhost:8080 -> Spring Boot Main Application
- http://localhost:8090 -> Spring Boot Replica Application

![Architecture](architecture.png)

## 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
```
5 changes: 5 additions & 0 deletions hazelcast/apps/hello-world/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
target
.idea
*.iml
*.log
*.gz
8 changes: 8 additions & 0 deletions hazelcast/apps/hello-world/Dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
6 changes: 6 additions & 0 deletions hazelcast/apps/hello-world/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

# Build App
mvn package
# Build Docker Image
docker build --tag hello-world-hazelcast .
73 changes: 73 additions & 0 deletions hazelcast/apps/hello-world/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.6</version>
</parent>

<groupId>de.codecentric</groupId>
<artifactId>hello-world-hazelcast</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Hello World</name>

<properties>
<java.version>17</java.version>
<spring-boot-admin.version>3.5.5</spring-boot-admin.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
<!-- Build-Info for Info-Actuator -->
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -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!";
}

}
Original file line number Diff line number Diff line change
@@ -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);
}

}
47 changes: 47 additions & 0 deletions hazelcast/apps/hello-world/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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() {
}

}
5 changes: 5 additions & 0 deletions hazelcast/apps/spring-boot-admin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
target
.idea
*.iml
*.log
*.gz
8 changes: 8 additions & 0 deletions hazelcast/apps/spring-boot-admin/Dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
6 changes: 6 additions & 0 deletions hazelcast/apps/spring-boot-admin/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

# Build App
mvn package
# Build Docker Image
docker build --tag spring-boot-admin-hazelcast .
81 changes: 81 additions & 0 deletions hazelcast/apps/spring-boot-admin/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.6</version>
</parent>

<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-hazelcast</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>spring-boot-admin-hazelcast</name>
<description>spring-boot-admin using hazelcast as cluster</description>

<properties>
<java.version>17</java.version>
<spring-boot-admin.version>3.5.5</spring-boot-admin.version>
<spring-cloud.version>2025.0.0</spring-cloud.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>

<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
<!-- Build-Info for Info-Actuator -->
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -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;
}

}
Loading