package org.littlewings.hazelcast.litemember;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import com.hazelcast.config.ClasspathXmlConfig;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.Partition;
import com.hazelcast.partition.NoDataMemberInClusterException;
import org.assertj.core.data.MapEntry;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
public class LiteMemberTest {
@Test
public void standaloneLiteMember() {
withLiteMember(hazelcast -> {
Map<String, String> map = hazelcast.getMap("default");
assertThatThrownBy(() -> map.put("key", "value"))
.isInstanceOf(NoDataMemberInClusterException.class)
.hasMessage("Partitions can't be assigned since all nodes in the cluster are lite members");
});
}
@Test
public void liteMemberWithNormalMember() {
withHazelcast(hasDataHazelcast -> {
withLiteMember(liteHazelcast -> {
Map<String, String> map = liteHazelcast.getMap("default");
map.put("key", "value");
assertThat(map)
.containsExactly(MapEntry.entry("key", "value"));
assertThat(liteHazelcast.getConfig().isLiteMember()).isTrue();
assertThat(liteHazelcast.getCluster().getMembers()).hasSize(2);
Set<Partition> partitions = liteHazelcast.getPartitionService().getPartitions();
assertThat(partitions).hasSize(271);
assertThat(partitions.stream().map(p -> p.getOwner()).distinct().count()).isEqualTo(1);
Partition partition = partitions.stream().findAny().get();
assertThat(partition.getOwner())
.isEqualTo(hasDataHazelcast.getCluster().getLocalMember())
.isNotEqualTo(liteHazelcast.getCluster().getLocalMember());
});
});
}
@Test
public void normalHazelcastCluster() {
withHazelcast(2, hazelcast -> {
Map<String, String> map = hazelcast.getMap("default");
map.put("key", "value");
assertThat(map)
.containsExactly(MapEntry.entry("key", "value"));
assertThat(hazelcast.getConfig().isLiteMember()).isFalse();
Set<Partition> partitions = hazelcast.getPartitionService().getPartitions();
assertThat(partitions).hasSize(271);
assertThat(partitions.stream().map(p -> p.getOwner()).distinct().count()).isEqualTo(2);
});
}
@Test
public void preConfigurationedInstances() {
withHazelcast("hazelcast-datamember.xml", 2, hasDataHazelcast -> {
withHazelcast("hazelcast-litemember.xml", liteHazelcast -> {
Map<String, String> map = liteHazelcast.getMap("default");
map.put("key", "value");
assertThat(map).containsExactly(MapEntry.entry("key", "value"));
try {
TimeUnit.SECONDS.sleep(5L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
assertThat(map).isEmpty();
assertThat(liteHazelcast.getCluster().getMembers())
.hasSize(3);
assertThat(liteHazelcast.getConfig().isLiteMember()).isTrue();
Set<Partition> partitions = liteHazelcast.getPartitionService().getPartitions();
assertThat(partitions).hasSize(271);
assertThat(partitions.stream().map(p -> p.getOwner()).distinct().count()).isEqualTo(2);
});
});
}
protected void withLiteMember(Consumer<HazelcastInstance> consumer) {
Config config = new Config();
config.setLiteMember(true);
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(config);
try {
consumer.accept(hazelcast);
} finally {
hazelcast.getLifecycleService().shutdown();
}
}
protected void withHazelcast(Consumer<HazelcastInstance> consumer) {
withHazelcast(1, consumer);
}
protected void withHazelcast(int numInstances, Consumer<HazelcastInstance> consumer) {
List<HazelcastInstance> hazelcastInstances = IntStream
.rangeClosed(1, numInstances)
.mapToObj(i -> Hazelcast.newHazelcastInstance(new Config()))
.collect(Collectors.toList());
hazelcastInstances.forEach(h -> h.getLifecycleService().shutdown());
}
protected void withHazelcast(String configFilePath, Consumer<HazelcastInstance> consumer) {
withHazelcast(configFilePath, 1, consumer);
}
protected void withHazelcast(String configFilePath, int numInstances, Consumer<HazelcastInstance> consumer) {
List<HazelcastInstance> hazelcastInstances = IntStream
.rangeClosed(1, numInstances)
.mapToObj(i -> {
ClasspathXmlConfig config = new ClasspathXmlConfig(configFilePath);
return Hazelcast.newHazelcastInstance(config);
})
.collect(Collectors.toList());
hazelcastInstances.forEach(h -> h.getLifecycleService().shutdown());
}
}