Skip to content

Commit

Permalink
Add auto-configuration support for Hazelcast client
Browse files Browse the repository at this point in the history
  • Loading branch information
vpavic authored and snicoll committed May 4, 2017
1 parent ae3225e commit 3fbf1a2
Show file tree
Hide file tree
Showing 10 changed files with 412 additions and 81 deletions.
5 changes: 5 additions & 0 deletions spring-boot-autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
<artifactId>hazelcast</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-client</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,80 +16,43 @@

package org.springframework.boot.autoconfigure.hazelcast;

import java.io.IOException;

import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.client.HazelcastClient;
import com.hazelcast.core.HazelcastInstance;

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.context.annotation.Import;

/**
* {@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
* @author Madhura Bhave
* @author Vedran Pavic
* @since 1.3.0
* @see HazelcastConfigResourceCondition
*/
@Configuration
@ConditionalOnClass(HazelcastInstance.class)
@ConditionalOnMissingBean(HazelcastInstance.class)
@EnableConfigurationProperties(HazelcastProperties.class)
public class HazelcastAutoConfiguration {

@Configuration
@ConditionalOnMissingBean(Config.class)
@Conditional(ConfigAvailableCondition.class)
static class HazelcastConfigFileConfiguration {

private final HazelcastProperties hazelcastProperties;

HazelcastConfigFileConfiguration(HazelcastProperties hazelcastProperties) {
this.hazelcastProperties = hazelcastProperties;
}

@Bean
public HazelcastInstance hazelcastInstance() throws IOException {
Resource config = this.hazelcastProperties.resolveConfigLocation();
if (config != null) {
return new HazelcastInstanceFactory(config).getHazelcastInstance();
}
return Hazelcast.newHazelcastInstance();
}
@ConditionalOnMissingBean(HazelcastInstance.class)
@Import(HazelcastServerConfiguration.class)
static class ServerConfiguration {

}

@Configuration
@ConditionalOnSingleCandidate(Config.class)
static class HazelcastConfigConfiguration {

@Bean
public HazelcastInstance hazelcastInstance(Config config) {
return new HazelcastInstanceFactory(config).getHazelcastInstance();
}

}

/**
* {@link HazelcastConfigResourceCondition} that checks if the
* {@code spring.hazelcast.config} configuration key is defined.
*/
static class ConfigAvailableCondition extends HazelcastConfigResourceCondition {

ConfigAvailableCondition() {
super("spring.hazelcast.config");
}
@ConditionalOnClass(HazelcastClient.class)
@ConditionalOnMissingBean(HazelcastInstance.class)
@Import(HazelcastClientConfiguration.class)
static class ClientConfiguration {

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2012-2017 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 com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.core.HazelcastInstance;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;

/**
* Configuration for Hazelcast client.
*
* @author Vedran Pavic
* @since 2.0.0
*/
class HazelcastClientConfiguration {

static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.client.config";

@Configuration
@ConditionalOnMissingBean(ClientConfig.class)
@Conditional(ConfigAvailableCondition.class)
static class HazelcastClientConfigFileConfiguration {

@Bean
public HazelcastInstance hazelcastInstance(HazelcastProperties properties)
throws IOException {
Resource config = properties.resolveConfigLocation();
if (config != null) {
return HazelcastInstanceFactory.createHazelcastClient(config);
}
return HazelcastClient.newHazelcastClient();
}

}

@Configuration
@ConditionalOnSingleCandidate(ClientConfig.class)
static class HazelcastClientConfigConfiguration {

@Bean
public HazelcastInstance hazelcastInstance(ClientConfig config) {
return HazelcastInstanceFactory.createHazelcastClient(config);
}

}

/**
* {@link HazelcastConfigResourceCondition} that checks if the
* {@code spring.hazelcast.config} configuration key is defined.
*/
static class ConfigAvailableCondition extends HazelcastConfigResourceCondition {

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

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.Assert;

/**
* {@link SpringBootCondition} used to check if the Hazelcast configuration is available.
Expand All @@ -29,22 +30,26 @@
*
* @author Stephane Nicoll
* @author Madhura Bhave
* @author Vedran Pavic
* @since 1.3.0
*/
public abstract class HazelcastConfigResourceCondition extends ResourceCondition {

static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.config";
private final String configSystemProperty;

protected HazelcastConfigResourceCondition(String property) {
super("Hazelcast", property, "file:./hazelcast.xml", "classpath:/hazelcast.xml");
protected HazelcastConfigResourceCondition(String configSystemProperty,
String... resourceLocations) {
super("Hazelcast", "spring.hazelcast.config", resourceLocations);
Assert.notNull(configSystemProperty, "ConfigSystemProperty must not be null");
this.configSystemProperty = configSystemProperty;
}

@Override
protected ConditionOutcome getResourceOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
if (System.getProperty(CONFIG_SYSTEM_PROPERTY) != null) {
if (System.getProperty(this.configSystemProperty) != null) {
return ConditionOutcome.match(startConditionMessage()
.because("System property '" + CONFIG_SYSTEM_PROPERTY + "' is set."));
.because("System property '" + this.configSystemProperty + "' is set."));
}
return super.getResourceOutcome(context, metadata);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 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 @@ -19,6 +19,9 @@
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.config.Config;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
Expand All @@ -34,32 +37,33 @@
*
* @author Stephane Nicoll
* @author Phillip Webb
* @author Vedran Pavic
* @since 1.3.0
*/
public class HazelcastInstanceFactory {

private Config config;

/**
* Create a {@link HazelcastInstanceFactory} for the specified configuration location.
* @param configLocation the location of the configuration file
* @throws IOException if the configuration location could not be read
*/
public HazelcastInstanceFactory(Resource configLocation) throws IOException {
Assert.notNull(configLocation, "ConfigLocation must not be null");
this.config = getConfig(configLocation);
}
public abstract class HazelcastInstanceFactory {

/**
* Create a {@link HazelcastInstanceFactory} for the specified configuration.
* Get the {@link HazelcastInstance}.
* @param config the configuration
* @return the {@link HazelcastInstance}
*/
public HazelcastInstanceFactory(Config config) {
public static HazelcastInstance createHazelcastInstance(Config config) {
Assert.notNull(config, "Config must not be null");
this.config = config;
if (StringUtils.hasText(config.getInstanceName())) {
return Hazelcast.getOrCreateHazelcastInstance(config);
}
return Hazelcast.newHazelcastInstance(config);
}

private Config getConfig(Resource configLocation) throws IOException {
/**
* Get the {@link HazelcastInstance}.
* @param configLocation the location of the configuration file
* @return the {@link HazelcastInstance}
* @throws IOException if the configuration location could not be read
*/
public static HazelcastInstance createHazelcastInstance(Resource configLocation)
throws IOException {
Assert.notNull(configLocation, "ConfigLocation must not be null");
URL configUrl = configLocation.getURL();
Config config = new XmlConfigBuilder(configUrl).build();
if (ResourceUtils.isFileURL(configUrl)) {
Expand All @@ -68,18 +72,34 @@ private Config getConfig(Resource configLocation) throws IOException {
else {
config.setConfigurationUrl(configUrl);
}
return config;
return createHazelcastInstance(config);
}

/**
* Get the {@link HazelcastInstance}.
* @return the {@link HazelcastInstance}
* Get the client {@link HazelcastInstance}.
* @param config the client configuration
* @return the client {@link HazelcastInstance}
*/
public HazelcastInstance getHazelcastInstance() {
if (StringUtils.hasText(this.config.getInstanceName())) {
return Hazelcast.getOrCreateHazelcastInstance(this.config);
public static HazelcastInstance createHazelcastClient(ClientConfig config) {
Assert.notNull(config, "Config must not be null");
if (StringUtils.hasText(config.getInstanceName())) {
return HazelcastClient.getHazelcastClientByName(config.getInstanceName());
}
return Hazelcast.newHazelcastInstance(this.config);
return HazelcastClient.newHazelcastClient(config);
}

/**
* Get the client {@link HazelcastInstance}.
* @param configLocation the location of the client configuration file
* @return the client {@link HazelcastInstance}
* @throws IOException if the configuration location could not be read
*/
public static HazelcastInstance createHazelcastClient(Resource configLocation)
throws IOException {
Assert.notNull(configLocation, "ConfigLocation must not be null");
URL configUrl = configLocation.getURL();
ClientConfig config = new XmlClientConfigBuilder(configUrl).build();
return createHazelcastClient(config);
}

}
Loading

0 comments on commit 3fbf1a2

Please sign in to comment.