Polish "Add auto-configuration support for Hazelcast client"
Closes gh-7469
This commit is contained in:
parent
3fbf1a2ea6
commit
0aded58884
|
|
@ -16,12 +16,10 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.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.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
|
@ -39,21 +37,7 @@ import org.springframework.context.annotation.Import;
|
|||
@Configuration
|
||||
@ConditionalOnClass(HazelcastInstance.class)
|
||||
@EnableConfigurationProperties(HazelcastProperties.class)
|
||||
@Import({ HazelcastClientConfiguration.class, HazelcastServerConfiguration.class })
|
||||
public class HazelcastAutoConfiguration {
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(HazelcastInstance.class)
|
||||
@Import(HazelcastServerConfiguration.class)
|
||||
static class ServerConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(HazelcastClient.class)
|
||||
@ConditionalOnMissingBean(HazelcastInstance.class)
|
||||
@Import(HazelcastClientConfiguration.class)
|
||||
static class ClientConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.hazelcast.client.HazelcastClient;
|
|||
import com.hazelcast.client.config.ClientConfig;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
|
@ -33,8 +34,10 @@ import org.springframework.core.io.Resource;
|
|||
* Configuration for Hazelcast client.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ConditionalOnClass(HazelcastClient.class)
|
||||
@ConditionalOnMissingBean(HazelcastInstance.class)
|
||||
class HazelcastClientConfiguration {
|
||||
|
||||
static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.client.config";
|
||||
|
|
@ -49,7 +52,7 @@ class HazelcastClientConfiguration {
|
|||
throws IOException {
|
||||
Resource config = properties.resolveConfigLocation();
|
||||
if (config != null) {
|
||||
return HazelcastInstanceFactory.createHazelcastClient(config);
|
||||
return new HazelcastClientFactory(config).getHazelcastInstance();
|
||||
}
|
||||
return HazelcastClient.newHazelcastClient();
|
||||
}
|
||||
|
|
@ -62,7 +65,7 @@ class HazelcastClientConfiguration {
|
|||
|
||||
@Bean
|
||||
public HazelcastInstance hazelcastInstance(ClientConfig config) {
|
||||
return HazelcastInstanceFactory.createHazelcastClient(config);
|
||||
return new HazelcastClientFactory(config).getHazelcastInstance();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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 java.net.URL;
|
||||
|
||||
import com.hazelcast.client.HazelcastClient;
|
||||
import com.hazelcast.client.config.ClientConfig;
|
||||
import com.hazelcast.client.config.XmlClientConfigBuilder;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Factory that can be used to create a client {@link HazelcastInstance}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class HazelcastClientFactory {
|
||||
|
||||
private final ClientConfig clientConfig;
|
||||
|
||||
/**
|
||||
* Create a {@link HazelcastClientFactory} for the specified configuration location.
|
||||
* @param clientConfigLocation the location of the configuration file
|
||||
* @throws IOException if the configuration location could not be read
|
||||
*/
|
||||
public HazelcastClientFactory(Resource clientConfigLocation) throws IOException {
|
||||
this.clientConfig = getClientConfig(clientConfigLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link HazelcastClientFactory} for the specified configuration.
|
||||
* @param clientConfig the configuration
|
||||
*/
|
||||
public HazelcastClientFactory(ClientConfig clientConfig) {
|
||||
Assert.notNull(clientConfig, "ClientConfig must not be null");
|
||||
this.clientConfig = clientConfig;
|
||||
}
|
||||
|
||||
|
||||
private ClientConfig getClientConfig(Resource clientConfigLocation)
|
||||
throws IOException {
|
||||
URL configUrl = clientConfigLocation.getURL();
|
||||
return new XmlClientConfigBuilder(configUrl).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link HazelcastInstance}.
|
||||
* @return the {@link HazelcastInstance}
|
||||
*/
|
||||
public HazelcastInstance getHazelcastInstance() {
|
||||
if (StringUtils.hasText(this.clientConfig.getInstanceName())) {
|
||||
return HazelcastClient.getHazelcastClientByName(
|
||||
this.clientConfig.getInstanceName());
|
||||
}
|
||||
return HazelcastClient.newHazelcastClient(this.clientConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,9 +19,6 @@ 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.config.Config;
|
||||
import com.hazelcast.config.XmlConfigBuilder;
|
||||
import com.hazelcast.core.Hazelcast;
|
||||
|
|
@ -37,33 +34,32 @@ import org.springframework.util.StringUtils;
|
|||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Vedran Pavic
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public abstract class HazelcastInstanceFactory {
|
||||
public class HazelcastInstanceFactory {
|
||||
|
||||
private final Config config;
|
||||
|
||||
/**
|
||||
* Get the {@link HazelcastInstance}.
|
||||
* @param config the configuration
|
||||
* @return the {@link HazelcastInstance}
|
||||
* 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 static HazelcastInstance createHazelcastInstance(Config config) {
|
||||
Assert.notNull(config, "Config must not be null");
|
||||
if (StringUtils.hasText(config.getInstanceName())) {
|
||||
return Hazelcast.getOrCreateHazelcastInstance(config);
|
||||
}
|
||||
return Hazelcast.newHazelcastInstance(config);
|
||||
public HazelcastInstanceFactory(Resource configLocation) throws IOException {
|
||||
Assert.notNull(configLocation, "ConfigLocation must not be null");
|
||||
this.config = getConfig(configLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Create a {@link HazelcastInstanceFactory} for the specified configuration.
|
||||
* @param config the configuration
|
||||
*/
|
||||
public static HazelcastInstance createHazelcastInstance(Resource configLocation)
|
||||
throws IOException {
|
||||
Assert.notNull(configLocation, "ConfigLocation must not be null");
|
||||
public HazelcastInstanceFactory(Config config) {
|
||||
Assert.notNull(config, "Config must not be null");
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
private Config getConfig(Resource configLocation) throws IOException {
|
||||
URL configUrl = configLocation.getURL();
|
||||
Config config = new XmlConfigBuilder(configUrl).build();
|
||||
if (ResourceUtils.isFileURL(configUrl)) {
|
||||
|
|
@ -72,34 +68,18 @@ public abstract class HazelcastInstanceFactory {
|
|||
else {
|
||||
config.setConfigurationUrl(configUrl);
|
||||
}
|
||||
return createHazelcastInstance(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client {@link HazelcastInstance}.
|
||||
* @param config the client configuration
|
||||
* @return the client {@link HazelcastInstance}
|
||||
* Get the {@link HazelcastInstance}.
|
||||
* @return the {@link HazelcastInstance}
|
||||
*/
|
||||
public static HazelcastInstance createHazelcastClient(ClientConfig config) {
|
||||
Assert.notNull(config, "Config must not be null");
|
||||
if (StringUtils.hasText(config.getInstanceName())) {
|
||||
return HazelcastClient.getHazelcastClientByName(config.getInstanceName());
|
||||
public HazelcastInstance getHazelcastInstance() {
|
||||
if (StringUtils.hasText(this.config.getInstanceName())) {
|
||||
return Hazelcast.getOrCreateHazelcastInstance(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);
|
||||
return Hazelcast.newHazelcastInstance(this.config);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ import org.springframework.core.io.Resource;
|
|||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@ConditionalOnMissingBean(HazelcastInstance.class)
|
||||
class HazelcastServerConfiguration {
|
||||
|
||||
static final String CONFIG_SYSTEM_PROPERTY = "hazelcast.config";
|
||||
|
|
@ -50,7 +50,7 @@ class HazelcastServerConfiguration {
|
|||
throws IOException {
|
||||
Resource config = properties.resolveConfigLocation();
|
||||
if (config != null) {
|
||||
return HazelcastInstanceFactory.createHazelcastInstance(config);
|
||||
return new HazelcastInstanceFactory(config).getHazelcastInstance();
|
||||
}
|
||||
return Hazelcast.newHazelcastInstance();
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ class HazelcastServerConfiguration {
|
|||
|
||||
@Bean
|
||||
public HazelcastInstance hazelcastInstance(Config config) {
|
||||
return HazelcastInstanceFactory.createHazelcastInstance(config);
|
||||
return new HazelcastInstanceFactory(config).getHazelcastInstance();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,9 +39,10 @@ import org.springframework.context.annotation.Configuration;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for client {@link HazelcastAutoConfiguration}.
|
||||
* Tests for {@link HazelcastAutoConfiguration} specific to the client.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class HazelcastAutoConfigurationClientTests {
|
||||
|
||||
|
|
@ -50,24 +51,27 @@ public class HazelcastAutoConfigurationClientTests {
|
|||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static HazelcastInstance hazelcastInstance;
|
||||
/**
|
||||
* Servers the test clients will connect to.
|
||||
*/
|
||||
private static HazelcastInstance hazelcastServer;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
hazelcastInstance = Hazelcast.newHazelcastInstance();
|
||||
hazelcastServer = Hazelcast.newHazelcastInstance();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void close() {
|
||||
if (hazelcastInstance != null) {
|
||||
hazelcastInstance.shutdown();
|
||||
if (hazelcastServer != null) {
|
||||
hazelcastServer.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +119,7 @@ public class HazelcastAutoConfigurationClientTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void clientConfigHasPriority() {
|
||||
public void clientConfigTakesPrecedence() {
|
||||
load(HazelcastServerAndClientConfig.class, "spring.hazelcast.config=this-is-ignored.xml");
|
||||
HazelcastInstance hazelcastInstance = this.context
|
||||
.getBean(HazelcastInstance.class);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import org.springframework.core.io.ClassPathResource;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link HazelcastAutoConfiguration}.
|
||||
* Tests for {@link HazelcastAutoConfiguration} when the client library is not present.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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.core.HazelcastInstance;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link HazelcastAutoConfiguration} with full classpath.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class HazelcastAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultConfigFile() throws IOException {
|
||||
load(); // no hazelcast-client.xml and hazelcast.xml is present in root classpath
|
||||
HazelcastInstance hazelcastInstance = this.context
|
||||
.getBean(HazelcastInstance.class);
|
||||
assertThat(hazelcastInstance.getConfig().getConfigurationUrl())
|
||||
.isEqualTo(new ClassPathResource("hazelcast.xml").getURL());
|
||||
}
|
||||
|
||||
private void load(String... environment) {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(ctx, environment);
|
||||
ctx.register(HazelcastAutoConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5111,9 +5111,8 @@ 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.
|
||||
If hazelcast is on the classpath and a suitable configuration is found, Spring Boot
|
||||
will auto-configure an `HazelcastInstance` that you can inject in your application.
|
||||
|
||||
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
|
||||
|
|
@ -5132,6 +5131,14 @@ classpath. We also check if the `hazelcast.config` system property is set. Check
|
|||
http://docs.hazelcast.org/docs/latest/manual/html-single/[Hazelcast documentation] for
|
||||
more details.
|
||||
|
||||
If `hazelcast-client` is present on the classpath, Spring Boot will first attempt to
|
||||
create a client with similar rules as above, that is:
|
||||
|
||||
* The presence of a `com.hazelcast.client.config.ClientConfig` bean
|
||||
* A configuration file defined by the `spring.hazelcast.config` property
|
||||
* The presence of the `hazelcast.client.config` system property
|
||||
* A `hazelcast-client.xml` in the working directory or at the root of the classpath
|
||||
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue