Skip to content

Commit

Permalink
Merge pull request spring-projects#16632 from leszko
Browse files Browse the repository at this point in the history
* pr/16632:
  Polish "Add support for Hazelcast YAML configuration"
  Add support for Hazelcast YAML configuration
  • Loading branch information
snicoll committed Apr 29, 2019
2 parents b527d36 + 704da17 commit 84530ce
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ static class ConfigAvailableCondition extends HazelcastConfigResourceCondition {

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");
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2019 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.
Expand All @@ -22,6 +22,7 @@
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;
Expand Down Expand Up @@ -59,6 +60,10 @@ public HazelcastClientFactory(ClientConfig clientConfig) {
private ClientConfig getClientConfig(Resource clientConfigLocation)
throws IOException {
URL configUrl = clientConfigLocation.getURL();
String configFileName = configUrl.getPath();
if (configFileName.endsWith(".yaml")) {
return new YamlClientConfigBuilder(configUrl).build();
}
return new XmlClientConfigBuilder(configUrl).build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2019 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.
Expand All @@ -21,6 +21,7 @@

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;

Expand Down Expand Up @@ -61,7 +62,7 @@ public HazelcastInstanceFactory(Config config) {

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());
}
Expand All @@ -71,6 +72,14 @@ private Config getConfig(Resource configLocation) throws IOException {
return config;
}

private static Config createConfig(URL configUrl) throws IOException {
String configFileName = configUrl.getPath();
if (configFileName.endsWith(".yaml")) {
return new YamlConfigBuilder(configUrl).build();
}
return new XmlConfigBuilder(configUrl).build();
}

/**
* Get the {@link HazelcastInstance}.
* @return the {@link HazelcastInstance}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ static class ConfigAvailableCondition extends HazelcastConfigResourceCondition {

ConfigAvailableCondition() {
super(CONFIG_SYSTEM_PROPERTY, "file:./hazelcast.xml",
"classpath:/hazelcast.xml");
"classpath:/hazelcast.xml", "file:./hazelcast.yaml",
"classpath:/hazelcast.yaml");
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@

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.test.context.runner.ContextConsumer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

Expand Down Expand Up @@ -63,35 +65,55 @@ public static void close() {
.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class));

@Test
public void systemProperty() {
public void systemPropertyWithXml() {
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_")));
.run(assertSpecificHazelcastClient("explicit-xml"));
}

@Test
public void explicitConfigFile() {
public void systemPropertyWithYaml() {
this.contextRunner
.withSystemProperties(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-client-specific.yaml")
.run(assertSpecificHazelcastClient("explicit-yaml"));
}

@Test
public void explicitConfigFileWithXml() {
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_")));
.run(assertSpecificHazelcastClient("explicit-xml"));
}

@Test
public void explicitConfigUrl() {
public void explicitConfigFileWithYaml() {
this.contextRunner
.withPropertyValues(
"spring.hazelcast.config=hazelcast-client-default.xml")
.run((context) -> assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastClientProxy.class)
.has(nameStartingWith("hz.client_")));
"spring.hazelcast.config=org/springframework/boot/autoconfigure/"
+ "hazelcast/hazelcast-client-specific.yaml")
.run(assertSpecificHazelcastClient("explicit-yaml"));
}

@Test
public void explicitConfigUrlWithXml() {
this.contextRunner.withPropertyValues(
"spring.hazelcast.config=classpath:org/springframework/"
+ "boot/autoconfigure/hazelcast/hazelcast-client-specific.xml")
.run(assertSpecificHazelcastClient("explicit-xml"));
}

@Test
public void explicitConfigUrlWithYaml() {
this.contextRunner.withPropertyValues(
"spring.hazelcast.config=classpath:org/springframework/"
+ "boot/autoconfigure/hazelcast/hazelcast-client-specific.yaml")
.run(assertSpecificHazelcastClient("explicit-yaml"));
}

@Test
Expand All @@ -111,9 +133,16 @@ public void clientConfigTakesPrecedence() {
.isInstanceOf(HazelcastClientProxy.class));
}

private Condition<HazelcastInstance> nameStartingWith(String prefix) {
return new Condition<>((o) -> o.getName().startsWith(prefix),
"Name starts with " + prefix);
private ContextConsumer<AssertableApplicationContext> assertSpecificHazelcastClient(
String label) {
return (context) -> assertThat(context).getBean(HazelcastInstance.class)
.isInstanceOf(HazelcastInstance.class).has(labelEqualTo(label));
}

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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@

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.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner;
import org.springframework.context.annotation.Bean;
Expand Down Expand Up @@ -59,39 +61,71 @@ public void defaultConfigFile() {
}

@Test
public void systemProperty() {
public void systemPropertyWithXml() {
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");
assertThat(config.getMapConfigs().keySet()).containsOnly("foobar");
});
}

@Test
public void explicitConfigFile() {
this.contextRunner.withPropertyValues(
"spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-specific.xml")
public void systemPropertyWithYaml() {
this.contextRunner
.withSystemProperties(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml")
.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getConfigurationFile())
.isEqualTo(new ClassPathResource(
"org/springframework/boot/autoconfigure/hazelcast"
+ "/hazelcast-specific.xml").getFile());
assertThat(config.getMapConfigs().keySet()).containsOnly("foobar");
});
}

@Test
public void explicitConfigUrl() {
public void explicitConfigFileWithXml() {
this.contextRunner.withPropertyValues(
"spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-specific.xml")
.run(assertSpecificHazelcastServer(
"org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml"));
}

@Test
public void explicitConfigFileWithYaml() {
this.contextRunner.withPropertyValues(
"spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/"
+ "hazelcast-specific.yaml")
.run(assertSpecificHazelcastServer(
"org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml"));
}

@Test
public void explicitConfigUrlWithXml() {
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());
});
.withPropertyValues(
"spring.hazelcast.config=classpath:org/springframework/"
+ "boot/autoconfigure/hazelcast/hazelcast-specific.xml")
.run(assertSpecificHazelcastServer(
"org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml"));
}

@Test
public void explicitConfigUrlWithYaml() {
this.contextRunner
.withPropertyValues(
"spring.hazelcast.config=classpath:org/springframework/"
+ "boot/autoconfigure/hazelcast/hazelcast-specific.yaml")
.run(assertSpecificHazelcastServer(
"org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml"));
}

private ContextConsumer<AssertableApplicationContext> assertSpecificHazelcastServer(
String location) {
return (context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getConfigurationUrl()).asString().endsWith(location);
};
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2018 the original author or authors.
* Copyright 2012-2019 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.
Expand Down Expand Up @@ -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())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
hazelcast:
network:
join:
multicast:
enabled: false
Original file line number Diff line number Diff line change
Expand Up @@ -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>explicit-xml</label>
</client-labels>

</hazelcast-client>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
hazelcast-client:
client-labels:
- explicit-yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
hazelcast:
network:
join:
multicast:
enabled: false

map:
foobar:
time-to-live-seconds: 3600
max-idle-seconds: 600
Original file line number Diff line number Diff line change
Expand Up @@ -6539,17 +6539,18 @@ If you define a `com.hazelcast.config.Config` bean, Spring Boot uses that. If yo
configuration defines an instance name, Spring Boot tries to locate an existing instance
rather than creating a new one.

You could also specify the `hazelcast.xml` configuration file to use through
configuration, as shown in the following example:
You could also specify the Hazelcast configuration file to use through configuration, as
shown in the following example:

[source,properties,indent=0]
----
spring.hazelcast.config=classpath:config/my-hazelcast.xml
----

Otherwise, Spring Boot tries to find the Hazelcast configuration from the default
locations: `hazelcast.xml` in the working directory or at the root of the classpath. We
also check if the `hazelcast.config` system property is set. See the
locations: `hazelcast.xml` in the working directory or at the root of the classpath, or
a `.yaml` counterpart in the same locations. We also check if the `hazelcast.config`
system property is set. See the
https://docs.hazelcast.org/docs/latest/manual/html-single/[Hazelcast documentation] for
more details.

Expand All @@ -6560,6 +6561,7 @@ client by checking the following configuration options:
* A configuration file defined by the `spring.hazelcast.config` property.
* The presence of the `hazelcast.client.config` system property.
* A `hazelcast-client.xml` in the working directory or at the root of the classpath.
* A `hazelcast-client.yaml` in the working directory or at the root of the classpath.

NOTE: Spring Boot also has
<<boot-features-caching-provider-hazelcast,explicit caching support for Hazelcast>>. If
Expand Down

0 comments on commit 84530ce

Please sign in to comment.