diff --git a/spring/pom.xml b/spring/pom.xml index 2f4af3bcc..371df8c69 100644 --- a/spring/pom.xml +++ b/spring/pom.xml @@ -37,6 +37,7 @@ + spring-boot-embedded spring-boot-caching-hazelcast-cache-manager spring-configuration spring-data-hazelcast-chemistry-sample diff --git a/spring/spring-boot-embedded/README.adoc b/spring/spring-boot-embedded/README.adoc new file mode 100755 index 000000000..2ed866b50 --- /dev/null +++ b/spring/spring-boot-embedded/README.adoc @@ -0,0 +1 @@ +See the link:https://docs.hazelcast.com/tutorials/hazelcast-embedded-springboot[tutorial]. diff --git a/spring/spring-boot-embedded/pom.xml b/spring/spring-boot-embedded/pom.xml new file mode 100755 index 000000000..8f274bcc2 --- /dev/null +++ b/spring/spring-boot-embedded/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.0 + + + + com.hazelcast.samples + spring-boot-hazelcast-embedded + 0.1-SNAPSHOT + Spring Boot with Hazelcast Embedded + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.hazelcast + hazelcast-spring + 5.5.0 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-webflux + test + + + + + + + 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 new file mode 100755 index 000000000..7c7b33f3c --- /dev/null +++ b/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/CommandController.java @@ -0,0 +1,31 @@ +package guides.hazelcast.springboot; + +import com.hazelcast.map.IMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import static java.util.Objects.requireNonNull; + +@RestController +public class CommandController { + + private final IMap keyValueMap; + + public CommandController(IMap keyValueMap) { + this.keyValueMap = requireNonNull(keyValueMap); + } + + @PostMapping("/put") + public CommandResponse put(@RequestParam(value = "key") String key, @RequestParam(value = "value") String value) { + keyValueMap.put(key, value); + return new CommandResponse(value); + } + + @GetMapping("/get") + public CommandResponse get(@RequestParam(value = "key") String key) { + String value = keyValueMap.get(key); + return new CommandResponse(value); + } +} diff --git a/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/CommandResponse.java b/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/CommandResponse.java new file mode 100755 index 000000000..731f648d8 --- /dev/null +++ b/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/CommandResponse.java @@ -0,0 +1,4 @@ +package guides.hazelcast.springboot; + +public record CommandResponse(String value) { +} 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 new file mode 100755 index 000000000..ab4af11d9 --- /dev/null +++ b/spring/spring-boot-embedded/src/main/java/guides/hazelcast/springboot/HazelcastApplication.java @@ -0,0 +1,21 @@ +package guides.hazelcast.springboot; + +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.map.IMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class HazelcastApplication { + + public static void main(String[] args) { + SpringApplication.run(HazelcastApplication.class, args); + } + + @Bean + public IMap keyValueMap(@Autowired HazelcastInstance hazelcast) { + return hazelcast.getMap("keyValueMap"); + } +} diff --git a/spring/spring-boot-embedded/src/main/resources/hazelcast.yaml b/spring/spring-boot-embedded/src/main/resources/hazelcast.yaml new file mode 100755 index 000000000..6064ac32a --- /dev/null +++ b/spring/spring-boot-embedded/src/main/resources/hazelcast.yaml @@ -0,0 +1,2 @@ +hazelcast: + cluster-name: hazelcast-cluster 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/CommandControllerTest.java new file mode 100755 index 000000000..04e9d2d1f --- /dev/null +++ b/spring/spring-boot-embedded/src/test/java/guides/hazelcast/springboot/CommandControllerTest.java @@ -0,0 +1,83 @@ +package guides.hazelcast.springboot; + +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.reactive.server.WebTestClient; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +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 { + + @Autowired + private WebTestClient webTestClient; + + @Autowired + private HazelcastInstance hazelcastInstance; + + @Autowired + private Map keyValueMap; + + @Test + public void testPutRequest() { + //when + WebTestClient.ResponseSpec responseSpec = makePutRequest("key1", "value1"); + + //then + responseSpec.expectStatus() + .is2xxSuccessful() + .expectHeader() + .contentType(APPLICATION_JSON) + .expectBody() + .jsonPath("$.value").isEqualTo("value1"); + + assertThat(keyValueMap).containsEntry("key1", "value1"); + } + + @Test + public void testGetRequest() { + //given + makePutRequest("key1", "value1"); + + //when + WebTestClient.ResponseSpec responseSpec = webTestClient + .get() + .uri("/get?key={key}", "key1") + .header(ACCEPT, APPLICATION_JSON_VALUE) + .exchange(); + + //then + responseSpec.expectStatus() + .is2xxSuccessful() + .expectHeader() + .contentType(APPLICATION_JSON) + .expectBody() + .jsonPath("$.value").isEqualTo("value1"); + } + + private WebTestClient.ResponseSpec makePutRequest(Object... parameters) { + return webTestClient + .post() + .uri("/put?key={key}&value={value}", parameters) + .header(ACCEPT, APPLICATION_JSON_VALUE) + .exchange(); + } + + @Test + public void testHazelcastCluster() { + //given + Hazelcast.newHazelcastInstance(); + + //then + assertThat(hazelcastInstance.getCluster().getMembers()) + .hasSize(2); + } +} diff --git a/spring/spring-boot-embedded/src/test/resources/hazelcast.yaml b/spring/spring-boot-embedded/src/test/resources/hazelcast.yaml new file mode 100755 index 000000000..34ee5060d --- /dev/null +++ b/spring/spring-boot-embedded/src/test/resources/hazelcast.yaml @@ -0,0 +1,6 @@ +hazelcast: + cluster-name: hazelcast-cluster + network: + join: + multicast: + enabled: true