Revert "GH-9441: Deprecate Hazelcast module"

This reverts commit 96ddc019
This commit is contained in:
Artem Bilan
2025-04-16 12:18:44 -04:00
parent 5a1c3be1ee
commit 0f225d86c1
69 changed files with 6154 additions and 71 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -26,7 +26,6 @@ package org.springframework.integration.hazelcast;
*
* @see org.springframework.integration.hazelcast.inbound.AbstractHazelcastMessageProducer
*/
@Deprecated(forRemoval = true, since = "6.5")
public enum CacheEventType {
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -26,7 +26,6 @@ package org.springframework.integration.hazelcast;
*
* @see org.springframework.integration.hazelcast.inbound.AbstractHazelcastMessageProducer
*/
@Deprecated(forRemoval = true, since = "6.5")
public enum CacheListeningPolicyType {
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -28,7 +28,6 @@ package org.springframework.integration.hazelcast;
* @see com.hazelcast.core.DistributedObjectListener
* @see com.hazelcast.core.LifecycleListener
*/
@Deprecated(forRemoval = true, since = "6.5")
public enum ClusterMonitorType {
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -27,7 +27,6 @@ package org.springframework.integration.hazelcast;
* @see org.springframework.integration.hazelcast.inbound.HazelcastDistributedSQLMessageSource
* @see com.hazelcast.map.IMap
*/
@Deprecated(forRemoval = true, since = "6.5")
public enum DistributedSQLIterationType {
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -24,7 +24,6 @@ package org.springframework.integration.hazelcast;
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
public abstract class HazelcastHeaders {
private static final String PREFIX = "hazelcast_";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -40,8 +40,6 @@ import org.springframework.util.StringUtils;
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public final class HazelcastIntegrationDefinitionValidator {
public static <E extends Enum<E>> Set<String> validateEnumType(final Class<E> enumType, final String types) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -40,8 +40,6 @@ import org.springframework.integration.hazelcast.listener.HazelcastMembershipLis
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastLocalInstanceRegistrar implements SmartInitializingSingleton {
private static final Log logger = LogFactory.getLog(HazelcastLocalInstanceRegistrar.class);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -31,8 +31,6 @@ import org.springframework.integration.hazelcast.HazelcastLocalInstanceRegistrar
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastIntegrationConfigurationInitializer implements IntegrationConfigurationInitializer {
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -34,8 +34,6 @@ import org.springframework.util.StringUtils;
* @author Eren Avsarogullari
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastClusterMonitorInboundChannelAdapterParser extends
AbstractSingleBeanDefinitionParser {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -37,8 +37,6 @@ import org.springframework.util.StringUtils;
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastContinuousQueryInboundChannelAdapterParser extends AbstractSingleBeanDefinitionParser {
private static final String CHANNEL_ATTRIBUTE = "channel";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-2024 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.
@@ -33,8 +33,6 @@ import org.springframework.util.StringUtils;
* @author Eren Avsarogullari
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastDistributedSQLInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
private static final String CACHE_ATTRIBUTE = "cache";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015 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.
@@ -35,8 +35,6 @@ import org.springframework.util.StringUtils;
* @author Eren Avsarogullari
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastEventDrivenInboundChannelAdapterParser extends AbstractSingleBeanDefinitionParser {
private static final String CHANNEL_ATTRIBUTE = "channel";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015 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.
@@ -24,8 +24,6 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
* @author Eren Avsarogullari
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastIntegrationNamespaceHandler extends AbstractIntegrationNamespaceHandler {
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015 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.
@@ -33,8 +33,6 @@ import org.springframework.integration.hazelcast.outbound.HazelcastCacheWritingM
* @author Eren Avsarogullari
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
private static final String CACHE_ATTRIBUTE = "cache";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-2024 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.
@@ -54,8 +54,6 @@ import org.springframework.util.Assert;
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public abstract class AbstractHazelcastMessageProducer extends MessageProducerSupport {
protected final DistributedObject distributedObject;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -50,8 +50,6 @@ import org.springframework.util.Assert;
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastClusterMonitorMessageProducer extends MessageProducerSupport {
private final HazelcastInstance hazelcastInstance;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -30,8 +30,6 @@ import org.springframework.util.Assert;
* @author Eren Avsarogullari
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastContinuousQueryMessageProducer extends AbstractHazelcastMessageProducer {
private final String predicate;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-2023 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.
@@ -36,8 +36,7 @@ import org.springframework.util.CollectionUtils;
*
* @since 6.0
*/
@SuppressWarnings({ "rawtypes", "removal" })
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("rawtypes")
public class HazelcastDistributedSQLMessageSource extends AbstractMessageSource {
private final IMap<?, ?> distributedMap;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-2023 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.
@@ -49,8 +49,6 @@ import org.springframework.util.Assert;
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastEventDrivenMessageProducer extends AbstractHazelcastMessageProducer {
public HazelcastEventDrivenMessageProducer(DistributedObject distributedObject) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-2024 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.
@@ -58,7 +58,6 @@ import org.springframework.util.Assert;
* @author Christian Tzolov
* @author Emil Palm
*/
@Deprecated(forRemoval = true, since = "6.5")
public class LeaderInitiator implements SmartLifecycle, DisposableBean, ApplicationEventPublisherAware {
private static final LogAccessor logger = new LogAccessor(LeaderInitiator.class);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -37,8 +37,6 @@ import org.springframework.integration.hazelcast.HazelcastLocalInstanceRegistrar
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastMembershipListener extends MembershipAdapter {
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2025 the original author or authors.
* Copyright 2017-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.
@@ -28,7 +28,6 @@ import org.springframework.util.Assert;
*
* @author Artem Bilan
*/
@Deprecated(forRemoval = true, since = "6.5")
public class HazelcastLockRegistry implements LockRegistry {
private final HazelcastInstance client;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-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.
@@ -29,7 +29,6 @@ import org.springframework.util.Assert;
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
public class EntryEventMessagePayload<K, V> {
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2025 the original author or authors.
* Copyright 2017-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.
@@ -37,7 +37,6 @@ import org.springframework.util.Assert;
* @author Vinicius Carvalho
* @author Artem Bilan
*/
@Deprecated(forRemoval = true, since = "6.5")
public class HazelcastMetadataStore implements ListenableMetadataStore, InitializingBean {
private static final String METADATA_STORE_MAP_NAME = "SPRING_INTEGRATION_METADATA_STORE";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2025 the original author or authors.
* Copyright 2015-2024 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.
@@ -40,8 +40,6 @@ import org.springframework.util.Assert;
*
* @since 6.0
*/
@Deprecated(forRemoval = true, since = "6.5")
@SuppressWarnings("removal")
public class HazelcastCacheWritingMessageHandler extends AbstractMessageHandler {
private DistributedObject distributedObject;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2025 the original author or authors.
* Copyright 2017-2023 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.
@@ -32,7 +32,6 @@ import org.springframework.util.Assert;
* @author Vinicius Carvalho
* @author Artem Bilan
*/
@Deprecated(forRemoval = true, since = "6.5")
public class HazelcastMessageStore extends AbstractKeyValueMessageStore {
private static final String MESSAGE_STORE_MAP_NAME = "SPRING_INTEGRATION_MESSAGE_STORE";

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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="distList" factory-bean="hzInstance" factory-method="getList">
<constructor-arg value="distList"/>
</bean>
<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"/>
</bean>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,128 @@
/*
* Copyright 2015-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.integration.hazelcast;
import java.util.HashSet;
import java.util.Set;
import com.hazelcast.collection.IList;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Integration Definition Validator Test Class
*
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"rawtypes"})
public class HazelcastIntegrationDefinitionValidatorTests {
@Autowired
private IList distList;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Test
public void testValidateEnumType() {
final String cacheEventTypes =
" ADDED, REMOVED, UPDATED, EVICTED, EVICT_ALL, CLEAR_ALL ";
final Set<String> typeSet = HazelcastIntegrationDefinitionValidator
.validateEnumType(CacheEventType.class, cacheEventTypes);
assertThat(typeSet.size()).isEqualTo(6);
for (String type : typeSet) {
Enum.valueOf(CacheEventType.class, type);
}
}
@Test(expected = IllegalArgumentException.class)
public void testValidateEnumTypeWithInvalidValue() {
final String cacheEventTypes = "Invalid_Enum_Type";
HazelcastIntegrationDefinitionValidator
.validateEnumType(CacheEventType.class, cacheEventTypes);
}
@Test
public void testValidateCacheEventsByDistributedObject() {
Set<String> cacheEventTypeSet = new HashSet<>(2);
cacheEventTypeSet.add(CacheEventType.ADDED.toString());
cacheEventTypeSet.add(CacheEventType.REMOVED.toString());
HazelcastIntegrationDefinitionValidator
.validateCacheEventsByDistributedObject(this.distList, cacheEventTypeSet);
}
@Test(expected = IllegalArgumentException.class)
public void testValidateCacheEventsByDistributedObjectWithInvalidValue() {
Set<String> cacheEventTypeSet = new HashSet<>(1);
cacheEventTypeSet.add("Invalid_Cache_Event_Type");
HazelcastIntegrationDefinitionValidator
.validateCacheEventsByDistributedObject(this.distList, cacheEventTypeSet);
}
@Test
public void testValidateCacheTypeForEventDrivenMessageProducer() {
HazelcastIntegrationDefinitionValidator
.validateCacheTypeForEventDrivenMessageProducer(this.distList);
}
@Test(expected = IllegalArgumentException.class)
public void testValidateCacheTypeForEventDrivenMessageProducerWithUnexpectedDistObject() {
HazelcastIntegrationDefinitionValidator
.validateCacheTypeForEventDrivenMessageProducer(new DistributedObject() {
@Override
public String getPartitionKey() {
return null;
}
@Override
public String getName() {
return null;
}
@Override
public String getServiceName() {
return null;
}
@Override
public void destroy() {
}
});
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright 2015-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.integration.hazelcast;
import java.io.Serializable;
import java.util.Objects;
/**
* User Bean for Hazelcast Integration Unit Tests
*
* @author Eren Avsarogullari
* @since 6.0
*/
public class HazelcastIntegrationTestUser implements Comparable<HazelcastIntegrationTestUser>, Serializable {
private static final long serialVersionUID = -5357485957528362705L;
private int id;
private String name;
private String surname;
private int age;
public HazelcastIntegrationTestUser(int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
public HazelcastIntegrationTestUser(int id, String name, String surname, int age) {
this.id = id;
this.name = name;
this.surname = surname;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", surname=" + surname + ", age="
+ age + "]";
}
@Override
public int compareTo(HazelcastIntegrationTestUser user) {
return (this.id < user.getId()) ? -1 : (this.id > user.getId()) ? 1 : 0;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
HazelcastIntegrationTestUser that = (HazelcastIntegrationTestUser) o;
return id == that.id &&
age == that.age &&
Objects.equals(name, that.name) &&
Objects.equals(surname, that.surname);
}
@Override
public int hashCode() {
return Objects.hash(id, name, surname, age);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2015-2019 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.integration.hazelcast;
import java.util.concurrent.CountDownLatch;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.messaging.Message;
/**
* {@link AbstractRequestHandlerAdvice} advice class for Hazelcast Integration Unit Tests.
*
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 6.0
*/
public class HazelcastTestRequestHandlerAdvice extends AbstractRequestHandlerAdvice {
public CountDownLatch executeLatch = null;
public HazelcastTestRequestHandlerAdvice(int count) {
this.executeLatch = new CountDownLatch(count);
}
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
try {
return callback.execute();
}
finally {
this.executeLatch.countDown();
}
}
}

View File

@@ -0,0 +1,372 @@
/*
* Copyright 2014-2024 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.integration.hazelcast;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.aopalliance.aop.Advice;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.IntegrationMessageHeaderAccessor;
import org.springframework.integration.MessageRejectedException;
import org.springframework.integration.annotation.BridgeFrom;
import org.springframework.integration.annotation.BridgeTo;
import org.springframework.integration.annotation.IdempotentReceiver;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.config.GlobalChannelInterceptor;
import org.springframework.integration.handler.MessageProcessor;
import org.springframework.integration.handler.ServiceActivatingHandler;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.integration.handler.advice.IdempotentReceiverInterceptor;
import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport;
import org.springframework.integration.metadata.ConcurrentMetadataStore;
import org.springframework.integration.metadata.MetadataStore;
import org.springframework.integration.metadata.SimpleMetadataStore;
import org.springframework.integration.selector.MetadataStoreSelector;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.transaction.PseudoTransactionManager;
import org.springframework.integration.transaction.TransactionInterceptorBuilder;
import org.springframework.integration.transformer.Transformer;
import org.springframework.jmx.support.MBeanServerFactoryBean;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.DirtiesContext;
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 static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.spy;
/**
* @author Artem Bilan
* @author Gary Russell
*
* @since 4.1
*/
@SpringJUnitConfig
@DirtiesContext
public class IdempotentReceiverIntegrationTests {
@Autowired
private MessageChannel input;
@Autowired
private PollableChannel output;
@Autowired
private MetadataStore store;
@Autowired
private IdempotentReceiverInterceptor idempotentReceiverInterceptor;
@Autowired
private AtomicInteger adviceCalled;
@Autowired
private MessageChannel annotatedMethodChannel;
@Autowired
private FooService fooService;
@Autowired
private MessageChannel annotatedBeanMessageHandlerChannel;
@Autowired
private MessageChannel annotatedBeanMessageHandlerChannel2;
@Autowired
private MessageChannel bridgeChannel;
@Autowired
private MessageChannel toBridgeChannel;
@Autowired
private PollableChannel bridgePollableChannel;
@Autowired
private AtomicBoolean txSupplied;
@Test
@SuppressWarnings("unchecked")
public void testIdempotentReceiver() {
this.idempotentReceiverInterceptor.setThrowExceptionOnRejection(true);
TestUtils.getPropertyValue(this.store, "metadata", Map.class).clear();
Message<String> message = new GenericMessage<>("foo");
this.input.send(message);
Message<?> receive = this.output.receive(10000);
assertThat(receive).isNotNull();
assertThat(this.adviceCalled.get()).isEqualTo(1);
assertThat(TestUtils.getPropertyValue(this.store, "metadata", Map.class)).hasSize(1);
String foo = this.store.get("foo");
assertThat(foo).isEqualTo("FOO");
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()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
assertThat(TestUtils.getPropertyValue(store, "metadata", Map.class)).hasSize(1);
assertThat(this.txSupplied.get()).isTrue();
}
@Test
public void testIdempotentReceiverOnMethod() {
TestUtils.getPropertyValue(this.store, "metadata", Map.class).clear();
Message<String> message = new GenericMessage<>("foo");
this.annotatedMethodChannel.send(message);
this.annotatedMethodChannel.send(message);
assertThat(this.fooService.messages.size()).isEqualTo(2);
assertThat(this.fooService.messages.get(1)
.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}
@Test
public void testIdempotentReceiverOnBeanMessageHandler() {
PollableChannel replyChannel = new QueueChannel();
Message<String> message = MessageBuilder.withPayload("bar").setReplyChannel(replyChannel).build();
this.annotatedBeanMessageHandlerChannel.send(message);
Message<?> receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);
this.annotatedBeanMessageHandlerChannel.send(message);
receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
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");
}
@Test
public void testIdempotentReceiverOnBridgeTo() {
PollableChannel replyChannel = new QueueChannel();
Message<String> message = MessageBuilder.withPayload("bridgeTo").setReplyChannel(replyChannel).build();
this.bridgeChannel.send(message);
Message<?> receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);
this.bridgeChannel.send(message);
receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}
@Test
public void testIdempotentReceiverOnBridgeFrom() {
Message<String> message = MessageBuilder.withPayload("bridgeFrom").build();
this.toBridgeChannel.send(message);
Message<?> receive = this.bridgePollableChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);
this.toBridgeChannel.send(message);
receive = this.bridgePollableChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}
@Configuration
@EnableIntegration
@EnableIntegrationMBeanExport(server = "mBeanServer")
public static class ContextConfiguration {
@Bean
public static MBeanServerFactoryBean mBeanServer() {
return new MBeanServerFactoryBean();
}
@Bean(destroyMethod = "shutdown")
public HazelcastInstance hazelcastInstance() {
return Hazelcast.newHazelcastInstance();
}
@Bean
public ConcurrentMetadataStore store() {
return new SimpleMetadataStore(
hazelcastInstance()
.getMap("idempotentReceiverMetadataStore"));
}
@Bean
public IdempotentReceiverInterceptor idempotentReceiverInterceptor() {
return new IdempotentReceiverInterceptor(
new MetadataStoreSelector(
message -> message.getPayload().toString(),
message -> message.getPayload().toString().toUpperCase(), store()));
}
@Bean
public PlatformTransactionManager transactionManager() {
return spy(new PseudoTransactionManager());
}
@Bean
public TransactionInterceptor transactionInterceptor() {
return new TransactionInterceptorBuilder(true)
.build();
}
@Bean
public MessageChannel input() {
return new DirectChannel();
}
@Bean
public PollableChannel output() {
return new QueueChannel();
}
@Bean
public AtomicBoolean txSupplied() {
return new AtomicBoolean();
}
@Bean
@GlobalChannelInterceptor(patterns = "output")
public ChannelInterceptor txSuppliedChannelInterceptor(final AtomicBoolean txSupplied) {
return new ChannelInterceptor() {
@Override
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
txSupplied.set(TransactionSynchronizationManager.isActualTransactionActive());
}
};
}
@Bean
@org.springframework.integration.annotation.Transformer(inputChannel = "input",
outputChannel = "output",
adviceChain = {"fooAdvice",
"idempotentReceiverInterceptor",
"transactionInterceptor"})
public Transformer transformer() {
return message -> message;
}
@Bean
public AtomicInteger adviceCalled() {
return new AtomicInteger();
}
@Bean
public Advice fooAdvice(@SuppressWarnings("unused") final AtomicInteger adviceCalled) {
return new AbstractRequestHandlerAdvice() {
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
adviceCalled.incrementAndGet();
return callback.execute();
}
};
}
@Bean
public MessageChannel annotatedMethodChannel() {
return new DirectChannel();
}
@Bean
public FooService fooService() {
return new FooService();
}
@Bean
@BridgeTo
@IdempotentReceiver("idempotentReceiverInterceptor")
public MessageChannel bridgeChannel() {
return new DirectChannel();
}
@Bean
@BridgeFrom("toBridgeChannel")
@IdempotentReceiver("idempotentReceiverInterceptor")
public PollableChannel bridgePollableChannel() {
return new QueueChannel();
}
@Bean
@ServiceActivator(inputChannel = "annotatedBeanMessageHandlerChannel")
@IdempotentReceiver("idempotentReceiverInterceptor")
public MessageHandler messageHandler() {
return new ServiceActivatingHandler((MessageProcessor<Object>) message -> message);
}
@Bean
@ServiceActivator(inputChannel = "annotatedBeanMessageHandlerChannel2")
@IdempotentReceiver("idempotentReceiverInterceptor")
public MessageHandler messageHandler2() {
return message -> {
if (message.getHeaders().containsKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE)) {
throw new MessageHandlingException(message, "duplicate message has been received");
}
};
}
}
@Component
private static class FooService {
private final List<Message<?>> messages = new ArrayList<Message<?>>();
@ServiceActivator(inputChannel = "annotatedMethodChannel")
@IdempotentReceiver("idempotentReceiverInterceptor")
public void handle(Message<?> message) {
this.messages.add(message);
}
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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" destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="CPSubsystemConfig">
<bean class="com.hazelcast.config.cp.CPSubsystemConfig">
<property name="CPMemberCount" value="0"/>
</bean>
</property>
</bean>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="cqMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="cqMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="cqMapChannel3">
<int:queue/>
</int:channel>
<int:channel id="cqMapChannel4">
<int:queue/>
</int:channel>
<int:channel id="cqMapChannel5">
<int:queue/>
</int:channel>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel1" cache="cqDistributedMap1"
predicate="name=TestName1"/>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel2" cache="cqDistributedMap2" cache-events="REMOVED"
predicate="name=TestName2"/>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel3" cache="cqDistributedMap3"
cache-events="ADDED,REMOVED,UPDATED,CLEAR_ALL"
predicate="name=TestName1 OR name=TestName2"/>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel4" cache="cqDistributedMap4" cache-events="UPDATED"
predicate="surname=TestSurname2"/>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel5" cache="cqDistributedMap5" cache-events="UPDATED"
predicate="surname=TestSurname2" include-value="false"/>
<bean id="cqDistributedMap1" factory-bean="instance" factory-method="getMap">
<constructor-arg value="cqDistributedMap1"/>
</bean>
<bean id="cqDistributedMap2" factory-bean="instance" factory-method="getMap">
<constructor-arg value="cqDistributedMap2"/>
</bean>
<bean id="cqDistributedMap3" factory-bean="instance" factory-method="getMap">
<constructor-arg value="cqDistributedMap3"/>
</bean>
<bean id="cqDistributedMap4" factory-bean="instance" factory-method="getMap">
<constructor-arg value="cqDistributedMap4"/>
</bean>
<bean id="cqDistributedMap5" factory-bean="instance" factory-method="getMap">
<constructor-arg value="cqDistributedMap5"/>
</bean>
</beans>

View File

@@ -0,0 +1,157 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Continuous Query Inbound Channel Adapter Unit Test Class
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastCQDistributedMapInboundChannelAdapterTests {
@Autowired
private PollableChannel cqMapChannel1;
@Autowired
private PollableChannel cqMapChannel2;
@Autowired
private PollableChannel cqMapChannel3;
@Autowired
private PollableChannel cqMapChannel4;
@Autowired
private PollableChannel cqMapChannel5;
@Autowired
private IMap cqDistributedMap1;
@Autowired
private IMap cqDistributedMap2;
@Autowired
private IMap cqDistributedMap3;
@Autowired
private IMap cqDistributedMap4;
@Autowired
private IMap cqDistributedMap5;
@Test
public void testContinuousQueryForOnlyADDEDEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForADDEDDistributedMapEntryEvent(cqDistributedMap1,
cqMapChannel1, "cqDistributedMap1");
}
@Test
public void testContinuousQueryForOnlyREMOVEDEntryEvent() {
cqDistributedMap2
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
cqDistributedMap2
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
cqDistributedMap2.remove(2);
Message<?> msg =
cqMapChannel2.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.REMOVED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("cqDistributedMap2");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(2));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getId()).isEqualTo(2);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getName()).isEqualTo("TestName2");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getSurname()).isEqualTo("TestSurname2");
}
@Test
public void testContinuousQueryForALLEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedMapEntryEvents(cqDistributedMap3,
cqMapChannel3, "cqDistributedMap3");
}
@Test
public void testContinuousQueryForOnlyUPDATEDEntryEvent() {
cqDistributedMap4
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
cqDistributedMap4
.put(1, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg =
cqMapChannel4.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.UPDATED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("cqDistributedMap4");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(1));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getId()).isEqualTo(1);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getName()).isEqualTo("TestName1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getSurname()).isEqualTo("TestSurname1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getId()).isEqualTo(2);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getName()).isEqualTo("TestName2");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getSurname()).isEqualTo("TestSurname2");
}
@Test
public void testContinuousQueryForOnlyUPDATEDEntryEventWhenIncludeValueIsFalse() {
HazelcastInboundChannelAdapterTestUtils
.testContinuousQueryForUPDATEDEntryEventWhenIncludeValueIsFalse(
cqDistributedMap5, cqMapChannel5, "cqDistributedMap5");
}
}

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="cmChannel1">
<int:queue/>
</int:channel>
<int:channel id="cmChannel2">
<int:queue/>
</int:channel>
<int:channel id="cmChannel3">
<int:queue/>
</int:channel>
<int:channel id="cmChannel4">
<int:queue/>
</int:channel>
<int:channel id="cmChannel5">
<int:queue/>
</int:channel>
<int:channel id="cmChannel6">
<int:queue/>
</int:channel>
<int-hazelcast:cm-inbound-channel-adapter
channel="cmChannel1"
hazelcast-instance="hazelcastInstance"
monitor-types="MEMBERSHIP" />
<int-hazelcast:cm-inbound-channel-adapter
channel="cmChannel2"
hazelcast-instance="hazelcastInstance"
monitor-types="DISTRIBUTED_OBJECT" />
<int-hazelcast:cm-inbound-channel-adapter
channel="cmChannel3"
hazelcast-instance="hazelcastInstance"
monitor-types="MIGRATION" />
<int-hazelcast:cm-inbound-channel-adapter
channel="cmChannel4"
hazelcast-instance="hazelcastInstance2"
monitor-types="LIFECYCLE" />
<int-hazelcast:cm-inbound-channel-adapter
channel="cmChannel5"
hazelcast-instance="hazelcastInstance"
monitor-types="CLIENT" />
<int-hazelcast:cm-inbound-channel-adapter
channel="cmChannel6"
hazelcast-instance="hazelcastInstance"
monitor-types="MEMBERSHIP,DISTRIBUTED_OBJECT" />
<bean id="hazelcastInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="groupConfig">
<bean class="com.hazelcast.config.GroupConfig">
<property name="name" value="Test_Group_Name1"/>
<property name="password" value="dev-pass"/>
</bean>
</property>
<property name="networkConfig">
<bean class="com.hazelcast.config.NetworkConfig">
<property name="port" value="5701"/>
<property name="portAutoIncrement" value="false"/>
<property name="join">
<bean class="com.hazelcast.config.JoinConfig">
<property name="multicastConfig">
<bean class="com.hazelcast.config.MulticastConfig">
<property name="enabled" value="false" />
</bean>
</property>
<property name="tcpIpConfig">
<bean class="com.hazelcast.config.TcpIpConfig">
<property name="members" value="127.0.0.1:5701,127.0.0.1:5703" />
<property name="enabled" value="true" />
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
</constructor-arg>
</bean>
<bean id="hazelcastInstance2" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="groupConfig">
<bean class="com.hazelcast.config.GroupConfig">
<property name="name" value="Test_Group_Name2"/>
</bean>
</property>
<property name="networkConfig">
<bean class="com.hazelcast.config.NetworkConfig">
<property name="port" value="5702"/>
<property name="portAutoIncrement" value="false"/>
<property name="join">
<bean class="com.hazelcast.config.JoinConfig">
<property name="multicastConfig">
<bean class="com.hazelcast.config.MulticastConfig">
<property name="enabled" value="false" />
</bean>
</property>
<property name="tcpIpConfig">
<bean class="com.hazelcast.config.TcpIpConfig">
<property name="members" value="127.0.0.1:5702" />
<property name="enabled" value="true" />
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
</constructor-arg>
</bean>
<bean id="hazelcastInstance3" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="groupConfig">
<bean class="com.hazelcast.config.GroupConfig">
<property name="name" value="Test_Group_Name1"/>
<property name="password" value="dev-pass"/>
</bean>
</property>
<property name="networkConfig">
<bean class="com.hazelcast.config.NetworkConfig">
<property name="port" value="5703"/>
<property name="portAutoIncrement" value="false"/>
<property name="join">
<bean class="com.hazelcast.config.JoinConfig">
<property name="multicastConfig">
<bean class="com.hazelcast.config.MulticastConfig">
<property name="enabled" value="false" />
</bean>
</property>
<property name="tcpIpConfig">
<bean class="com.hazelcast.config.TcpIpConfig">
<property name="members" value="127.0.0.1:5701,127.0.0.1:5703" />
<property name="enabled" value="true" />
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.LifecycleEvent;
import com.hazelcast.core.LifecycleEvent.LifecycleState;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Cluster Monitor Inbound Channel Adapter Unit Test Class
*
* @author Eren Avsarogullari
* @author Artem Bilan
*/
@RunWith(SpringRunner.class)
@SpringJUnitConfig
@DirtiesContext
@Ignore("Hard to reach CP consensus with limited number of members in two clusters")
public class HazelcastClusterMonitorInboundChannelAdapterTests {
private static final String TEST_GROUP_NAME1 = "Test_Group_Name1";
@Autowired
private PollableChannel cmChannel1;
@Autowired
private PollableChannel cmChannel2;
@Autowired
private PollableChannel cmChannel3;
@Autowired
private PollableChannel cmChannel4;
@Autowired
private PollableChannel cmChannel5;
@Autowired
private PollableChannel cmChannel6;
@Autowired
private HazelcastInstance hazelcastInstance;
@Autowired
private HazelcastInstance hazelcastInstance2;
@Autowired
private HazelcastInstance hazelcastInstance3;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Test
public void testDistributedObjectEvent() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedObjectEventByChannelAndHazelcastInstance(cmChannel2,
hazelcastInstance, "Test_Distributed_Map4");
}
@Test
public void testLifecycleEvent() {
hazelcastInstance2.getLifecycleService().terminate();
Message<?> msg =
cmChannel4.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
verifyLifecycleEvent(msg, LifecycleState.SHUTTING_DOWN);
msg = cmChannel4.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
verifyLifecycleEvent(msg, LifecycleState.SHUTDOWN);
}
private void verifyLifecycleEvent(final Message<?> msg,
final LifecycleState lifecycleState) {
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof LifecycleEvent).isTrue();
assertThat(((LifecycleEvent) msg.getPayload()).getState()).isEqualTo(lifecycleState);
}
}

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="edListChannel1">
<int:queue/>
</int:channel>
<int:channel id="edListChannel2">
<int:queue/>
</int:channel>
<int:channel id="edListChannel3">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edListChannel1" cache="edDistributedList1"/>
<int-hazelcast:inbound-channel-adapter channel="edListChannel2" cache="edDistributedList2" cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edListChannel3" cache="edDistributedList3"
cache-events="ADDED,REMOVED"/>
<bean id="edDistributedList1" factory-bean="instance" factory-method="getList">
<constructor-arg value="edDistributedList1"/>
</bean>
<bean id="edDistributedList2" factory-bean="instance" factory-method="getList">
<constructor-arg value="edDistributedList2"/>
</bean>
<bean id="edDistributedList3" factory-bean="instance" factory-method="getList">
<constructor-arg value="edDistributedList3"/>
</bean>
</beans>

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.collection.IList;
import com.hazelcast.core.EntryEventType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Distributed List Event Driven Inbound Channel Adapter Test Class
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedListEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edListChannel1;
@Autowired
private PollableChannel edListChannel2;
@Autowired
private PollableChannel edListChannel3;
@Autowired
private IList edDistributedList1;
@Autowired
private IList edDistributedList2;
@Autowired
private IList edDistributedList3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedList1.add(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edListChannel1.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE).toString()).isEqualTo(EntryEventType.ADDED.toString());
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getId()).isEqualTo(1);
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getName()).isEqualTo("TestName1");
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getSurname()).isEqualTo("TestSurname1");
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
HazelcastIntegrationTestUser user = new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedList2.add(user);
edDistributedList2.remove(user);
Message<?> msg = edListChannel2.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE).toString()).isEqualTo(EntryEventType.REMOVED.toString());
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getId()).isEqualTo(2);
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getName()).isEqualTo("TestName2");
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getSurname()).isEqualTo("TestSurname2");
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedCollectionItemEvents(edDistributedList3, edListChannel3);
}
}

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="edMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="edMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="edMapChannel3">
<int:queue/>
</int:channel>
<int:channel id="edMapChannel4">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edMapChannel1" cache="edDistributedMap1"/>
<int-hazelcast:inbound-channel-adapter channel="edMapChannel2" cache="edDistributedMap2" cache-events="UPDATED"/>
<int-hazelcast:inbound-channel-adapter channel="edMapChannel3" cache="edDistributedMap3" cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edMapChannel4" cache="edDistributedMap4"
cache-events="ADDED,REMOVED,UPDATED,CLEAR_ALL"/>
<bean id="edDistributedMap1" factory-bean="instance" factory-method="getMap">
<constructor-arg value="edDistributedMap1"/>
</bean>
<bean id="edDistributedMap2" factory-bean="instance" factory-method="getMap">
<constructor-arg value="edDistributedMap2"/>
</bean>
<bean id="edDistributedMap3" factory-bean="instance" factory-method="getMap">
<constructor-arg value="edDistributedMap3"/>
</bean>
<bean id="edDistributedMap4" factory-bean="instance" factory-method="getMap">
<constructor-arg value="edDistributedMap4"/>
</bean>
</beans>

View File

@@ -0,0 +1,144 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Distributed Map Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edMapChannel1;
@Autowired
private PollableChannel edMapChannel2;
@Autowired
private PollableChannel edMapChannel3;
@Autowired
private PollableChannel edMapChannel4;
@Autowired
private IMap edDistributedMap1;
@Autowired
private IMap edDistributedMap2;
@Autowired
private IMap edDistributedMap3;
@Autowired
private IMap edDistributedMap4;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForADDEDDistributedMapEntryEvent(edDistributedMap1,
edMapChannel1, "edDistributedMap1");
}
@Test
public void testEventDrivenForOnlyUPDATEDEntryEvent() {
edDistributedMap2
.put(2, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edDistributedMap2
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg =
edMapChannel2.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.UPDATED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edDistributedMap2");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(2));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getId()).isEqualTo(1);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getName()).isEqualTo("TestName1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getSurname()).isEqualTo("TestSurname1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getId()).isEqualTo(2);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getName()).isEqualTo("TestName2");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getSurname()).isEqualTo("TestSurname2");
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
edDistributedMap3
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edDistributedMap3
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
edDistributedMap3.remove(2);
Message<?> msg =
edMapChannel3.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.REMOVED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edDistributedMap3");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(2));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getId()).isEqualTo(2);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getName()).isEqualTo("TestName2");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getSurname()).isEqualTo("TestSurname2");
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedMapEntryEvents(edDistributedMap4, edMapChannel4,
"edDistributedMap4");
}
}

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="edQueueChannel1">
<int:queue/>
</int:channel>
<int:channel id="edQueueChannel2">
<int:queue/>
</int:channel>
<int:channel id="edQueueChannel3">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edQueueChannel1" cache="edDistributedQueue1"/>
<int-hazelcast:inbound-channel-adapter channel="edQueueChannel2" cache="edDistributedQueue2"
cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edQueueChannel3" cache="edDistributedQueue3"
cache-events="ADDED,REMOVED"/>
<bean id="edDistributedQueue1" factory-bean="instance" factory-method="getQueue">
<constructor-arg value="edDistributedQueue1"/>
</bean>
<bean id="edDistributedQueue2" factory-bean="instance" factory-method="getQueue">
<constructor-arg value="edDistributedQueue2"/>
</bean>
<bean id="edDistributedQueue3" factory-bean="instance" factory-method="getQueue">
<constructor-arg value="edDistributedQueue3"/>
</bean>
</beans>

View File

@@ -0,0 +1,105 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.collection.IQueue;
import com.hazelcast.core.EntryEventType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Distributed Queue Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedQueueEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edQueueChannel1;
@Autowired
private PollableChannel edQueueChannel2;
@Autowired
private PollableChannel edQueueChannel3;
@Autowired
private IQueue edDistributedQueue1;
@Autowired
private IQueue edDistributedQueue2;
@Autowired
private IQueue edDistributedQueue3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedQueue1
.add(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg =
edQueueChannel1.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE).toString()).isEqualTo(EntryEventType.ADDED.toString());
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getId())).isEqualTo(1);
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getName())).isEqualTo("TestName1");
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getSurname())).isEqualTo("TestSurname1");
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
HazelcastIntegrationTestUser user =
new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedQueue2.add(user);
edDistributedQueue2.remove(user);
Message<?> msg =
edQueueChannel2.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE).toString()).isEqualTo(EntryEventType.REMOVED.toString());
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getId())).isEqualTo(2);
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getName())).isEqualTo("TestName2");
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getSurname())).isEqualTo("TestSurname2");
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedCollectionItemEvents(edDistributedQueue3,
edQueueChannel3);
}
}

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="dsMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="dsMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="dsMapChannel3">
<int:queue/>
</int:channel>
<int:channel id="dsMapChannel4">
<int:queue/>
</int:channel>
<int-hazelcast:ds-inbound-channel-adapter channel="dsMapChannel1" cache="dsDistributedMap1" iteration-type="ENTRY"
distributed-sql="age = 40">
<int:poller fixed-delay="100"/>
</int-hazelcast:ds-inbound-channel-adapter>
<int-hazelcast:ds-inbound-channel-adapter channel="dsMapChannel2" cache="dsDistributedMap2" iteration-type="KEY"
distributed-sql="age > 0 AND age &lt;= 10">
<int:poller fixed-delay="100"/>
</int-hazelcast:ds-inbound-channel-adapter>
<int-hazelcast:ds-inbound-channel-adapter channel="dsMapChannel3" cache="dsDistributedMap3"
iteration-type="KEY" distributed-sql="age > 10 AND age &lt;= 20">
<int:poller fixed-delay="100"/>
</int-hazelcast:ds-inbound-channel-adapter>
<int-hazelcast:ds-inbound-channel-adapter channel="dsMapChannel4" cache="dsDistributedMap4"
distributed-sql="age > 20 AND age &lt;= 30">
<int:poller fixed-delay="100"/>
</int-hazelcast:ds-inbound-channel-adapter>
<bean id="dsDistributedMap1" factory-bean="instance" factory-method="getMap">
<constructor-arg value="dsDistributedMap1"/>
</bean>
<bean id="dsDistributedMap2" factory-bean="instance" factory-method="getMap">
<constructor-arg value="dsDistributedMap2"/>
</bean>
<bean id="dsDistributedMap3" factory-bean="instance" factory-method="getMap">
<constructor-arg value="dsDistributedMap3"/>
</bean>
<bean id="dsDistributedMap4" factory-bean="instance" factory-method="getMap">
<constructor-arg value="dsDistributedMap4"/>
</bean>
</beans>

View File

@@ -0,0 +1,90 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Hazelcast Distributed SQL Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedSQLInboundChannelAdapterTests {
@Autowired
private PollableChannel dsMapChannel1;
@Autowired
private PollableChannel dsMapChannel2;
@Autowired
private PollableChannel dsMapChannel3;
@Autowired
private PollableChannel dsMapChannel4;
@Autowired
private IMap dsDistributedMap1;
@Autowired
private IMap dsDistributedMap2;
@Autowired
private IMap dsDistributedMap3;
@Autowired
private IMap dsDistributedMap4;
@Test
public void testDistributedSQLForOnlyENTRYIterationType() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedSQLForENTRYIterationType(dsDistributedMap1, dsMapChannel1);
}
@Test
public void testDistributedSQLForOnlyKEYIterationType() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedSQLForKEYIterationType(dsDistributedMap2, dsMapChannel2);
}
@Test
public void testDistributedSQLForOnlyLOCAL_KEYIterationType() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedSQLForLOCAL_KEYIterationType(dsDistributedMap3, dsMapChannel3);
}
@Test
public void testDistributedSQLForOnlyVALUEIterationType() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedSQLForVALUEIterationType(dsDistributedMap4, dsMapChannel4);
}
}

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="edSetChannel1">
<int:queue/>
</int:channel>
<int:channel id="edSetChannel2">
<int:queue/>
</int:channel>
<int:channel id="edSetChannel3">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edSetChannel1" cache="edDistributedSet1"/>
<int-hazelcast:inbound-channel-adapter channel="edSetChannel2" cache="edDistributedSet2" cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edSetChannel3" cache="edDistributedSet3"
cache-events="ADDED,REMOVED"/>
<bean id="edDistributedSet1" factory-bean="instance" factory-method="getSet">
<constructor-arg value="edDistributedSet1"/>
</bean>
<bean id="edDistributedSet2" factory-bean="instance" factory-method="getSet">
<constructor-arg value="edDistributedSet2"/>
</bean>
<bean id="edDistributedSet3" factory-bean="instance" factory-method="getSet">
<constructor-arg value="edDistributedSet3"/>
</bean>
</beans>

View File

@@ -0,0 +1,105 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.collection.ISet;
import com.hazelcast.core.EntryEventType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Distributed Set Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedSetEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edSetChannel1;
@Autowired
private PollableChannel edSetChannel2;
@Autowired
private PollableChannel edSetChannel3;
@Autowired
private ISet edDistributedSet1;
@Autowired
private ISet edDistributedSet2;
@Autowired
private ISet edDistributedSet3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedSet1
.add(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg =
edSetChannel1.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE).toString()).isEqualTo(EntryEventType.ADDED.toString());
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getId())).isEqualTo(1);
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getName())).isEqualTo("TestName1");
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getSurname())).isEqualTo("TestSurname1");
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
HazelcastIntegrationTestUser user =
new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedSet2.add(user);
edDistributedSet2.remove(user);
Message<?> msg =
edSetChannel2.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE).toString()).isEqualTo(EntryEventType.REMOVED.toString());
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getId())).isEqualTo(2);
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getName())).isEqualTo("TestName2");
assertThat((((HazelcastIntegrationTestUser) msg.getPayload()).getSurname())).isEqualTo("TestSurname2");
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedCollectionItemEvents(edDistributedSet3,
edSetChannel3);
}
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="edTopicChannel1">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edTopicChannel1" cache="edDistributedTopic1"/>
<bean id="edDistributedTopic1" factory-bean="instance" factory-method="getTopic">
<constructor-arg value="edDistributedTopic1"/>
</bean>
</beans>

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.topic.ITopic;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Hazelcast Distributed Topic Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedTopicEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edTopicChannel1;
@Autowired
private ITopic edDistributedTopic1;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForTopicMessageEvent(edDistributedTopic1, edTopicChannel1);
}
}

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="edMultiMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="edMultiMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="edMultiMapChannel3">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edMultiMapChannel1" cache="edMultiMap1"/>
<int-hazelcast:inbound-channel-adapter channel="edMultiMapChannel2" cache="edMultiMap2" cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edMultiMapChannel3" cache="edMultiMap3"
cache-events="ADDED,REMOVED,CLEAR_ALL"/>
<bean id="edMultiMap1" factory-bean="instance" factory-method="getMultiMap">
<constructor-arg value="edMultiMap1"/>
</bean>
<bean id="edMultiMap2" factory-bean="instance" factory-method="getMultiMap">
<constructor-arg value="edMultiMap2"/>
</bean>
<bean id="edMultiMap3" factory-bean="instance" factory-method="getMultiMap">
<constructor-arg value="edMultiMap3"/>
</bean>
</beans>

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.multimap.MultiMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast MultiMap Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @author Artem Bilan
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastMultiMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edMultiMapChannel1;
@Autowired
private PollableChannel edMultiMapChannel2;
@Autowired
private PollableChannel edMultiMapChannel3;
@Autowired
private MultiMap edMultiMap1;
@Autowired
private MultiMap edMultiMap2;
@Autowired
private MultiMap edMultiMap3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edMultiMap1
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg =
edMultiMapChannel1.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.ADDED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edMultiMap1");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(1));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getId()).isEqualTo(1);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getName()).isEqualTo("TestName1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getSurname()).isEqualTo("TestSurname1");
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
edMultiMap2
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edMultiMap2
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
edMultiMap2.remove(2);
Message<?> msg =
edMultiMapChannel2.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.REMOVED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edMultiMap2");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(2));
assertThat(((EntryEventMessagePayload<?, ?>) msg.getPayload()).value).isNull();
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getId()).isEqualTo(2);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getName()).isEqualTo("TestName2");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getSurname()).isEqualTo("TestSurname2");
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForMultiMapEntryEvents(edMultiMap3, edMultiMapChannel3,
"edMultiMap3");
}
}

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="edReplicatedMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="edReplicatedMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="edReplicatedMapChannel3">
<int:queue/>
</int:channel>
<int:channel id="edReplicatedMapChannel4">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edReplicatedMapChannel1" cache="edReplicatedMap1"/>
<int-hazelcast:inbound-channel-adapter channel="edReplicatedMapChannel2" cache="edReplicatedMap2"
cache-events="UPDATED"/>
<int-hazelcast:inbound-channel-adapter channel="edReplicatedMapChannel3" cache="edReplicatedMap3"
cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edReplicatedMapChannel4" cache="edReplicatedMap4"
cache-events="ADDED,REMOVED,UPDATED"/>
<bean id="edReplicatedMap1" factory-bean="instance" factory-method="getReplicatedMap">
<constructor-arg value="edReplicatedMap1"/>
</bean>
<bean id="edReplicatedMap2" factory-bean="instance" factory-method="getReplicatedMap">
<constructor-arg value="edReplicatedMap2"/>
</bean>
<bean id="edReplicatedMap3" factory-bean="instance" factory-method="getReplicatedMap">
<constructor-arg value="edReplicatedMap3"/>
</bean>
<bean id="edReplicatedMap4" factory-bean="instance" factory-method="getReplicatedMap">
<constructor-arg value="edReplicatedMap4"/>
</bean>
</beans>

View File

@@ -0,0 +1,161 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.replicatedmap.ReplicatedMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Replicated Map Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastReplicatedMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edReplicatedMapChannel1;
@Autowired
private PollableChannel edReplicatedMapChannel2;
@Autowired
private PollableChannel edReplicatedMapChannel3;
@Autowired
private PollableChannel edReplicatedMapChannel4;
@Autowired
private ReplicatedMap edReplicatedMap1;
@Autowired
private ReplicatedMap edReplicatedMap2;
@Autowired
private ReplicatedMap edReplicatedMap3;
@Autowired
private ReplicatedMap edReplicatedMap4;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edReplicatedMap1
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edReplicatedMapChannel1
.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.ADDED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edReplicatedMap1");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(1));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getId()).isEqualTo(1);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getName()).isEqualTo("TestName1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getSurname()).isEqualTo("TestSurname1");
}
@Test
public void testEventDrivenForOnlyUPDATEDEntryEvent() {
edReplicatedMap2
.put(2, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edReplicatedMap2
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg = edReplicatedMapChannel2
.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.UPDATED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edReplicatedMap2");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(2));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getId()).isEqualTo(1);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getName()).isEqualTo("TestName1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getSurname()).isEqualTo("TestSurname1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getId()).isEqualTo(2);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getName()).isEqualTo("TestName2");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getSurname()).isEqualTo("TestSurname2");
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
edReplicatedMap3
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edReplicatedMap3
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
edReplicatedMap3.remove(2);
Message<?> msg = edReplicatedMapChannel3
.receive(HazelcastInboundChannelAdapterTestUtils.TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.REMOVED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edReplicatedMap3");
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(2));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getId()).isEqualTo(2);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getName()).isEqualTo("TestName2");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).getSurname()).isEqualTo("TestSurname2");
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForReplicatedMapEntryEvents(edReplicatedMap4,
edReplicatedMapChannel4, "edReplicatedMap4");
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound.config;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
/**
* Hazelcast Continuous Query Inbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationInboundTestConfiguration.class,
loader = AnnotationConfigContextLoader.class)
@DirtiesContext
public class HazelcastCQDistributedMapInboundChannelAdapterConfigTests {
@Autowired
private PollableChannel cqDistributedMapChannel1;
@Autowired
private PollableChannel cqDistributedMapChannel2;
@Autowired
private PollableChannel cqDistributedMapChannel3;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap1;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap2;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap3;
@Test
public void testContinuousQueryForADDEDEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForADDEDDistributedMapEntryEvent(testCQDistributedMap1,
cqDistributedMapChannel1, "Test_CQ_Distributed_Map1");
}
@Test
public void testContinuousQueryForALLEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedMapEntryEvents(testCQDistributedMap2,
cqDistributedMapChannel2, "Test_CQ_Distributed_Map2");
}
@Test
public void testContinuousQueryForUPDATEDEntryEventWhenIncludeValueIsFalse() {
HazelcastInboundChannelAdapterTestUtils
.testContinuousQueryForUPDATEDEntryEventWhenIncludeValueIsFalse(
testCQDistributedMap3, cqDistributedMapChannel3,
"Test_CQ_Distributed_Map3");
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound.config;
import com.hazelcast.core.HazelcastInstance;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Hazelcast Cluster Monitor Inbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationInboundTestConfiguration.class)
@DirtiesContext
public class HazelcastClusterMonitorInboundChannelAdapterConfigTests {
@Autowired
private PollableChannel cmonChannel;
@Autowired
private PollableChannel cmonChannel2;
@Autowired
private HazelcastInstance testHazelcastInstance;
@Test
public void testConfigDrivenDistributedObjectEvent() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedObjectEventByChannelAndHazelcastInstance(cmonChannel2,
testHazelcastInstance, "Test_Distributed_Map3");
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound.config;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
/**
* Hazelcast Distributed SQL Inbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationInboundTestConfiguration.class,
loader = AnnotationConfigContextLoader.class)
@DirtiesContext
public class HazelcastDistributedSQLInboundChannelAdapterConfigTests {
@Autowired
private PollableChannel dsDistributedMapChannel;
@Autowired
private PollableChannel dsDistributedMapChannel2;
@Autowired
private PollableChannel dsDistributedMapChannel3;
@Autowired
private PollableChannel dsDistributedMapChannel4;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap2;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap3;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap4;
@Test
public void testDistributedSQLForENTRYIterationType() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedSQLForENTRYIterationType(testDSDistributedMap,
dsDistributedMapChannel);
}
@Test
public void testDistributedSQLForKEYIterationType() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedSQLForKEYIterationType(testDSDistributedMap2,
dsDistributedMapChannel2);
}
@Test
public void testDistributedSQLForLOCAL_KEYIterationType() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedSQLForLOCAL_KEYIterationType(testDSDistributedMap3,
dsDistributedMapChannel3);
}
@Test
public void testDistributedSQLForVALUEIterationType() {
HazelcastInboundChannelAdapterTestUtils
.testDistributedSQLForVALUEIterationType(testDSDistributedMap4,
dsDistributedMapChannel4);
}
}

View File

@@ -0,0 +1,153 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound.config;
import com.hazelcast.collection.IList;
import com.hazelcast.collection.IQueue;
import com.hazelcast.collection.ISet;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
/**
* Hazelcast Event Driven Inbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 6.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationInboundTestConfiguration.class,
loader = AnnotationConfigContextLoader.class)
@DirtiesContext
public class HazelcastEventDrivenInboundChannelAdapterConfigTests {
@Autowired
private PollableChannel distributedMapChannel;
@Autowired
private PollableChannel distributedMapChannel2;
@Autowired
private PollableChannel distributedListChannel;
@Autowired
private PollableChannel distributedSetChannel;
@Autowired
private PollableChannel distributedQueueChannel;
@Autowired
private PollableChannel topicChannel;
@Autowired
private PollableChannel replicatedMapChannel;
@Autowired
private PollableChannel multiMapChannel;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDistributedMap;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDistributedMap2;
@Autowired
private IList<HazelcastIntegrationTestUser> testDistributedList;
@Autowired
private ISet<HazelcastIntegrationTestUser> testDistributedSet;
@Autowired
private IQueue<HazelcastIntegrationTestUser> testDistributedQueue;
@Autowired
private ITopic<HazelcastIntegrationTestUser> testTopic;
@Autowired
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> testReplicatedMap;
@Autowired
private MultiMap<Integer, HazelcastIntegrationTestUser> testMultiMap;
@Test
public void testEventDrivenForADDEDEntryEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForADDEDDistributedMapEntryEvent(testDistributedMap,
distributedMapChannel, "Test_Distributed_Map");
}
@Test
public void testEventDrivenForEntryEvents() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedMapEntryEvents(testDistributedMap2,
distributedMapChannel2, "Test_Distributed_Map2");
}
@Test
public void testEventDrivenForDistributedListItemEvents() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedCollectionItemEvents(testDistributedList,
distributedListChannel);
}
@Test
public void testEventDrivenForDistributedSetItemEvents() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedCollectionItemEvents(testDistributedSet,
distributedSetChannel);
}
@Test
public void testEventDrivenForDistributedQueueItemEvents() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForDistributedCollectionItemEvents(testDistributedQueue,
distributedQueueChannel);
}
@Test
public void testEventDrivenForADDEDMessageEvent() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForTopicMessageEvent(testTopic, topicChannel);
}
@Test
public void testEventDrivenForReplicatedMapEntryEvents() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForReplicatedMapEntryEvents(testReplicatedMap,
replicatedMapChannel, "Test_Replicated_Map");
}
@Test
public void testEventDrivenForMultiMapEntryEvents() {
HazelcastInboundChannelAdapterTestUtils
.testEventDrivenForMultiMapEntryEvents(testMultiMap, multiMapChannel,
"Test_Multi_Map");
}
}

View File

@@ -0,0 +1,394 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound.config;
import com.hazelcast.collection.IList;
import com.hazelcast.collection.IQueue;
import com.hazelcast.collection.ISet;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.InboundChannelAdapter;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.hazelcast.DistributedSQLIterationType;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.HazelcastLocalInstanceRegistrar;
import org.springframework.integration.hazelcast.inbound.HazelcastClusterMonitorMessageProducer;
import org.springframework.integration.hazelcast.inbound.HazelcastContinuousQueryMessageProducer;
import org.springframework.integration.hazelcast.inbound.HazelcastDistributedSQLMessageSource;
import org.springframework.integration.hazelcast.inbound.HazelcastEventDrivenMessageProducer;
import org.springframework.messaging.PollableChannel;
/**
* Configuration Class for Hazelcast Integration Inbound Test
*
* @author Eren Avsarogullari
* @author Artem Bilan
*/
@Configuration
@EnableIntegration
public class HazelcastIntegrationInboundTestConfiguration {
@Bean
public PollableChannel distributedMapChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel distributedMapChannel2() {
return new QueueChannel();
}
@Bean
public PollableChannel distributedListChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel distributedSetChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel distributedQueueChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel topicChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel multiMapChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel replicatedMapChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel cqDistributedMapChannel1() {
return new QueueChannel();
}
@Bean
public PollableChannel cqDistributedMapChannel2() {
return new QueueChannel();
}
@Bean
public PollableChannel cqDistributedMapChannel3() {
return new QueueChannel();
}
@Bean
public PollableChannel dsDistributedMapChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel dsDistributedMapChannel2() {
return new QueueChannel();
}
@Bean
public PollableChannel dsDistributedMapChannel3() {
return new QueueChannel();
}
@Bean
public PollableChannel dsDistributedMapChannel4() {
return new QueueChannel();
}
@Bean
public PollableChannel cmonChannel() {
return new QueueChannel();
}
@Bean
public PollableChannel cmonChannel2() {
return new QueueChannel();
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testDistributedMap() {
return testHazelcastInstance().getMap("Test_Distributed_Map");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testDistributedMap2() {
return testHazelcastInstance().getMap("Test_Distributed_Map2");
}
@Bean
public IList<HazelcastIntegrationTestUser> testDistributedList() {
return testHazelcastInstance().getList("Test_Distributed_List");
}
@Bean
public ISet<HazelcastIntegrationTestUser> testDistributedSet() {
return testHazelcastInstance().getSet("Test_Distributed_Set");
}
@Bean
public IQueue<HazelcastIntegrationTestUser> testDistributedQueue() {
return testHazelcastInstance().getQueue("Test_Distributed_Queue");
}
@Bean
public ITopic<HazelcastIntegrationTestUser> testTopic() {
return testHazelcastInstance().getTopic("Test_Topic");
}
@Bean
public MultiMap<Integer, HazelcastIntegrationTestUser> testMultiMap() {
return testHazelcastInstance().getMultiMap("Test_Multi_Map");
}
@Bean
public ReplicatedMap<Integer, HazelcastIntegrationTestUser> testReplicatedMap() {
return testHazelcastInstance().getReplicatedMap("Test_Replicated_Map");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap1() {
return testHazelcastInstance().getMap("Test_CQ_Distributed_Map1");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap2() {
return testHazelcastInstance().getMap("Test_CQ_Distributed_Map2");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap3() {
return testHazelcastInstance().getMap("Test_CQ_Distributed_Map3");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap() {
return testHazelcastInstance().getMap("Test_DS_Distributed_Map");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap2() {
return testHazelcastInstance().getMap("Test_DS_Distributed_Map2");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap3() {
return testHazelcastInstance().getMap("Test_DS_Distributed_Map3");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap4() {
return testHazelcastInstance().getMap("Test_DS_Distributed_Map4");
}
@Bean
public Config hazelcastConfig() {
Config config = new Config();
config.getCPSubsystemConfig().setCPMemberCount(0)
.setSessionHeartbeatIntervalSeconds(1);
return config;
}
@Bean(destroyMethod = "shutdown")
public HazelcastInstance testHazelcastInstance() {
return Hazelcast.newHazelcastInstance(hazelcastConfig());
}
@Bean(HazelcastLocalInstanceRegistrar.BEAN_NAME)
public HazelcastLocalInstanceRegistrar hazelcastLocalInstanceRegistrar() {
return new HazelcastLocalInstanceRegistrar(testHazelcastInstance());
}
@Bean
public HazelcastEventDrivenMessageProducer hazelcastEventDrivenMessageProducer() {
final HazelcastEventDrivenMessageProducer producer =
new HazelcastEventDrivenMessageProducer(testDistributedMap());
producer.setOutputChannel(distributedMapChannel());
return producer;
}
@Bean
public HazelcastEventDrivenMessageProducer hazelcastEventDrivenMessageProducer2() {
final HazelcastEventDrivenMessageProducer producer =
new HazelcastEventDrivenMessageProducer(testDistributedMap2());
producer.setOutputChannel(distributedMapChannel2());
producer.setCacheEventTypes("ADDED,REMOVED,UPDATED,CLEAR_ALL");
return producer;
}
@Bean
public HazelcastEventDrivenMessageProducer hazelcastEventDrivenMessageProducer3() {
final HazelcastEventDrivenMessageProducer producer =
new HazelcastEventDrivenMessageProducer(testDistributedList());
producer.setOutputChannel(distributedListChannel());
producer.setCacheEventTypes("ADDED,REMOVED");
return producer;
}
@Bean
public HazelcastEventDrivenMessageProducer hazelcastEventDrivenMessageProducer4() {
final HazelcastEventDrivenMessageProducer producer =
new HazelcastEventDrivenMessageProducer(testDistributedSet());
producer.setOutputChannel(distributedSetChannel());
producer.setCacheEventTypes("ADDED,REMOVED");
return producer;
}
@Bean
public HazelcastEventDrivenMessageProducer hazelcastEventDrivenMessageProducer5() {
final HazelcastEventDrivenMessageProducer producer =
new HazelcastEventDrivenMessageProducer(testDistributedQueue());
producer.setOutputChannel(distributedQueueChannel());
producer.setCacheEventTypes("ADDED,REMOVED");
return producer;
}
@Bean
public HazelcastEventDrivenMessageProducer hazelcastEventDrivenMessageProducer6() {
final HazelcastEventDrivenMessageProducer producer =
new HazelcastEventDrivenMessageProducer(testTopic());
producer.setOutputChannel(topicChannel());
return producer;
}
@Bean
public HazelcastEventDrivenMessageProducer hazelcastEventDrivenMessageProducer7() {
final HazelcastEventDrivenMessageProducer producer =
new HazelcastEventDrivenMessageProducer(testReplicatedMap());
producer.setOutputChannel(replicatedMapChannel());
producer.setCacheEventTypes("ADDED,REMOVED,UPDATED");
return producer;
}
@Bean
public HazelcastEventDrivenMessageProducer hazelcastEventDrivenMessageProducer8() {
final HazelcastEventDrivenMessageProducer producer =
new HazelcastEventDrivenMessageProducer(testMultiMap());
producer.setOutputChannel(multiMapChannel());
producer.setCacheEventTypes("ADDED,REMOVED,CLEAR_ALL");
return producer;
}
@Bean
public HazelcastContinuousQueryMessageProducer hazelcastContinuousQueryMessageProducer() {
final HazelcastContinuousQueryMessageProducer producer =
new HazelcastContinuousQueryMessageProducer(testCQDistributedMap1(),
"name=TestName1");
producer.setOutputChannel(cqDistributedMapChannel1());
return producer;
}
@Bean
public HazelcastContinuousQueryMessageProducer hazelcastContinuousQueryMessageProducer2() {
final HazelcastContinuousQueryMessageProducer producer =
new HazelcastContinuousQueryMessageProducer(testCQDistributedMap2(),
"name=TestName1 OR name=TestName2");
producer.setOutputChannel(cqDistributedMapChannel2());
producer.setCacheEventTypes("ADDED,REMOVED,UPDATED,CLEAR_ALL");
return producer;
}
@Bean
public HazelcastContinuousQueryMessageProducer hazelcastContinuousQueryMessageProducer3() {
final HazelcastContinuousQueryMessageProducer producer =
new HazelcastContinuousQueryMessageProducer(testCQDistributedMap3(),
"surname=TestSurname2");
producer.setOutputChannel(cqDistributedMapChannel3());
producer.setCacheEventTypes("UPDATED");
producer.setIncludeValue(false);
return producer;
}
@Bean
public HazelcastClusterMonitorMessageProducer hazelcastClusterMonitorMessageProducer() {
final HazelcastClusterMonitorMessageProducer producer =
new HazelcastClusterMonitorMessageProducer(testHazelcastInstance());
producer.setOutputChannel(cmonChannel());
return producer;
}
@Bean
public HazelcastClusterMonitorMessageProducer hazelcastClusterMonitorMessageProducer2() {
final HazelcastClusterMonitorMessageProducer producer =
new HazelcastClusterMonitorMessageProducer(testHazelcastInstance());
producer.setOutputChannel(cmonChannel2());
producer.setMonitorEventTypes("DISTRIBUTED_OBJECT");
return producer;
}
@Bean
@InboundChannelAdapter(value = "dsDistributedMapChannel",
poller = @Poller(maxMessagesPerPoll = "1"))
public HazelcastDistributedSQLMessageSource hazelcastDistributedSQLMessageSource() {
final HazelcastDistributedSQLMessageSource messageSource =
new HazelcastDistributedSQLMessageSource(testDSDistributedMap(),
"name='TestName4' AND surname='TestSurname4'");
messageSource.setIterationType(DistributedSQLIterationType.ENTRY);
return messageSource;
}
@Bean
@InboundChannelAdapter(value = "dsDistributedMapChannel2",
poller = @Poller(maxMessagesPerPoll = "1"))
public HazelcastDistributedSQLMessageSource hazelcastDistributedSQLMessageSource2() {
final HazelcastDistributedSQLMessageSource messageSource =
new HazelcastDistributedSQLMessageSource(testDSDistributedMap2(),
"name='TestName1' AND surname='TestSurname1'");
messageSource.setIterationType(DistributedSQLIterationType.KEY);
return messageSource;
}
@Bean
@InboundChannelAdapter(value = "dsDistributedMapChannel3",
poller = @Poller(maxMessagesPerPoll = "1"))
public HazelcastDistributedSQLMessageSource hazelcastDistributedSQLMessageSource3() {
final HazelcastDistributedSQLMessageSource messageSource =
new HazelcastDistributedSQLMessageSource(testDSDistributedMap3(),
"age > 5");
messageSource.setIterationType(DistributedSQLIterationType.KEY);
return messageSource;
}
@Bean
@InboundChannelAdapter(value = "dsDistributedMapChannel4",
poller = @Poller(maxMessagesPerPoll = "1"))
public HazelcastDistributedSQLMessageSource hazelcastDistributedSQLMessageSource4() {
final HazelcastDistributedSQLMessageSource messageSource =
new HazelcastDistributedSQLMessageSource(testDSDistributedMap4(),
"name='TestName3' AND surname='TestSurname3'");
messageSource.setIterationType(DistributedSQLIterationType.VALUE);
return messageSource;
}
}

View File

@@ -0,0 +1,370 @@
/*
* Copyright 2015-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.integration.hazelcast.inbound.util;
import java.util.Collection;
import java.util.Map;
import com.hazelcast.cluster.MembershipEvent;
import com.hazelcast.collection.ICollection;
import com.hazelcast.core.DistributedObjectEvent;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.spi.exception.DistributedObjectDestroyedException;
import com.hazelcast.topic.ITopic;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
/**
* Util Class for Hazelcast Inbound Channel Adapters Test Support.
*
* @author Eren Avsarogullari
* @since 6.0
*/
@SuppressWarnings("unchecked")
public final class HazelcastInboundChannelAdapterTestUtils {
public static final int TIMEOUT = 30_000;
public static void verifyEntryEvent(Message<?> msg, String cacheName,
EntryEventType event) {
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
if (event == EntryEventType.CLEAR_ALL || event == EntryEventType.EVICT_ALL) {
assertThat(msg.getPayload() instanceof Integer).isTrue();
}
else {
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
}
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo(cacheName);
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(event.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
}
public static void verifyItemEvent(Message<?> msg, EntryEventType event) {
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE).toString()).isEqualTo(event.toString());
}
public static void testEventDrivenForADDEDDistributedMapEntryEvent(
final IMap<Integer, HazelcastIntegrationTestUser> distributedMap,
final PollableChannel channel, final String cacheName) {
HazelcastIntegrationTestUser hazelcastIntegrationTestUser =
new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1");
distributedMap.put(1, hazelcastIntegrationTestUser);
Message<?> msg = channel.receive(TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.ADDED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo(cacheName);
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(1));
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getId()).isEqualTo(1);
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getName()).isEqualTo("TestName1");
assertThat((((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).getSurname()).isEqualTo("TestSurname1");
}
public static void testEventDrivenForDistributedMapEntryEvents(
final IMap<Integer, HazelcastIntegrationTestUser> distributedMap,
final PollableChannel channel, final String cacheName) {
distributedMap
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.ADDED);
distributedMap.put(1,
new HazelcastIntegrationTestUser(1, "TestName1", "TestSurnameUpdated"));
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.UPDATED);
distributedMap.remove(1);
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.REMOVED);
distributedMap
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.ADDED);
distributedMap.clear();
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.CLEAR_ALL);
}
public static void testEventDrivenForDistributedCollectionItemEvents(
final ICollection<HazelcastIntegrationTestUser> distributedObject,
final PollableChannel channel) {
HazelcastIntegrationTestUser user =
new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1");
distributedObject.add(user);
Message<?> msg = channel.receive(TIMEOUT);
verifyItemEvent(msg, EntryEventType.ADDED);
distributedObject.remove(user);
msg = channel.receive(TIMEOUT);
verifyItemEvent(msg, EntryEventType.REMOVED);
user = new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
distributedObject.add(user);
msg = channel.receive(TIMEOUT);
verifyItemEvent(msg, EntryEventType.ADDED);
}
public static void testEventDrivenForReplicatedMapEntryEvents(
final ReplicatedMap<Integer, HazelcastIntegrationTestUser> replicatedMap,
final PollableChannel channel, final String cacheName) {
replicatedMap
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.ADDED);
replicatedMap.put(1,
new HazelcastIntegrationTestUser(1, "TestName1", "TestSurnameUpdated"));
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.UPDATED);
replicatedMap.remove(1);
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.REMOVED);
replicatedMap
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.ADDED);
}
public static void testEventDrivenForTopicMessageEvent(
final ITopic<HazelcastIntegrationTestUser> topic, final PollableChannel channel) {
topic.publish(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = channel.receive(TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.PUBLISHING_TIME)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo(topic.getName());
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getId()).isEqualTo(1);
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getName()).isEqualTo("TestName1");
assertThat(((HazelcastIntegrationTestUser) msg.getPayload()).getSurname()).isEqualTo("TestSurname1");
}
public static void testEventDrivenForMultiMapEntryEvents(
final MultiMap<Integer, HazelcastIntegrationTestUser> multiMap,
final PollableChannel channel, final String cacheName) {
multiMap.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.ADDED);
multiMap.put(1,
new HazelcastIntegrationTestUser(1, "TestName1", "TestSurnameUpdated"));
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.ADDED);
multiMap.remove(1);
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.REMOVED);
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.REMOVED);
multiMap.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.ADDED);
multiMap.clear();
msg = channel.receive(TIMEOUT);
verifyEntryEvent(msg, cacheName, EntryEventType.CLEAR_ALL);
}
public static void testContinuousQueryForUPDATEDEntryEventWhenIncludeValueIsFalse(
final IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap,
final PollableChannel channel, final String cacheName) {
cqDistributedMap
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
cqDistributedMap
.put(1, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg = channel.receive(TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof EntryEventMessagePayload).isTrue();
assertThat(msg.getHeaders().get(HazelcastHeaders.MEMBER)).isNotNull();
assertThat(msg.getHeaders().get(HazelcastHeaders.EVENT_TYPE)).isEqualTo(EntryEventType.UPDATED.name());
assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo(cacheName);
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).key).isEqualTo(Integer.valueOf(1));
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).oldValue).isNull();
assertThat(((EntryEventMessagePayload<Integer, HazelcastIntegrationTestUser>) msg
.getPayload()).value).isNull();
}
public static void testDistributedSQLForENTRYIterationType(
final IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap,
final PollableChannel channel) {
dsDistributedMap
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1", 10));
dsDistributedMap
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2", 20));
dsDistributedMap
.put(3, new HazelcastIntegrationTestUser(3, "TestName3", "TestSurname3", 30));
dsDistributedMap
.put(4, new HazelcastIntegrationTestUser(4, "TestName4", "TestSurname4", 40));
dsDistributedMap
.put(5, new HazelcastIntegrationTestUser(5, "TestName5", "TestSurname5", 50));
Message<?> msg = channel.receive(TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof Collection).isTrue();
assertThat((((Map.Entry<?, ?>) ((Collection<?>) msg.getPayload()).iterator().next())
.getKey())).isEqualTo(4);
assertThat(((HazelcastIntegrationTestUser) ((Map.Entry<?, ?>) ((Collection<?>) msg
.getPayload()).iterator().next()).getValue()).getId()).isEqualTo(4);
assertThat(((HazelcastIntegrationTestUser) ((Map.Entry<?, ?>) ((Collection<?>) msg
.getPayload()).iterator().next()).getValue()).getName()).isEqualTo("TestName4");
assertThat(((HazelcastIntegrationTestUser) ((Map.Entry<?, ?>) ((Collection<?>) msg
.getPayload()).iterator().next()).getValue()).getSurname()).isEqualTo("TestSurname4");
}
public static void testDistributedSQLForKEYIterationType(
final IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap,
final PollableChannel channel) {
dsDistributedMap
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1", 10));
dsDistributedMap
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2", 20));
dsDistributedMap
.put(3, new HazelcastIntegrationTestUser(3, "TestName3", "TestSurname3", 30));
Message<?> msg = channel.receive(TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof Collection).isTrue();
assertThat(((Collection<?>) msg.getPayload()).iterator().next()).isEqualTo(1);
}
public static void testDistributedSQLForLOCAL_KEYIterationType(
final IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap,
final PollableChannel channel) {
dsDistributedMap
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1", 10));
dsDistributedMap
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2", 20));
dsDistributedMap
.put(3, new HazelcastIntegrationTestUser(3, "TestName3", "TestSurname3", 30));
Message<?> msg = channel.receive(TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof Collection).isTrue();
}
public static void testDistributedSQLForVALUEIterationType(
final IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap,
final PollableChannel channel) {
dsDistributedMap
.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1", 10));
dsDistributedMap
.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2", 20));
dsDistributedMap
.put(3, new HazelcastIntegrationTestUser(3, "TestName3", "TestSurname3", 30));
dsDistributedMap
.put(4, new HazelcastIntegrationTestUser(4, "TestName4", "TestSurname4", 40));
dsDistributedMap
.put(5, new HazelcastIntegrationTestUser(5, "TestName5", "TestSurname5", 50));
Message<?> msg = channel.receive(TIMEOUT);
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof Collection).isTrue();
assertThat(((HazelcastIntegrationTestUser) (((Collection<?>) msg.getPayload()).iterator()
.next())).getId()).isEqualTo(3);
assertThat(((HazelcastIntegrationTestUser) (((Collection<?>) msg.getPayload()).iterator()
.next())).getName()).isEqualTo("TestName3");
assertThat(((HazelcastIntegrationTestUser) (((Collection<?>) msg.getPayload()).iterator()
.next())).getSurname()).isEqualTo("TestSurname3");
}
public static void testDistributedObjectEventByChannelAndHazelcastInstance(
final PollableChannel channel, final HazelcastInstance hazelcastInstance,
final String distributedObjectName) {
final IMap<Integer, String> distributedMap =
hazelcastInstance.getMap(distributedObjectName);
Message<?> msg = channel.receive(TIMEOUT);
verifyDistributedObjectEvent(msg, DistributedObjectEvent.EventType.CREATED,
distributedObjectName);
distributedMap.destroy();
msg = channel.receive(TIMEOUT);
try {
// Since Hazelcast 3.6 we can use DistributedObjectEvent.getDistributedObject() for DESTROYED objects.
verifyDistributedObjectEvent(msg, DistributedObjectEvent.EventType.DESTROYED, distributedObjectName);
fail("DistributedObjectDestroyedException expected");
}
catch (Exception e) {
assertThat(e).isInstanceOf(DistributedObjectDestroyedException.class);
}
}
private static void verifyMembershipEvent(final Message<?> msg,
final int membershipEvent) {
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof MembershipEvent).isTrue();
assertThat(((MembershipEvent) msg.getPayload()).getEventType()).isEqualTo(membershipEvent);
assertThat(((MembershipEvent) msg.getPayload()).getMember()).isNotNull();
}
private static void verifyDistributedObjectEvent(final Message<?> msg,
final DistributedObjectEvent.EventType eventType,
final String distributedObjectName) {
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof DistributedObjectEvent).isTrue();
assertThat(((DistributedObjectEvent) msg.getPayload()).getEventType()).isEqualTo(eventType);
assertThat(distributedObjectName).as((((DistributedObjectEvent) msg.getPayload()).getDistributedObject())
.getName()).isNotNull();
}
private HazelcastInboundChannelAdapterTestUtils() {
}
}

View File

@@ -0,0 +1,356 @@
/*
* Copyright 2015-2024 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.integration.hazelcast.leader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.cp.CPGroupId;
import com.hazelcast.cp.CPSubsystem;
import com.hazelcast.cp.lock.FencedLock;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.leader.Candidate;
import org.springframework.integration.leader.Context;
import org.springframework.integration.leader.DefaultCandidate;
import org.springframework.integration.leader.event.AbstractLeaderEvent;
import org.springframework.integration.leader.event.DefaultLeaderEventPublisher;
import org.springframework.integration.leader.event.LeaderEventPublisher;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
/**
* Tests for hazelcast leader election.
*
* @author Janne Valkealahti
* @author Patrick Peralta
* @author Dave Syer
* @author Artem Bilan
* @author Mael Le Guével
* @author Emil Palm
*/
@SpringJUnitConfig
@DirtiesContext
public class LeaderInitiatorTests {
@Autowired
private HazelcastInstance hazelcastInstance;
@Autowired
private TestCandidate candidate;
@Autowired
private TestEventListener listener;
@Autowired
private LeaderInitiator initiator;
@Test
public void testLeaderElections() throws Exception {
assertThat(this.candidate.onGrantedLatch.await(5, TimeUnit.SECONDS)).isTrue();
assertThat(this.listener.onEventLatch.await(5, TimeUnit.SECONDS)).isTrue();
assertThat(this.listener.events.size()).isEqualTo(1);
this.initiator.destroy();
CountDownLatch granted = new CountDownLatch(1);
CountingPublisher countingPublisher = new CountingPublisher(granted);
List<LeaderInitiator> initiators = new ArrayList<>();
for (int i = 0; i < 2; i++) {
LeaderInitiator initiator = new LeaderInitiator(this.hazelcastInstance, new DefaultCandidate());
initiator.setLeaderEventPublisher(countingPublisher);
initiators.add(initiator);
}
for (LeaderInitiator initiator : initiators) {
initiator.start();
}
assertThat(granted.await(10, TimeUnit.SECONDS)).isTrue();
LeaderInitiator initiator1 = countingPublisher.initiator;
LeaderInitiator initiator2 = null;
for (LeaderInitiator initiator : initiators) {
if (initiator != initiator1) {
initiator2 = initiator;
break;
}
}
assertThat(initiator2).isNotNull();
assertThat(initiator1.getContext().isLeader()).isTrue();
assertThat(initiator2.getContext().isLeader()).isFalse();
final CountDownLatch granted1 = new CountDownLatch(1);
final CountDownLatch granted2 = new CountDownLatch(1);
CountDownLatch revoked1 = new CountDownLatch(1);
CountDownLatch revoked2 = new CountDownLatch(1);
initiator1.setLeaderEventPublisher(new CountingPublisher(granted1, revoked1) {
@Override
public void publishOnRevoked(Object source, Context context, String role) {
try {
// It's difficult to see round-robin election, so block one initiator until the second is elected.
assertThat(granted2.await(10, TimeUnit.SECONDS)).isTrue();
}
catch (InterruptedException e) {
// No op
}
super.publishOnRevoked(source, context, role);
}
});
initiator2.setLeaderEventPublisher(new CountingPublisher(granted2, revoked2) {
@Override
public void publishOnRevoked(Object source, Context context, String role) {
try {
// It's difficult to see round-robin election, so block one initiator until the second is elected.
assertThat(granted1.await(10, TimeUnit.SECONDS)).isTrue();
}
catch (InterruptedException e) {
// No op
}
super.publishOnRevoked(source, context, role);
}
});
initiator1.getContext().yield();
assertThat(revoked1.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(initiator2.getContext().isLeader()).isTrue();
assertThat(initiator1.getContext().isLeader()).isFalse();
initiator2.getContext().yield();
assertThat(revoked2.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(initiator1.getContext().isLeader()).isTrue();
assertThat(initiator2.getContext().isLeader()).isFalse();
initiator2.destroy();
CountDownLatch revoked11 = new CountDownLatch(1);
initiator1.setLeaderEventPublisher(new CountingPublisher(new CountDownLatch(1), revoked11));
initiator1.getContext().yield();
assertThat(revoked11.await(10, TimeUnit.SECONDS)).isTrue();
initiator1.destroy();
CountDownLatch onGranted = new CountDownLatch(1);
DefaultCandidate candidate = spy(new DefaultCandidate());
willAnswer(invocation -> {
try {
return invocation.callRealMethod();
}
finally {
onGranted.countDown();
}
})
.given(candidate).onGranted(any(Context.class));
LeaderInitiator initiator = new LeaderInitiator(this.hazelcastInstance, candidate);
initiator.setLeaderEventPublisher(new DefaultLeaderEventPublisher() {
@Override
public void publishOnGranted(Object source, Context context, String role) {
throw new RuntimeException("intentional");
}
});
initiator.start();
assertThat(onGranted.await(5, TimeUnit.SECONDS)).isTrue();
assertThat(initiator.getContext().isLeader()).isTrue();
initiator.destroy();
}
@Test
public void testRevokeLeadershipCalledWhenLockNotAcquiredButStillLeader() throws Exception {
// Initialize mocks and objects needed for the revoke leadership when fenced lock is no longer acquired
HazelcastInstance hazelcastInstance = mock();
Candidate candidate = mock();
FencedLock fencedLock = mock();
LeaderEventPublisher leaderEventPublisher = mock();
CPSubsystem cpSubsystem = mock(CPSubsystem.class);
given(candidate.getRole()).willReturn("role");
given(hazelcastInstance.getCPSubsystem()).willReturn(cpSubsystem);
given(cpSubsystem.getLock(anyString())).willReturn(fencedLock);
given(fencedLock.getGroupId())
.willReturn(new CPGroupId() {
@Override
public String getName() {
return "";
}
@Override
public long getId() {
return 0;
}
});
LeaderInitiator leaderInitiator = new LeaderInitiator(hazelcastInstance, candidate);
leaderInitiator.setLeaderEventPublisher(leaderEventPublisher);
// Simulate that the lock is currently held by this thread
given(fencedLock.isLockedByCurrentThread()).willReturn(true, false);
given(fencedLock.tryLock(anyLong(), any(TimeUnit.class))).willReturn(false); // Lock acquisition fails
// Start the LeaderInitiator to trigger the leader election process
leaderInitiator.start();
// Simulate the lock acquisition check process
Thread.sleep(1000); // Give time for the async task to run
// Verify that revokeLeadership was called due to lock not being acquired
// unlock is part of revokeLeadership
verify(fencedLock).unlock();
// verify revoke event is published
verify(leaderEventPublisher).publishOnRevoked(any(Object.class), any(Context.class), anyString());
leaderInitiator.destroy();
}
@Configuration
public static class TestConfig {
@Bean
TestCandidate candidate() {
return new TestCandidate();
}
@Bean
Config hazelcastConfig() {
Config config = new Config();
config.getCPSubsystemConfig()
.setSessionHeartbeatIntervalSeconds(1);
return config;
}
@Bean(destroyMethod = "shutdown")
HazelcastInstance hazelcastInstance() {
return Hazelcast.newHazelcastInstance(hazelcastConfig());
}
@Bean
LeaderInitiator initiator() {
return new LeaderInitiator(hazelcastInstance(), candidate());
}
@Bean
TestEventListener testEventListener() {
return new TestEventListener();
}
}
static class TestCandidate extends DefaultCandidate {
CountDownLatch onGrantedLatch = new CountDownLatch(1);
@Override
public void onGranted(Context ctx) {
this.onGrantedLatch.countDown();
super.onGranted(ctx);
}
}
static class TestEventListener implements ApplicationListener<AbstractLeaderEvent> {
CountDownLatch onEventLatch = new CountDownLatch(1);
ArrayList<AbstractLeaderEvent> events = new ArrayList<>();
@Override
public void onApplicationEvent(AbstractLeaderEvent event) {
this.events.add(event);
this.onEventLatch.countDown();
}
}
private static class CountingPublisher implements LeaderEventPublisher {
private CountDownLatch granted;
private CountDownLatch revoked;
private volatile LeaderInitiator initiator;
CountingPublisher(CountDownLatch granted, CountDownLatch revoked) {
this.granted = granted;
this.revoked = revoked;
}
CountingPublisher(CountDownLatch granted) {
this(granted, new CountDownLatch(1));
}
@Override
public void publishOnRevoked(Object source, Context context, String role) {
this.revoked.countDown();
}
@Override
public void publishOnFailedToAcquire(Object source, Context context, String role) {
}
@Override
public void publishOnGranted(Object source, Context context, String role) {
this.initiator = (LeaderInitiator) source;
this.granted.countDown();
}
}
}

View File

@@ -0,0 +1,284 @@
/*
* Copyright 2017-2024 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.integration.hazelcast.lock;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.cp.lock.FencedLock;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Artem Bilan
*/
public class HazelcastLockRegistryTests {
private static final Config CONFIG = new Config();
static {
CONFIG.getCPSubsystemConfig().setCPMemberCount(0);
}
private static final HazelcastInstance instance = Hazelcast.newHazelcastInstance(CONFIG);
@AfterAll
public static void destroy() {
HazelcastInstanceFactory.terminateAll();
}
@Test
public void testLock() {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
for (int i = 0; i < 10; i++) {
Lock lock = registry.obtain("foo");
lock.lock();
try {
assertThat(((FencedLock) lock).isLocked()).isTrue();
assertThat(((FencedLock) lock).isLockedByCurrentThread()).isTrue();
}
finally {
lock.unlock();
}
}
}
@Test
public void testLockInterruptibly() throws Exception {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
for (int i = 0; i < 10; i++) {
Lock lock = registry.obtain("foo");
lock.lockInterruptibly();
try {
assertThat(((FencedLock) lock).isLocked()).isTrue();
assertThat(((FencedLock) lock).isLockedByCurrentThread()).isTrue();
}
finally {
lock.unlock();
}
}
}
@Test
public void testReentrantLock() {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
for (int i = 0; i < 10; i++) {
Lock lock1 = registry.obtain("foo");
lock1.lock();
try {
Lock lock2 = registry.obtain("foo");
assertThat(lock2).isSameAs(lock1);
lock2.lock();
lock2.unlock();
}
finally {
lock1.unlock();
}
}
}
@Test
public void testReentrantLockInterruptibly() throws Exception {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
for (int i = 0; i < 10; i++) {
Lock lock1 = registry.obtain("foo");
lock1.lockInterruptibly();
try {
Lock lock2 = registry.obtain("foo");
assertThat(lock2).isSameAs(lock1);
lock2.lockInterruptibly();
lock2.unlock();
}
finally {
lock1.unlock();
}
}
}
@Test
public void testTwoLocks() throws Exception {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
for (int i = 0; i < 10; i++) {
Lock lock1 = registry.obtain("foo");
lock1.lockInterruptibly();
try {
Lock lock2 = registry.obtain("bar");
assertThat(lock2).isNotSameAs(lock1);
lock2.lockInterruptibly();
lock2.unlock();
}
finally {
lock1.unlock();
}
}
}
@Test
public void testTwoThreadsSecondFailsToGetLock() throws Exception {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
Lock lock1 = registry.obtain("foo");
lock1.lockInterruptibly();
AtomicBoolean locked = new AtomicBoolean();
CountDownLatch latch = new CountDownLatch(1);
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Object> result = executorService.submit(() -> {
Lock lock2 = registry.obtain("foo");
locked.set(lock2.tryLock(200, TimeUnit.MILLISECONDS));
latch.countDown();
try {
lock2.unlock();
}
catch (Exception e) {
return e;
}
return null;
});
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(locked.get()).isFalse();
lock1.unlock();
Object ise = result.get(10, TimeUnit.SECONDS);
assertThat(ise).isInstanceOf(IllegalMonitorStateException.class);
assertThat(((Exception) ise).getMessage()).contains("Current thread is not owner of the lock!");
executorService.shutdown();
}
@Test
public void testTwoThreads() throws Exception {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
Lock lock1 = registry.obtain("foo");
AtomicBoolean locked = new AtomicBoolean();
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
CountDownLatch latch3 = new CountDownLatch(1);
lock1.lockInterruptibly();
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
Lock lock2 = registry.obtain("foo");
try {
latch1.countDown();
lock2.lockInterruptibly();
latch2.await(10, TimeUnit.SECONDS);
locked.set(true);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
finally {
lock2.unlock();
latch3.countDown();
}
});
assertThat(latch1.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(locked.get()).isFalse();
lock1.unlock();
latch2.countDown();
assertThat(latch3.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(locked.get()).isTrue();
executorService.shutdown();
}
@Test
public void testTwoThreadsDifferentRegistries() throws Exception {
HazelcastLockRegistry registry1 = new HazelcastLockRegistry(instance);
HazelcastLockRegistry registry2 = new HazelcastLockRegistry(instance);
Lock lock1 = registry1.obtain("foo");
AtomicBoolean locked = new AtomicBoolean();
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
CountDownLatch latch3 = new CountDownLatch(1);
lock1.lockInterruptibly();
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
Lock lock2 = registry2.obtain("foo");
try {
latch1.countDown();
lock2.lockInterruptibly();
latch2.await(10, TimeUnit.SECONDS);
locked.set(true);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
finally {
lock2.unlock();
latch3.countDown();
}
});
assertThat(latch1.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(locked.get()).isFalse();
lock1.unlock();
latch2.countDown();
assertThat(latch3.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(locked.get()).isTrue();
executorService.shutdown();
}
@Test
public void testTwoThreadsWrongOneUnlocks() throws Exception {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
final Lock lock = registry.obtain("foo");
lock.lockInterruptibly();
final AtomicBoolean locked = new AtomicBoolean();
final CountDownLatch latch = new CountDownLatch(1);
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Object> result = executorService.submit(() -> {
try {
lock.unlock();
}
catch (Exception e) {
latch.countDown();
return e;
}
return null;
});
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(locked.get()).isFalse();
lock.unlock();
Object imse = result.get(10, TimeUnit.SECONDS);
assertThat(imse).isInstanceOf(IllegalMonitorStateException.class);
assertThat(((Exception) imse).getMessage()).contains("Current thread is not owner of the lock!");
executorService.shutdown();
}
@Test
public void testTryLock() throws Exception {
HazelcastLockRegistry registry = new HazelcastLockRegistry(instance);
for (int i = 0; i < 10; i++) {
Lock lock = registry.obtain("foo");
int n = 0;
while (!lock.tryLock() && n++ < 100) {
Thread.sleep(100);
}
assertThat(n).isLessThan(100);
lock.unlock();
}
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright 2017-2023 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.integration.hazelcast.metadata;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.integration.metadata.MetadataStoreListener;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.awaitility.Awaitility.await;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* @author Vinicius Carvalho
* @author Artem Bilan
*/
public class HazelcastMetadataStoreTests {
private static HazelcastInstance instance;
private static IMap<String, String> map;
HazelcastMetadataStore metadataStore;
@BeforeAll
public static void init() {
instance = Hazelcast.newHazelcastInstance();
map = instance.getMap("customTestsMetadataStore");
}
@AfterAll
public static void destroy() {
instance.shutdown();
}
@BeforeEach
public void setup() {
this.metadataStore = new HazelcastMetadataStore(map);
this.metadataStore.afterPropertiesSet();
}
@AfterEach
public void clean() {
map.clear();
}
@Test
public void testGetNonExistingKeyValue() {
String retrievedValue = this.metadataStore.get("does-not-exist");
assertThat(retrievedValue).isNull();
}
@Test
public void testPersistKeyValue() {
this.metadataStore.put("HazelcastMetadataStoreTests-Spring", "Integration");
assertThat(map.get("HazelcastMetadataStoreTests-Spring")).isEqualTo("Integration");
}
@Test
public void testGetValueFromMetadataStore() {
this.metadataStore.put("HazelcastMetadataStoreTests-GetValue", "Hello Hazelcast");
String retrievedValue = this.metadataStore.get("HazelcastMetadataStoreTests-GetValue");
assertThat(retrievedValue).isEqualTo("Hello Hazelcast");
}
@Test
public void testPersistEmptyStringToMetadataStore() {
this.metadataStore.put("HazelcastMetadataStoreTests-PersistEmpty", "");
String retrievedValue = this.metadataStore.get("HazelcastMetadataStoreTests-PersistEmpty");
assertThat(retrievedValue).isEqualTo("");
}
@Test
public void testPersistNullStringToMetadataStore() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.metadataStore.put("HazelcastMetadataStoreTests-PersistEmpty", null))
.withMessage("'value' must not be null.");
}
@Test
public void testPersistWithEmptyKeyToMetadataStore() {
this.metadataStore.put("", "PersistWithEmptyKey");
String retrievedValue = this.metadataStore.get("");
assertThat(retrievedValue).isEqualTo("PersistWithEmptyKey");
}
@Test
public void testPersistWithNullKeyToMetadataStore() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.metadataStore.put(null, "something"))
.withMessage("'key' must not be null.");
}
@Test
public void testGetValueWithNullKeyFromMetadataStore() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.metadataStore.get(null))
.withMessage("'key' must not be null.");
}
@Test
public void testRemoveFromMetadataStore() {
String testKey = "HazelcastMetadataStoreTests-Remove";
String testValue = "Integration";
this.metadataStore.put(testKey, testValue);
assertThat(this.metadataStore.remove(testKey)).isEqualTo(testValue);
assertThat(this.metadataStore.remove(testKey)).isNull();
}
@Test
public void testPersistKeyValueIfAbsent() {
this.metadataStore.putIfAbsent("HazelcastMetadataStoreTests-Spring", "Integration");
assertThat(map.get("HazelcastMetadataStoreTests-Spring")).isEqualTo("Integration");
}
@Test
public void testReplaceValue() {
this.metadataStore.put("key", "old");
assertThat(map.get("key")).isEqualTo("old");
this.metadataStore.replace("key", "old", "new");
assertThat(map.get("key")).isEqualTo("new");
}
@Test
public void testListener() {
MetadataStoreListener listener = mock(MetadataStoreListener.class);
this.metadataStore.addListener(listener);
this.metadataStore.put("foo", "bar");
this.metadataStore.replace("foo", "bar", "baz");
this.metadataStore.remove("foo");
await().untilAsserted(() -> verify(listener).onAdd("foo", "bar"));
verify(listener).onUpdate("foo", "baz");
verify(listener).onRemove("foo", "baz");
}
}

View File

@@ -0,0 +1,280 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
https://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<import resource="classpath:org/springframework/integration/hazelcast/common-config.xml"/>
<int:channel id="firstMapChannel"/>
<int:channel id="secondMapChannel"/>
<int:channel id="thirdMapChannel"/>
<int:channel id="fourthMapChannel"/>
<int:channel id="fifthMapChannel"/>
<int:channel id="sixthMapChannel"/>
<int:channel id="bulkMapChannel"/>
<int:channel id="multiMapChannel"/>
<int:channel id="replicatedMapChannel"/>
<int:channel id="bulkReplicatedMapChannel"/>
<int:channel id="listChannel"/>
<int:channel id="bulkListChannel"/>
<int:channel id="setChannel"/>
<int:channel id="bulkSetChannel"/>
<int:channel id="queueChannel">
<int:queue/>
</int:channel>
<int:channel id="bulkQueueChannel">
<int:queue/>
</int:channel>
<int:channel id="topicChannel"/>
<bean id="testFirstMapRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="firstMapChannel" cache="distributedMap" key-expression="payload.id">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testFirstMapRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testSecondMapRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="secondMapChannel" cache-expression="@distributedMap" key-expression="payload.id">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testSecondMapRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testThirdMapRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="thirdMapChannel" key-expression="payload.id">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testThirdMapRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testFourthMapRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="fourthMapChannel" key-expression="payload.id" extract-payload="false">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testFourthMapRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<int-hazelcast:outbound-channel-adapter channel="fifthMapChannel" key-expression="payload.id" />
<int-hazelcast:outbound-channel-adapter channel="sixthMapChannel" />
<bean id="testBulkMapRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="1"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="bulkMapChannel" cache="distributedBulkMap" key-expression="payload.id">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testBulkMapRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testMultiMapRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="multiMapChannel" cache="multiMap" key-expression="payload.id">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testMultiMapRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testReplicatedMapRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="replicatedMapChannel" cache="replicatedMap" key-expression="payload.id">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testReplicatedMapRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testBulkReplicatedMapRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="1"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="bulkReplicatedMapChannel" cache="bulkReplicatedMap" key-expression="payload.id">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testBulkReplicatedMapRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testListRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="listChannel" cache="distributedList">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testListRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testBulkListRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="1"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="bulkListChannel" cache="distributedBulkList">
<int-hazelcast:request-handler-advice-chain>
<ref bean="testBulkListRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testSetRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="setChannel" cache="distributedSet" >
<int-hazelcast:request-handler-advice-chain>
<ref bean="testSetRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testBulkSetRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="1"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="bulkSetChannel" cache="distributedBulkSet" >
<int-hazelcast:request-handler-advice-chain>
<ref bean="testBulkSetRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testQueueRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="queueChannel" cache="distributedQueue">
<int:poller fixed-delay="100"/>
<int-hazelcast:request-handler-advice-chain>
<ref bean="testQueueRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testBulkQueueRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="1"/>
</bean>
<int-hazelcast:outbound-channel-adapter channel="bulkQueueChannel" cache="distributedBulkQueue">
<int:poller fixed-delay="100"/>
<int-hazelcast:request-handler-advice-chain>
<ref bean="testBulkQueueRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<bean id="testTopicRequestHandlerAdvice"
class="org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice">
<constructor-arg type="int" value="100" />
</bean>
<int-hazelcast:outbound-channel-adapter channel="topicChannel" cache="topic" >
<int-hazelcast:request-handler-advice-chain>
<ref bean="testTopicRequestHandlerAdvice"/>
</int-hazelcast:request-handler-advice-chain>
</int-hazelcast:outbound-channel-adapter>
<int-hazelcast:outbound-channel-adapter id="lockChannel" cache="myLock" />
<bean id="distributedMap" factory-bean="instance" factory-method="getMap">
<constructor-arg value="distributedMap"/>
</bean>
<bean id="distributedBulkMap" factory-bean="instance" factory-method="getMap">
<constructor-arg value="distributedBulkMap"/>
</bean>
<bean id="distributedList" factory-bean="instance" factory-method="getList">
<constructor-arg value="distributedList"/>
</bean>
<bean id="distributedBulkList" factory-bean="instance" factory-method="getList">
<constructor-arg value="distributedBulkList"/>
</bean>
<bean id="distributedSet" factory-bean="instance" factory-method="getSet">
<constructor-arg value="distributedSet"/>
</bean>
<bean id="distributedBulkSet" factory-bean="instance" factory-method="getSet">
<constructor-arg value="distributedBulkSet"/>
</bean>
<bean id="distributedQueue" factory-bean="instance" factory-method="getQueue">
<constructor-arg value="distributedQueue"/>
</bean>
<bean id="distributedBulkQueue" factory-bean="instance" factory-method="getQueue">
<constructor-arg value="distributedBulkQueue"/>
</bean>
<bean id="multiMap" factory-bean="instance" factory-method="getMultiMap">
<constructor-arg value="multiMap"/>
</bean>
<bean id="replicatedMap" factory-bean="instance" factory-method="getReplicatedMap">
<constructor-arg value="replicatedMap"/>
</bean>
<bean id="bulkReplicatedMap" factory-bean="instance" factory-method="getReplicatedMap">
<constructor-arg value="bulkReplicatedMap"/>
</bean>
<bean id="topic" factory-bean="instance" factory-method="getTopic">
<constructor-arg value="topic"/>
</bean>
<bean id="cpSubsystem" factory-bean="instance" factory-method="getCPSubsystem"/>
<bean id="myLock" factory-bean="cpSubsystem" factory-method="getLock">
<constructor-arg value="myLock"/>
</bean>
</beans>

View File

@@ -0,0 +1,471 @@
/*
* Copyright 2015-2024 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.integration.hazelcast.outbound;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice;
import org.springframework.integration.hazelcast.outbound.util.HazelcastOutboundChannelAdapterTestUtils;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
import org.springframework.integration.support.MessageBuilderFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Hazelcast Outbound Channel Adapter Test Class.
*
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 6.0
*/
@SpringJUnitConfig
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastOutboundChannelAdapterTests {
private static final String DISTRIBUTED_MAP = "distributedMap";
private static final String CACHE_HEADER = "CACHE_HEADER";
private final MessageBuilderFactory messageBuilderFactory =
new DefaultMessageBuilderFactory();
@Autowired
@Qualifier("firstMapChannel")
private MessageChannel firstMapChannel;
@Autowired
@Qualifier("secondMapChannel")
private MessageChannel secondMapChannel;
@Autowired
@Qualifier("thirdMapChannel")
private MessageChannel thirdMapChannel;
@Autowired
@Qualifier("fourthMapChannel")
private MessageChannel fourthMapChannel;
@Autowired
@Qualifier("fifthMapChannel")
private MessageChannel fifthMapChannel;
@Autowired
@Qualifier("sixthMapChannel")
private MessageChannel sixthMapChannel;
@Autowired
@Qualifier("bulkMapChannel")
private MessageChannel bulkMapChannel;
@Autowired
@Qualifier("multiMapChannel")
private MessageChannel multiMapChannel;
@Autowired
@Qualifier("replicatedMapChannel")
private MessageChannel replicatedMapChannel;
@Autowired
@Qualifier("bulkReplicatedMapChannel")
private MessageChannel bulkReplicatedMapChannel;
@Autowired
@Qualifier("listChannel")
private MessageChannel listChannel;
@Autowired
@Qualifier("bulkListChannel")
private MessageChannel bulkListChannel;
@Autowired
@Qualifier("setChannel")
private MessageChannel setChannel;
@Autowired
@Qualifier("bulkSetChannel")
private MessageChannel bulkSetChannel;
@Autowired
@Qualifier("queueChannel")
private MessageChannel queueChannel;
@Autowired
@Qualifier("bulkQueueChannel")
private MessageChannel bulkQueueChannel;
@Autowired
@Qualifier("topicChannel")
private MessageChannel topicChannel;
@Autowired
@Qualifier("lockChannel")
private MessageChannel lockChannel;
@Autowired
private Map<?, ?> distributedMap;
@Autowired
private Map<?, ?> distributedBulkMap;
@Autowired
private MultiMap multiMap;
@Autowired
private ReplicatedMap replicatedMap;
@Autowired
private ReplicatedMap bulkReplicatedMap;
@Autowired
private List distributedList;
@Autowired
private List distributedBulkList;
@Autowired
private Set distributedSet;
@Autowired
private Set distributedBulkSet;
@Autowired
private Queue distributedQueue;
@Autowired
private Queue distributedBulkQueue;
@Autowired
private ITopic topic;
@Autowired
@Qualifier("testFirstMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testFirstMapRequestHandlerAdvice;
@Autowired
@Qualifier("testSecondMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testSecondMapRequestHandlerAdvice;
@Autowired
@Qualifier("testThirdMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testThirdMapRequestHandlerAdvice;
@Autowired
@Qualifier("testFourthMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testFourthMapRequestHandlerAdvice;
@Autowired
@Qualifier("testBulkMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testBulkMapRequestHandlerAdvice;
@Autowired
@Qualifier("testMultiMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testMultiMapRequestHandlerAdvice;
@Autowired
@Qualifier("testReplicatedMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testReplicatedMapRequestHandlerAdvice;
@Autowired
@Qualifier("testBulkReplicatedMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testBulkReplicatedMapRequestHandlerAdvice;
@Autowired
@Qualifier("testListRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testListRequestHandlerAdvice;
@Autowired
@Qualifier("testBulkListRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testBulkListRequestHandlerAdvice;
@Autowired
@Qualifier("testSetRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testSetRequestHandlerAdvice;
@Autowired
@Qualifier("testBulkSetRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testBulkSetRequestHandlerAdvice;
@Autowired
@Qualifier("testQueueRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testQueueRequestHandlerAdvice;
@Autowired
@Qualifier("testBulkQueueRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testBulkQueueRequestHandlerAdvice;
@Autowired
@Qualifier("testTopicRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testTopicRequestHandlerAdvice;
@AfterAll
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@BeforeEach
public void setUp() {
this.distributedMap.clear();
this.distributedBulkMap.clear();
this.distributedList.clear();
this.distributedBulkList.clear();
this.distributedSet.clear();
this.distributedBulkSet.clear();
this.distributedQueue.clear();
this.distributedBulkQueue.clear();
this.multiMap.clear();
this.replicatedMap.clear();
this.bulkReplicatedMap.clear();
}
@Test
public void testWriteToDistributedMap() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToDistributedMap(this.firstMapChannel, this.distributedMap,
this.testFirstMapRequestHandlerAdvice);
}
@Test
public void testBulkWriteToDistributedMap() {
HazelcastOutboundChannelAdapterTestUtils
.testBulkWriteToDistributedMap(this.bulkMapChannel, this.distributedBulkMap,
this.testBulkMapRequestHandlerAdvice);
}
@Test
public void testWriteToDistributedMapWhenCacheExpressionIsSet()
throws InterruptedException {
sendMessageWithCacheHeaderToChannel(this.secondMapChannel, CACHE_HEADER,
DISTRIBUTED_MAP);
assertThat(this.testSecondMapRequestHandlerAdvice.executeLatch
.await(10, TimeUnit.SECONDS)).isTrue();
HazelcastOutboundChannelAdapterTestUtils
.verifyMapForPayload(new TreeMap(this.distributedMap));
}
@Test
public void testWriteToDistributedMapWhenHazelcastHeaderIsSet()
throws InterruptedException {
sendMessageWithCacheHeaderToChannel(this.thirdMapChannel,
HazelcastHeaders.CACHE_NAME, DISTRIBUTED_MAP);
assertThat(this.testThirdMapRequestHandlerAdvice.executeLatch
.await(10, TimeUnit.SECONDS)).isTrue();
HazelcastOutboundChannelAdapterTestUtils
.verifyMapForPayload(new TreeMap(this.distributedMap));
}
@Test
public void testWriteToDistributedMapWhenExtractPayloadIsFalse()
throws InterruptedException {
sendMessageWithCacheHeaderToChannel(this.fourthMapChannel,
HazelcastHeaders.CACHE_NAME, DISTRIBUTED_MAP);
assertThat(this.testFourthMapRequestHandlerAdvice.executeLatch
.await(10, TimeUnit.SECONDS)).isTrue();
verifyMapForMessage(new TreeMap(this.distributedMap));
}
@Test
public void testWriteToMultiMap() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToMultiMap(this.multiMapChannel, this.multiMap,
this.testMultiMapRequestHandlerAdvice);
}
@Test
public void testWriteToReplicatedMap() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToReplicatedMap(this.replicatedMapChannel, this.replicatedMap,
this.testReplicatedMapRequestHandlerAdvice);
}
@Test
public void testBulkWriteToReplicatedMap() throws InterruptedException {
Map<Integer, HazelcastIntegrationTestUser> userMap =
new HashMap<>(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userMap.put(index, HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
}
this.bulkReplicatedMapChannel.send(new GenericMessage<>(userMap));
assertThat(this.testBulkReplicatedMapRequestHandlerAdvice.executeLatch
.await(10, TimeUnit.SECONDS)).isTrue();
HazelcastOutboundChannelAdapterTestUtils
.verifyMapForPayload(new TreeMap(this.bulkReplicatedMap));
}
@Test
public void testWriteToDistributedList() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToDistributedList(this.listChannel, this.distributedList,
this.testListRequestHandlerAdvice);
}
@Test
public void testBulkWriteToDistributedList() throws InterruptedException {
List<HazelcastIntegrationTestUser> userList =
new ArrayList<>(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userList.add(HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
}
this.bulkListChannel.send(new GenericMessage<>(userList));
assertThat(this.testBulkListRequestHandlerAdvice.executeLatch
.await(10, TimeUnit.SECONDS)).isTrue();
HazelcastOutboundChannelAdapterTestUtils
.verifyCollection(this.distributedBulkList,
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Test
public void testWriteToDistributedSet() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToDistributedSet(this.setChannel, this.distributedSet,
this.testSetRequestHandlerAdvice);
}
@Test
public void testBulkWriteToDistributedSet() throws InterruptedException {
Set<HazelcastIntegrationTestUser> userSet =
new HashSet<>(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userSet.add(HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
}
this.bulkSetChannel.send(new GenericMessage<>(userSet));
assertThat(this.testBulkSetRequestHandlerAdvice.executeLatch
.await(10, TimeUnit.SECONDS)).isTrue();
final List<HazelcastIntegrationTestUser> list =
new ArrayList(this.distributedBulkSet);
Collections.sort(list);
HazelcastOutboundChannelAdapterTestUtils
.verifyCollection(list, HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Test
public void testWriteToDistributedQueue() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToDistributedQueue(this.queueChannel, this.distributedQueue,
this.testQueueRequestHandlerAdvice);
}
@Test
public void testBulkWriteToDistributedQueue() throws InterruptedException {
Queue<HazelcastIntegrationTestUser> userQueue =
new ArrayBlockingQueue(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userQueue.add(HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
}
this.bulkQueueChannel.send(new GenericMessage<>(userQueue));
assertThat(this.testBulkQueueRequestHandlerAdvice.executeLatch
.await(10, TimeUnit.SECONDS)).isTrue();
HazelcastOutboundChannelAdapterTestUtils
.verifyCollection(this.distributedBulkQueue,
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Test
public void testWriteToTopic() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToTopic(this.topicChannel, this.topic,
this.testTopicRequestHandlerAdvice);
}
@Test
public void testWriteToDistributedMapWhenCacheIsNotSet() {
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() ->
this.fifthMapChannel.send(
new GenericMessage<>(HazelcastOutboundChannelAdapterTestUtils.getTestUser(1))));
}
@Test
public void testWriteToDistributedMapWhenKeyExpressionIsNotSet() {
Message<HazelcastIntegrationTestUser> message = this.messageBuilderFactory
.withPayload(HazelcastOutboundChannelAdapterTestUtils.getTestUser(1))
.setHeader(HazelcastHeaders.CACHE_NAME, DISTRIBUTED_MAP).build();
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> this.sixthMapChannel.send(message));
}
@Test
public void testWriteToLock() {
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> this.lockChannel.send(new GenericMessage<>("foo")));
}
private void sendMessageWithCacheHeaderToChannel(final MessageChannel channel,
final String headerName, final String distributedObjectName) {
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
Message<HazelcastIntegrationTestUser> message = this.messageBuilderFactory
.withPayload(HazelcastOutboundChannelAdapterTestUtils.getTestUser(index))
.setHeader(headerName, distributedObjectName).build();
channel.send(message);
}
}
private static void verifyMapForMessage(final Map<Integer, Message<HazelcastIntegrationTestUser>> map) {
int index = 1;
assertThat(map).isNotNull();
assertThat(map.size()).isEqualTo(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (Entry<Integer, Message<HazelcastIntegrationTestUser>> entry : map.entrySet()) {
assertThat(entry).isNotNull();
assertThat(entry.getKey().intValue()).isEqualTo(index);
assertThat(entry.getValue().getHeaders().size() > 0).isTrue();
HazelcastOutboundChannelAdapterTestUtils
.verifyHazelcastIntegrationTestUser(entry.getValue().getPayload(), index);
index++;
}
}
}

View File

@@ -0,0 +1,298 @@
/*
* Copyright 2015-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.integration.hazelcast.outbound.config;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice;
import org.springframework.integration.hazelcast.outbound.HazelcastCacheWritingMessageHandler;
import org.springframework.integration.hazelcast.outbound.util.HazelcastOutboundChannelAdapterTestUtils;
import org.springframework.messaging.MessageChannel;
/**
* Configuration Class for Hazelcast Integration Outbound Test
*
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 6.0
*/
@Configuration
@EnableIntegration
public class HazelcastIntegrationOutboundTestConfiguration {
@Bean
public MessageChannel distMapChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel distMapBulkChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel distListChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel distSetChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel distQueueChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel topicChannel2() {
return new DirectChannel();
}
@Bean
public MessageChannel multiMapChannel2() {
return new DirectChannel();
}
@Bean
public MessageChannel replicatedMapChannel2() {
return new DirectChannel();
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> distMap() {
return testHzInstance().getMap("Distributed_Map1");
}
@Bean
public IMap<Integer, HazelcastIntegrationTestUser> distBulkMap() {
return testHzInstance().getMap("Distributed_Bulk_Map1");
}
@Bean
public List<HazelcastIntegrationTestUser> distList() {
return testHzInstance().getList("Distributed_List1");
}
@Bean
public Set<HazelcastIntegrationTestUser> distSet() {
return testHzInstance().getSet("Distributed_Set1");
}
@Bean
public Queue<HazelcastIntegrationTestUser> distQueue() {
return testHzInstance().getQueue("Distributed_Queue1");
}
@Bean
public ITopic<HazelcastIntegrationTestUser> topic() {
return testHzInstance().getTopic("Topic1");
}
@Bean
public MultiMap<Integer, HazelcastIntegrationTestUser> multiMap() {
return testHzInstance().getMultiMap("Multi_Map1");
}
@Bean
public ReplicatedMap<Integer, HazelcastIntegrationTestUser> replicatedMap() {
return testHzInstance().getReplicatedMap("Replicated_Map1");
}
@Bean(destroyMethod = "shutdown")
public HazelcastInstance testHzInstance() {
return Hazelcast.newHazelcastInstance();
}
@Bean
public HazelcastTestRequestHandlerAdvice distMapRequestHandlerAdvice() {
return new HazelcastTestRequestHandlerAdvice(
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Bean
public HazelcastTestRequestHandlerAdvice distBulkMapRequestHandlerAdvice() {
return new HazelcastTestRequestHandlerAdvice(1);
}
@Bean
public HazelcastTestRequestHandlerAdvice distListRequestHandlerAdvice() {
return new HazelcastTestRequestHandlerAdvice(
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Bean
public HazelcastTestRequestHandlerAdvice distSetRequestHandlerAdvice() {
return new HazelcastTestRequestHandlerAdvice(
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Bean
public HazelcastTestRequestHandlerAdvice distQueueRequestHandlerAdvice() {
return new HazelcastTestRequestHandlerAdvice(
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Bean
public HazelcastTestRequestHandlerAdvice topicRequestHandlerAdvice() {
return new HazelcastTestRequestHandlerAdvice(
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Bean
public HazelcastTestRequestHandlerAdvice multiMapRequestHandlerAdvice() {
return new HazelcastTestRequestHandlerAdvice(
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Bean
public HazelcastTestRequestHandlerAdvice replicatedMapRequestHandlerAdvice() {
return new HazelcastTestRequestHandlerAdvice(
HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
}
@Bean
@ServiceActivator(inputChannel = "distMapChannel", adviceChain = "distMapRequestHandlerAdvice")
public HazelcastCacheWritingMessageHandler hazelcastCacheWritingMessageHandler() {
final HazelcastCacheWritingMessageHandler handler =
new HazelcastCacheWritingMessageHandler();
handler.setDistributedObject(distMap());
handler
.setKeyExpression(new SpelExpressionParser().parseExpression("payload.id"));
handler.setExtractPayload(true);
return handler;
}
@Bean
@ServiceActivator(inputChannel = "distMapBulkChannel",
adviceChain = "distBulkMapRequestHandlerAdvice")
public HazelcastCacheWritingMessageHandler hazelcastCacheWritingMessageHandler2() {
final HazelcastCacheWritingMessageHandler handler =
new HazelcastCacheWritingMessageHandler();
handler.setDistributedObject(distBulkMap());
handler
.setKeyExpression(new SpelExpressionParser().parseExpression("payload.id"));
handler.setExtractPayload(true);
return handler;
}
@Bean
@ServiceActivator(inputChannel = "distListChannel",
adviceChain = "distListRequestHandlerAdvice")
public HazelcastCacheWritingMessageHandler hazelcastCacheWritingMessageHandler3() {
final HazelcastCacheWritingMessageHandler handler =
new HazelcastCacheWritingMessageHandler();
handler.setDistributedObject((DistributedObject) distList());
handler
.setKeyExpression(new SpelExpressionParser().parseExpression("payload.id"));
handler.setExtractPayload(true);
return handler;
}
@Bean
@ServiceActivator(inputChannel = "distSetChannel",
adviceChain = "distSetRequestHandlerAdvice")
public HazelcastCacheWritingMessageHandler hazelcastCacheWritingMessageHandler4() {
final HazelcastCacheWritingMessageHandler handler =
new HazelcastCacheWritingMessageHandler();
handler.setDistributedObject((DistributedObject) distSet());
handler
.setKeyExpression(new SpelExpressionParser().parseExpression("payload.id"));
handler.setExtractPayload(true);
return handler;
}
@Bean
@ServiceActivator(inputChannel = "distQueueChannel",
adviceChain = "distQueueRequestHandlerAdvice")
public HazelcastCacheWritingMessageHandler hazelcastCacheWritingMessageHandler5() {
final HazelcastCacheWritingMessageHandler handler =
new HazelcastCacheWritingMessageHandler();
handler.setDistributedObject((DistributedObject) distQueue());
handler
.setKeyExpression(new SpelExpressionParser().parseExpression("payload.id"));
handler.setExtractPayload(true);
return handler;
}
@Bean
@ServiceActivator(inputChannel = "topicChannel2",
adviceChain = "topicRequestHandlerAdvice")
public HazelcastCacheWritingMessageHandler hazelcastCacheWritingMessageHandler6() {
final HazelcastCacheWritingMessageHandler handler =
new HazelcastCacheWritingMessageHandler();
handler.setDistributedObject(topic());
handler
.setKeyExpression(new SpelExpressionParser().parseExpression("payload.id"));
handler.setExtractPayload(true);
return handler;
}
@Bean
@ServiceActivator(inputChannel = "multiMapChannel2",
adviceChain = "multiMapRequestHandlerAdvice")
public HazelcastCacheWritingMessageHandler hazelcastCacheWritingMessageHandler7() {
final HazelcastCacheWritingMessageHandler handler =
new HazelcastCacheWritingMessageHandler();
handler.setDistributedObject(multiMap());
handler
.setKeyExpression(new SpelExpressionParser().parseExpression("payload.id"));
handler.setExtractPayload(true);
return handler;
}
@Bean
@ServiceActivator(inputChannel = "replicatedMapChannel2",
adviceChain = "replicatedMapRequestHandlerAdvice")
public HazelcastCacheWritingMessageHandler hazelcastCacheWritingMessageHandler8() {
final HazelcastCacheWritingMessageHandler handler =
new HazelcastCacheWritingMessageHandler();
handler.setDistributedObject(replicatedMap());
handler
.setKeyExpression(new SpelExpressionParser().parseExpression("payload.id"));
handler.setExtractPayload(true);
return handler;
}
}

View File

@@ -0,0 +1,200 @@
/*
* Copyright 2015-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.integration.hazelcast.outbound.config;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice;
import org.springframework.integration.hazelcast.outbound.util.HazelcastOutboundChannelAdapterTestUtils;
import org.springframework.messaging.MessageChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
* Hazelcast Outbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @author Atem Bilan
*
* @since 6.0
*/
@SpringJUnitConfig(classes = HazelcastIntegrationOutboundTestConfiguration.class)
@DirtiesContext
public class HazelcastOutboundChannelAdapterConfigTests {
@Autowired
@Qualifier("distMapChannel")
private MessageChannel distMapChannel;
@Autowired
@Qualifier("distMapBulkChannel")
private MessageChannel distMapBulkChannel;
@Autowired
@Qualifier("distListChannel")
private MessageChannel distListChannel;
@Autowired
@Qualifier("distSetChannel")
private MessageChannel distSetChannel;
@Autowired
@Qualifier("distQueueChannel")
private MessageChannel distQueueChannel;
@Autowired
@Qualifier("topicChannel2")
private MessageChannel topicChannel2;
@Autowired
@Qualifier("multiMapChannel2")
private MessageChannel multiMapChannel2;
@Autowired
@Qualifier("replicatedMapChannel2")
private MessageChannel replicatedMapChannel2;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> distMap;
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> distBulkMap;
@Autowired
private List<HazelcastIntegrationTestUser> distList;
@Autowired
private Set<HazelcastIntegrationTestUser> distSet;
@Autowired
private Queue<HazelcastIntegrationTestUser> distQueue;
@Autowired
private ITopic<HazelcastIntegrationTestUser> topic;
@Autowired
private MultiMap<Integer, HazelcastIntegrationTestUser> multiMap;
@Autowired
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> replicatedMap;
@Autowired
@Qualifier("distMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice distMapRequestHandlerAdvice;
@Autowired
@Qualifier("distBulkMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice distBulkMapRequestHandlerAdvice;
@Autowired
@Qualifier("distListRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice distListRequestHandlerAdvice;
@Autowired
@Qualifier("distSetRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice distSetRequestHandlerAdvice;
@Autowired
@Qualifier("distQueueRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice distQueueRequestHandlerAdvice;
@Autowired
@Qualifier("topicRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice topicRequestHandlerAdvice;
@Autowired
@Qualifier("multiMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice multiMapRequestHandlerAdvice;
@Autowired
@Qualifier("replicatedMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice replicatedMapRequestHandlerAdvice;
@AfterAll
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Test
public void testWriteToDistributedMap() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToDistributedMap(this.distMapChannel, this.distMap,
this.distMapRequestHandlerAdvice);
}
@Test
public void testBulkWriteToDistributedMap() {
HazelcastOutboundChannelAdapterTestUtils
.testBulkWriteToDistributedMap(this.distMapBulkChannel, this.distBulkMap,
this.distBulkMapRequestHandlerAdvice);
}
@Test
public void testWriteToDistributedList() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToDistributedList(this.distListChannel, this.distList,
this.distListRequestHandlerAdvice);
}
@Test
public void testWriteToDistributedSet() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToDistributedSet(this.distSetChannel, this.distSet,
this.distSetRequestHandlerAdvice);
}
@Test
public void testWriteToDistributedQueue() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToDistributedQueue(this.distQueueChannel, this.distQueue,
this.distQueueRequestHandlerAdvice);
}
@Test
public void testWriteToTopic() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToTopic(this.topicChannel2, this.topic, this.topicRequestHandlerAdvice);
}
@Test
public void testWriteToMultiMap() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToMultiMap(this.multiMapChannel2, this.multiMap,
this.multiMapRequestHandlerAdvice);
}
@Test
public void testWriteToReplicatedMap() {
HazelcastOutboundChannelAdapterTestUtils
.testWriteToReplicatedMap(this.replicatedMapChannel2, this.replicatedMap,
this.replicatedMapRequestHandlerAdvice);
}
}

View File

@@ -0,0 +1,248 @@
/*
* Copyright 2016-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.integration.hazelcast.outbound.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import com.hazelcast.topic.MessageListener;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
/**
* Util Class for Hazelcast Outbound Channel Adapter Test Support
*
* @author Eren Avsarogullari
*
* @since 6.0
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public final class HazelcastOutboundChannelAdapterTestUtils {
public static final int DATA_COUNT = 100;
public static final int DEFAULT_AGE = 5;
public static final String TEST_NAME = "Test_Name";
public static final String TEST_SURNAME = "Test_Surname";
public static void testWriteToDistributedMap(MessageChannel channel,
Map<?, ?> distributedMap,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
testWriteToMap(channel, distributedMap, requestHandlerAdvice);
}
private static void testWriteToMap(MessageChannel channel,
Map<?, ?> distributedMap,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
try {
sendMessageToChannel(channel);
assertThat(requestHandlerAdvice.executeLatch.await(10, TimeUnit.SECONDS)).isTrue();
verifyMapForPayload(new TreeMap(distributedMap));
}
catch (InterruptedException e) {
fail("Test has been failed due to " + e.getMessage());
}
}
public static void testBulkWriteToDistributedMap(MessageChannel channel,
Map<?, ?> distributedMap,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
try {
Map<Integer, HazelcastIntegrationTestUser> userMap =
new HashMap<>(DATA_COUNT);
for (int index = 1; index <= DATA_COUNT; index++) {
userMap.put(index, getTestUser(index));
}
channel.send(new GenericMessage<>(userMap));
assertThat(requestHandlerAdvice.executeLatch.await(10, TimeUnit.SECONDS)).isTrue();
verifyMapForPayload(new TreeMap(distributedMap));
}
catch (InterruptedException e) {
fail("Test has been failed due to " + e.getMessage());
}
}
public static void testWriteToMultiMap(MessageChannel channel,
MultiMap<Integer, HazelcastIntegrationTestUser> multiMap,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
try {
sendMessageToChannel(channel);
assertThat(requestHandlerAdvice.executeLatch.await(10, TimeUnit.SECONDS)).isTrue();
verifyMultiMapForPayload(multiMap);
}
catch (InterruptedException e) {
fail("Test has been failed due to " + e.getMessage());
}
}
public static void testWriteToReplicatedMap(MessageChannel channel,
ReplicatedMap<Integer, HazelcastIntegrationTestUser> replicatedMap,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
testWriteToMap(channel, replicatedMap, requestHandlerAdvice);
}
public static void testWriteToDistributedList(MessageChannel channel,
List<HazelcastIntegrationTestUser> distributedList,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
testWriteToDistributedCollection(channel, distributedList, requestHandlerAdvice);
}
private static void testWriteToDistributedCollection(MessageChannel channel,
Collection<HazelcastIntegrationTestUser> distributedList,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
try {
sendMessageToChannel(channel);
assertThat(requestHandlerAdvice.executeLatch.await(10, TimeUnit.SECONDS)).isTrue();
verifyCollection(distributedList, DATA_COUNT);
}
catch (InterruptedException e) {
fail("Test has been failed due to " + e.getMessage());
}
}
public static void testWriteToDistributedSet(MessageChannel channel,
Set<HazelcastIntegrationTestUser> distributedSet,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
try {
sendMessageToChannel(channel);
assertThat(requestHandlerAdvice.executeLatch.await(10, TimeUnit.SECONDS)).isTrue();
final List<HazelcastIntegrationTestUser> list = new ArrayList(distributedSet);
Collections.sort(list);
verifyCollection(list, DATA_COUNT);
}
catch (InterruptedException e) {
fail("Test has been failed due to " + e.getMessage());
}
}
public static void testWriteToDistributedQueue(MessageChannel channel,
Queue<HazelcastIntegrationTestUser> distributedQueue,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
testWriteToDistributedCollection(channel, distributedQueue, requestHandlerAdvice);
}
public static void testWriteToTopic(MessageChannel channel,
ITopic<HazelcastIntegrationTestUser> topic,
HazelcastTestRequestHandlerAdvice requestHandlerAdvice) {
try {
topic.addMessageListener(new MessageListener() {
private int index = 1;
@Override
public void onMessage(com.hazelcast.topic.Message message) {
HazelcastIntegrationTestUser user =
(HazelcastIntegrationTestUser) message.getMessageObject();
verifyHazelcastIntegrationTestUser(user, index);
index++;
}
});
sendMessageToChannel(channel);
assertThat(requestHandlerAdvice.executeLatch.await(10, TimeUnit.SECONDS)).isTrue();
}
catch (InterruptedException e) {
fail("Test has been failed due to " + e.getMessage());
}
}
public static HazelcastIntegrationTestUser getTestUser(int index) {
return new HazelcastIntegrationTestUser(index, TEST_NAME, TEST_SURNAME,
index + DEFAULT_AGE);
}
public static void verifyMapForPayload(
final Map<Integer, HazelcastIntegrationTestUser> map) {
int index = 1;
assertThat(map).isNotNull();
assertThat(map.size() == DATA_COUNT).isEqualTo(true);
for (Map.Entry<Integer, HazelcastIntegrationTestUser> entry : map.entrySet()) {
assertThat(entry).isNotNull();
assertThat(entry.getKey().intValue()).isEqualTo(index);
verifyHazelcastIntegrationTestUser(entry.getValue(), index);
index++;
}
}
public static void verifyCollection(
final Collection<HazelcastIntegrationTestUser> coll, final int dataCount) {
int index = 1;
assertThat(coll).isNotNull();
assertThat(coll.size() == dataCount).isEqualTo(true);
for (HazelcastIntegrationTestUser user : coll) {
verifyHazelcastIntegrationTestUser(user, index);
index++;
}
}
public static void verifyHazelcastIntegrationTestUser(
HazelcastIntegrationTestUser user, int index) {
assertThat(user).isNotNull();
assertThat(user.getId()).isEqualTo(index);
assertThat(user.getName()).isEqualTo(TEST_NAME);
assertThat(user.getSurname()).isEqualTo(TEST_SURNAME);
assertThat(user.getAge()).isEqualTo(index + DEFAULT_AGE);
}
private static void sendMessageToChannel(final MessageChannel channel) {
for (int index = 1; index <= DATA_COUNT; index++) {
channel.send(new GenericMessage<>(getTestUser(index)));
}
}
private static void verifyMultiMapForPayload(
final MultiMap<Integer, HazelcastIntegrationTestUser> multiMap) {
int index = 1;
assertThat(multiMap).isNotNull();
assertThat(multiMap.size() == DATA_COUNT).isEqualTo(true);
SortedSet<Integer> keys = new TreeSet<>(multiMap.keySet());
for (Integer key : keys) {
assertThat(key).isNotNull();
assertThat(key.intValue()).isEqualTo(index);
HazelcastIntegrationTestUser user = multiMap.get(key).iterator().next();
verifyHazelcastIntegrationTestUser(user, index);
index++;
}
}
private HazelcastOutboundChannelAdapterTestUtils() {
}
}

View File

@@ -0,0 +1,176 @@
/*
* Copyright 2017-2023 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.integration.hazelcast.store;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.store.MessageGroup;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Vinicius Carvalho
* @author Artem Bilan
*/
public class HazelcastMessageStoreTests {
private static HazelcastMessageStore store;
private static HazelcastInstance instance;
private static IMap<Object, Object> map;
@BeforeAll
public static void init() {
instance = Hazelcast.newHazelcastInstance();
map = instance.getMap("customTestsMessageStore");
store = new HazelcastMessageStore(map);
}
@AfterAll
public static void destroy() {
instance.shutdown();
}
@BeforeEach
public void clean() {
map.clear();
}
@Test
public void testWithMessageHistory() {
Message<?> message = new GenericMessage<>("Hello");
DirectChannel fooChannel = new DirectChannel();
fooChannel.setBeanName("fooChannel");
DirectChannel barChannel = new DirectChannel();
barChannel.setBeanName("barChannel");
message = MessageHistory.write(message, fooChannel);
message = MessageHistory.write(message, barChannel);
store.addMessage(message);
message = store.getMessage(message.getHeaders().getId());
MessageHistory messageHistory = MessageHistory.read(message);
assertThat(messageHistory).isNotNull();
assertThat(messageHistory.size()).isEqualTo(2);
Properties fooChannelHistory = messageHistory.get(0);
assertThat(fooChannelHistory.get("name")).isEqualTo("fooChannel");
assertThat(fooChannelHistory.get("type")).isEqualTo("channel");
}
@Test
public void testAddAndRemoveMessagesFromMessageGroup() {
String groupId = "X";
List<Message<?>> messages = new ArrayList<>();
for (int i = 0; i < 25; i++) {
Message<String> message = MessageBuilder.withPayload("foo").setCorrelationId(groupId).build();
store.addMessagesToGroup(groupId, message);
messages.add(message);
}
MessageGroup group = store.getMessageGroup(groupId);
assertThat(group.size()).isEqualTo(25);
store.removeMessagesFromGroup(groupId, messages);
group = store.getMessageGroup(groupId);
assertThat(group.size()).isEqualTo(0);
}
@Test
public void addAndGetMessage() {
Message<?> message = MessageBuilder.withPayload("test").build();
store.addMessage(message);
Message<?> retrieved = store.getMessage(message.getHeaders().getId());
assertThat(retrieved).isEqualTo(message);
}
@Test
public void customMap() {
assertThat(TestUtils.getPropertyValue(store, "map")).isSameAs(map);
HazelcastMessageStore store2 = new HazelcastMessageStore(instance);
assertThat(TestUtils.getPropertyValue(store2, "map")).isNotSameAs(map);
}
@Test
public void messageStoreSize() {
Message<?> message1 = MessageBuilder.withPayload("test").build();
Message<?> message2 = MessageBuilder.withPayload("test").build();
store.addMessage(message1);
store.addMessage(message2);
long size = store.getMessageCount();
assertThat(size).isEqualTo(2);
}
@Test
public void messageStoreIterator() {
Message<?> message1 = MessageBuilder.withPayload("test").build();
Message<?> message2 = MessageBuilder.withPayload("test").build();
store.addMessageToGroup("test", message1);
store.addMessageToGroup("test", message2);
int groupCount = 0;
for (MessageGroup messageGroup : store) {
assertThat(messageGroup.size()).isEqualTo(2);
groupCount++;
}
assertThat(groupCount).isEqualTo(1);
}
@Test
public void sameMessageInTwoGroupsNotRemovedByFirstGroup() {
GenericMessage<String> testMessage = new GenericMessage<>("test data");
store.addMessageToGroup("1", testMessage);
store.addMessageToGroup("2", testMessage);
store.removeMessageGroup("1");
assertThat(store.getMessageCount()).isEqualTo(1);
store.removeMessageGroup("2");
assertThat(store.getMessageCount()).isEqualTo(0);
}
@Test
public void removeMessagesFromGroupDontRemoveSameMessageInOtherGroup() {
GenericMessage<String> testMessage = new GenericMessage<>("test data");
store.addMessageToGroup("1", testMessage);
store.addMessageToGroup("2", testMessage);
store.removeMessagesFromGroup("1", testMessage);
assertThat(store.getMessageCount()).isEqualTo(1);
assertThat(store.messageGroupSize("1")).isEqualTo(0);
assertThat(store.messageGroupSize("2")).isEqualTo(1);
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p [%t] [%c] - %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.springframework" level="warn"/>
<Logger name="org.springframework.integration" level="warn"/>
<Logger name="org.springframework.integration.hazelcast" level="info"/>
<Root level="warn">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>

View File

@@ -1,9 +1,6 @@
[[hazelcast]]
= Hazelcast Support
IMPORTANT: This module has been deprecated in version 6.5 and will be removed altogether in 7.0.
Due to Hazelcast migration of many important features, this module depends on, to the https://docs.hazelcast.com/hazelcast/5.5/migrate/community-to-enterprise[Enterprise Edition], we cannot provide an Open Source support here anymore.
Spring Integration provides channel adapters and other utility components to interact with an in-memory data grid https://hazelcast.com[Hazelcast].
You need to include this dependency into your project: