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
pull/16684/head
Rafal Leszko 6 years ago committed by Stephane Nicoll
parent b527d364dc
commit 82e18ae88f

@ -79,7 +79,8 @@ class HazelcastClientConfiguration {
ConfigAvailableCondition() { ConfigAvailableCondition() {
super(CONFIG_SYSTEM_PROPERTY, "file:./hazelcast-client.xml", 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.HazelcastClient;
import com.hazelcast.client.config.ClientConfig; import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.config.XmlClientConfigBuilder; import com.hazelcast.client.config.XmlClientConfigBuilder;
import com.hazelcast.client.config.YamlClientConfigBuilder;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
@ -59,8 +60,15 @@ public class HazelcastClientFactory {
private ClientConfig getClientConfig(Resource clientConfigLocation) private ClientConfig getClientConfig(Resource clientConfigLocation)
throws IOException { throws IOException {
URL configUrl = clientConfigLocation.getURL(); URL configUrl = clientConfigLocation.getURL();
String configFileName = configUrl.getFile();
if (configFileName.endsWith(".xml")) {
return new XmlClientConfigBuilder(configUrl).build(); return new XmlClientConfigBuilder(configUrl).build();
} }
else {
return new YamlClientConfigBuilder(configUrl).build();
}
}
/** /**
* Get the {@link HazelcastInstance}. * Get the {@link HazelcastInstance}.

@ -21,6 +21,7 @@ import java.net.URL;
import com.hazelcast.config.Config; import com.hazelcast.config.Config;
import com.hazelcast.config.XmlConfigBuilder; import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.config.YamlConfigBuilder;
import com.hazelcast.core.Hazelcast; import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
@ -61,7 +62,7 @@ public class HazelcastInstanceFactory {
private Config getConfig(Resource configLocation) throws IOException { private Config getConfig(Resource configLocation) throws IOException {
URL configUrl = configLocation.getURL(); URL configUrl = configLocation.getURL();
Config config = new XmlConfigBuilder(configUrl).build(); Config config = createConfig(configUrl);
if (ResourceUtils.isFileURL(configUrl)) { if (ResourceUtils.isFileURL(configUrl)) {
config.setConfigurationFile(configLocation.getFile()); config.setConfigurationFile(configLocation.getFile());
} }
@ -71,6 +72,14 @@ public class HazelcastInstanceFactory {
return config; 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}. * Get the {@link HazelcastInstance}.
* @return the {@link HazelcastInstance} * @return the {@link HazelcastInstance}

@ -77,7 +77,8 @@ class HazelcastServerConfiguration {
ConfigAvailableCondition() { ConfigAvailableCondition() {
super(CONFIG_SYSTEM_PROPERTY, "file:./hazelcast.xml", 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.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.AutoConfigurations; 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.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -63,35 +64,58 @@ public class HazelcastAutoConfigurationClientTests {
.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class)); .withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class));
@Test @Test
public void systemProperty() { public void systemPropertyWithXml() {
this.contextRunner systemProperty(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY
.withSystemProperties(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/" + "=classpath:org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-client-specific.xml") + "hazelcast-client-specific.xml");
.run((context) -> assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastInstance.class)
.has(nameStartingWith("hz.client_")));
} }
@Test @Test
public void explicitConfigFile() { public void systemPropertyWithYaml() {
this.contextRunner systemProperty(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY
.withPropertyValues( + "=classpath:org/springframework/boot/autoconfigure/hazelcast/"
"spring.hazelcast.config=org/springframework/boot/autoconfigure/" + "hazelcast-client-specific.yaml");
+ "hazelcast/hazelcast-client-specific.xml") }
.run((context) -> assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastClientProxy.class) private void systemProperty(String systemProperty) {
.has(nameStartingWith("hz.client_"))); this.contextRunner.withSystemProperties(systemProperty)
.run((context) -> assertHazelcastClientSpecific(context));
} }
@Test @Test
public void explicitConfigUrl() { public void explicitConfigFileWithXml() {
this.contextRunner propertyValues("spring.hazelcast.config=org/springframework/boot/autoconfigure/"
.withPropertyValues( + "hazelcast/hazelcast-client-specific.xml");
"spring.hazelcast.config=hazelcast-client-default.xml") }
.run((context) -> assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastClientProxy.class) @Test
.has(nameStartingWith("hz.client_"))); 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 @Test
@ -111,9 +135,10 @@ public class HazelcastAutoConfigurationClientTests {
.isInstanceOf(HazelcastClientProxy.class)); .isInstanceOf(HazelcastClientProxy.class));
} }
private Condition<HazelcastInstance> nameStartingWith(String prefix) { private static Condition<HazelcastInstance> labelEqualTo(String label) {
return new Condition<>((o) -> o.getName().startsWith(prefix), return new Condition<>((o) -> ((HazelcastClientProxy) o).getClientConfig()
"Name starts with " + prefix); .getLabels().stream().anyMatch((e) -> e.equals(label)),
"Label equals to " + label);
} }
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)

@ -27,6 +27,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.AutoConfigurations; 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.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner;
@ -59,39 +60,56 @@ public class HazelcastAutoConfigurationServerTests {
} }
@Test @Test
public void systemProperty() { public void systemPropertyWithXml() {
this.contextRunner systemProperty(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY
.withSystemProperties(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY + "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml");
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml")
.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getQueueConfigs().keySet()).containsOnly("foobar");
});
} }
@Test @Test
public void explicitConfigFile() { public void systemPropertyWithYaml() {
this.contextRunner.withPropertyValues( 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 explicitConfigFileWithXml() {
propertyValues(
"spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/" "spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-specific.xml") + "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());
});
} }
@Test @Test
public void explicitConfigUrl() { public void explicitConfigFileWithYaml() {
this.contextRunner propertyValues(
.withPropertyValues("spring.hazelcast.config=hazelcast-default.xml") "spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/"
.run((context) -> { + "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(); Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getConfigurationUrl()).isEqualTo( assertThat(config.getMapConfigs().keySet()).containsOnly("foobar");
new ClassPathResource("hazelcast-default.xml").getURL());
});
} }
@Test @Test

@ -39,6 +39,8 @@ public class HazelcastAutoConfigurationTests {
@Test @Test
public void defaultConfigFile() { public void defaultConfigFile() {
// no hazelcast-client.xml and hazelcast.xml is present in root classpath // 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) -> { this.contextRunner.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig(); Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getConfigurationUrl()) assertThat(config.getConfigurationUrl())

@ -0,0 +1,5 @@
hazelcast:
network:
join:
multicast:
enabled: false

@ -2,5 +2,8 @@
<hazelcast-client xmlns="http://www.hazelcast.com/schema/client-config" <hazelcast-client xmlns="http://www.hazelcast.com/schema/client-config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/client-config hazelcast-client-config-3.12.xsd"> 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-client>

@ -0,0 +1,10 @@
hazelcast:
network:
join:
multicast:
enabled: false
map:
foobar:
time-to-live-seconds: 3600
max-idle-seconds: 600
Loading…
Cancel
Save