Hazelcast auto-configuration
Provide a general purpose Hazelcast integration (i.e. not tied to caching). Auto-configure a `HazelcastInstance` either based on the presence of a `Config` bean or a configuration file. Said configuration file can be specified explicitly or automatically found from default locations. The cache integration already supports Hazelcast so it has been reworked to automatically reuse an existing `HazelcastInstance` if available. Closes gh-2942
This commit is contained in:
parent
35b2bca614
commit
721b5a2395
|
@ -20,6 +20,7 @@ import net.sf.ehcache.Cache;
|
||||||
import net.sf.ehcache.CacheManager;
|
import net.sf.ehcache.CacheManager;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ResourceCondition;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.cache.ehcache.EhCacheCacheManager;
|
import org.springframework.cache.ehcache.EhCacheCacheManager;
|
||||||
|
@ -68,10 +69,10 @@ class EhCacheCacheConfiguration {
|
||||||
* default configuration has been found or if property referring to the file to use
|
* default configuration has been found or if property referring to the file to use
|
||||||
* has been set.
|
* has been set.
|
||||||
*/
|
*/
|
||||||
static class ConfigAvailableCondition extends CacheConfigFileCondition {
|
static class ConfigAvailableCondition extends ResourceCondition {
|
||||||
|
|
||||||
public ConfigAvailableCondition() {
|
public ConfigAvailableCondition() {
|
||||||
super("EhCache", "spring.cache.ehcache", "classpath:/ehcache.xml");
|
super("EhCache", "spring.cache.ehcache", "config", "classpath:/ehcache.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,85 +16,118 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.cache;
|
package org.springframework.boot.autoconfigure.cache;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
|
||||||
import org.springframework.cache.CacheManager;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.ConditionContext;
|
|
||||||
import org.springframework.context.annotation.Conditional;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
|
||||||
|
|
||||||
import com.hazelcast.config.Config;
|
|
||||||
import com.hazelcast.config.XmlConfigBuilder;
|
|
||||||
import com.hazelcast.core.Hazelcast;
|
import com.hazelcast.core.Hazelcast;
|
||||||
import com.hazelcast.core.HazelcastInstance;
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
import com.hazelcast.spring.cache.HazelcastCacheManager;
|
import com.hazelcast.spring.cache.HazelcastCacheManager;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||||
|
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.hazelcast.HazelcastConfigResourceCondition;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hazelcast cache configuration. Only kick in if a configuration file location is set or
|
* Hazelcast cache configuration. Can either reuse the {@link HazelcastInstance} that
|
||||||
* if a default configuration file exists (either placed in the default location or set
|
* has been configured by the general {@link HazelcastAutoConfiguration} or create
|
||||||
* via the {@value #CONFIG_SYSTEM_PROPERTY} system property).
|
* a separate one if the {@code spring.cache.hazelcast.config} property has been set.
|
||||||
|
* <p>
|
||||||
|
* If the {@link HazelcastAutoConfiguration} has been disabled, an attempt to configure
|
||||||
|
* a default {@link HazelcastInstance} is still made, using the same defaults.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 1.3.0
|
* @since 1.3.0
|
||||||
|
* @see HazelcastConfigResourceCondition
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass({ HazelcastInstance.class, HazelcastCacheManager.class })
|
@ConditionalOnClass({HazelcastInstance.class, HazelcastCacheManager.class})
|
||||||
@ConditionalOnMissingBean(CacheManager.class)
|
@ConditionalOnMissingBean(CacheManager.class)
|
||||||
@Conditional({ CacheCondition.class,
|
@Conditional(CacheCondition.class)
|
||||||
HazelcastCacheConfiguration.ConfigAvailableCondition.class })
|
@AutoConfigureAfter(HazelcastAutoConfiguration.class)
|
||||||
class HazelcastCacheConfiguration {
|
class HazelcastCacheConfiguration {
|
||||||
|
|
||||||
static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.config";
|
@Configuration
|
||||||
|
@ConditionalOnSingleCandidate(HazelcastInstance.class)
|
||||||
|
static class ExistingHazelcastInstanceConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CacheProperties cacheProperties;
|
private CacheProperties cacheProperties;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public HazelcastCacheManager cacheManager(HazelcastInstance hazelcastInstance) {
|
public HazelcastCacheManager cacheManager(HazelcastInstance existingHazelcastInstance)
|
||||||
return new HazelcastCacheManager(hazelcastInstance);
|
throws IOException {
|
||||||
|
Resource location = this.cacheProperties
|
||||||
|
.resolveConfigLocation(this.cacheProperties.getHazelcast().getConfig());
|
||||||
|
if (location != null) {
|
||||||
|
HazelcastInstance cacheHazelcastInstance =
|
||||||
|
HazelcastAutoConfiguration.createHazelcastInstance(location);
|
||||||
|
return new CloseableHazelcastCacheManager(cacheHazelcastInstance);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new HazelcastCacheManager(existingHazelcastInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Configuration
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean(HazelcastInstance.class)
|
||||||
public HazelcastInstance hazelcastInstance() throws IOException {
|
@Conditional(ConfigAvailableCondition.class)
|
||||||
Resource location = this.cacheProperties
|
static class DefaultHazelcastInstanceConfiguration {
|
||||||
.resolveConfigLocation(this.cacheProperties.getHazelcast().getConfig());
|
|
||||||
if (location != null) {
|
@Autowired
|
||||||
Config cfg = new XmlConfigBuilder(location.getURL()).build();
|
private CacheProperties cacheProperties;
|
||||||
return Hazelcast.newHazelcastInstance(cfg);
|
|
||||||
|
@Bean
|
||||||
|
public HazelcastInstance hazelcastInstance() throws IOException {
|
||||||
|
Resource location = this.cacheProperties
|
||||||
|
.resolveConfigLocation(this.cacheProperties.getHazelcast().getConfig());
|
||||||
|
if (location != null) {
|
||||||
|
HazelcastAutoConfiguration.createHazelcastInstance(location);
|
||||||
|
}
|
||||||
|
return Hazelcast.newHazelcastInstance();
|
||||||
}
|
}
|
||||||
return Hazelcast.newHazelcastInstance();
|
|
||||||
|
@Bean
|
||||||
|
public HazelcastCacheManager cacheManager() throws IOException {
|
||||||
|
return new HazelcastCacheManager(hazelcastInstance());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the Hazelcast configuration is available. This either kicks in if a
|
* {@link HazelcastConfigResourceCondition} that checks if the
|
||||||
* default configuration has been found or if property referring to the file to use
|
* {@code spring.cache.hazelcast.config} configuration key is defined.
|
||||||
* has been set.
|
|
||||||
*/
|
*/
|
||||||
static class ConfigAvailableCondition extends CacheConfigFileCondition {
|
static class ConfigAvailableCondition extends HazelcastConfigResourceCondition {
|
||||||
|
|
||||||
public ConfigAvailableCondition() {
|
public ConfigAvailableCondition() {
|
||||||
super("Hazelcast", "spring.cache.hazelcast", "file:./hazelcast.xml",
|
super("spring.cache.hazelcast", "config");
|
||||||
"classpath:/hazelcast.xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ConditionOutcome getResourceOutcome(ConditionContext context,
|
|
||||||
AnnotatedTypeMetadata metadata) {
|
|
||||||
if (System.getProperty(CONFIG_SYSTEM_PROPERTY) != null) {
|
|
||||||
return ConditionOutcome.match("System property '"
|
|
||||||
+ CONFIG_SYSTEM_PROPERTY + "' is set.");
|
|
||||||
}
|
|
||||||
return super.getResourceOutcome(context, metadata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class CloseableHazelcastCacheManager extends HazelcastCacheManager implements Closeable {
|
||||||
|
private final HazelcastInstance hazelcastInstance;
|
||||||
|
|
||||||
|
public CloseableHazelcastCacheManager(HazelcastInstance hazelcastInstance) {
|
||||||
|
super(hazelcastInstance);
|
||||||
|
this.hazelcastInstance = hazelcastInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
this.hazelcastInstance.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,33 +14,44 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.cache;
|
package org.springframework.boot.autoconfigure.condition;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
|
||||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
||||||
import org.springframework.context.annotation.ConditionContext;
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link SpringBootCondition} used to check if a cache configuration file can be found.
|
* {@link SpringBootCondition} used to check if a resource can be found using a
|
||||||
|
* configurable property and optional default location(s).
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
abstract class CacheConfigFileCondition extends SpringBootCondition {
|
public abstract class ResourceCondition extends SpringBootCondition {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private final String prefix;
|
private final String prefix;
|
||||||
|
|
||||||
|
private final String propertyName;
|
||||||
|
|
||||||
private final String[] resourceLocations;
|
private final String[] resourceLocations;
|
||||||
|
|
||||||
public CacheConfigFileCondition(String name, String prefix,
|
/**
|
||||||
|
* Create a new condition.
|
||||||
|
* @param name the name of the component
|
||||||
|
* @param prefix the prefix of the configuration key
|
||||||
|
* @param propertyName the name of the configuration key
|
||||||
|
* @param resourceLocations default location(s) where the configuration file can be
|
||||||
|
* found if the configuration key is not specified
|
||||||
|
*/
|
||||||
|
protected ResourceCondition(String name, String prefix, String propertyName,
|
||||||
String... resourceLocations) {
|
String... resourceLocations) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.prefix = (prefix.endsWith(".") ? prefix : prefix + ".");
|
this.prefix = (prefix.endsWith(".") ? prefix : prefix + ".");
|
||||||
|
this.propertyName = propertyName;
|
||||||
this.resourceLocations = resourceLocations;
|
this.resourceLocations = resourceLocations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,13 +60,19 @@ abstract class CacheConfigFileCondition extends SpringBootCondition {
|
||||||
AnnotatedTypeMetadata metadata) {
|
AnnotatedTypeMetadata metadata) {
|
||||||
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(
|
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(
|
||||||
context.getEnvironment(), this.prefix);
|
context.getEnvironment(), this.prefix);
|
||||||
if (resolver.containsProperty("config")) {
|
if (resolver.containsProperty(propertyName)) {
|
||||||
return ConditionOutcome.match("A '" + this.prefix + ".config' "
|
return ConditionOutcome.match("A '" + this.prefix + propertyName +"' "
|
||||||
+ "property is specified");
|
+ "property is specified");
|
||||||
}
|
}
|
||||||
return getResourceOutcome(context, metadata);
|
return getResourceOutcome(context, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if one of the default resource locations actually exists.
|
||||||
|
* @param context the condition context
|
||||||
|
* @param metadata the annotation metadata
|
||||||
|
* @return the condition outcome
|
||||||
|
*/
|
||||||
protected ConditionOutcome getResourceOutcome(ConditionContext context,
|
protected ConditionOutcome getResourceOutcome(ConditionContext context,
|
||||||
AnnotatedTypeMetadata metadata) {
|
AnnotatedTypeMetadata metadata) {
|
||||||
for (String location : this.resourceLocations) {
|
for (String location : this.resourceLocations) {
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2015 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
|
||||||
|
*
|
||||||
|
* http://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.net.URL;
|
||||||
|
|
||||||
|
import com.hazelcast.config.Config;
|
||||||
|
import com.hazelcast.config.XmlConfigBuilder;
|
||||||
|
import com.hazelcast.core.Hazelcast;
|
||||||
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
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.util.Assert;
|
||||||
|
import org.springframework.util.ResourceUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link EnableAutoConfiguration Auto-configuration} for Hazelcast. Creates a
|
||||||
|
* {@link HazelcastInstance} based on explicit configuration or when a default
|
||||||
|
* configuration file is found in the environment.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @since 1.3.0
|
||||||
|
* @see HazelcastConfigResourceCondition
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(HazelcastInstance.class)
|
||||||
|
@ConditionalOnMissingBean(HazelcastInstance.class)
|
||||||
|
@EnableConfigurationProperties(HazelcastProperties.class)
|
||||||
|
public class HazelcastAutoConfiguration {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link HazelcastInstance} based on the specified configuration location.
|
||||||
|
* @param location the location of the configuration file
|
||||||
|
* @return a {@link HazelcastInstance} for the specified configuration
|
||||||
|
* @throws IOException the configuration file could not be read
|
||||||
|
*/
|
||||||
|
public static HazelcastInstance createHazelcastInstance(Resource location)
|
||||||
|
throws IOException {
|
||||||
|
Assert.notNull(location, "Config must not be null");
|
||||||
|
URL configUrl = location.getURL();
|
||||||
|
Config config = new XmlConfigBuilder(configUrl).build();
|
||||||
|
if (ResourceUtils.isFileURL(configUrl)) {
|
||||||
|
config.setConfigurationFile(location.getFile());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
config.setConfigurationUrl(configUrl);
|
||||||
|
}
|
||||||
|
return createHazelcastInstance(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HazelcastInstance createHazelcastInstance(Config config) {
|
||||||
|
if (StringUtils.hasText(config.getInstanceName())) {
|
||||||
|
return Hazelcast.getOrCreateHazelcastInstance(config);
|
||||||
|
}
|
||||||
|
return Hazelcast.newHazelcastInstance(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnMissingBean({HazelcastInstance.class, Config.class})
|
||||||
|
@Conditional(ConfigAvailableCondition.class)
|
||||||
|
static class HazelcastConfigFileConfiguration {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HazelcastProperties hazelcastProperties;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public HazelcastInstance hazelcastInstance() throws IOException {
|
||||||
|
Resource config = this.hazelcastProperties.resolveConfigLocation();
|
||||||
|
if (config != null) {
|
||||||
|
return createHazelcastInstance(config);
|
||||||
|
}
|
||||||
|
return Hazelcast.newHazelcastInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnMissingBean(HazelcastInstance.class)
|
||||||
|
@ConditionalOnSingleCandidate(Config.class)
|
||||||
|
static class HazelcastConfigConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public HazelcastInstance hazelcastInstance(Config config) {
|
||||||
|
return createHazelcastInstance(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link HazelcastConfigResourceCondition} that checks if the
|
||||||
|
* {@code spring.hazelcast.config} configuration key is defined.
|
||||||
|
*/
|
||||||
|
static class ConfigAvailableCondition extends HazelcastConfigResourceCondition {
|
||||||
|
|
||||||
|
public ConfigAvailableCondition() {
|
||||||
|
super("spring.hazelcast", "config");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2015 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
|
||||||
|
*
|
||||||
|
* http://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 org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ResourceCondition;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SpringBootCondition} used to check if the Hazelcast configuration is
|
||||||
|
* available. This either kicks in if a default configuration has been found or
|
||||||
|
* if configurable property referring to the resource to use has been set.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
public abstract class HazelcastConfigResourceCondition extends ResourceCondition {
|
||||||
|
|
||||||
|
static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.config";
|
||||||
|
|
||||||
|
protected HazelcastConfigResourceCondition(String prefix, String propertyName) {
|
||||||
|
super("Hazelcast", prefix, propertyName, "file:./hazelcast.xml",
|
||||||
|
"classpath:/hazelcast.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConditionOutcome getResourceOutcome(ConditionContext context,
|
||||||
|
AnnotatedTypeMetadata metadata) {
|
||||||
|
if (System.getProperty(CONFIG_SYSTEM_PROPERTY) != null) {
|
||||||
|
return ConditionOutcome.match("System property '"
|
||||||
|
+ CONFIG_SYSTEM_PROPERTY + "' is set.");
|
||||||
|
}
|
||||||
|
return super.getResourceOutcome(context, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2015 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
|
||||||
|
*
|
||||||
|
* http://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 org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration properties for the hazelcast integration.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties("spring.hazelcast")
|
||||||
|
public class HazelcastProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The location of the configuration file to use to initialize Hazelcast.
|
||||||
|
*/
|
||||||
|
private Resource config;
|
||||||
|
|
||||||
|
public Resource getConfig() {
|
||||||
|
return this.config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Resource config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the config location if set.
|
||||||
|
* @return the location or {@code null} if it is not set
|
||||||
|
* @throws IllegalArgumentException if the config attribute is set to an unknown
|
||||||
|
* location
|
||||||
|
*/
|
||||||
|
public Resource resolveConfigLocation() {
|
||||||
|
if (this.config != null) {
|
||||||
|
Assert.isTrue(this.config.exists(), "Hazelcast configuration does not exist '"
|
||||||
|
+ this.config.getDescription() + "'");
|
||||||
|
return this.config;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2015 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
|
||||||
|
*
|
||||||
|
* http://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 Hazelcast.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.autoconfigure.hazelcast;
|
|
@ -24,6 +24,7 @@ org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
|
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
|
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
|
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
|
||||||
|
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
|
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
|
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
|
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.boot.autoconfigure.cache;
|
package org.springframework.boot.autoconfigure.cache;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ import org.springframework.beans.DirectFieldAccessor;
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.boot.autoconfigure.cache.support.MockCachingProvider;
|
import org.springframework.boot.autoconfigure.cache.support.MockCachingProvider;
|
||||||
|
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
|
||||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
|
@ -74,6 +76,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.core.Is.is;
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.hamcrest.core.IsNot.not;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
|
@ -367,6 +370,51 @@ public class CacheAutoConfigurationTests {
|
||||||
is(this.context.getBean("customHazelcastInstance")));
|
is(this.context.getBean("customHazelcastInstance")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hazelcastCacheWithMainHazelcastAutoConfiguration() throws IOException {
|
||||||
|
Collection<Class<?>> configs = new ArrayList<Class<?>>();
|
||||||
|
configs.add(DefaultCacheConfiguration.class);
|
||||||
|
configs.add(HazelcastAutoConfiguration.class);
|
||||||
|
String mainConfig =
|
||||||
|
"org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml";
|
||||||
|
doLoad(configs, "spring.cache.type=hazelcast",
|
||||||
|
"spring.hazelcast.config=" + mainConfig);
|
||||||
|
|
||||||
|
HazelcastCacheManager cacheManager = validateCacheManager(HazelcastCacheManager.class);
|
||||||
|
HazelcastInstance hazelcastInstance = this.context.getBean(HazelcastInstance.class);
|
||||||
|
assertThat(
|
||||||
|
new DirectFieldAccessor(cacheManager)
|
||||||
|
.getPropertyValue("hazelcastInstance"),
|
||||||
|
is((Object) hazelcastInstance));
|
||||||
|
assertThat(hazelcastInstance.getConfig().getConfigurationFile(),
|
||||||
|
is(new ClassPathResource(mainConfig).getFile()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hazelcastCacheWithMainHazelcastAutoConfigurationAndSeparateCacheConfig()
|
||||||
|
throws IOException {
|
||||||
|
Collection<Class<?>> configs = new ArrayList<Class<?>>();
|
||||||
|
configs.add(DefaultCacheConfiguration.class);
|
||||||
|
configs.add(HazelcastAutoConfiguration.class);
|
||||||
|
String mainConfig = "org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml";
|
||||||
|
String cacheConfig = "org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml";
|
||||||
|
doLoad(configs, "spring.cache.type=hazelcast",
|
||||||
|
"spring.cache.hazelcast.config=" + cacheConfig,
|
||||||
|
"spring.hazelcast.config=" + mainConfig);
|
||||||
|
HazelcastInstance hazelcastInstance = this.context.getBean(HazelcastInstance.class);
|
||||||
|
HazelcastCacheManager cacheManager = validateCacheManager(HazelcastCacheManager.class);
|
||||||
|
HazelcastInstance cacheHazelcastInstance = (HazelcastInstance)
|
||||||
|
new DirectFieldAccessor(cacheManager).getPropertyValue("hazelcastInstance");
|
||||||
|
|
||||||
|
assertThat(
|
||||||
|
cacheHazelcastInstance,
|
||||||
|
is(not(hazelcastInstance))); // Our custom cache instance
|
||||||
|
assertThat(hazelcastInstance.getConfig().getConfigurationFile(),
|
||||||
|
is(new ClassPathResource(mainConfig).getFile()));
|
||||||
|
assertThat(cacheHazelcastInstance.getConfig().getConfigurationFile(),
|
||||||
|
is(new ClassPathResource(cacheConfig).getFile()));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hazelcastAsJCacheWithCaches() {
|
public void hazelcastAsJCacheWithCaches() {
|
||||||
String cachingProviderFqn = HazelcastCachingProvider.class.getName();
|
String cachingProviderFqn = HazelcastCachingProvider.class.getName();
|
||||||
|
@ -499,17 +547,21 @@ public class CacheAutoConfigurationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(Class<?> config, String... environment) {
|
private void load(Class<?> config, String... environment) {
|
||||||
this.context = doLoad(config, environment);
|
Collection<Class<?>> configs = new ArrayList<Class<?>>();
|
||||||
|
configs.add(config);
|
||||||
|
doLoad(configs, environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnnotationConfigApplicationContext doLoad(Class<?> config,
|
private void doLoad(Collection<Class<?>> configs,
|
||||||
String... environment) {
|
String... environment) {
|
||||||
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||||
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
|
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
|
||||||
applicationContext.register(config);
|
for (Class<?> config : configs) {
|
||||||
|
applicationContext.register(config);
|
||||||
|
}
|
||||||
applicationContext.register(CacheAutoConfiguration.class);
|
applicationContext.register(CacheAutoConfiguration.class);
|
||||||
applicationContext.refresh();
|
applicationContext.refresh();
|
||||||
return applicationContext;
|
this.context = applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
|
@ -14,10 +14,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.cache;
|
package org.springframework.boot.autoconfigure.condition;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
@ -29,11 +30,11 @@ import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for {@link CacheConfigFileCondition}.
|
* Test for {@link ResourceCondition}.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
*/
|
*/
|
||||||
public class CacheConfigFileConditionTests {
|
public class ResourceConditionTests {
|
||||||
|
|
||||||
private ConfigurableApplicationContext context;
|
private ConfigurableApplicationContext context;
|
||||||
|
|
||||||
|
@ -45,20 +46,21 @@ public class CacheConfigFileConditionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void defaultFileAndNoExplicitKey() {
|
public void defaultResourceAndNoExplicitKey() {
|
||||||
load(DefaultFileConfiguration.class);
|
load(DefaultLocationConfiguration.class);
|
||||||
assertTrue(this.context.containsBean("foo"));
|
assertTrue(this.context.containsBean("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noDefaultFileAndNoExplicitKey() {
|
public void unknownDefaultLocationAndNoExplicitKey() {
|
||||||
load(NoDefaultFileConfiguration.class);
|
load(UnknownDefaultLocationConfiguration.class);
|
||||||
assertFalse(this.context.containsBean("foo"));
|
assertFalse(this.context.containsBean("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noDefaultFileAndExplicitKeyToResource() {
|
public void unknownDefaultLocationAndExplicitKeyToResource() {
|
||||||
load(NoDefaultFileConfiguration.class, "spring.cache.test.config=ehcache.xml");
|
load(UnknownDefaultLocationConfiguration.class,
|
||||||
|
"spring.foo.test.config=logging.properties");
|
||||||
assertTrue(this.context.containsBean("foo"));
|
assertTrue(this.context.containsBean("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +73,8 @@ public class CacheConfigFileConditionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Conditional(CacheConfigFileDefaultFileCondition.class)
|
@Conditional(DefaultLocationResourceCondition.class)
|
||||||
static class DefaultFileConfiguration {
|
static class DefaultLocationConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public String foo() {
|
public String foo() {
|
||||||
|
@ -81,8 +83,8 @@ public class CacheConfigFileConditionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Conditional(CacheConfigFileNoDefaultFileCondition.class)
|
@Conditional(UnknownDefaultLocationResourceCondition.class)
|
||||||
static class NoDefaultFileConfiguration {
|
static class UnknownDefaultLocationConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public String foo() {
|
public String foo() {
|
||||||
|
@ -90,19 +92,19 @@ public class CacheConfigFileConditionTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CacheConfigFileDefaultFileCondition extends
|
private static class DefaultLocationResourceCondition extends
|
||||||
CacheConfigFileCondition {
|
ResourceCondition {
|
||||||
|
|
||||||
public CacheConfigFileDefaultFileCondition() {
|
public DefaultLocationResourceCondition() {
|
||||||
super("test", "spring.cache.test.", "classpath:/ehcache.xml");
|
super("test", "spring.foo.test.", "config", "classpath:/logging.properties");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CacheConfigFileNoDefaultFileCondition extends
|
private static class UnknownDefaultLocationResourceCondition extends
|
||||||
CacheConfigFileCondition {
|
ResourceCondition {
|
||||||
public CacheConfigFileNoDefaultFileCondition() {
|
public UnknownDefaultLocationResourceCondition() {
|
||||||
super("test", "spring.cache.test",
|
super("test", "spring.foo.test", "config",
|
||||||
"classpath:/this-cache-file-does-not-exist.xml");
|
"classpath:/this-file-does-not-exist.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2015 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
|
||||||
|
*
|
||||||
|
* http://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.util.Map;
|
||||||
|
|
||||||
|
import com.hazelcast.config.Config;
|
||||||
|
import com.hazelcast.config.QueueConfig;
|
||||||
|
import com.hazelcast.core.Hazelcast;
|
||||||
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
|
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
|
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
|
||||||
|
import static org.hamcrest.collection.IsMapContaining.hasKey;
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link HazelcastAutoConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
public class HazelcastAutoConfigurationTests {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
private AnnotationConfigApplicationContext context;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void closeContext() {
|
||||||
|
if (this.context != null) {
|
||||||
|
this.context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void defaultConfigFile() throws IOException {
|
||||||
|
load(); // hazelcast.xml present in root classpath
|
||||||
|
HazelcastInstance hazelcastInstance = this.context.getBean(
|
||||||
|
HazelcastInstance.class);
|
||||||
|
assertThat(hazelcastInstance.getConfig().getConfigurationUrl(),
|
||||||
|
is(new ClassPathResource("hazelcast.xml").getURL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void systemProperty() throws IOException {
|
||||||
|
System.setProperty(HazelcastConfigResourceCondition.CONFIG_SYSTEM_PROPERTY,
|
||||||
|
"classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml");
|
||||||
|
try {
|
||||||
|
load();
|
||||||
|
HazelcastInstance hazelcastInstance = this.context.getBean(
|
||||||
|
HazelcastInstance.class);
|
||||||
|
Map<String, QueueConfig> queueConfigs = hazelcastInstance.getConfig().getQueueConfigs();
|
||||||
|
assertThat(queueConfigs.values(), hasSize(1));
|
||||||
|
assertThat(queueConfigs, hasKey("foobar"));
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
System.clearProperty(HazelcastConfigResourceCondition.CONFIG_SYSTEM_PROPERTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void explicitConfigFile() throws IOException {
|
||||||
|
load("spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/" +
|
||||||
|
"hazelcast-specific.xml");
|
||||||
|
HazelcastInstance hazelcastInstance = this.context.getBean(
|
||||||
|
HazelcastInstance.class);
|
||||||
|
assertThat(hazelcastInstance.getConfig().getConfigurationFile(),
|
||||||
|
is(new ClassPathResource("org/springframework/boot/autoconfigure/hazelcast" +
|
||||||
|
"/hazelcast-specific.xml").getFile()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void explicitConfigUrl() throws IOException {
|
||||||
|
load("spring.hazelcast.config=hazelcast-default.xml");
|
||||||
|
HazelcastInstance hazelcastInstance = this.context.getBean(
|
||||||
|
HazelcastInstance.class);
|
||||||
|
assertThat(hazelcastInstance.getConfig().getConfigurationUrl(),
|
||||||
|
is(new ClassPathResource("hazelcast-default.xml").getURL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unknownConfigFile() {
|
||||||
|
this.thrown.expect(BeanCreationException.class);
|
||||||
|
this.thrown.expectMessage("foo/bar/unknown.xml");
|
||||||
|
load("spring.hazelcast.config=foo/bar/unknown.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configInstanceWithName() {
|
||||||
|
Config config = new Config("my-test-instance");
|
||||||
|
HazelcastInstance existingHazelcastInstance = Hazelcast.newHazelcastInstance(config);
|
||||||
|
try {
|
||||||
|
load(HazelcastConfigWithName.class,
|
||||||
|
"spring.hazelcast.config=this-is-ignored.xml");
|
||||||
|
HazelcastInstance hazelcastInstance = this.context.getBean(
|
||||||
|
HazelcastInstance.class);
|
||||||
|
assertThat(hazelcastInstance.getConfig().getInstanceName(), is("my-test-instance"));
|
||||||
|
// Should reuse any existing instance by default.
|
||||||
|
assertThat(hazelcastInstance, is(existingHazelcastInstance));
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
existingHazelcastInstance.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configInstanceWithoutName() {
|
||||||
|
load(HazelcastConfigNoName.class,
|
||||||
|
"spring.hazelcast.config=this-is-ignored.xml");
|
||||||
|
HazelcastInstance hazelcastInstance = this.context.getBean(
|
||||||
|
HazelcastInstance.class);
|
||||||
|
Map<String, QueueConfig> queueConfigs = hazelcastInstance.getConfig().getQueueConfigs();
|
||||||
|
assertThat(queueConfigs.values(), hasSize(1));
|
||||||
|
assertThat(queueConfigs, hasKey("another-queue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void load(String... environment) {
|
||||||
|
load(null, environment);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void load(Class<?> config, String... environment) {
|
||||||
|
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||||
|
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
|
||||||
|
if (config != null) {
|
||||||
|
applicationContext.register(config);
|
||||||
|
}
|
||||||
|
applicationContext.register(HazelcastAutoConfiguration.class);
|
||||||
|
applicationContext.refresh();
|
||||||
|
this.context = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class HazelcastConfigWithName {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Config myHazelcastConfig() {
|
||||||
|
return new Config("my-test-instance");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class HazelcastConfigNoName {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Config anotherHazelcastConfig() {
|
||||||
|
Config config = new Config();
|
||||||
|
config.addQueueConfig(new QueueConfig("another-queue"));
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.5.xsd"
|
||||||
|
xmlns="http://www.hazelcast.com/schema/config"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
|
<queue name="foobar"/>
|
||||||
|
|
||||||
|
</hazelcast>
|
|
@ -585,6 +585,9 @@ content into your application; rather pick only the properties that you need.
|
||||||
spring.cache.jcache.provider= # fully qualified name of the CachingProvider implementation to use
|
spring.cache.jcache.provider= # fully qualified name of the CachingProvider implementation to use
|
||||||
spring.cache.guava.spec= # link:http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilderSpec.html[guava specs]
|
spring.cache.guava.spec= # link:http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilderSpec.html[guava specs]
|
||||||
|
|
||||||
|
# HAZELCAST ({sc-spring-boot-autoconfigure}/hazelcast/HazelcastProperties.{sc-ext}[HazelcastProperties])
|
||||||
|
spring.hazelcast.config= # location of the hazelcast configuration
|
||||||
|
|
||||||
# AOP
|
# AOP
|
||||||
spring.aop.auto=
|
spring.aop.auto=
|
||||||
spring.aop.proxy-target-class=
|
spring.aop.proxy-target-class=
|
||||||
|
|
|
@ -2900,16 +2900,23 @@ manager. An alternate configuration file can be provide a well using:
|
||||||
|
|
||||||
[[boot-features-caching-provider-hazelcast]]
|
[[boot-features-caching-provider-hazelcast]]
|
||||||
==== Hazelcast
|
==== Hazelcast
|
||||||
Hazelcast is used if a `hazelcast.xml` file can be found in the current working
|
|
||||||
directory, at the root of the classpath or a location specified via the `hazelcast.config`
|
Spring Boot has a <<boot-features-hazelcast,general support for Hazelcast>>. If
|
||||||
system property. Spring Boot detects all of these and also allows for explicit location
|
a `HazelcastInstance` has been auto-configured, it is automatically wrapped in a
|
||||||
using:
|
`CacheManager`.
|
||||||
|
|
||||||
|
If for some reason you need a different `HazelcastInstance` for caching, you can
|
||||||
|
request Spring Boot to create a separate one that will only used by the
|
||||||
|
`CacheManager`:
|
||||||
|
|
||||||
[source,properties,indent=0]
|
[source,properties,indent=0]
|
||||||
----
|
----
|
||||||
spring.cache.hazelcast.config=classpath:config/my-hazelcast.xml
|
spring.cache.hazelcast.config=classpath:config/my-cache-hazelcast.xml
|
||||||
----
|
----
|
||||||
|
|
||||||
|
TIP: If a separate `HazelcastInstance` is created that way, it is not registered
|
||||||
|
in the application context.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[boot-features-caching-provider-infinispan]]
|
[[boot-features-caching-provider-infinispan]]
|
||||||
|
@ -3391,6 +3398,36 @@ provide good examples of how to write XA wrappers.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[boot-features-hazelcast]]
|
||||||
|
== Hazelcast
|
||||||
|
|
||||||
|
If hazelcast is on the classpath, Spring Boot will auto-configure an `HazelcastInstance`
|
||||||
|
that you can inject in your application. The `HazelcastInstance` is only created if a
|
||||||
|
configuration is found.
|
||||||
|
|
||||||
|
You can define a `com.hazelcast.config.Config` bean and we'll use that. If your
|
||||||
|
configuration defines an instance name, we'll try to locate an existing instance rather
|
||||||
|
than creating a new one.
|
||||||
|
|
||||||
|
You could also specify the `hazelcast.xml` configuration file to use via configuration:
|
||||||
|
|
||||||
|
[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, that is `hazelcast.xml` in the working directory or at the root of the
|
||||||
|
classpath. We also check if the `hazelcast.config` system property is set. Check the
|
||||||
|
Hazelcast documentation for more details.
|
||||||
|
|
||||||
|
NOTE: Spring Boot also has an
|
||||||
|
<<boot-features-caching-provider-hazelcast,explicit caching support for Hazelcast>>. The
|
||||||
|
`HazelcastInstance` is automatically wrapped in a `CacheManager` implementation if
|
||||||
|
caching is enabled.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[boot-features-integration]]
|
[[boot-features-integration]]
|
||||||
== Spring Integration
|
== Spring Integration
|
||||||
Spring Integration provides abstractions over messaging and also other transports such as
|
Spring Integration provides abstractions over messaging and also other transports such as
|
||||||
|
|
Loading…
Reference in New Issue