Skip to content

Commit

Permalink
Improve Hazelcast test suite performance
Browse files Browse the repository at this point in the history
* Add recommended JVM args to the Gradle module for HZ performance
* Move `IdempotentReceiverIntegrationTests` from JMX module to HZ for consistency
* Remove component scan from the `HazelcastIntegrationOutboundTestConfiguration` - redundant
* Use `HazelcastInstance.shutdown()` during normal context lifecycle.
The `@AfterClass` may happen early, so the `stop()` of the channel adapters may fail with
an exception that HZ is not available causing the `LifecycleProcessor` to wait for 30 seconds
on the lifecycle barrier
* Wrap `AbstractEndpoint.doStop()` call into `try..catch` to log error instead of re-throwing
to avoid the mentioned above 30 secs delay of the application context stop
  • Loading branch information
artembilan committed May 25, 2022
1 parent a322f5c commit 751d808
Show file tree
Hide file tree
Showing 19 changed files with 65 additions and 155 deletions.
30 changes: 20 additions & 10 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,26 @@ project('spring-integration-groovy') {
}
}

project('spring-integration-hazelcast') {
description = 'Spring Integration Hazelcast Support'
dependencies {
api project(':spring-integration-core')
api "com.hazelcast:hazelcast:$hazelcastVersion"

testImplementation project(':spring-integration-jmx')
}

tasks.withType(JavaForkOptions) {
jvmArgs '--add-modules', 'java.se',
'--add-exports', 'java.base/jdk.internal.ref=ALL-UNNAMED',
'--add-opens', 'java.base/java.lang=ALL-UNNAMED',
'--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED',
'--add-opens', 'java.management/sun.management=ALL-UNNAMED',
'--add-opens', 'jdk.management/com.sun.management.internal=ALL-UNNAMED',
'-Dhazelcast.logging.type=log4j2'
}
}

project('spring-integration-http') {
description = 'Spring Integration HTTP Support'
dependencies {
Expand Down Expand Up @@ -722,7 +742,6 @@ project('spring-integration-jmx') {
api project(':spring-integration-core')

testImplementation "org.aspectj:aspectjweaver:$aspectjVersion"
testImplementation "com.hazelcast:hazelcast:$hazelcastVersion"
}
}

Expand Down Expand Up @@ -1080,15 +1099,6 @@ project('spring-integration-bom') {
}
}


project('spring-integration-hazelcast') {
description = 'Spring Integration Hazelcast Support'
dependencies {
api "com.hazelcast:hazelcast:$hazelcastVersion"
api project(':spring-integration-core')
}
}

sonarqube {
properties {
property 'sonar.links.homepage', linkHomepage
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-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.
Expand Down Expand Up @@ -204,7 +204,12 @@ public final void stop(Runnable callback) {
* @param callback the Runnable to invoke.
*/
protected void doStop(Runnable callback) {
doStop();
try {
doStop();
}
catch (Exception ex) {
logger.error(ex, "Error during stopping: " + this);
}
callback.run();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<constructor-arg value="distList"/>
</bean>

<bean id="hzInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance">
<bean id="hzInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance" destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="instanceName" value="Test_Hazelcast_Instance"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-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.
Expand All @@ -14,10 +14,10 @@
* limitations under the License.
*/

package org.springframework.integration.monitor;
package org.springframework.integration.hazelcast;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.spy;

import java.util.ArrayList;
Expand All @@ -27,8 +27,7 @@
import java.util.concurrent.atomic.AtomicInteger;

import org.aopalliance.aop.Advice;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
Expand Down Expand Up @@ -67,21 +66,21 @@
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.support.TransactionSynchronizationManager;

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

/**
* @author Artem Bilan
* @author Gary Russell
*
* @since 4.1
*/
@RunWith(SpringRunner.class)
@SpringJUnitConfig
@DirtiesContext
public class IdempotentReceiverIntegrationTests {

Expand Down Expand Up @@ -125,6 +124,7 @@ public class IdempotentReceiverIntegrationTests {
private AtomicBoolean txSupplied;

@Test
@SuppressWarnings("unchecked")
public void testIdempotentReceiver() {
this.idempotentReceiverInterceptor.setThrowExceptionOnRejection(true);
TestUtils.getPropertyValue(this.store, "metadata", Map.class).clear();
Expand All @@ -133,25 +133,20 @@ public void testIdempotentReceiver() {
Message<?> receive = this.output.receive(10000);
assertThat(receive).isNotNull();
assertThat(this.adviceCalled.get()).isEqualTo(1);
assertThat(TestUtils.getPropertyValue(this.store, "metadata", Map.class).size()).isEqualTo(1);
assertThat(TestUtils.getPropertyValue(this.store, "metadata", Map.class)).hasSize(1);
String foo = this.store.get("foo");
assertThat(foo).isEqualTo("FOO");

try {
this.input.send(message);
fail("MessageRejectedException expected");
}
catch (Exception e) {
assertThat(e).isInstanceOf(MessageRejectedException.class);
}
assertThatExceptionOfType(MessageRejectedException.class)
.isThrownBy(() -> this.input.send(message));

this.idempotentReceiverInterceptor.setThrowExceptionOnRejection(false);
this.input.send(message);
receive = this.output.receive(10000);
assertThat(receive).isNotNull();
assertThat(this.adviceCalled.get()).isEqualTo(2);
assertThat(receive.getHeaders().get(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, Boolean.class))
.isTrue();
assertThat(TestUtils.getPropertyValue(store, "metadata", Map.class).size()).isEqualTo(1);
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
assertThat(TestUtils.getPropertyValue(store, "metadata", Map.class)).hasSize(1);

assertThat(this.txSupplied.get()).isTrue();
}
Expand All @@ -165,8 +160,7 @@ public void testIdempotentReceiverOnMethod() {

assertThat(this.fooService.messages.size()).isEqualTo(2);
assertThat(this.fooService.messages.get(1)
.getHeaders()
.get(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, Boolean.class)).isTrue();
.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}

@Test
Expand All @@ -177,23 +171,18 @@ public void testIdempotentReceiverOnBeanMessageHandler() {

Message<?> receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders().containsKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE)).isFalse();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);

this.annotatedBeanMessageHandlerChannel.send(message);
receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders().containsKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE)).isTrue();
assertThat(receive.getHeaders().get(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, Boolean.class))
.isTrue();

this.annotatedBeanMessageHandlerChannel2.send(new GenericMessage<String>("baz"));
try {
this.annotatedBeanMessageHandlerChannel2.send(new GenericMessage<String>("baz"));
fail("MessageHandlingException expected");
}
catch (Exception e) {
assertThat(e.getMessage()).contains("duplicate message has been received");
}
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);

this.annotatedBeanMessageHandlerChannel2.send(new GenericMessage<>("baz"));

assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> this.annotatedBeanMessageHandlerChannel2.send(new GenericMessage<>("baz")))
.withMessageContaining("duplicate message has been received");
}


Expand All @@ -205,14 +194,12 @@ public void testIdempotentReceiverOnBridgeTo() {

Message<?> receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders().containsKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE)).isFalse();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);

this.bridgeChannel.send(message);
receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders().containsKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE)).isTrue();
assertThat(receive.getHeaders().get(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, Boolean.class))
.isTrue();
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}

@Test
Expand All @@ -222,14 +209,12 @@ public void testIdempotentReceiverOnBridgeFrom() {

Message<?> receive = this.bridgePollableChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders().containsKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE)).isFalse();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);

this.toBridgeChannel.send(message);
receive = this.bridgePollableChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders().containsKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE)).isTrue();
assertThat(receive.getHeaders().get(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, Boolean.class))
.isTrue();
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}

@Configuration
Expand All @@ -242,9 +227,9 @@ public static MBeanServerFactoryBean mBeanServer() {
return new MBeanServerFactoryBean();
}

@Bean
@Bean(destroyMethod = "shutdown")
public HazelcastInstance hazelcastInstance() {
return Hazelcast.newHazelcastInstance(new Config().setProperty("hazelcast.logging.type", "slf4j"));
return Hazelcast.newHazelcastInstance();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="instance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance">
<bean id="instance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance" destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="CPSubsystemConfig">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -34,7 +33,6 @@
import org.springframework.test.context.junit4.SpringRunner;

import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;

/**
Expand Down Expand Up @@ -79,11 +77,6 @@ public class HazelcastCQDistributedMapInboundChannelAdapterTests {
@Autowired
private IMap cqDistributedMap5;

@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}

@Test
public void testContinuousQueryForOnlyADDEDEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -34,7 +33,6 @@

import com.hazelcast.collection.IList;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;

/**
* Hazelcast Distributed List Event Driven Inbound Channel Adapter Test Class
Expand Down Expand Up @@ -66,11 +64,6 @@ public class HazelcastDistributedListEventDrivenInboundChannelAdapterTests {
@Autowired
private IList edDistributedList3;

@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}

@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedList1.add(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -34,7 +33,6 @@
import org.springframework.test.context.junit4.SpringRunner;

import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;

/**
Expand Down Expand Up @@ -73,11 +71,6 @@ public class HazelcastDistributedMapEventDrivenInboundChannelAdapterTests {
@Autowired
private IMap edDistributedMap4;

@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}

@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -34,7 +33,6 @@

import com.hazelcast.collection.IQueue;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;

/**
* Hazelcast Distributed Queue Event Driven Inbound Channel Adapter Test
Expand Down Expand Up @@ -66,11 +64,6 @@ public class HazelcastDistributedQueueEventDrivenInboundChannelAdapterTests {
@Autowired
private IQueue edDistributedQueue3;

@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}

@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedQueue1
Expand Down
Loading

0 comments on commit 751d808

Please sign in to comment.