From 28293bfd0e5667729b86dbb8edbfe3014d825e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Fri, 7 Feb 2025 14:29:39 +0100 Subject: [PATCH 01/16] Refresh example, make it work with proper parent project --- pom.xml | 35 +++++++--- spring/spring-boot-embedded/pom.xml | 65 ++++++++++++++----- .../springboot/CommandController.java | 4 +- .../springboot/HazelcastApplication.java | 6 +- .../src/main/resources/hazelcast.yaml | 6 ++ .../src/main/resources/log4j2.xml | 13 ++++ ...llerTest.java => CommandControllerIT.java} | 19 ++++-- .../src/test/resources/hazelcast.yaml | 11 ++++ .../src/test/resources/log4j2.xml | 13 ++++ .../guide/controller/SessionController.java | 12 ++-- 10 files changed, 146 insertions(+), 38 deletions(-) create mode 100644 spring/spring-boot-embedded/src/main/resources/log4j2.xml rename spring/spring-boot-embedded/src/test/java/guides/hazelcast/springboot/{CommandControllerTest.java => CommandControllerIT.java} (81%) create mode 100644 spring/spring-boot-embedded/src/test/resources/log4j2.xml diff --git a/pom.xml b/pom.xml index e7140044f..0d72c5eb9 100644 --- a/pom.xml +++ b/pom.xml @@ -122,6 +122,23 @@ maven-surefire-plugin + + maven-failsafe-plugin + 3.5.2 + + + + integration-test + verify + + integration-test + + + + ${project.build.outputDirectory} + -Djava.net.preferIPv4Stack=true + + org.apache.maven.plugins maven-enforcer-plugin @@ -191,23 +208,23 @@ - - - org.junit.jupiter - junit-jupiter-api - 5.10.0 - test - + + + org.junit.jupiter + junit-jupiter-api + 5.11.4 + test + org.junit.vintage junit-vintage-engine - 5.10.0 + 5.11.4 test org.junit.jupiter junit-jupiter-engine - 5.10.0 + 5.11.4 test diff --git a/spring/spring-boot-embedded/pom.xml b/spring/spring-boot-embedded/pom.xml index 8f274bcc2..40d6bef24 100755 --- a/spring/spring-boot-embedded/pom.xml +++ b/spring/spring-boot-embedded/pom.xml @@ -3,21 +3,54 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 3.4.0 - + com.hazelcast.samples + spring + 0.1-SNAPSHOT - com.hazelcast.samples spring-boot-hazelcast-embedded - 0.1-SNAPSHOT Spring Boot with Hazelcast Embedded + jar + + + + + org.springframework.boot + spring-boot-dependencies + 3.4.2 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.springframework.boot spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + org.apache.logging.log4j + log4j-spring-boot @@ -38,14 +71,16 @@ spring-boot-starter-webflux test + + org.awaitility + awaitility + 4.2.2 + test + + + commons-logging + commons-logging + 1.3.4 + - - - - - org.springframework.boot - spring-boot-maven-plugin - - - diff --git a/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/CommandController.java b/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/CommandController.java index 7c7b33f3c..d743662ec 100755 --- a/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/CommandController.java +++ b/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/CommandController.java @@ -1,6 +1,8 @@ package guides.hazelcast.springboot; import com.hazelcast.map.IMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -13,7 +15,7 @@ public class CommandController { private final IMap keyValueMap; - public CommandController(IMap keyValueMap) { + public CommandController(@Autowired @Qualifier("map") IMap keyValueMap) { this.keyValueMap = requireNonNull(keyValueMap); } diff --git a/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/HazelcastApplication.java b/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/HazelcastApplication.java index ab4af11d9..bc26d2f9b 100755 --- a/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/HazelcastApplication.java +++ b/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/HazelcastApplication.java @@ -14,8 +14,10 @@ public static void main(String[] args) { SpringApplication.run(HazelcastApplication.class, args); } + //tag::imap-bean[] @Bean - public IMap keyValueMap(@Autowired HazelcastInstance hazelcast) { - return hazelcast.getMap("keyValueMap"); + public IMap map(@Autowired HazelcastInstance hazelcast) { + return hazelcast.getMap("map"); } + //end::imap-bean[] } diff --git a/spring/spring-boot-embedded/src/main/resources/hazelcast.yaml b/spring/spring-boot-embedded/src/main/resources/hazelcast.yaml index 6064ac32a..bb15dcd39 100755 --- a/spring/spring-boot-embedded/src/main/resources/hazelcast.yaml +++ b/spring/spring-boot-embedded/src/main/resources/hazelcast.yaml @@ -1,2 +1,8 @@ hazelcast: cluster-name: hazelcast-cluster + properties: + hazelcast.logging.type: log4j2 + network: + join: + multicast: + enabled: true diff --git a/spring/spring-boot-embedded/src/main/resources/log4j2.xml b/spring/spring-boot-embedded/src/main/resources/log4j2.xml new file mode 100644 index 000000000..7e0d17a6b --- /dev/null +++ b/spring/spring-boot-embedded/src/main/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/spring/spring-boot-embedded/src/test/java/guides/hazelcast/springboot/CommandControllerTest.java b/spring/spring-boot-embedded/src/test/java/guides/hazelcast/springboot/CommandControllerIT.java similarity index 81% rename from spring/spring-boot-embedded/src/test/java/guides/hazelcast/springboot/CommandControllerTest.java rename to spring/spring-boot-embedded/src/test/java/guides/hazelcast/springboot/CommandControllerIT.java index 04e9d2d1f..cab5c2e6a 100755 --- a/spring/spring-boot-embedded/src/test/java/guides/hazelcast/springboot/CommandControllerTest.java +++ b/spring/spring-boot-embedded/src/test/java/guides/hazelcast/springboot/CommandControllerIT.java @@ -1,5 +1,6 @@ package guides.hazelcast.springboot; +import com.hazelcast.config.Config; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; import org.junit.jupiter.api.Test; @@ -7,15 +8,17 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.reactive.server.WebTestClient; +import java.time.Duration; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; import static org.springframework.http.HttpHeaders.ACCEPT; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class CommandControllerTest { +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = HazelcastApplication.class) +public class CommandControllerIT { @Autowired private WebTestClient webTestClient; @@ -74,10 +77,16 @@ private WebTestClient.ResponseSpec makePutRequest(Object... parameters) { @Test public void testHazelcastCluster() { //given - Hazelcast.newHazelcastInstance(); + Config config = Config.load(); + var hz = Hazelcast.newHazelcastInstance(config); //then - assertThat(hazelcastInstance.getCluster().getMembers()) - .hasSize(2); + try { + await() + .atMost(Duration.ofMinutes(2)) + .until(() -> hazelcastInstance.getCluster().getMembers().size() == 2); + } finally { + hz.shutdown(); + } } } diff --git a/spring/spring-boot-embedded/src/test/resources/hazelcast.yaml b/spring/spring-boot-embedded/src/test/resources/hazelcast.yaml index 34ee5060d..e5fe64831 100755 --- a/spring/spring-boot-embedded/src/test/resources/hazelcast.yaml +++ b/spring/spring-boot-embedded/src/test/resources/hazelcast.yaml @@ -1,6 +1,17 @@ hazelcast: cluster-name: hazelcast-cluster + properties: + hazelcast.logging.type: log4j2 + # for faster execution of tests + hazelcast.partition.count: 11 + hazelcast.operation.thread.count: 2 + hazelcast.operation.generic.thread.count: 2 + hazelcast.event.thread.count: 1 + metrics: + enabled: false + network: join: multicast: enabled: true + loopbackModeEnabled: true diff --git a/spring/spring-boot-embedded/src/test/resources/log4j2.xml b/spring/spring-boot-embedded/src/test/resources/log4j2.xml new file mode 100644 index 000000000..7e0d17a6b --- /dev/null +++ b/spring/spring-boot-embedded/src/test/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java index 0420fca66..6f5d24c40 100644 --- a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java +++ b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java @@ -92,18 +92,18 @@ public String getSessionInfo(HttpServletRequest request) { } private String toHtmlTable(Map attributes) { - StringBuilder html = new StringBuilder(""); - html.append(""); + StringBuilder html = new StringBuilder(""); + html.append("
"); attributes.forEach((k, v) -> addHtmlTableRow(html, k, v)); - html.append("
"); + html.append(""); return html.toString(); } private void addHtmlTableRow(StringBuilder content, String key, Object value) { content.append("") - .append("").append(key).append("") - .append("").append(value).append("") - .append(""); + .append("").append(key).append("") + .append("").append(value).append("") + .append(""); } } From 75426eaa336048c884b42bc378fd7314ecd6fab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Fri, 7 Feb 2025 17:45:36 +0100 Subject: [PATCH 02/16] Making use of project parent structure; refreshing examples --- spring/pom.xml | 28 +++++- .../pom.xml | 57 ++++++----- spring/spring-boot-caching-jcache/pom.xml | 57 ++++++++--- spring/spring-boot-embedded/pom.xml | 7 +- .../README.md | 2 - .../client/pom.xml | 5 - .../data/chemistry/ClientController.java | 21 ++-- .../pom.xml | 95 ++++++++----------- .../server/pom.xml | 7 +- .../samples/spring/data/chemistry/Server.java | 23 +++-- .../spring/data/chemistry/ServerCommands.java | 36 ++++--- .../META-INF/spring/spring-shell-plugin.xml | 11 --- .../src/main/resources/application.properties | 4 + 13 files changed, 188 insertions(+), 165 deletions(-) delete mode 100644 spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/META-INF/spring/spring-shell-plugin.xml create mode 100644 spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/application.properties diff --git a/spring/pom.xml b/spring/pom.xml index 371df8c69..5c8fa93fd 100644 --- a/spring/pom.xml +++ b/spring/pom.xml @@ -30,10 +30,24 @@ 0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + ${project.parent.basedir} UTF-8 + + 3.4.2 @@ -45,20 +59,26 @@ spring-hibernate-2ndlevel-cache springaware-annotation spring-boot-caching-jcache - spring-boot-session-replication-spring-session-hazelcast + + + com.hazelcast.samples + helper + ${project.version} + com.hazelcast hazelcast ${hazelcast.version} + - com.hazelcast.samples - helper - ${project.version} + commons-logging + commons-logging + 1.3.4 diff --git a/spring/spring-boot-caching-hazelcast-cache-manager/pom.xml b/spring/spring-boot-caching-hazelcast-cache-manager/pom.xml index ce507279e..db3999a74 100644 --- a/spring/spring-boot-caching-hazelcast-cache-manager/pom.xml +++ b/spring/spring-boot-caching-hazelcast-cache-manager/pom.xml @@ -3,37 +3,59 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 3.4.0 - + com.hazelcast.samples + spring + 0.1-SNAPSHOT - com.hazelcast.samples spring-boot-caching-hazelcast-cache-manager 0.1-SNAPSHOT jar Spring Boot Caching with Hazelcast Cache Manager - - 5.5.0 - + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.springframework.boot spring-boot-starter-cache + + + org.springframework.boot + spring-boot-starter-logging + + org.springframework.boot spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + - - com.hazelcast - hazelcast - ${hazelcast.version} - com.hazelcast @@ -47,13 +69,4 @@ test - - - - - org.springframework.boot - spring-boot-maven-plugin - - - diff --git a/spring/spring-boot-caching-jcache/pom.xml b/spring/spring-boot-caching-jcache/pom.xml index e94199ef1..f7a2302ff 100644 --- a/spring/spring-boot-caching-jcache/pom.xml +++ b/spring/spring-boot-caching-jcache/pom.xml @@ -3,26 +3,65 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 3.4.0 - + com.hazelcast.samples + spring + 0.1-SNAPSHOT - com.hazelcast.samples spring-boot-caching-jcache 0.1-SNAPSHOT Caching with Spring Boot, JCache and Hazelcast + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.springframework.boot spring-boot-starter-cache + + + org.springframework.boot + spring-boot-starter-logging + + org.springframework.boot spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + org.apache.logging.log4j + log4j-spring-boot @@ -52,12 +91,4 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - diff --git a/spring/spring-boot-embedded/pom.xml b/spring/spring-boot-embedded/pom.xml index 40d6bef24..9e95a687e 100755 --- a/spring/spring-boot-embedded/pom.xml +++ b/spring/spring-boot-embedded/pom.xml @@ -17,7 +17,7 @@ org.springframework.boot spring-boot-dependencies - 3.4.2 + ${spring.boot.version} pom import @@ -77,10 +77,5 @@ 4.2.2 test - - commons-logging - commons-logging - 1.3.4 -
diff --git a/spring/spring-data-hazelcast-chemistry-sample/README.md b/spring/spring-data-hazelcast-chemistry-sample/README.md index dde2fd1e0..2fec57a80 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/README.md +++ b/spring/spring-data-hazelcast-chemistry-sample/README.md @@ -100,8 +100,6 @@ Try `http://localhost:8080`, as this lists the other available URLs. Experiment with running the `load` and `unload` command on the server to populate and depopulate the test data, to see how the web page responses change. Really though this should be fairly obvious, it's how little coding is required that's the area to focus on. ## Potential improvements -### Spring Shell -The server site uses _spring-shell_ to make an executable Jar file that takes command line input. This should not be too difficult to convert to be a _spring-boot_ `CommandLineRunner` that bootstraps into the command line shell. ### Controller URLs For simplicity, on the `ClientController` module the landing page returns a list of the other URLs that the controller supports. Adding HATEOAS (_spring-hateoas_), Swagger or `@RepositoryRestController` would be simple steps to make this self-generate. diff --git a/spring/spring-data-hazelcast-chemistry-sample/client/pom.xml b/spring/spring-data-hazelcast-chemistry-sample/client/pom.xml index 8f3e62c6d..3705e7d5a 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/client/pom.xml +++ b/spring/spring-data-hazelcast-chemistry-sample/client/pom.xml @@ -20,11 +20,6 @@ - - com.hazelcast - hazelcast-client - ${hazelcast.version} - ${project.groupId} common diff --git a/spring/spring-data-hazelcast-chemistry-sample/client/src/main/java/com/hazelcast/samples/spring/data/chemistry/ClientController.java b/spring/spring-data-hazelcast-chemistry-sample/client/src/main/java/com/hazelcast/samples/spring/data/chemistry/ClientController.java index d86e657d4..433dea1ca 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/client/src/main/java/com/hazelcast/samples/spring/data/chemistry/ClientController.java +++ b/spring/spring-data-hazelcast-chemistry-sample/client/src/main/java/com/hazelcast/samples/spring/data/chemistry/ClientController.java @@ -2,7 +2,7 @@ import com.hazelcast.samples.spring.data.chemistry.domain.Element; import com.hazelcast.samples.spring.data.chemistry.service.ChemistryService; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -33,18 +33,19 @@ @RestController public class ClientController { - @Autowired - private ChemistryService chemistryService; + private final ChemistryService chemistryService; + + public ClientController(ChemistryService chemistryService) { + this.chemistryService = chemistryService; + } /** * Return the other URLs supported by this controller. - * + *

* HATEOAS or Swagger would be an alternative mechanism here, * although unrelated to the purpose of the example. - * - * @throws MalformedURLException */ - @RequestMapping(value = "/", method = RequestMethod.GET) + @GetMapping("/") public List index() throws MalformedURLException { List urls = new ArrayList(); @@ -64,7 +65,7 @@ public List index() throws MalformedURLException { * * @return A list of elements that form salt compounds */ - @RequestMapping(value = "/halogens", method = RequestMethod.GET) + @GetMapping("/halogens") public List halogens() { return this.chemistryService.findElementsByGroupSorted(17); } @@ -94,8 +95,8 @@ public Map> neutrons() { * @param weight atomic weight to find * @return A possibly empty, non-null list */ - @RequestMapping(value = "/weight/{weight}", method = RequestMethod.GET) - public List weight(@PathVariable final int weight) { + @GetMapping("/weight/{weight}") + public List weight(@PathVariable(name = "weight") int weight) { List elements = this.chemistryService.findElementsByAtomicWeight(weight); diff --git a/spring/spring-data-hazelcast-chemistry-sample/pom.xml b/spring/spring-data-hazelcast-chemistry-sample/pom.xml index 4484c3513..cfa99bb01 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/pom.xml +++ b/spring/spring-data-hazelcast-chemistry-sample/pom.xml @@ -3,8 +3,8 @@ 4.0.0 - spring com.hazelcast.samples + spring 0.1-SNAPSHOT @@ -21,10 +21,8 @@ ${project.parent.parent.basedir} UTF-8 - - 3.12.7 - 2.2.5 - 1.2.0.RELEASE + 2.4.0 + 3.4.0 @@ -33,12 +31,50 @@ client + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.shell + spring-shell-dependencies + ${spring-shell.version} + pom + import + + + + com.hazelcast spring-data-hazelcast ${spring-data-hazelcast.version} + + com.hazelcast + hazelcast + ${hazelcast.version} + org.projectlombok lombok @@ -49,53 +85,4 @@ 1.0.2.Final - - - - - com.hazelcast - spring-data-hazelcast - ${spring-data-hazelcast.version} - - - com.hazelcast - hazelcast - - - - - com.hazelcast - hazelcast-client - ${hazelcast.version} - - - - org.springframework.shell - spring-shell - ${spring-shell.version} - - - - - - org.springframework.boot - spring-boot-starter-parent - pom - import - ${spring.boot.version} - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring.boot.version} - - - - diff --git a/spring/spring-data-hazelcast-chemistry-sample/server/pom.xml b/spring/spring-data-hazelcast-chemistry-sample/server/pom.xml index c7b142a92..e8b005112 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/server/pom.xml +++ b/spring/spring-data-hazelcast-chemistry-sample/server/pom.xml @@ -26,14 +26,9 @@ ${project.version} - - org.springframework.boot - spring-boot-starter - - org.springframework.shell - spring-shell + spring-shell-starter diff --git a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/java/com/hazelcast/samples/spring/data/chemistry/Server.java b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/java/com/hazelcast/samples/spring/data/chemistry/Server.java index 7b04a66a8..6f32e4789 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/java/com/hazelcast/samples/spring/data/chemistry/Server.java +++ b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/java/com/hazelcast/samples/spring/data/chemistry/Server.java @@ -1,13 +1,15 @@ package com.hazelcast.samples.spring.data.chemistry; -import org.springframework.shell.Bootstrap; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.shell.command.annotation.CommandScan; +import org.springframework.shell.command.annotation.EnableCommand; /** * Run a Hazelcast server embedded in a command line interpreter. - * - * Use Spring Shell to provide the framework of the command line interpreter, and + *

* extend this with extra commands for this example. - * + *

* Commands *

    *
  1. helpList available commands.[built-in] @@ -30,21 +32,18 @@ * * @see */ +@EnableCommand(ServerCommands.class) +@SpringBootApplication public class Server { /** * Launch Spring Shell, pulling in Spring beans for Hazelcast and added * command line interpreter commands. * - * Spring Shell expects XML style config, in - * {@code classpath:/META-INF/spring/spring-shell-plugin.xml}. - * * @param args From the O/s to pass on - * @throws Exception Allow failure */ - // TODO: Convert to Spring Boot - public static void main(String[] args) throws Exception { - System.setProperty("hazelcast.logging.type", "slf4j"); - Bootstrap.main(args); + public static void main(String[] args) { + System.setProperty("hazelcast.logging.type", "log4j2"); + SpringApplication.run(Server.class, args); } } diff --git a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/java/com/hazelcast/samples/spring/data/chemistry/ServerCommands.java b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/java/com/hazelcast/samples/spring/data/chemistry/ServerCommands.java index 975bc2be9..fcdc02d0e 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/java/com/hazelcast/samples/spring/data/chemistry/ServerCommands.java +++ b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/java/com/hazelcast/samples/spring/data/chemistry/ServerCommands.java @@ -1,10 +1,8 @@ package com.hazelcast.samples.spring.data.chemistry; import com.hazelcast.samples.spring.data.chemistry.service.ChemistryService; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.stereotype.Component; +import org.springframework.shell.command.annotation.Command; +import org.springframework.shell.command.annotation.Option; import javax.annotation.Resource; import java.util.Map; @@ -13,15 +11,15 @@ /** * Define commands to manipulate the test data from the command line. */ -@Component -public class ServerCommands implements CommandMarker { +@Command(group = "Server Commands") +public class ServerCommands { @Resource private ChemistryService chemistyService; /** * List all test data present in the cluster. - * + *

    * Usage *

      *
    • list
    • @@ -29,7 +27,7 @@ public class ServerCommands implements CommandMarker { * * @return A string displayed in the shell */ - @CliCommand(value = "count", help = "Count the Chemistry test data in the cluster") + @Command(command = "count", description = "Count the Chemistry test data in the cluster") public String count() { Map items = this.chemistyService.count(); @@ -38,7 +36,7 @@ public String count() { /** * List all test data present in the cluster. - * + *

      * Usage *

        *
      • list
      • @@ -46,7 +44,7 @@ public String count() { * * @return A string displayed in the shell */ - @CliCommand(value = "list", help = "Display the Chemistry test data in the cluster") + @Command(description = "Display the Chemistry test data in the cluster") public String list() { Map> elements = this.chemistyService.neutrons(); @@ -54,8 +52,8 @@ public String list() { } /** - * Insert the predefined test data in {@link example.springdata.keyvalue.chemistry.utils.PeriodicTable} into the cluster. - * + * Insert the predefined test data in {@link Constants#PERIODIC_TABLE} into the cluster. + *

        * Usage *

          *
        • load
        • @@ -63,7 +61,7 @@ public String list() { * * @return A string displayed in the shell */ - @CliCommand(value = "load", help = "Insert Chemistry test data into the cluster") + @Command(description = "Insert Chemistry test data into the cluster") public String load() { int count = this.chemistyService.load(); @@ -72,7 +70,7 @@ public String load() { /** * Remove data from the cluster. - * + *

          * Usage *

            *
          • unload @@ -87,13 +85,11 @@ public String load() { * * @return A string displayed in the shell */ - @CliCommand(value = "unload", help = "Remove Chemistry test data from the cluster") + @Command(description = "Remove Chemistry test data from the cluster") public String unload( - @CliOption(key = {"isotope"} - , mandatory = false - , help = "Optionally '--isotope true' or '--isotope false' to only unload isotopes" - , specifiedDefaultValue = "false" - , unspecifiedDefaultValue = "true" + @Option( + label = "isotope", + description = "Optionally '--isotope true' or '--isotope false' to only unload isotopes" ) final boolean onlyIsotopes ) { diff --git a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/META-INF/spring/spring-shell-plugin.xml b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/META-INF/spring/spring-shell-plugin.xml deleted file mode 100644 index 3aad03467..000000000 --- a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/META-INF/spring/spring-shell-plugin.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/application.properties b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/application.properties new file mode 100644 index 000000000..6c26325d6 --- /dev/null +++ b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/application.properties @@ -0,0 +1,4 @@ +logging.level.root=OFF +spring.main.banner-mode=off +spring.main.web-application-type=none +spring.shell.interactive.enabled=true \ No newline at end of file From d8271d89e21a7993f602b3b840ff6531488d604a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Fri, 7 Feb 2025 17:58:18 +0100 Subject: [PATCH 03/16] Cleanups --- .../samples/spring/data/chemistry/Client.java | 2 +- spring/spring-hibernate-2ndlevel-cache/pom.xml | 1 - .../hibernate/springhibernate2lc/Runner.java | 9 ++++----- .../SecondLevelCacheVisualizer.java | 11 +++++++---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/spring/spring-data-hazelcast-chemistry-sample/client/src/main/java/com/hazelcast/samples/spring/data/chemistry/Client.java b/spring/spring-data-hazelcast-chemistry-sample/client/src/main/java/com/hazelcast/samples/spring/data/chemistry/Client.java index e4edb3aa8..1e7fe9265 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/client/src/main/java/com/hazelcast/samples/spring/data/chemistry/Client.java +++ b/spring/spring-data-hazelcast-chemistry-sample/client/src/main/java/com/hazelcast/samples/spring/data/chemistry/Client.java @@ -6,7 +6,7 @@ /** * Run a Hazelcast client as a REST application. Data can be inspected * using simple URL calls in a browser. - * + *

            * Use http://localhost:8080/ * to discover what URLs are available. */ diff --git a/spring/spring-hibernate-2ndlevel-cache/pom.xml b/spring/spring-hibernate-2ndlevel-cache/pom.xml index 57cb43df2..d6324a95c 100644 --- a/spring/spring-hibernate-2ndlevel-cache/pom.xml +++ b/spring/spring-hibernate-2ndlevel-cache/pom.xml @@ -84,7 +84,6 @@ org.springframework.boot spring-boot-maven-plugin - ${spring.boot.version} diff --git a/spring/spring-hibernate-2ndlevel-cache/src/main/java/com/hazelcast/hibernate/springhibernate2lc/Runner.java b/spring/spring-hibernate-2ndlevel-cache/src/main/java/com/hazelcast/hibernate/springhibernate2lc/Runner.java index 126010dd6..26cd10ab9 100644 --- a/spring/spring-hibernate-2ndlevel-cache/src/main/java/com/hazelcast/hibernate/springhibernate2lc/Runner.java +++ b/spring/spring-hibernate-2ndlevel-cache/src/main/java/com/hazelcast/hibernate/springhibernate2lc/Runner.java @@ -42,7 +42,7 @@ class Runner implements CommandLineRunner { } @Override - public void run(String... args) throws Exception { + public void run(String... args) { Book book1 = new Book(); book1.setName("Alice in Wonderland"); Book book2 = new Book(); @@ -93,18 +93,17 @@ private void printCachesFromCacheManager() { private void printCachesFromHazelcast() { LOGGER.info("Caches from hazelcast:"); for (DistributedObject distributedObject : hazelcastInstance.getDistributedObjects()) { - LOGGER.info(" - " + distributedObject.getName()); + LOGGER.info(" - {}", distributedObject.getName()); } } private void findAllBooks() { Iterable books = repository.findAll(); - LOGGER.info("Loaded all books: " + books); + LOGGER.info("Loaded all books: {}", books); } - private Optional getBookById(long id) { + private void getBookById(long id) { Optional book = repository.findById(id); book.ifPresent(p -> LOGGER.info("Loaded book: {}", p)); - return book; } } diff --git a/spring/spring-hibernate-2ndlevel-cache/src/main/java/com/hazelcast/hibernate/springhibernate2lc/SecondLevelCacheVisualizer.java b/spring/spring-hibernate-2ndlevel-cache/src/main/java/com/hazelcast/hibernate/springhibernate2lc/SecondLevelCacheVisualizer.java index 93ab8c413..356831f85 100644 --- a/spring/spring-hibernate-2ndlevel-cache/src/main/java/com/hazelcast/hibernate/springhibernate2lc/SecondLevelCacheVisualizer.java +++ b/spring/spring-hibernate-2ndlevel-cache/src/main/java/com/hazelcast/hibernate/springhibernate2lc/SecondLevelCacheVisualizer.java @@ -2,6 +2,8 @@ import com.hazelcast.client.HazelcastClient; import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.hibernate.serialization.Value; import com.hazelcast.hibernate.springhibernate2lc.persistence.Book; import com.hazelcast.map.IMap; import org.springframework.scheduling.annotation.Scheduled; @@ -16,10 +18,11 @@ class SecondLevelCacheVisualizer { @Scheduled(fixedDelay = 10000) public void cachePeek() { - IMap bookCache = - Stream.concat(Hazelcast.getAllHazelcastInstances().stream(), HazelcastClient.getAllHazelcastClients().stream()) - .findAny().orElseThrow(IllegalStateException::new) - .getMap(Book.class.getName()); + HazelcastInstance hazelcastInstance = Stream.concat(Hazelcast.getAllHazelcastInstances().stream(), + HazelcastClient.getAllHazelcastClients().stream()) + .findAny().orElseThrow(IllegalStateException::new); + + IMap bookCache = hazelcastInstance.getMap(Book.class.getName()); System.out.println(LocalTime.now()); System.out.println("size: " + bookCache.size()); From 021c8218a7d82fca96376b2515a157b75dc7493c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Fri, 7 Feb 2025 18:21:05 +0100 Subject: [PATCH 04/16] Fix flakiness, cleanup --- .run/Template JUnit.run.xml | 11 +++++ pom.xml | 4 ++ spring/pom.xml | 2 +- .../pom.xml | 40 +++++++++++-------- .../guide/config/SessionConfiguration.java | 4 +- ... HazelcastSpringSessionApplicationIT.java} | 15 +++---- 6 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 .run/Template JUnit.run.xml rename spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/{HazelcastSpringSessionApplicationTests.java => HazelcastSpringSessionApplicationIT.java} (89%) diff --git a/.run/Template JUnit.run.xml b/.run/Template JUnit.run.xml new file mode 100644 index 000000000..b583927bd --- /dev/null +++ b/.run/Template JUnit.run.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0d72c5eb9..b5ff033bb 100644 --- a/pom.xml +++ b/pom.xml @@ -121,6 +121,10 @@ maven-surefire-plugin + + ${project.build.outputDirectory} + -Djava.net.preferIPv4Stack=true + maven-failsafe-plugin diff --git a/spring/pom.xml b/spring/pom.xml index 5c8fa93fd..3ad5ad374 100644 --- a/spring/pom.xml +++ b/spring/pom.xml @@ -59,7 +59,7 @@ spring-hibernate-2ndlevel-cache springaware-annotation spring-boot-caching-jcache - + spring-boot-session-replication-spring-session-hazelcast diff --git a/spring/spring-boot-session-replication-spring-session-hazelcast/pom.xml b/spring/spring-boot-session-replication-spring-session-hazelcast/pom.xml index 71b44f091..3f0c1a472 100644 --- a/spring/spring-boot-session-replication-spring-session-hazelcast/pom.xml +++ b/spring/spring-boot-session-replication-spring-session-hazelcast/pom.xml @@ -3,20 +3,35 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 3.4.0 - + com.hazelcast.samples + spring + 0.1-SNAPSHOT - com.hazelcast.samples spring-boot-session-replication-spring-session-hazelcast 0.1-SNAPSHOT Spring Boot Session Replication with Spring Session Hazelcast - - 5.5.0 - + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + @@ -40,13 +55,4 @@ test - - - - - org.springframework.boot - spring-boot-maven-plugin - - - diff --git a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/config/SessionConfiguration.java b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/config/SessionConfiguration.java index ce234aa46..dc951548b 100644 --- a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/config/SessionConfiguration.java +++ b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/config/SessionConfiguration.java @@ -4,6 +4,7 @@ import com.hazelcast.config.Config; import com.hazelcast.config.IndexConfig; import com.hazelcast.config.IndexType; +import com.hazelcast.config.NetworkConfig; import com.hazelcast.config.SerializerConfig; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; @@ -43,7 +44,8 @@ public HazelcastInstance hazelcastInstance() { Config config = new Config(); config.setClusterName("spring-session-cluster"); - config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(true); + NetworkConfig networkConf = config.getNetworkConfig(); + networkConf.getJoin().getMulticastConfig().setEnabled(true); // Add this attribute to be able to query sessions by their PRINCIPAL_NAME_ATTRIBUTE's AttributeConfig attributeConfig = new AttributeConfig() diff --git a/spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationTests.java b/spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationIT.java similarity index 89% rename from spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationTests.java rename to spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationIT.java index 60e452e21..c0478edbd 100644 --- a/spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationTests.java +++ b/spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationIT.java @@ -21,9 +21,9 @@ import static org.springframework.http.HttpMethod.GET; @SuppressWarnings("DataFlowIssue") -class HazelcastSpringSessionApplicationTests { +class HazelcastSpringSessionApplicationIT { - private static final Logger logger = LoggerFactory.getLogger(HazelcastSpringSessionApplicationTests.class); + private static final Logger logger = LoggerFactory.getLogger(HazelcastSpringSessionApplicationIT.class); static final String COOKIE_NAME = "SESSION"; @@ -31,7 +31,9 @@ class HazelcastSpringSessionApplicationTests { void contextLoads() { // given String port1 = startApplication(); + System.out.println("Started 1st on port: " + port1); String port2 = startApplication(); + System.out.println("Started 2nd on port: " + port2); Map principalMap = Collections.singletonMap("principal", "hazelcast2020"); waitForCluster(port1); @@ -39,14 +41,12 @@ void contextLoads() { // when ResponseEntity response1 = makeRequest(port1, "create", null, principalMap); String sessionCookie1 = extractSessionCookie(response1); - logger.info("First request headers: {}", response1.getHeaders()); - logger.info("First request body: {}", response1.getBody().toString()); logger.info("First session cookie: {}", sessionCookie1); // then ResponseEntity response2 = makeRequest(port2, "create", sessionCookie1, principalMap); String body = response2.getBody().toString(); - logger.info("Body contains: {}", body); + logger.info("Body of second query contains: {}", body); assertThat(body).contains("Session already exists"); } @@ -95,9 +95,10 @@ public static void waitForCluster(String port) { var requestEntity = new HttpEntity<>(new HttpHeaders()); await() - .atMost(Duration.ofMinutes(5)) - .pollInterval(Duration.ofSeconds(1)) + .atMost(Duration.ofMinutes(2)) + .pollInterval(Duration.ofSeconds(2)) .logging(logger::info) + .alias("Waiting for correct cluster size") .until(() -> { ResponseEntity clusterSize = restTemplate.exchange(url, GET, requestEntity, Integer.class); return clusterSize.getBody() == 2; From 875c1d08005e6f68193cee8146f01eb47cfe76df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Fri, 7 Feb 2025 18:37:55 +0100 Subject: [PATCH 05/16] Fix some versions --- serialization/hazelcast-airlines/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serialization/hazelcast-airlines/pom.xml b/serialization/hazelcast-airlines/pom.xml index c3af839f0..28200596d 100644 --- a/serialization/hazelcast-airlines/pom.xml +++ b/serialization/hazelcast-airlines/pom.xml @@ -20,9 +20,9 @@ ${project.parent.parent.basedir} UTF-8 - 4.0 + 5.5.0 4.0.0 - 1.2.0.RELEASE + 3.4.0 From eb3526751bc719da208bc765eebf505b89527c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Fri, 7 Feb 2025 19:24:29 +0100 Subject: [PATCH 06/16] Fix airplane sample --- pom.xml | 20 ++++++---- .../hazelcast-airlines/grid-node/pom.xml | 3 +- .../hazelcast/airlines/Application.java | 6 +-- .../serialization/hazelcast/airlines/CLI.java | 37 +++++++++---------- .../META-INF/spring/spring-shell-plugin.xml | 11 ------ .../src/main/resources/application.properties | 4 ++ serialization/hazelcast-airlines/pom.xml | 15 +++++++- .../hazelcast-airlines/the-code/pom.xml | 6 +++ .../SeatReservationEntryProcessorTest.java | 2 +- .../hazelcast/airlines/V1FlightTest.java | 2 +- .../hazelcast/airlines/V2FlightTest.java | 2 +- .../hazelcast/airlines/V3FlightTest.java | 2 +- .../hazelcast/airlines/V4FlightTest.java | 2 +- .../hazelcast/airlines/V5FlightTest.java | 2 +- 14 files changed, 66 insertions(+), 48 deletions(-) delete mode 100644 serialization/hazelcast-airlines/grid-node/src/main/resources/META-INF/spring/spring-shell-plugin.xml create mode 100644 serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties diff --git a/pom.xml b/pom.xml index b5ff033bb..45c8c099c 100644 --- a/pom.xml +++ b/pom.xml @@ -212,13 +212,13 @@ - - - org.junit.jupiter - junit-jupiter-api - 5.11.4 - test - + + + org.junit.jupiter + junit-jupiter-api + 5.11.4 + test + org.junit.vintage junit-vintage-engine @@ -231,6 +231,12 @@ 5.11.4 test + + org.junit.platform + junit-platform-commons + 1.11.4 + test + org.mockito mockito-core diff --git a/serialization/hazelcast-airlines/grid-node/pom.xml b/serialization/hazelcast-airlines/grid-node/pom.xml index 5aabd83c2..2822713de 100644 --- a/serialization/hazelcast-airlines/grid-node/pom.xml +++ b/serialization/hazelcast-airlines/grid-node/pom.xml @@ -25,9 +25,10 @@ 0.1-SNAPSHOT + org.springframework.shell - spring-shell + spring-shell-starter diff --git a/serialization/hazelcast-airlines/grid-node/src/main/java/com/hazelcast/samples/serialization/hazelcast/airlines/Application.java b/serialization/hazelcast-airlines/grid-node/src/main/java/com/hazelcast/samples/serialization/hazelcast/airlines/Application.java index 637405b1b..144b0279a 100644 --- a/serialization/hazelcast-airlines/grid-node/src/main/java/com/hazelcast/samples/serialization/hazelcast/airlines/Application.java +++ b/serialization/hazelcast-airlines/grid-node/src/main/java/com/hazelcast/samples/serialization/hazelcast/airlines/Application.java @@ -1,7 +1,7 @@ package com.hazelcast.samples.serialization.hazelcast.airlines; +import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.shell.Bootstrap; /** *

            Use Spring Boot and Spring Shell to build a Hazelcast @@ -19,9 +19,9 @@ public class Application { * * @param args From command line */ - public static void main(String[] args) throws Exception { + public static void main(String[] args) { System.setProperty("hazelcast.logging.type", "slf4j"); - Bootstrap.main(args); + SpringApplication.run(Application.class, args); } } diff --git a/serialization/hazelcast-airlines/grid-node/src/main/java/com/hazelcast/samples/serialization/hazelcast/airlines/CLI.java b/serialization/hazelcast-airlines/grid-node/src/main/java/com/hazelcast/samples/serialization/hazelcast/airlines/CLI.java index 1a81a9493..f1fe8f6b2 100644 --- a/serialization/hazelcast-airlines/grid-node/src/main/java/com/hazelcast/samples/serialization/hazelcast/airlines/CLI.java +++ b/serialization/hazelcast-airlines/grid-node/src/main/java/com/hazelcast/samples/serialization/hazelcast/airlines/CLI.java @@ -7,9 +7,8 @@ import com.hazelcast.samples.serialization.hazelcast.airlines.util.Constants; import com.hazelcast.samples.serialization.hazelcast.airlines.util.FlightBuilder; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; +import org.springframework.shell.command.annotation.Command; +import org.springframework.shell.command.annotation.Option; import org.springframework.stereotype.Component; import java.util.Arrays; @@ -28,7 +27,7 @@ *

            */ @Component -public class CLI implements CommandMarker { +public class CLI { @Autowired private HazelcastInstance hazelcastInstance; @@ -59,12 +58,12 @@ public class CLI implements CommandMarker { * @param name Who to book the seat for * @return The seat booked */ - @CliCommand(value = "BOOK", - help = "BOOK A SEAT ON A FLIGHT") + @Command(command = "BOOK", + description = "BOOK A SEAT ON A FLIGHT") public String loading( - @CliOption(key = {"CODE"}, mandatory = true, help = "THE FLIGHT TO BOOK ONTO") + @Option(label = "CODE", required = true, description = "THE FLIGHT TO BOOK ONTO") String code, - @CliOption(key = {"NAME"}, mandatory = true, help = "WHO TO BOOK ONTO THE FLIGHT") + @Option(label = "NAME", required = true, description = "WHO TO BOOK ONTO THE FLIGHT") String name ) { IMap flightsMap = this.hazelcastInstance.getMap(Constants.IMAP_FLIGHTS); @@ -96,10 +95,10 @@ public String loading( * @param code The flight code, Date is hardcoded * @return Flight if found */ - @CliCommand(value = "GET", - help = "RETRIEVE A FLIGHT") + @Command(command = "GET", + description = "RETRIEVE A FLIGHT") public String get( - @CliOption(key = {"CODE"}, mandatory = true) String code + @Option(label = "CODE", required = true) String code ) { IMap flightsMap = this.hazelcastInstance.getMap(Constants.IMAP_FLIGHTS); @@ -119,12 +118,12 @@ public String get( *

            List the stored flights, keys are {@link java.lang.Comparable} so sort before printing. *

            */ - @CliCommand(value = "KEYS", - help = "DISPLAY THE STORED FLIGHTS") + @Command(command = "KEYS", + description = "DISPLAY THE STORED FLIGHTS") public String keys() { IMap flightsMap = this.hazelcastInstance.getMap(Constants.IMAP_FLIGHTS); - Set keys = flightsMap.keySet().stream().collect(Collectors.toCollection(TreeSet::new)); + Set keys = new TreeSet<>(flightsMap.keySet()); keys.forEach(key -> System.out.println(" -> " + key)); @@ -143,10 +142,10 @@ public String keys() { * @param code The flight code, Date is hardcoded * @return How many passengers */ - @CliCommand(value = "LOADING", - help = "HOW MANY SEATS ARE IN USE ON A FLIGHT") + @Command(command = "LOADING", + description = "HOW MANY SEATS ARE IN USE ON A FLIGHT") public String loading( - @CliOption(key = {"CODE"}, mandatory = true) String code + @Option(label = "CODE", required = true) String code ) { IMap flightsMap = this.hazelcastInstance.getMap(Constants.IMAP_FLIGHTS); @@ -168,8 +167,8 @@ public String loading( *

            Load test data into the cluster. *

            */ - @CliCommand(value = "TESTDATA", - help = "INJECT TEST DATA INTO THE CLUSTER") + @Command(command = "TESTDATA", + description = "INJECT TEST DATA INTO THE CLUSTER") public String testData() { IMap hazelcastMap = this.hazelcastInstance.getMap(Constants.IMAP_FLIGHTS); StringBuilder sb = new StringBuilder(); diff --git a/serialization/hazelcast-airlines/grid-node/src/main/resources/META-INF/spring/spring-shell-plugin.xml b/serialization/hazelcast-airlines/grid-node/src/main/resources/META-INF/spring/spring-shell-plugin.xml deleted file mode 100644 index 5f63df57d..000000000 --- a/serialization/hazelcast-airlines/grid-node/src/main/resources/META-INF/spring/spring-shell-plugin.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties b/serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties new file mode 100644 index 000000000..6c26325d6 --- /dev/null +++ b/serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties @@ -0,0 +1,4 @@ +logging.level.root=OFF +spring.main.banner-mode=off +spring.main.web-application-type=none +spring.shell.interactive.enabled=true \ No newline at end of file diff --git a/serialization/hazelcast-airlines/pom.xml b/serialization/hazelcast-airlines/pom.xml index 28200596d..5fff03e22 100644 --- a/serialization/hazelcast-airlines/pom.xml +++ b/serialization/hazelcast-airlines/pom.xml @@ -52,14 +52,27 @@ org.springframework.boot spring-boot-starter + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.platform + * + + + org.springframework.shell - spring-shell + spring-shell-dependencies ${spring-shell.version} + pom + import diff --git a/serialization/hazelcast-airlines/the-code/pom.xml b/serialization/hazelcast-airlines/the-code/pom.xml index a7781717e..84363723c 100644 --- a/serialization/hazelcast-airlines/the-code/pom.xml +++ b/serialization/hazelcast-airlines/the-code/pom.xml @@ -24,6 +24,12 @@ spring-boot-starter-test test + + org.junit.jupiter + junit-jupiter-api + 5.11.4 + test + diff --git a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/SeatReservationEntryProcessorTest.java b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/SeatReservationEntryProcessorTest.java index ca937a852..c1cde642f 100644 --- a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/SeatReservationEntryProcessorTest.java +++ b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/SeatReservationEntryProcessorTest.java @@ -8,7 +8,7 @@ import com.hazelcast.samples.serialization.hazelcast.airlines.util.FlightBuilder; import com.hazelcast.samples.serialization.hazelcast.airlines.util.MyDataSerializableFactory; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.AbstractMap.SimpleEntry; import java.util.Map.Entry; diff --git a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V1FlightTest.java b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V1FlightTest.java index fa07b8487..237010518 100644 --- a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V1FlightTest.java +++ b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V1FlightTest.java @@ -2,7 +2,7 @@ import com.hazelcast.samples.serialization.hazelcast.airlines.util.FlightBuilder; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V2FlightTest.java b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V2FlightTest.java index 4ac4145c5..f3e26dac5 100644 --- a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V2FlightTest.java +++ b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V2FlightTest.java @@ -2,7 +2,7 @@ import com.hazelcast.samples.serialization.hazelcast.airlines.util.FlightBuilder; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V3FlightTest.java b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V3FlightTest.java index 334f9bfc1..da0c64c1f 100644 --- a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V3FlightTest.java +++ b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V3FlightTest.java @@ -4,7 +4,7 @@ import com.hazelcast.internal.serialization.SerializationService; import com.hazelcast.samples.serialization.hazelcast.airlines.util.FlightBuilder; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.Arrays; diff --git a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V4FlightTest.java b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V4FlightTest.java index f58145c31..273b5c648 100644 --- a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V4FlightTest.java +++ b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V4FlightTest.java @@ -6,7 +6,7 @@ import com.hazelcast.samples.serialization.hazelcast.airlines.util.FlightBuilder; import com.hazelcast.samples.serialization.hazelcast.airlines.util.MyDataSerializableFactory; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.Arrays; diff --git a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V5FlightTest.java b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V5FlightTest.java index 54584a6a0..50e4388c1 100644 --- a/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V5FlightTest.java +++ b/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast/airlines/V5FlightTest.java @@ -6,7 +6,7 @@ import com.hazelcast.internal.serialization.SerializationService; import com.hazelcast.samples.serialization.hazelcast.airlines.util.FlightBuilder; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.Arrays; From 306baded8e6ab12c6ad87bc888eea5a14f21c10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Mon, 10 Feb 2025 18:17:01 +0100 Subject: [PATCH 07/16] Make the build pass --- .../sample/ClientCertCheckingLoginModuleTest.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/enterprise/tls-custom-login-module/src/test/java/sample/ClientCertCheckingLoginModuleTest.java b/enterprise/tls-custom-login-module/src/test/java/sample/ClientCertCheckingLoginModuleTest.java index 971bd6beb..c82f9a978 100644 --- a/enterprise/tls-custom-login-module/src/test/java/sample/ClientCertCheckingLoginModuleTest.java +++ b/enterprise/tls-custom-login-module/src/test/java/sample/ClientCertCheckingLoginModuleTest.java @@ -97,12 +97,13 @@ private Config createMemberConfig(String storeName, String memberRealmAllowedSan .setProperty("hazelcast.phone.home.enabled", "false"); JoinConfig joinConfig = config.getNetworkConfig().getJoin(); joinConfig.getTcpIpConfig().setEnabled(true).addMember("127.0.0.1"); - config.getNetworkConfig().setSSLConfig(new SSLConfig()).getSSLConfig().setEnabled(true) - .setProperty("mutualAuthentication", "REQUIRED") // - .setProperty("keyStore", "src/" + storeName + ".p12") // - .setProperty("keyStorePassword", "123456") // - .setProperty("trustStore", "src/ca.p12") // - .setProperty("trustStorePassword", "123456"); + SSLConfig sslConf = config.getNetworkConfig().setSSLConfig(new SSLConfig()).getSSLConfig(); + sslConf.setEnabled(true) + .setProperty("mutualAuthentication", "REQUIRED") // + .setProperty("keyStore", "src/" + storeName + ".p12") // + .setProperty("keyStorePassword", "123456") // + .setProperty("trustStore", "src/ca.p12") // + .setProperty("trustStorePassword", "123456"); SecurityConfig securityConfig = config.getSecurityConfig().setEnabled(true); securityConfig.setMemberRealmConfig("memberRealm", new RealmConfig().setJaasAuthenticationConfig(new JaasAuthenticationConfig().addLoginModuleConfig( From 675f407f56bfbab25b14089888b5227dca2fbffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Mon, 10 Feb 2025 19:01:25 +0100 Subject: [PATCH 08/16] Update serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties --- .../grid-node/src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties b/serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties index 6c26325d6..484e3a134 100644 --- a/serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties +++ b/serialization/hazelcast-airlines/grid-node/src/main/resources/application.properties @@ -1,4 +1,4 @@ logging.level.root=OFF spring.main.banner-mode=off spring.main.web-application-type=none -spring.shell.interactive.enabled=true \ No newline at end of file +spring.shell.interactive.enabled=true From 748cf94c124bd98c5179c4cbe0ab2a16d3978b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Tue, 11 Feb 2025 11:24:42 +0100 Subject: [PATCH 09/16] Use BOM --- pom.xml | 10 ++++++---- serialization/hazelcast-airlines/the-code/pom.xml | 6 ------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 45c8c099c..e221f5d1e 100644 --- a/pom.xml +++ b/pom.xml @@ -209,6 +209,12 @@ lombok ${lombok.version} + + org.junit + junit-bom + 5.11.4 + impo + @@ -216,25 +222,21 @@ org.junit.jupiter junit-jupiter-api - 5.11.4 test org.junit.vintage junit-vintage-engine - 5.11.4 test org.junit.jupiter junit-jupiter-engine - 5.11.4 test org.junit.platform junit-platform-commons - 1.11.4 test diff --git a/serialization/hazelcast-airlines/the-code/pom.xml b/serialization/hazelcast-airlines/the-code/pom.xml index 84363723c..a7781717e 100644 --- a/serialization/hazelcast-airlines/the-code/pom.xml +++ b/serialization/hazelcast-airlines/the-code/pom.xml @@ -24,12 +24,6 @@ spring-boot-starter-test test - - org.junit.jupiter - junit-jupiter-api - 5.11.4 - test - From 2e2d45e6bf50af0591250a4c7e46d951afb567d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Tue, 11 Feb 2025 11:35:04 +0100 Subject: [PATCH 10/16] Better code style --- .../hazelcast-airlines/grid-node/pom.xml | 1 - .../guide/controller/SessionController.java | 29 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/serialization/hazelcast-airlines/grid-node/pom.xml b/serialization/hazelcast-airlines/grid-node/pom.xml index 2822713de..6e0cee095 100644 --- a/serialization/hazelcast-airlines/grid-node/pom.xml +++ b/serialization/hazelcast-airlines/grid-node/pom.xml @@ -25,7 +25,6 @@ 0.1-SNAPSHOT - org.springframework.shell spring-shell-starter diff --git a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java index 6f5d24c40..c3df5bc9a 100644 --- a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java +++ b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java @@ -92,18 +92,27 @@ public String getSessionInfo(HttpServletRequest request) { } private String toHtmlTable(Map attributes) { - StringBuilder html = new StringBuilder(""); - html.append(""); - attributes.forEach((k, v) -> addHtmlTableRow(html, k, v)); - html.append("
            "); - return html.toString(); + String html = """ + + + + %s +
            + + + """; + StringBuilder rows = new StringBuilder(""); + attributes.forEach((k, v) -> rows.append(addHtmlTableRow(k, v))); + return html.formatted(rows); } - private void addHtmlTableRow(StringBuilder content, String key, Object value) { - content.append("") - .append("").append(key).append("") - .append("").append(value).append("") - .append(""); + private String addHtmlTableRow(String key, Object value) { + return """ + + %s + %s + + """.formatted(key, value); } } From 73b29fd5b458c03ee74c12ce2aced38e2feb4301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Tue, 11 Feb 2025 11:37:40 +0100 Subject: [PATCH 11/16] Line ending, remove old projects --- .../server/src/main/resources/application.properties | 2 +- spring/springboot-caching/README.md | 3 --- spring/springboot-http/README.md | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 spring/springboot-caching/README.md delete mode 100644 spring/springboot-http/README.md diff --git a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/application.properties b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/application.properties index 6c26325d6..484e3a134 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/application.properties +++ b/spring/spring-data-hazelcast-chemistry-sample/server/src/main/resources/application.properties @@ -1,4 +1,4 @@ logging.level.root=OFF spring.main.banner-mode=off spring.main.web-application-type=none -spring.shell.interactive.enabled=true \ No newline at end of file +spring.shell.interactive.enabled=true diff --git a/spring/springboot-caching/README.md b/spring/springboot-caching/README.md deleted file mode 100644 index 908efe371..000000000 --- a/spring/springboot-caching/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Caching with Spring Boot and Hazelcast - -Moved to https://github.com/hazelcast-guides/springboot-caching \ No newline at end of file diff --git a/spring/springboot-http/README.md b/spring/springboot-http/README.md deleted file mode 100644 index 16c2d3817..000000000 --- a/spring/springboot-http/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Spring Boot: Hazelcast for Session Replication - -Moved to https://github.com/hazelcast-guides/springboot-session-replication \ No newline at end of file From 47119bec6310a85f05eb78a7522f7e9f35c70dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Tue, 11 Feb 2025 12:10:52 +0100 Subject: [PATCH 12/16] Fix typo --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e221f5d1e..5957db1d0 100644 --- a/pom.xml +++ b/pom.xml @@ -213,7 +213,7 @@ org.junit junit-bom 5.11.4 - impo + import
            From c49b0649b7783422e0135dd10e1083bdc6da902a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Tue, 11 Feb 2025 12:13:49 +0100 Subject: [PATCH 13/16] Fix typo --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 5957db1d0..2a7333f85 100644 --- a/pom.xml +++ b/pom.xml @@ -214,6 +214,7 @@ junit-bom 5.11.4 import + pom From 2c0ccc985c6472d29c7e4b208fec8f12cf568b4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Tue, 11 Feb 2025 14:18:20 +0100 Subject: [PATCH 14/16] Update spring/spring-data-hazelcast-chemistry-sample/README.md Co-authored-by: Jack Green --- spring/spring-data-hazelcast-chemistry-sample/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/spring/spring-data-hazelcast-chemistry-sample/README.md b/spring/spring-data-hazelcast-chemistry-sample/README.md index 2fec57a80..828f78a28 100644 --- a/spring/spring-data-hazelcast-chemistry-sample/README.md +++ b/spring/spring-data-hazelcast-chemistry-sample/README.md @@ -100,6 +100,5 @@ Try `http://localhost:8080`, as this lists the other available URLs. Experiment with running the `load` and `unload` command on the server to populate and depopulate the test data, to see how the web page responses change. Really though this should be fairly obvious, it's how little coding is required that's the area to focus on. ## Potential improvements - ### Controller URLs For simplicity, on the `ClientController` module the landing page returns a list of the other URLs that the controller supports. Adding HATEOAS (_spring-hateoas_), Swagger or `@RepositoryRestController` would be simple steps to make this self-generate. From cc9a0caecbba266fe5423143524873dc3b50b60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Tue, 11 Feb 2025 14:21:08 +0100 Subject: [PATCH 15/16] Removed usage of StringBuilder --- .../com/hazelcast/guide/controller/SessionController.java | 5 +++-- .../hazelcast/guide/HazelcastSpringSessionApplicationIT.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java index c3df5bc9a..9ab29d2aa 100644 --- a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java +++ b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java @@ -101,8 +101,9 @@ private String toHtmlTable(Map attributes) { """; - StringBuilder rows = new StringBuilder(""); - attributes.forEach((k, v) -> rows.append(addHtmlTableRow(k, v))); + String rows = attributes.entrySet().stream() + .map(e -> addHtmlTableRow(e.getKey(), e.getValue())) + .collect(Collectors.joining("\n")); return html.formatted(rows); } diff --git a/spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationIT.java b/spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationIT.java index c0478edbd..9bb6381be 100644 --- a/spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationIT.java +++ b/spring/spring-boot-session-replication-spring-session-hazelcast/src/test/java/com/hazelcast/guide/HazelcastSpringSessionApplicationIT.java @@ -31,9 +31,9 @@ class HazelcastSpringSessionApplicationIT { void contextLoads() { // given String port1 = startApplication(); - System.out.println("Started 1st on port: " + port1); + logger.info("Started 1st on port: {}", port1); String port2 = startApplication(); - System.out.println("Started 2nd on port: " + port2); + logger.info("Started 2nd on port: {}", port2); Map principalMap = Collections.singletonMap("principal", "hazelcast2020"); waitForCluster(port1); From c9be7c233a727e8d686e70e2974d798142a5b2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gaw=C4=99da?= Date: Tue, 11 Feb 2025 17:00:40 +0100 Subject: [PATCH 16/16] Update spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java Co-authored-by: Jack Green --- .../java/com/hazelcast/guide/controller/SessionController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java index 9ab29d2aa..2c985e8a6 100644 --- a/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java +++ b/spring/spring-boot-session-replication-spring-session-hazelcast/src/main/java/com/hazelcast/guide/controller/SessionController.java @@ -103,7 +103,7 @@ private String toHtmlTable(Map attributes) { """; String rows = attributes.entrySet().stream() .map(e -> addHtmlTableRow(e.getKey(), e.getValue())) - .collect(Collectors.joining("\n")); + .collect(Collectors.joining("%n")); return html.formatted(rows); }