Commit 82e18ae8 authored by Rafal Leszko's avatar Rafal Leszko Committed by Stephane Nicoll

Add support for Hazelcast YAML configuration

Since Hazlecast 3.12, YAML configuration format is supported in
addition to XML. Therefore, this change makes Spring Boot automatically
discover not only `hazelcast.xml` (and `hazelcast-client.xml`), but also
`hazelcast.yaml` (and `hazelcast-client.yaml`).

See gh-16632
parent b527d364
......@@ -79,7 +79,8 @@ class HazelcastClientConfiguration {
ConfigAvailableCondition() {
super(CONFIG_SYSTEM_PROPERTY, "file:./hazelcast-client.xml",
"classpath:/hazelcast-client.xml");
"classpath:/hazelcast-client.xml", "file:./hazelcast-client.yaml",
"classpath:/hazelcast-client.yaml");
}
}
......
......@@ -22,6 +22,7 @@ import java.net.URL;
import com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.config.XmlClientConfigBuilder;
import com.hazelcast.client.config.YamlClientConfigBuilder;
import com.hazelcast.core.HazelcastInstance;
import org.springframework.core.io.Resource;
......@@ -59,7 +60,14 @@ public class HazelcastClientFactory {
private ClientConfig getClientConfig(Resource clientConfigLocation)
throws IOException {
URL configUrl = clientConfigLocation.getURL();
return new XmlClientConfigBuilder(configUrl).build();
String configFileName = configUrl.getFile();
if (configFileName.endsWith(".xml")) {
return new XmlClientConfigBuilder(configUrl).build();
}
else {
return new YamlClientConfigBuilder(configUrl).build();
}
}
/**
......
......@@ -21,6 +21,7 @@ import java.net.URL;
import com.hazelcast.config.Config;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.config.YamlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
......@@ -61,7 +62,7 @@ public class HazelcastInstanceFactory {
private Config getConfig(Resource configLocation) throws IOException {
URL configUrl = configLocation.getURL();
Config config = new XmlConfigBuilder(configUrl).build();
Config config = createConfig(configUrl);
if (ResourceUtils.isFileURL(configUrl)) {
config.setConfigurationFile(configLocation.getFile());
}
......@@ -71,6 +72,14 @@ public class HazelcastInstanceFactory {
return config;
}
private static Config createConfig(URL configUrl) throws IOException {
String configFileName = configUrl.getFile();
if (configFileName.endsWith(".xml")) {
return new XmlConfigBuilder(configUrl).build();
}
return new YamlConfigBuilder(configUrl).build();
}
/**
* Get the {@link HazelcastInstance}.
* @return the {@link HazelcastInstance}
......
......@@ -77,7 +77,8 @@ class HazelcastServerConfiguration {
ConfigAvailableCondition() {
super(CONFIG_SYSTEM_PROPERTY, "file:./hazelcast.xml",
"classpath:/hazelcast.xml");
"classpath:/hazelcast.xml", "file:./hazelcast.yaml",
"classpath:/hazelcast.yaml");
}
}
......
......@@ -28,6 +28,7 @@ import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......@@ -63,35 +64,58 @@ public class HazelcastAutoConfigurationClientTests {
.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class));
@Test
public void systemProperty() {
this.contextRunner
.withSystemProperties(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-client-specific.xml")
.run((context) -> assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastInstance.class)
.has(nameStartingWith("hz.client_")));
public void systemPropertyWithXml() {
systemProperty(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-client-specific.xml");
}
@Test
public void explicitConfigFile() {
this.contextRunner
.withPropertyValues(
"spring.hazelcast.config=org/springframework/boot/autoconfigure/"
+ "hazelcast/hazelcast-client-specific.xml")
.run((context) -> assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastClientProxy.class)
.has(nameStartingWith("hz.client_")));
public void systemPropertyWithYaml() {
systemProperty(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-client-specific.yaml");
}
private void systemProperty(String systemProperty) {
this.contextRunner.withSystemProperties(systemProperty)
.run((context) -> assertHazelcastClientSpecific(context));
}
@Test
public void explicitConfigUrl() {
this.contextRunner
.withPropertyValues(
"spring.hazelcast.config=hazelcast-client-default.xml")
.run((context) -> assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastClientProxy.class)
.has(nameStartingWith("hz.client_")));
public void explicitConfigFileWithXml() {
propertyValues("spring.hazelcast.config=org/springframework/boot/autoconfigure/"
+ "hazelcast/hazelcast-client-specific.xml");
}
@Test
public void explicitConfigFileWithYaml() {
propertyValues("spring.hazelcast.config=org/springframework/boot/autoconfigure/"
+ "hazelcast/hazelcast-client-specific.yaml");
}
@Test
public void explicitConfigUrlWithXml() {
propertyValues("spring.hazelcast.config=classpath:org/springframework/"
+ "boot/autoconfigure/hazelcast/hazelcast-client-specific.xml");
}
@Test
public void explicitConfigUrlWithYaml() {
propertyValues("spring.hazelcast.config=classpath:org/springframework/"
+ "boot/autoconfigure/hazelcast/hazelcast-client-specific.yaml");
}
private void propertyValues(String propertyValues) {
this.contextRunner.withPropertyValues(propertyValues)
.run((context) -> assertHazelcastClientSpecific(context));
}
private static void assertHazelcastClientSpecific(
AssertableApplicationContext context) {
assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastInstance.class)
.has(labelEqualTo("configured-client"));
}
@Test
......@@ -111,9 +135,10 @@ public class HazelcastAutoConfigurationClientTests {
.isInstanceOf(HazelcastClientProxy.class));
}
private Condition<HazelcastInstance> nameStartingWith(String prefix) {
return new Condition<>((o) -> o.getName().startsWith(prefix),
"Name starts with " + prefix);
private static Condition<HazelcastInstance> labelEqualTo(String label) {
return new Condition<>((o) -> ((HazelcastClientProxy) o).getClientConfig()
.getLabels().stream().anyMatch((e) -> e.equals(label)),
"Label equals to " + label);
}
@Configuration(proxyBeanMethods = false)
......
......@@ -27,6 +27,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner;
......@@ -59,39 +60,56 @@ public class HazelcastAutoConfigurationServerTests {
}
@Test
public void systemProperty() {
this.contextRunner
.withSystemProperties(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml")
.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getQueueConfigs().keySet()).containsOnly("foobar");
});
public void systemPropertyWithXml() {
systemProperty(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml");
}
@Test
public void systemPropertyWithYaml() {
systemProperty(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml");
}
private void systemProperty(String systemProperties) {
this.contextRunner.withSystemProperties(systemProperties)
.run((context) -> assertHazelcastSpecific(context));
}
@Test
public void explicitConfigFile() {
this.contextRunner.withPropertyValues(
public void explicitConfigFileWithXml() {
propertyValues(
"spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-specific.xml")
.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getConfigurationFile())
.isEqualTo(new ClassPathResource(
"org/springframework/boot/autoconfigure/hazelcast"
+ "/hazelcast-specific.xml").getFile());
});
+ "hazelcast-specific.xml");
}
@Test
public void explicitConfigUrl() {
this.contextRunner
.withPropertyValues("spring.hazelcast.config=hazelcast-default.xml")
.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getConfigurationUrl()).isEqualTo(
new ClassPathResource("hazelcast-default.xml").getURL());
});
public void explicitConfigFileWithYaml() {
propertyValues(
"spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-specific.yaml");
}
@Test
public void explicitConfigUrlWithXml() {
propertyValues("spring.hazelcast.config=classpath:org/springframework/"
+ "boot/autoconfigure/hazelcast/hazelcast-specific.xml");
}
@Test
public void explicitConfigUrlWithYaml() {
propertyValues("spring.hazelcast.config=classpath:org/springframework/"
+ "boot/autoconfigure/hazelcast/hazelcast-specific.yaml");
}
private void propertyValues(String propertyValues) {
this.contextRunner.withPropertyValues(propertyValues)
.run((context) -> assertHazelcastSpecific(context));
}
private static void assertHazelcastSpecific(AssertableApplicationContext context) {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getMapConfigs().keySet()).containsOnly("foobar");
}
@Test
......
......@@ -39,6 +39,8 @@ public class HazelcastAutoConfigurationTests {
@Test
public void defaultConfigFile() {
// no hazelcast-client.xml and hazelcast.xml is present in root classpath
// this also asserts that XML has priority over YAML
// as both hazelcast.yaml and hazelcast.xml in test classpath.
this.contextRunner.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getConfigurationUrl())
......
......@@ -2,5 +2,8 @@
<hazelcast-client xmlns="http://www.hazelcast.com/schema/client-config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/client-config hazelcast-client-config-3.12.xsd">
<client-labels>
<label>configured-client</label>
</client-labels>
</hazelcast-client>
hazelcast:
network:
join:
multicast:
enabled: false
map:
foobar:
time-to-live-seconds: 3600
max-idle-seconds: 600
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment