Skip to content

Commit c6668c2

Browse files
committed
Add auto-configuration support for Hazelcast client
1 parent 15401a3 commit c6668c2

File tree

12 files changed

+563
-87
lines changed

12 files changed

+563
-87
lines changed

spring-boot-autoconfigure/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@
7575
<artifactId>hazelcast</artifactId>
7676
<optional>true</optional>
7777
</dependency>
78+
<dependency>
79+
<groupId>com.hazelcast</groupId>
80+
<artifactId>hazelcast-client</artifactId>
81+
<optional>true</optional>
82+
</dependency>
7883
<dependency>
7984
<groupId>com.hazelcast</groupId>
8085
<artifactId>hazelcast-spring</artifactId>

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfiguration.java

Lines changed: 10 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,79 +16,43 @@
1616

1717
package org.springframework.boot.autoconfigure.hazelcast;
1818

19-
import java.io.IOException;
20-
21-
import com.hazelcast.config.Config;
22-
import com.hazelcast.core.Hazelcast;
19+
import com.hazelcast.client.HazelcastClient;
2320
import com.hazelcast.core.HazelcastInstance;
2421

2522
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2623
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2724
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
28-
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
2925
import org.springframework.boot.context.properties.EnableConfigurationProperties;
30-
import org.springframework.context.annotation.Bean;
31-
import org.springframework.context.annotation.Conditional;
3226
import org.springframework.context.annotation.Configuration;
33-
import org.springframework.core.io.Resource;
27+
import org.springframework.context.annotation.Import;
3428

3529
/**
3630
* {@link EnableAutoConfiguration Auto-configuration} for Hazelcast. Creates a
3731
* {@link HazelcastInstance} based on explicit configuration or when a default
3832
* configuration file is found in the environment.
3933
*
4034
* @author Stephane Nicoll
35+
* @author Vedran Pavic
4136
* @since 1.3.0
4237
* @see HazelcastConfigResourceCondition
4338
*/
4439
@Configuration
4540
@ConditionalOnClass(HazelcastInstance.class)
46-
@ConditionalOnMissingBean(HazelcastInstance.class)
4741
@EnableConfigurationProperties(HazelcastProperties.class)
4842
public class HazelcastAutoConfiguration {
4943

5044
@Configuration
51-
@ConditionalOnMissingBean(Config.class)
52-
@Conditional(ConfigAvailableCondition.class)
53-
static class HazelcastConfigFileConfiguration {
54-
55-
private final HazelcastProperties hazelcastProperties;
56-
57-
HazelcastConfigFileConfiguration(HazelcastProperties hazelcastProperties) {
58-
this.hazelcastProperties = hazelcastProperties;
59-
}
60-
61-
@Bean
62-
public HazelcastInstance hazelcastInstance() throws IOException {
63-
Resource config = this.hazelcastProperties.resolveConfigLocation();
64-
if (config != null) {
65-
return new HazelcastInstanceFactory(config).getHazelcastInstance();
66-
}
67-
return Hazelcast.newHazelcastInstance();
68-
}
45+
@ConditionalOnClass(HazelcastClient.class)
46+
@ConditionalOnMissingBean(HazelcastInstance.class)
47+
@Import(HazelcastClientConfiguration.class)
48+
static class ClientConfig {
6949

7050
}
7151

7252
@Configuration
73-
@ConditionalOnSingleCandidate(Config.class)
74-
static class HazelcastConfigConfiguration {
75-
76-
@Bean
77-
public HazelcastInstance hazelcastInstance(Config config) {
78-
return new HazelcastInstanceFactory(config).getHazelcastInstance();
79-
}
80-
81-
}
82-
83-
/**
84-
* {@link HazelcastConfigResourceCondition} that checks if the
85-
* {@code spring.hazelcast.config} configuration key is defined.
86-
*/
87-
static class ConfigAvailableCondition extends HazelcastConfigResourceCondition {
88-
89-
ConfigAvailableCondition() {
90-
super("spring.hazelcast", "config");
91-
}
53+
@ConditionalOnMissingBean(HazelcastInstance.class)
54+
@Import(HazelcastServerConfiguration.class)
55+
static class ServerConfig {
9256

9357
}
9458

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.hazelcast;
18+
19+
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
20+
import org.springframework.boot.autoconfigure.condition.ResourceCondition;
21+
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
22+
import org.springframework.context.annotation.ConditionContext;
23+
import org.springframework.core.type.AnnotatedTypeMetadata;
24+
25+
/**
26+
* {@link SpringBootCondition} used to check if the Hazelcast Client configuration is
27+
* available. This either kicks in if a default configuration has been found or if
28+
* configurable property referring to the resource to use has been set.
29+
*
30+
* @author Vedran Pavic
31+
*/
32+
public abstract class HazelcastClientConfigResourceCondition extends ResourceCondition {
33+
34+
static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.client.config";
35+
36+
protected HazelcastClientConfigResourceCondition(String prefix, String propertyName) {
37+
super("Hazelcast", prefix, propertyName, "file:./hazelcast-client.xml",
38+
"classpath:/hazelcast-client.xml");
39+
}
40+
41+
@Override
42+
protected ConditionOutcome getResourceOutcome(ConditionContext context,
43+
AnnotatedTypeMetadata metadata) {
44+
if (System.getProperty(CONFIG_SYSTEM_PROPERTY) != null) {
45+
return ConditionOutcome.match(startConditionMessage()
46+
.because("System property '" + CONFIG_SYSTEM_PROPERTY + "' is set."));
47+
}
48+
return super.getResourceOutcome(context, metadata);
49+
}
50+
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.hazelcast;
18+
19+
import java.io.IOException;
20+
21+
import com.hazelcast.client.HazelcastClient;
22+
import com.hazelcast.client.config.ClientConfig;
23+
import com.hazelcast.core.HazelcastInstance;
24+
25+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.Conditional;
29+
import org.springframework.context.annotation.Configuration;
30+
import org.springframework.core.io.Resource;
31+
32+
/**
33+
* Hazelcast client instance configuration.
34+
*
35+
* @author Vedran Pavic
36+
* @see HazelcastClientConfigResourceCondition
37+
*/
38+
@Configuration
39+
class HazelcastClientConfiguration {
40+
41+
@Configuration
42+
@ConditionalOnMissingBean(ClientConfig.class)
43+
@Conditional(ClientConfigAvailableCondition.class)
44+
static class HazelcastClientConfigFileConfiguration {
45+
46+
private final HazelcastProperties hazelcastProperties;
47+
48+
HazelcastClientConfigFileConfiguration(HazelcastProperties hazelcastProperties) {
49+
this.hazelcastProperties = hazelcastProperties;
50+
}
51+
52+
@Bean
53+
public HazelcastInstance hazelcastClient() throws IOException {
54+
Resource clientConfig = this.hazelcastProperties
55+
.resolveClientConfigLocation();
56+
if (clientConfig != null) {
57+
return new HazelcastClientInstanceFactory(clientConfig)
58+
.getHazelcastInstance();
59+
}
60+
return HazelcastClient.newHazelcastClient();
61+
}
62+
63+
}
64+
65+
@Configuration
66+
@ConditionalOnSingleCandidate(ClientConfig.class)
67+
static class HazelcastClientConfigConfiguration {
68+
69+
@Bean
70+
public HazelcastInstance hazelcastClient(ClientConfig clientConfig) {
71+
return new HazelcastClientInstanceFactory(clientConfig)
72+
.getHazelcastInstance();
73+
}
74+
75+
}
76+
77+
/**
78+
* {@link HazelcastClientConfigResourceCondition} that checks if the
79+
* {@code spring.hazelcast.client-config} configuration key is defined.
80+
*/
81+
static class ClientConfigAvailableCondition
82+
extends HazelcastClientConfigResourceCondition {
83+
84+
ClientConfigAvailableCondition() {
85+
super("spring.hazelcast", "client-config");
86+
}
87+
88+
}
89+
90+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.hazelcast;
18+
19+
import java.io.IOException;
20+
import java.net.URL;
21+
22+
import com.hazelcast.client.HazelcastClient;
23+
import com.hazelcast.client.config.ClientConfig;
24+
import com.hazelcast.client.config.XmlClientConfigBuilder;
25+
import com.hazelcast.core.HazelcastInstance;
26+
27+
import org.springframework.core.io.Resource;
28+
import org.springframework.util.Assert;
29+
30+
/**
31+
* Factory that can be used to create a client {@link HazelcastInstance}.
32+
*
33+
* @author Vedran Pavic
34+
*/
35+
public class HazelcastClientInstanceFactory {
36+
37+
private ClientConfig config;
38+
39+
/**
40+
* Create a {@link HazelcastClientInstanceFactory} for the specified configuration
41+
* location.
42+
* @param configLocation the location of the configuration file
43+
* @throws IOException if the configuration location could not be read
44+
*/
45+
public HazelcastClientInstanceFactory(Resource configLocation) throws IOException {
46+
Assert.notNull(configLocation, "ConfigLocation must not be null");
47+
this.config = getConfig(configLocation);
48+
}
49+
50+
/**
51+
* Create a {@link HazelcastClientInstanceFactory} for the specified configuration.
52+
* @param config the configuration
53+
*/
54+
public HazelcastClientInstanceFactory(ClientConfig config) {
55+
Assert.notNull(config, "Config must not be null");
56+
this.config = config;
57+
}
58+
59+
private ClientConfig getConfig(Resource configLocation) throws IOException {
60+
URL configUrl = configLocation.getURL();
61+
return new XmlClientConfigBuilder(configUrl).build();
62+
}
63+
64+
/**
65+
* Get the {@link HazelcastInstance}.
66+
* @return the {@link HazelcastInstance}
67+
*/
68+
public HazelcastInstance getHazelcastInstance() {
69+
return HazelcastClient.newHazelcastClient(this.config);
70+
}
71+
72+
}

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastProperties.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
2424
* Configuration properties for the hazelcast integration.
2525
*
2626
* @author Stephane Nicoll
27+
* @author Vedran Pavic
2728
* @since 1.3.0
2829
*/
2930
@ConfigurationProperties("spring.hazelcast")
@@ -34,6 +35,11 @@ public class HazelcastProperties {
3435
*/
3536
private Resource config;
3637

38+
/**
39+
* The location of the configuration file to use to initialize Hazelcast client.
40+
*/
41+
private Resource clientConfig;
42+
3743
public Resource getConfig() {
3844
return this.config;
3945
}
@@ -42,6 +48,14 @@ public void setConfig(Resource config) {
4248
this.config = config;
4349
}
4450

51+
public Resource getClientConfig() {
52+
return this.clientConfig;
53+
}
54+
55+
public void setClientConfig(Resource clientConfig) {
56+
this.clientConfig = clientConfig;
57+
}
58+
4559
/**
4660
* Resolve the config location if set.
4761
* @return the location or {@code null} if it is not set
@@ -57,4 +71,19 @@ public Resource resolveConfigLocation() {
5771
return this.config;
5872
}
5973

74+
/**
75+
* Resolve the client config location if set.
76+
* @return the location or {@code null} if it is not set
77+
* @throws IllegalArgumentException if the client config attribute is set to an
78+
* unknown location
79+
*/
80+
public Resource resolveClientConfigLocation() {
81+
if (this.clientConfig == null) {
82+
return null;
83+
}
84+
Assert.isTrue(this.clientConfig.exists(), "Hazelcast client configuration does " +
85+
"not exist '" + this.clientConfig.getDescription() + "'");
86+
return this.clientConfig;
87+
}
88+
6089
}

0 commit comments

Comments
 (0)