Associate application classloader to auto-configured Hazelcast instance
Closes gh-24836
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -16,18 +16,17 @@
|
||||
|
||||
package org.springframework.boot.actuate.hazelcast;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.hazelcast.core.HazelcastException;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastInstanceFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathOverrides;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -45,19 +44,16 @@ import static org.mockito.Mockito.mock;
|
||||
class Hazelcast3HazelcastHealthIndicatorTests {
|
||||
|
||||
@Test
|
||||
void hazelcastUp() throws IOException {
|
||||
HazelcastInstance hazelcast = new HazelcastInstanceFactory(new ClassPathResource("hazelcast-3.xml"))
|
||||
.getHazelcastInstance();
|
||||
try {
|
||||
Health health = new HazelcastHealthIndicator(hazelcast).health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsOnlyKeys("name", "uuid").containsEntry("name",
|
||||
"actuator-hazelcast-3");
|
||||
assertThat(health.getDetails().get("uuid")).asString().isNotEmpty();
|
||||
}
|
||||
finally {
|
||||
hazelcast.shutdown();
|
||||
}
|
||||
void hazelcastUp() {
|
||||
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class))
|
||||
.withPropertyValues("spring.hazelcast.config=hazelcast-3.xml").run((context) -> {
|
||||
HazelcastInstance hazelcast = context.getBean(HazelcastInstance.class);
|
||||
Health health = new HazelcastHealthIndicator(hazelcast).health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsOnlyKeys("name", "uuid").containsEntry("name",
|
||||
"actuator-hazelcast-3");
|
||||
assertThat(health.getDetails().get("uuid")).asString().isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -16,16 +16,15 @@
|
||||
|
||||
package org.springframework.boot.actuate.hazelcast;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.hazelcast.core.HazelcastException;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastInstanceFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -41,19 +40,16 @@ import static org.mockito.Mockito.mock;
|
||||
class HazelcastHealthIndicatorTests {
|
||||
|
||||
@Test
|
||||
void hazelcastUp() throws IOException {
|
||||
HazelcastInstance hazelcast = new HazelcastInstanceFactory(new ClassPathResource("hazelcast.xml"))
|
||||
.getHazelcastInstance();
|
||||
try {
|
||||
Health health = new HazelcastHealthIndicator(hazelcast).health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsOnlyKeys("name", "uuid").containsEntry("name",
|
||||
"actuator-hazelcast");
|
||||
assertThat(health.getDetails().get("uuid")).asString().isNotEmpty();
|
||||
}
|
||||
finally {
|
||||
hazelcast.shutdown();
|
||||
}
|
||||
void hazelcastUp() {
|
||||
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class))
|
||||
.withPropertyValues("spring.hazelcast.config=hazelcast.xml").run((context) -> {
|
||||
HazelcastInstance hazelcast = context.getBean(HazelcastInstance.class);
|
||||
Health health = new HazelcastHealthIndicator(hazelcast).health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsOnlyKeys("name", "uuid").containsEntry("name",
|
||||
"actuator-hazelcast");
|
||||
assertThat(health.getDetails().get("uuid")).asString().isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -17,9 +17,12 @@
|
||||
package org.springframework.boot.autoconfigure.hazelcast;
|
||||
|
||||
import java.io.IOException;
|
||||
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.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
@@ -29,6 +32,8 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Configuration for Hazelcast client.
|
||||
@@ -43,18 +48,34 @@ class HazelcastClientConfiguration {
|
||||
|
||||
static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.client.config";
|
||||
|
||||
private static HazelcastInstance getHazelcastInstance(ClientConfig config) {
|
||||
if (StringUtils.hasText(config.getInstanceName())) {
|
||||
return HazelcastClient.getOrCreateHazelcastClient(config);
|
||||
}
|
||||
return HazelcastClient.newHazelcastClient(config);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(ClientConfig.class)
|
||||
@Conditional(HazelcastClientConfigAvailableCondition.class)
|
||||
static class HazelcastClientConfigFileConfiguration {
|
||||
|
||||
@Bean
|
||||
HazelcastInstance hazelcastInstance(HazelcastProperties properties) throws IOException {
|
||||
Resource config = properties.resolveConfigLocation();
|
||||
if (config != null) {
|
||||
return new HazelcastClientFactory(config).getHazelcastInstance();
|
||||
HazelcastInstance hazelcastInstance(HazelcastProperties properties, ResourceLoader resourceLoader)
|
||||
throws IOException {
|
||||
Resource configLocation = properties.resolveConfigLocation();
|
||||
ClientConfig config = (configLocation != null) ? loadClientConfig(configLocation) : ClientConfig.load();
|
||||
config.setClassLoader(resourceLoader.getClassLoader());
|
||||
return getHazelcastInstance(config);
|
||||
}
|
||||
|
||||
private ClientConfig loadClientConfig(Resource configLocation) throws IOException {
|
||||
URL configUrl = configLocation.getURL();
|
||||
String configFileName = configUrl.getPath();
|
||||
if (configFileName.endsWith(".yaml")) {
|
||||
return new YamlClientConfigBuilder(configUrl).build();
|
||||
}
|
||||
return HazelcastClient.newHazelcastClient();
|
||||
return new XmlClientConfigBuilder(configUrl).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -65,7 +86,7 @@ class HazelcastClientConfiguration {
|
||||
|
||||
@Bean
|
||||
HazelcastInstance hazelcastInstance(ClientConfig config) {
|
||||
return new HazelcastClientFactory(config).getHazelcastInstance();
|
||||
return getHazelcastInstance(config);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -34,7 +34,9 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
* @deprecated since 2.3.4 in favor of using the Hazelcast API directly
|
||||
*/
|
||||
@Deprecated
|
||||
public class HazelcastClientFactory {
|
||||
|
||||
private final ClientConfig clientConfig;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -36,7 +36,9 @@ import org.springframework.util.StringUtils;
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @since 1.3.0
|
||||
* @deprecated since 2.3.4 in favor of using the Hazelcast API directly
|
||||
*/
|
||||
@Deprecated
|
||||
public class HazelcastInstanceFactory {
|
||||
|
||||
private final Config config;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -17,8 +17,11 @@
|
||||
package org.springframework.boot.autoconfigure.hazelcast;
|
||||
|
||||
import java.io.IOException;
|
||||
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;
|
||||
|
||||
@@ -28,6 +31,9 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Configuration for Hazelcast server.
|
||||
@@ -41,18 +47,45 @@ class HazelcastServerConfiguration {
|
||||
|
||||
static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.config";
|
||||
|
||||
private static HazelcastInstance getHazelcastInstance(Config config) {
|
||||
if (StringUtils.hasText(config.getInstanceName())) {
|
||||
return Hazelcast.getOrCreateHazelcastInstance(config);
|
||||
}
|
||||
return Hazelcast.newHazelcastInstance(config);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(Config.class)
|
||||
@Conditional(ConfigAvailableCondition.class)
|
||||
static class HazelcastServerConfigFileConfiguration {
|
||||
|
||||
@Bean
|
||||
HazelcastInstance hazelcastInstance(HazelcastProperties properties) throws IOException {
|
||||
Resource config = properties.resolveConfigLocation();
|
||||
if (config != null) {
|
||||
return new HazelcastInstanceFactory(config).getHazelcastInstance();
|
||||
HazelcastInstance hazelcastInstance(HazelcastProperties properties, ResourceLoader resourceLoader)
|
||||
throws IOException {
|
||||
Resource configLocation = properties.resolveConfigLocation();
|
||||
Config config = (configLocation != null) ? loadConfig(configLocation) : Config.load();
|
||||
config.setClassLoader(resourceLoader.getClassLoader());
|
||||
return getHazelcastInstance(config);
|
||||
}
|
||||
|
||||
private Config loadConfig(Resource configLocation) throws IOException {
|
||||
URL configUrl = configLocation.getURL();
|
||||
Config config = loadConfig(configUrl);
|
||||
if (ResourceUtils.isFileURL(configUrl)) {
|
||||
config.setConfigurationFile(configLocation.getFile());
|
||||
}
|
||||
return Hazelcast.newHazelcastInstance();
|
||||
else {
|
||||
config.setConfigurationUrl(configUrl);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
private static Config loadConfig(URL configUrl) throws IOException {
|
||||
String configFileName = configUrl.getPath();
|
||||
if (configFileName.endsWith(".yaml")) {
|
||||
return new YamlConfigBuilder(configUrl).build();
|
||||
}
|
||||
return new XmlConfigBuilder(configUrl).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,7 +96,7 @@ class HazelcastServerConfiguration {
|
||||
|
||||
@Bean
|
||||
HazelcastInstance hazelcastInstance(Config config) {
|
||||
return new HazelcastInstanceFactory(config).getHazelcastInstance();
|
||||
return getHazelcastInstance(config);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -135,6 +135,18 @@ class HazelcastAutoConfigurationClientTests {
|
||||
.extracting(HazelcastInstance::getName).isEqualTo("spring-boot"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfiguredClientConfigUsesApplicationClassLoader() {
|
||||
this.contextRunner.withPropertyValues("spring.hazelcast.config=org/springframework/boot/autoconfigure/"
|
||||
+ "hazelcast/hazelcast-client-specific.xml").run((context) -> {
|
||||
HazelcastInstance hazelcast = context.getBean(HazelcastInstance.class);
|
||||
assertThat(hazelcast).isInstanceOf(HazelcastClientProxy.class);
|
||||
ClientConfig clientConfig = ((HazelcastClientProxy) hazelcast).getClientConfig();
|
||||
assertThat(clientConfig.getClassLoader())
|
||||
.isSameAs(context.getSourceApplicationContext().getClassLoader());
|
||||
});
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> assertSpecificHazelcastClient(String label) {
|
||||
return (context) -> assertThat(context).getBean(HazelcastInstance.class).isInstanceOf(HazelcastInstance.class)
|
||||
.has(labelEqualTo(label));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -156,6 +156,14 @@ class HazelcastAutoConfigurationServerTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfiguredConfigUsesApplicationClassLoader() {
|
||||
this.contextRunner.run((context) -> {
|
||||
Config config = context.getBean(HazelcastInstance.class).getConfig();
|
||||
assertThat(config.getClassLoader()).isSameAs(context.getSourceApplicationContext().getClassLoader());
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class HazelcastConfigWithName {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user