23 changed files with 756 additions and 35 deletions
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.autoconfigure.hazelcast; |
||||
|
||||
import com.hazelcast.client.HazelcastClient; |
||||
import com.hazelcast.client.config.ClientConfig; |
||||
import com.hazelcast.core.HazelcastInstance; |
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Configuration for Hazelcast client instance. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
@Configuration(proxyBeanMethods = false) |
||||
@ConditionalOnBean(HazelcastConnectionDetails.class) |
||||
class HazelcastClientInstanceConfiguration { |
||||
|
||||
@Bean |
||||
HazelcastInstance hazelcastInstance(HazelcastConnectionDetails hazelcastConnectionDetails) { |
||||
ClientConfig config = hazelcastConnectionDetails.getClientConfig(); |
||||
if (StringUtils.hasText(config.getInstanceName())) { |
||||
return HazelcastClient.getOrCreateHazelcastClient(config); |
||||
} |
||||
return HazelcastClient.newHazelcastClient(config); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.autoconfigure.hazelcast; |
||||
|
||||
import com.hazelcast.client.config.ClientConfig; |
||||
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; |
||||
|
||||
/** |
||||
* Details required to establish a client connection to a Hazelcast instance. |
||||
* |
||||
* @author Dmytro Nosan |
||||
* @since 3.4.0 |
||||
*/ |
||||
public interface HazelcastConnectionDetails extends ConnectionDetails { |
||||
|
||||
/** |
||||
* The {@link ClientConfig} for Hazelcast client. |
||||
* @return the client config |
||||
*/ |
||||
ClientConfig getClientConfig(); |
||||
|
||||
} |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.autoconfigure.hazelcast; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.UncheckedIOException; |
||||
import java.net.URL; |
||||
|
||||
import com.hazelcast.client.config.ClientConfig; |
||||
import com.hazelcast.client.config.XmlClientConfigBuilder; |
||||
import com.hazelcast.client.config.YamlClientConfigBuilder; |
||||
|
||||
import org.springframework.core.io.Resource; |
||||
import org.springframework.core.io.ResourceLoader; |
||||
|
||||
/** |
||||
* Adapts {@link HazelcastProperties} to {@link HazelcastConnectionDetails}. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
class PropertiesHazelcastConnectionDetails implements HazelcastConnectionDetails { |
||||
|
||||
private final HazelcastProperties properties; |
||||
|
||||
private final ResourceLoader resourceLoader; |
||||
|
||||
PropertiesHazelcastConnectionDetails(HazelcastProperties properties, ResourceLoader resourceLoader) { |
||||
this.properties = properties; |
||||
this.resourceLoader = resourceLoader; |
||||
} |
||||
|
||||
@Override |
||||
public ClientConfig getClientConfig() { |
||||
Resource configLocation = this.properties.resolveConfigLocation(); |
||||
ClientConfig config = (configLocation != null) ? loadClientConfig(configLocation) : ClientConfig.load(); |
||||
config.setClassLoader(this.resourceLoader.getClassLoader()); |
||||
return config; |
||||
} |
||||
|
||||
private ClientConfig loadClientConfig(Resource configLocation) { |
||||
try { |
||||
URL configUrl = configLocation.getURL(); |
||||
String configFileName = configUrl.getPath(); |
||||
if (configFileName.endsWith(".yaml") || configFileName.endsWith(".yml")) { |
||||
return new YamlClientConfigBuilder(configUrl).build(); |
||||
} |
||||
return new XmlClientConfigBuilder(configUrl).build(); |
||||
} |
||||
catch (IOException ex) { |
||||
throw new UncheckedIOException("Failed to load Hazelcast config", ex); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.docker.compose.service.connection.hazelcast; |
||||
|
||||
import java.util.UUID; |
||||
|
||||
import com.hazelcast.client.HazelcastClient; |
||||
import com.hazelcast.client.config.ClientConfig; |
||||
import com.hazelcast.config.Config; |
||||
import com.hazelcast.core.HazelcastInstance; |
||||
import com.hazelcast.map.IMap; |
||||
|
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; |
||||
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; |
||||
import org.springframework.boot.testsupport.container.TestImage; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Integration tests for {@link HazelcastDockerComposeConnectionDetailsFactory}. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
class HazelcastDockerComposeConnectionDetailsFactoryIntegrationTests { |
||||
|
||||
@DockerComposeTest(composeFile = "hazelcast-compose.yaml", image = TestImage.HAZELCAST) |
||||
void runCreatesConnectionDetails(HazelcastConnectionDetails connectionDetails) { |
||||
ClientConfig config = connectionDetails.getClientConfig(); |
||||
assertThat(config.getClusterName()).isEqualTo(Config.DEFAULT_CLUSTER_NAME); |
||||
verifyConnection(config); |
||||
} |
||||
|
||||
@DockerComposeTest(composeFile = "hazelcast-cluster-name-compose.yaml", image = TestImage.HAZELCAST) |
||||
void runCreatesConnectionDetailsCustomClusterName(HazelcastConnectionDetails connectionDetails) { |
||||
ClientConfig config = connectionDetails.getClientConfig(); |
||||
assertThat(config.getClusterName()).isEqualTo("spring-boot"); |
||||
verifyConnection(config); |
||||
} |
||||
|
||||
private static void verifyConnection(ClientConfig config) { |
||||
HazelcastInstance hazelcastInstance = HazelcastClient.newHazelcastClient(config); |
||||
try { |
||||
IMap<String, String> map = hazelcastInstance.getMap(UUID.randomUUID().toString()); |
||||
map.put("docker", "compose"); |
||||
assertThat(map.get("docker")).isEqualTo("compose"); |
||||
} |
||||
finally { |
||||
hazelcastInstance.shutdown(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
services: |
||||
hazelcast: |
||||
image: '{imageName}' |
||||
environment: |
||||
HZ_CLUSTERNAME: "spring-boot" |
||||
ports: |
||||
- '5701' |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
services: |
||||
hazelcast: |
||||
image: '{imageName}' |
||||
ports: |
||||
- '5701' |
||||
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.docker.compose.service.connection.hazelcast; |
||||
|
||||
import com.hazelcast.client.config.ClientConfig; |
||||
|
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; |
||||
import org.springframework.boot.docker.compose.core.RunningService; |
||||
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; |
||||
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; |
||||
|
||||
/** |
||||
* {@link DockerComposeConnectionDetailsFactory} to create |
||||
* {@link HazelcastConnectionDetails} for a {@code hazelcast} service. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
class HazelcastDockerComposeConnectionDetailsFactory |
||||
extends DockerComposeConnectionDetailsFactory<HazelcastConnectionDetails> { |
||||
|
||||
private static final int DEFAULT_PORT = 5701; |
||||
|
||||
protected HazelcastDockerComposeConnectionDetailsFactory() { |
||||
super("hazelcast/hazelcast", "com.hazelcast.client.config.ClientConfig"); |
||||
} |
||||
|
||||
@Override |
||||
protected HazelcastConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) { |
||||
return new HazelcastDockerComposeConnectionDetails(source.getRunningService()); |
||||
} |
||||
|
||||
/** |
||||
* {@link HazelcastConnectionDetails} backed by a {@code hazelcast} |
||||
* {@link RunningService}. |
||||
*/ |
||||
static class HazelcastDockerComposeConnectionDetails extends DockerComposeConnectionDetails |
||||
implements HazelcastConnectionDetails { |
||||
|
||||
private final String host; |
||||
|
||||
private final int port; |
||||
|
||||
private final HazelcastEnvironment environment; |
||||
|
||||
HazelcastDockerComposeConnectionDetails(RunningService service) { |
||||
super(service); |
||||
this.host = service.host(); |
||||
this.port = service.ports().get(DEFAULT_PORT); |
||||
this.environment = new HazelcastEnvironment(service.env()); |
||||
} |
||||
|
||||
@Override |
||||
public ClientConfig getClientConfig() { |
||||
ClientConfig config = new ClientConfig(); |
||||
this.environment.getClusterName().ifPresent(config::setClusterName); |
||||
config.getNetworkConfig().addAddress(this.host + ":" + this.port); |
||||
return config; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.docker.compose.service.connection.hazelcast; |
||||
|
||||
import java.util.Map; |
||||
import java.util.Optional; |
||||
|
||||
/** |
||||
* Hazelcast environment details. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
class HazelcastEnvironment { |
||||
|
||||
private final String clusterName; |
||||
|
||||
HazelcastEnvironment(Map<String, String> env) { |
||||
this.clusterName = env.get("HZ_CLUSTERNAME"); |
||||
} |
||||
|
||||
Optional<String> getClusterName() { |
||||
return Optional.ofNullable(this.clusterName); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
/** |
||||
* Auto-configuration for Docker Compose Hazelcast service connections. |
||||
*/ |
||||
package org.springframework.boot.docker.compose.service.connection.hazelcast; |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.docker.compose.service.connection.hazelcast; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link HazelcastEnvironment}. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
class HazelcastEnvironmentTests { |
||||
|
||||
@Test |
||||
void getClusterNameWhenHasNoHzClusterNameSet() { |
||||
HazelcastEnvironment environment = new HazelcastEnvironment(Collections.emptyMap()); |
||||
assertThat(environment.getClusterName()).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
void getClusterNameWhenHzClusterNameSet() { |
||||
HazelcastEnvironment environment = new HazelcastEnvironment(Map.of("HZ_CLUSTERNAME", "spring-boot")); |
||||
assertThat(environment.getClusterName()).isNotEmpty().hasValue("spring-boot"); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.testcontainers.service.connection.hazelcast; |
||||
|
||||
import java.util.UUID; |
||||
import java.util.function.Consumer; |
||||
|
||||
import com.hazelcast.client.config.ClientConfig; |
||||
import com.hazelcast.client.impl.clientside.HazelcastClientProxy; |
||||
import com.hazelcast.core.HazelcastInstance; |
||||
import com.hazelcast.map.IMap; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.testcontainers.junit.jupiter.Container; |
||||
import org.testcontainers.junit.jupiter.Testcontainers; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; |
||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection; |
||||
import org.springframework.boot.testsupport.container.HazelcastContainer; |
||||
import org.springframework.boot.testsupport.container.TestImage; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link HazelcastContainerConnectionDetailsFactory} with a custom hazelcast |
||||
* cluster name. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
@SpringJUnitConfig |
||||
@Testcontainers(disabledWithoutDocker = true) |
||||
class CustomClusterNameHazelcastContainerConnectionDetailsFactoryIntegrationTests { |
||||
|
||||
@Container |
||||
@ServiceConnection |
||||
static final HazelcastContainer hazelcast = TestImage.container(HazelcastContainer.class) |
||||
.withEnv("HZ_CLUSTERNAME", "spring-boot"); |
||||
|
||||
@Autowired(required = false) |
||||
private HazelcastConnectionDetails connectionDetails; |
||||
|
||||
@Autowired |
||||
private HazelcastInstance hazelcastInstance; |
||||
|
||||
@Test |
||||
void connectionCanBeMadeToHazelcastContainer() { |
||||
assertThat(this.connectionDetails).isNotNull(); |
||||
assertThat(this.hazelcastInstance).satisfies(clusterName("spring-boot")); |
||||
IMap<String, String> map = this.hazelcastInstance.getMap(UUID.randomUUID().toString()); |
||||
map.put("test", "containers"); |
||||
assertThat(map.get("test")).isEqualTo("containers"); |
||||
} |
||||
|
||||
private static Consumer<HazelcastInstance> clusterName(String name) { |
||||
return (hazelcastInstance) -> { |
||||
assertThat(hazelcastInstance).isInstanceOf(HazelcastClientProxy.class); |
||||
HazelcastClientProxy proxy = (HazelcastClientProxy) hazelcastInstance; |
||||
assertThat(proxy.getClientConfig()).extracting(ClientConfig::getClusterName).isEqualTo(name); |
||||
}; |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@ImportAutoConfiguration(HazelcastAutoConfiguration.class) |
||||
static class TestConfiguration { |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.testcontainers.service.connection.hazelcast; |
||||
|
||||
import java.util.UUID; |
||||
|
||||
import com.hazelcast.core.HazelcastInstance; |
||||
import com.hazelcast.map.IMap; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.testcontainers.junit.jupiter.Container; |
||||
import org.testcontainers.junit.jupiter.Testcontainers; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; |
||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection; |
||||
import org.springframework.boot.testsupport.container.HazelcastContainer; |
||||
import org.springframework.boot.testsupport.container.TestImage; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link HazelcastContainerConnectionDetailsFactory}. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
@SpringJUnitConfig |
||||
@Testcontainers(disabledWithoutDocker = true) |
||||
class HazelcastContainerConnectionDetailsFactoryIntegrationTests { |
||||
|
||||
@Container |
||||
@ServiceConnection |
||||
static final HazelcastContainer hazelcast = TestImage.container(HazelcastContainer.class); |
||||
|
||||
@Autowired(required = false) |
||||
private HazelcastConnectionDetails connectionDetails; |
||||
|
||||
@Autowired |
||||
private HazelcastInstance hazelcastInstance; |
||||
|
||||
@Test |
||||
void connectionCanBeMadeToHazelcastContainer() { |
||||
assertThat(this.connectionDetails).isNotNull(); |
||||
IMap<String, String> map = this.hazelcastInstance.getMap(UUID.randomUUID().toString()); |
||||
map.put("test", "containers"); |
||||
assertThat(map.get("test")).isEqualTo("containers"); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@ImportAutoConfiguration(HazelcastAutoConfiguration.class) |
||||
static class TestConfiguration { |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.testcontainers.service.connection.hazelcast; |
||||
|
||||
import java.util.Map; |
||||
import java.util.Optional; |
||||
|
||||
import com.hazelcast.client.config.ClientConfig; |
||||
import org.testcontainers.containers.Container; |
||||
import org.testcontainers.containers.GenericContainer; |
||||
|
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; |
||||
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; |
||||
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; |
||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection; |
||||
|
||||
/** |
||||
* {@link ContainerConnectionDetailsFactory} to create {@link HazelcastConnectionDetails} |
||||
* from a {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer} |
||||
* using the {@code "hazelcast/hazelcast"} image. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
class HazelcastContainerConnectionDetailsFactory |
||||
extends ContainerConnectionDetailsFactory<Container<?>, HazelcastConnectionDetails> { |
||||
|
||||
private static final int DEFAULT_PORT = 5701; |
||||
|
||||
private static final String CLUSTER_NAME_ENV = "HZ_CLUSTERNAME"; |
||||
|
||||
HazelcastContainerConnectionDetailsFactory() { |
||||
super("hazelcast/hazelcast", "com.hazelcast.client.config.ClientConfig"); |
||||
} |
||||
|
||||
@Override |
||||
protected HazelcastConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) { |
||||
return new HazelcastContainerConnectionDetails(source); |
||||
} |
||||
|
||||
/** |
||||
* {@link HazelcastConnectionDetails} backed by a {@link ContainerConnectionSource}. |
||||
*/ |
||||
private static final class HazelcastContainerConnectionDetails extends ContainerConnectionDetails<Container<?>> |
||||
implements HazelcastConnectionDetails { |
||||
|
||||
private HazelcastContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) { |
||||
super(source); |
||||
} |
||||
|
||||
@Override |
||||
public ClientConfig getClientConfig() { |
||||
ClientConfig config = new ClientConfig(); |
||||
Container<?> container = getContainer(); |
||||
Map<String, String> env = container.getEnvMap(); |
||||
Optional.ofNullable(env.get(CLUSTER_NAME_ENV)).ifPresent(config::setClusterName); |
||||
config.getNetworkConfig().addAddress(container.getHost() + ":" + container.getMappedPort(DEFAULT_PORT)); |
||||
return config; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
/** |
||||
* Support for testcontainers Hazelcast service connections. |
||||
*/ |
||||
package org.springframework.boot.testcontainers.service.connection.hazelcast; |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.testsupport.container; |
||||
|
||||
import org.testcontainers.containers.GenericContainer; |
||||
import org.testcontainers.utility.DockerImageName; |
||||
|
||||
/** |
||||
* A {@link GenericContainer} for Hazelcast. |
||||
* |
||||
* @author Dmytro Nosan |
||||
*/ |
||||
public final class HazelcastContainer extends GenericContainer<HazelcastContainer> { |
||||
|
||||
private static final int DEFAULT_PORT = 5701; |
||||
|
||||
public HazelcastContainer(DockerImageName dockerImageName) { |
||||
super(dockerImageName); |
||||
addExposedPorts(DEFAULT_PORT); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue