Remove support for Hazelcast 3

Closes gh-29287
pull/29295/head
Stephane Nicoll 3 years ago
parent 9a05eb63c4
commit c62aa0deab

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2020 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,15 +16,12 @@
package org.springframework.boot.actuate.hazelcast; package org.springframework.boot.actuate.hazelcast;
import java.lang.reflect.Method;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/** /**
* {@link HealthIndicator} for Hazelcast. * {@link HealthIndicator} for Hazelcast.
@ -46,22 +43,10 @@ public class HazelcastHealthIndicator extends AbstractHealthIndicator {
@Override @Override
protected void doHealthCheck(Health.Builder builder) { protected void doHealthCheck(Health.Builder builder) {
this.hazelcast.executeTransaction((context) -> { this.hazelcast.executeTransaction((context) -> {
builder.up().withDetail("name", this.hazelcast.getName()).withDetail("uuid", extractUuid()); String uuid = this.hazelcast.getLocalEndpoint().getUuid().toString();
builder.up().withDetail("name", this.hazelcast.getName()).withDetail("uuid", uuid);
return null; return null;
}); });
} }
private String extractUuid() {
try {
return this.hazelcast.getLocalEndpoint().getUuid().toString();
}
catch (NoSuchMethodError ex) {
// Hazelcast 3
Method endpointAccessor = ReflectionUtils.findMethod(HazelcastInstance.class, "getLocalEndpoint");
Object endpoint = ReflectionUtils.invokeMethod(endpointAccessor, this.hazelcast);
Method uuidAccessor = ReflectionUtils.findMethod(endpoint.getClass(), "getUuid");
return (String) ReflectionUtils.invokeMethod(uuidAccessor, endpoint);
}
}
} }

@ -1,67 +0,0 @@
/*
* Copyright 2012-2022 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
*
* https://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.actuate.hazelcast;
import com.hazelcast.core.HazelcastException;
import com.hazelcast.core.HazelcastInstance;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.classpath.ClassPathOverrides;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link HazelcastHealthIndicator} with Hazelcast 3.
*
* @author Dmytro Nosan
* @author Stephane Nicoll
*/
@ClassPathExclusions("hazelcast*.jar")
@ClassPathOverrides("com.hazelcast:hazelcast:3.12.12")
class Hazelcast3HazelcastHealthIndicatorTests {
@Test
void hazelcastUp() {
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class))
.withPropertyValues("spring.hazelcast.config=hazelcast-3.xml").run((context) -> {
HazelcastInstance hazelcast = context.getBean(HazelcastInstance.class);
Health health = new HazelcastHealthIndicator(hazelcast).health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).containsOnlyKeys("name", "uuid").containsEntry("name",
"actuator-hazelcast-3");
assertThat(health.getDetails().get("uuid")).asString().isNotEmpty();
});
}
@Test
void hazelcastDown() {
HazelcastInstance hazelcast = mock(HazelcastInstance.class);
given(hazelcast.executeTransaction(any())).willThrow(new HazelcastException());
Health health = new HazelcastHealthIndicator(hazelcast).health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
}
}

@ -1,13 +0,0 @@
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config
http://www.hazelcast.com/schema/config/hazelcast-config-3.12.xsd">
<instance-name>actuator-hazelcast-3</instance-name>
<map name="defaultCache"/>
<network>
<join>
<tcp-ip enabled="false"/>
<multicast enabled="false"/>
</join>
</network>
</hazelcast>

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2020 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,19 +19,10 @@ package org.springframework.boot.autoconfigure.hazelcast;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Builder;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration.HazelcastDataGridCondition;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotatedTypeMetadata;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for Hazelcast IMDG. Creates a * {@link EnableAutoConfiguration Auto-configuration} for Hazelcast IMDG. Creates a
@ -44,26 +35,9 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
* @see HazelcastConfigResourceCondition * @see HazelcastConfigResourceCondition
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@Conditional(HazelcastDataGridCondition.class)
@ConditionalOnClass(HazelcastInstance.class) @ConditionalOnClass(HazelcastInstance.class)
@EnableConfigurationProperties(HazelcastProperties.class) @EnableConfigurationProperties(HazelcastProperties.class)
@Import({ HazelcastClientConfiguration.class, HazelcastServerConfiguration.class }) @Import({ HazelcastClientConfiguration.class, HazelcastServerConfiguration.class })
public class HazelcastAutoConfiguration { public class HazelcastAutoConfiguration {
static class HazelcastDataGridCondition extends SpringBootCondition {
private static final String HAZELCAST_JET_CONFIG_FILE = "classpath:/hazelcast-jet-default.yaml";
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Builder message = ConditionMessage.forCondition(HazelcastDataGridCondition.class.getSimpleName());
Resource resource = context.getResourceLoader().getResource(HAZELCAST_JET_CONFIG_FILE);
if (resource.exists()) {
return ConditionOutcome.noMatch(message.because("Found Hazelcast Jet on the classpath"));
}
return ConditionOutcome.match(message.because("Hazelcast Jet not found on the classpath"));
}
}
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2020 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,7 +45,7 @@ class HazelcastClientConfigAvailableCondition extends HazelcastConfigResourceCon
@Override @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (context.getEnvironment().containsProperty(HAZELCAST_CONFIG_PROPERTY)) { if (context.getEnvironment().containsProperty(HAZELCAST_CONFIG_PROPERTY)) {
ConditionOutcome configValidationOutcome = Hazelcast4ClientValidation.clientConfigOutcome(context, ConditionOutcome configValidationOutcome = HazelcastClientValidation.clientConfigOutcome(context,
HAZELCAST_CONFIG_PROPERTY, startConditionMessage()); HAZELCAST_CONFIG_PROPERTY, startConditionMessage());
return (configValidationOutcome != null) ? configValidationOutcome : ConditionOutcome return (configValidationOutcome != null) ? configValidationOutcome : ConditionOutcome
.match(startConditionMessage().foundExactly("property " + HAZELCAST_CONFIG_PROPERTY)); .match(startConditionMessage().foundExactly("property " + HAZELCAST_CONFIG_PROPERTY));
@ -53,7 +53,7 @@ class HazelcastClientConfigAvailableCondition extends HazelcastConfigResourceCon
return getResourceOutcome(context, metadata); return getResourceOutcome(context, metadata);
} }
static class Hazelcast4ClientValidation { static class HazelcastClientValidation {
static ConditionOutcome clientConfigOutcome(ConditionContext context, String propertyName, Builder builder) { static ConditionOutcome clientConfigOutcome(ConditionContext context, String propertyName, Builder builder) {
String resourcePath = context.getEnvironment().getProperty(propertyName); String resourcePath = context.getEnvironment().getProperty(propertyName);
@ -65,7 +65,7 @@ class HazelcastClientConfigAvailableCondition extends HazelcastConfigResourceCon
boolean clientConfig = new ClientConfigRecognizer().isRecognized(new ConfigStream(in)); boolean clientConfig = new ClientConfigRecognizer().isRecognized(new ConfigStream(in));
return new ConditionOutcome(clientConfig, existingConfigurationOutcome(resource, clientConfig)); return new ConditionOutcome(clientConfig, existingConfigurationOutcome(resource, clientConfig));
} }
catch (Throwable ex) { // Hazelcast 4 specific API catch (Throwable ex) {
return null; return null;
} }
} }

@ -1,93 +0,0 @@
/*
* Copyright 2012-2022 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
*
* https://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 com.hazelcast.client.impl.clientside.HazelcastClientProxy;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.spring.context.SpringManagedContext;
import org.assertj.core.api.Condition;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.classpath.ClassPathOverrides;
import org.springframework.core.io.ClassPathResource;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link HazelcastAutoConfiguration} with Hazelcast 3.
*
* @author Stephane Nicoll
*/
@ClassPathExclusions("hazelcast*.jar")
@ClassPathOverrides({ "com.hazelcast:hazelcast:3.12.12", "com.hazelcast:hazelcast-client:3.12.12",
"com.hazelcast:hazelcast-spring:3.12.12" })
class Hazelcast3AutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class));
@Test
void defaultConfigFile() {
// no hazelcast-client.xml and hazelcast.xml is present in root classpath
// this also asserts that XML has priority over YAML
// as both hazelcast.yaml and hazelcast.xml in test classpath.
this.contextRunner.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getConfigurationUrl()).isEqualTo(new ClassPathResource("hazelcast.xml").getURL());
});
}
@Test
void explicitConfigFileWithXml() {
HazelcastInstance hazelcastServer = Hazelcast.newHazelcastInstance();
try {
this.contextRunner
.withPropertyValues("spring.hazelcast.config=org/springframework/boot/autoconfigure/"
+ "hazelcast/hazelcast-client-specific.xml")
.run(assertSpecificHazelcastClient("explicit-xml"));
}
finally {
hazelcastServer.shutdown();
}
}
@Test
void autoConfiguredConfigUsesSpringManagedContext() {
this.contextRunner.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getManagedContext()).isInstanceOf(SpringManagedContext.class);
});
}
private ContextConsumer<AssertableApplicationContext> assertSpecificHazelcastClient(String label) {
return (context) -> assertThat(context).getBean(HazelcastInstance.class).isInstanceOf(HazelcastInstance.class)
.has(labelEqualTo(label));
}
private static Condition<HazelcastInstance> labelEqualTo(String label) {
return new Condition<>((o) -> ((HazelcastClientProxy) o).getClientConfig().getLabels().stream()
.anyMatch((e) -> e.equals(label)), "Label equals to " + label);
}
}

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2020 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,10 +16,6 @@
package org.springframework.boot.autoconfigure.hazelcast; package org.springframework.boot.autoconfigure.hazelcast;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import com.hazelcast.config.Config; import com.hazelcast.config.Config;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -27,7 +23,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -52,41 +47,4 @@ class HazelcastAutoConfigurationTests {
}); });
} }
@Test
void hazelcastInstanceNotCreatedWhenJetIsPresent() {
this.contextRunner.withClassLoader(new JetConfigClassLoader())
.run((context) -> assertThat(context).doesNotHaveBean(HazelcastInstance.class));
}
/**
* A test {@link URLClassLoader} that emulates the default Hazelcast Jet configuration
* file exists on the classpath.
*/
static class JetConfigClassLoader extends URLClassLoader {
private static final Resource FALLBACK = new ClassPathResource("hazelcast.yaml");
JetConfigClassLoader() {
super(new URL[0], JetConfigClassLoader.class.getClassLoader());
}
@Override
public URL getResource(String name) {
if (name.equals("hazelcast-jet-default.yaml")) {
return getEmulatedJetConfigUrl();
}
return super.getResource(name);
}
private URL getEmulatedJetConfigUrl() {
try {
return FALLBACK.getURL();
}
catch (IOException ex) {
throw new IllegalArgumentException(ex);
}
}
}
} }

@ -1,19 +0,0 @@
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.2.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queue name="foobar"/>
<map name="foobar">
<time-to-live-seconds>3600</time-to-live-seconds>
<max-idle-seconds>600</max-idle-seconds>
</map>
<network>
<join>
<tcp-ip enabled="false"/>
<multicast enabled="false"/>
</join>
</network>
</hazelcast>

@ -10,9 +10,6 @@ Spring Boot first attempts to create a client by checking the following configur
* A `hazelcast-client.xml` in the working directory or at the root of the classpath. * A `hazelcast-client.xml` in the working directory or at the root of the classpath.
* A `hazelcast-client.yaml` in the working directory or at the root of the classpath. * A `hazelcast-client.yaml` in the working directory or at the root of the classpath.
WARNING: Hazelcast 3 support is deprecated.
If you still need to downgrade to Hazelcast 3, `hazelcast-client` should be added to the classpath to configure a client.
If a client can not be created, Spring Boot attempts to configure an embedded server. If a client can not be created, Spring Boot attempts to configure an embedded server.
If you define a `com.hazelcast.config.Config` bean, Spring Boot uses that. If you define a `com.hazelcast.config.Config` bean, Spring Boot uses that.
If your configuration defines an instance name, Spring Boot tries to locate an existing instance rather than creating a new one. If your configuration defines an instance name, Spring Boot tries to locate an existing instance rather than creating a new one.

Loading…
Cancel
Save