refactoring

pull/5457/head
Nikita Koksharov 1 year ago
parent 69228326c3
commit 77ddce68a2

@ -1,12 +1,13 @@
package org.redisson; package org.redisson;
import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.api.model.ContainerNetwork;
import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.PortBinding; import com.github.dockerjava.api.model.PortBinding;
import com.github.dockerjava.api.model.Ports; import com.github.dockerjava.api.model.Ports;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.redisson.ClusterRunner.ClusterProcesses; import org.redisson.ClusterRunner.ClusterProcesses;
import org.redisson.RedisRunner.KEYSPACE_EVENTS_OPTIONS; import org.redisson.RedisRunner.KEYSPACE_EVENTS_OPTIONS;
import org.redisson.RedisRunner.RedisProcess; import org.redisson.RedisRunner.RedisProcess;
@ -24,14 +25,15 @@ import org.redisson.client.protocol.RedisStrictCommand;
import org.redisson.cluster.ClusterNodeInfo; import org.redisson.cluster.ClusterNodeInfo;
import org.redisson.config.Config; import org.redisson.config.Config;
import org.redisson.config.SubscriptionMode; import org.redisson.config.SubscriptionMode;
import org.redisson.connection.SequentialDnsAddressResolverFactory;
import org.redisson.connection.balancer.RandomLoadBalancer; import org.redisson.connection.balancer.RandomLoadBalancer;
import org.redisson.misc.RedisURI; import org.redisson.misc.RedisURI;
import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.ContainerState;
import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network; import org.testcontainers.containers.Network;
import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy; import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.time.Duration; import java.time.Duration;
@ -1000,9 +1002,6 @@ public class RedissonTopicTest extends RedisDockerTest {
Thread.sleep(5000); Thread.sleep(5000);
Config config = new Config(); Config config = new Config();
config.setAddressResolverGroupFactory(new SequentialDnsAddressResolverFactory() {
});
config.useSentinelServers() config.useSentinelServers()
.setNatMapper(new NatMapper() { .setNatMapper(new NatMapper() {
@ -1191,7 +1190,6 @@ public class RedissonTopicTest extends RedisDockerTest {
@Override @Override
public void onSubscribe(String channel) { public void onSubscribe(String channel) {
System.out.println("onSubscribe " + (System.currentTimeMillis() - t));
subscriptions.incrementAndGet(); subscriptions.incrementAndGet();
} }
}); });
@ -1313,72 +1311,63 @@ public class RedissonTopicTest extends RedisDockerTest {
} }
@Test @Test
public void testReattachInClusterSlave() throws Exception { public void testReattachInClusterSlave() {
GenericContainer redisCluster = new GenericContainer<>("vishnunair/docker-redis-cluster") withCluster(client -> {
.withExposedPorts(6379, 6380, 6381, 6382, 6383, 6384) Config config = client.getConfig();
.withStartupCheckStrategy(new MinimumDurationRunningStartupCheckStrategy(Duration.ofSeconds(10))); config.useClusterServers()
redisCluster.start(); .setSubscriptionMode(SubscriptionMode.SLAVE);
RedissonClient redisson = Redisson.create(config);
Config config = new Config(); final AtomicBoolean executed = new AtomicBoolean();
config.useClusterServers() final AtomicInteger subscriptions = new AtomicInteger();
.setNatMapper(new NatMapper() {
@Override RTopic topic = redisson.getTopic("topic");
public RedisURI map(RedisURI uri) { topic.addListener(new StatusListener() {
if (redisCluster.getMappedPort(uri.getPort()) == null) {
return uri; @Override
} public void onUnsubscribe(String channel) {
return new RedisURI(uri.getScheme(), redisCluster.getHost(), redisCluster.getMappedPort(uri.getPort())); }
}
}) @Override
.setSubscriptionMode(SubscriptionMode.SLAVE) public void onSubscribe(String channel) {
.addNodeAddress("redis://127.0.0.1:" + redisCluster.getFirstMappedPort()); subscriptions.incrementAndGet();
RedissonClient redisson = Redisson.create(config); }
});
final AtomicBoolean executed = new AtomicBoolean(); topic.addListener(Integer.class, new MessageListener<Integer>() {
final AtomicInteger subscriptions = new AtomicInteger(); @Override
public void onMessage(CharSequence channel, Integer msg) {
RTopic topic = redisson.getTopic("topic"); executed.set(true);
topic.addListener(new StatusListener() { }
});
@Override assertThat(topic.countListeners()).isEqualTo(2);
public void onUnsubscribe(String channel) {
} sendCommands(redisson, "topic");
@Override assertThat(subscriptions.get()).isEqualTo(1);
public void onSubscribe(String channel) {
subscriptions.incrementAndGet(); RedisCluster nodes = redisson.getRedisNodes(RedisNodes.CLUSTER);
} for (RedisClusterSlave slave : nodes.getSlaves()) {
}); RedisClientConfig cc = new RedisClientConfig();
topic.addListener(Integer.class, new MessageListener<Integer>() { cc.setAddress("redis://" + slave.getAddr().getHostString() + ":" + slave.getAddr().getPort());
@Override RedisClient c = RedisClient.create(cc);
public void onMessage(CharSequence channel, Integer msg) { c.connect().async(RedisCommands.SHUTDOWN);
executed.set(true); c.shutdown();
} }
});
assertThat(topic.countListeners()).isEqualTo(2);
sendCommands(redisson, "topic");
RedisCluster nodes = redisson.getRedisNodes(RedisNodes.CLUSTER); await().atMost(25, TimeUnit.SECONDS).until(() -> subscriptions.get() == 2);
for (RedisClusterSlave slave : nodes.getSlaves()) {
RedisClientConfig cc = new RedisClientConfig();
cc.setAddress("redis://" + slave.getAddr().getHostString() + ":" + slave.getAddr().getPort());
RedisClient c = RedisClient.create(cc);
c.connect().async(RedisCommands.SHUTDOWN);
c.shutdown();
Thread.sleep(18000);
}
Thread.sleep(15000); executed.set(false);
redisson.getTopic("topic").publish(1);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
assertThat(executed.get()).isTrue();
assertThat(topic.countListeners()).isEqualTo(2);
redisson.getTopic("topic").publish(1); redisson.shutdown();
});
await().atMost(75, TimeUnit.SECONDS).until(() -> subscriptions.get() == 2);
assertThat(topic.countListeners()).isEqualTo(2);
assertThat(executed.get()).isTrue();
redisson.shutdown();
redisCluster.stop();
} }
@Test @Test
@ -1464,57 +1453,59 @@ public class RedissonTopicTest extends RedisDockerTest {
@Test @Test
public void testReattachInClusterMaster2() throws Exception { public void testReattachInClusterMaster2() throws Exception {
withCluster(redisson -> { RedisRunner master1 = new RedisRunner().port(6890).randomDir().nosave();
Queue<String> messages = new ConcurrentLinkedQueue<>(); RedisRunner master2 = new RedisRunner().port(6891).randomDir().nosave();
Queue<String> subscriptions = new ConcurrentLinkedQueue<>(); RedisRunner master3 = new RedisRunner().port(6892).randomDir().nosave();
RedisRunner slave1 = new RedisRunner().port(6900).randomDir().nosave();
RedisRunner slave2 = new RedisRunner().port(6901).randomDir().nosave();
RedisRunner slave3 = new RedisRunner().port(6902).randomDir().nosave();
ClusterRunner clusterRunner = new ClusterRunner()
.addNode(master1, slave1)
.addNode(master2, slave2)
.addNode(master3, slave3);
ClusterProcesses process = clusterRunner.run();
int topicsAmount = 100; Config config = new Config();
for (int i = 0; i < topicsAmount; i++) { config.useClusterServers()
RTopic topic = redisson.getTopic("topic" + i); .addNodeAddress(process.getNodes().stream().findAny().get().getRedisServerAddressAndPort());
int finalI = i; RedissonClient redisson = Redisson.create(config);
topic.addListener(new StatusListener() {
@Override Queue<String> messages = new ConcurrentLinkedQueue<>();
public void onUnsubscribe(String channel) { Queue<String> subscriptions = new ConcurrentLinkedQueue<>();
}
@Override int topicsAmount = 100;
public void onSubscribe(String channel) { for (int i = 0; i < topicsAmount; i++) {
subscriptions.add("topic" + finalI); RTopic topic = redisson.getTopic("topic" + i);
} int finalI = i;
}); topic.addListener(new StatusListener() {
topic.addListener(String.class, (channel, msg) -> messages.add(msg));
}
RedisCluster nodes = redisson.getRedisNodes(RedisNodes.CLUSTER); @Override
nodes.getMasters().forEach(m -> { public void onUnsubscribe(String channel) {
RedisClientConfig cc = new RedisClientConfig(); }
cc.setAddress("redis://" + m.getAddr().getHostString() + ":" + m.getAddr().getPort());
RedisClient c = RedisClient.create(cc); @Override
c.connect().async(RedisCommands.SHUTDOWN); public void onSubscribe(String channel) {
c.shutdown(); subscriptions.add("topic" + finalI);
}
}); });
topic.addListener(String.class, (channel, msg) -> messages.add(msg));
}
try { RedisRunner.RedisProcess master = process.getNodes().stream().filter(x -> x.getRedisServerPort() == master1.getPort()).findFirst().get();
Thread.sleep(TimeUnit.SECONDS.toMillis(30)); master.stop();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
assertThat(subscriptions).hasSize(topicsAmount*2); Thread.sleep(TimeUnit.SECONDS.toMillis(40));
for (int i = 0; i < topicsAmount; i++) { assertThat(subscriptions).hasSize(140);
RTopic topic = redisson.getTopic("topic" + i);
topic.publish("topic" + i);
}
try { for (int i = 0; i < topicsAmount; i++) {
Thread.sleep(100); RTopic topic = redisson.getTopic("topic" + i);
} catch (InterruptedException e) { topic.publish("topic" + i);
throw new RuntimeException(e); }
}
assertThat(messages).hasSize(topicsAmount); Thread.sleep(100);
}); assertThat(messages).hasSize(topicsAmount);
} }
public void withCluster(Consumer<RedissonClient> callback) { public void withCluster(Consumer<RedissonClient> callback) {
@ -1542,38 +1533,106 @@ public class RedissonTopicTest extends RedisDockerTest {
redisCluster.stop(); redisCluster.stop();
} }
@Test public void withCluster2(Consumer<RedissonClient> callback) {
public void testReattachInClusterMaster() throws Exception { List<InspectContainerResponse> nodes = new ArrayList<>();
GenericContainer redisCluster = new GenericContainer<>("vishnunair/docker-redis-cluster")
.withExposedPorts(6379, 6380, 6381, 6382, 6383, 6384) DockerComposeContainer environment =
.withStartupCheckStrategy(new MinimumDurationRunningStartupCheckStrategy(Duration.ofSeconds(10))); new DockerComposeContainer(new File("src/test/resources/docker-compose.yml"))
redisCluster.start(); .withExposedService("redis-node-0", 6379)
.withExposedService("redis-node-1", 6379)
.withExposedService("redis-node-2", 6379)
.withExposedService("redis-node-3", 6379)
.withExposedService("redis-node-4", 6379)
.withExposedService("redis-node-5", 6379)
.withExposedService("redis-node-6", 6379)
.withExposedService("redis-node-7", 6379);
environment.start();
try {
Thread.sleep(25000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for (int i = 0; i < 8; i++) {
Optional<ContainerState> cc = environment.getContainerByServiceName("redis-node-" + i);
nodes.add(cc.get().getContainerInfo());
}
Optional<ContainerState> cc2 = environment.getContainerByServiceName("redis-node-0");
Config config = new Config(); Config config = new Config();
config.useClusterServers() config.useClusterServers()
.setSubscriptionMode(SubscriptionMode.MASTER)
.setNatMapper(new NatMapper() { .setNatMapper(new NatMapper() {
@Override @Override
public RedisURI map(RedisURI uri) { public RedisURI map(RedisURI uri) {
if (redisCluster.getMappedPort(uri.getPort()) == null) { for (InspectContainerResponse node : nodes) {
return uri; Ports.Binding[] mappedPort = node.getNetworkSettings()
.getPorts().getBindings().get(new ExposedPort(uri.getPort()));
Map<String, ContainerNetwork> ss = node.getNetworkSettings().getNetworks();
ContainerNetwork s = ss.values().iterator().next();
if (mappedPort != null
&& s.getIpAddress().equals(uri.getHost())) {
return new RedisURI(uri.getScheme(), "127.0.0.1", Integer.valueOf(mappedPort[0].getHostPortSpec()));
}
} }
return new RedisURI(uri.getScheme(), redisCluster.getHost(), redisCluster.getMappedPort(uri.getPort())); return uri;
} }
}) })
.addNodeAddress("redis://127.0.0.1:" + redisCluster.getFirstMappedPort()); .addNodeAddress("redis://127.0.0.1:" + cc2.get().getFirstMappedPort());
RedissonClient redisson = Redisson.create(config); RedissonClient redisson = Redisson.create(config);
RedisCluster nodes2 = redisson.getRedisNodes(RedisNodes.CLUSTER);
for (RedisClusterSlave slave : nodes2.getSlaves()) {
slave.setConfig("cluster-node-timeout", "1000");
}
for (RedisClusterMaster master : nodes2.getMasters()) {
master.setConfig("cluster-node-timeout", "1000");
}
callback.accept(redisson);
redisson.shutdown();
environment.stop();
}
@Test
public void testReattachInClusterMaster() throws Exception {
RedisRunner master1 = new RedisRunner().randomPort().randomDir().nosave();
RedisRunner master2 = new RedisRunner().randomPort().randomDir().nosave();
RedisRunner master3 = new RedisRunner().randomPort().randomDir().nosave();
RedisRunner slave1 = new RedisRunner().randomPort().randomDir().nosave();
RedisRunner slave2 = new RedisRunner().randomPort().randomDir().nosave();
RedisRunner slave3 = new RedisRunner().randomPort().randomDir().nosave();
ClusterRunner clusterRunner = new ClusterRunner()
.addNode(master1, slave1)
.addNode(master2, slave2)
.addNode(master3, slave3);
ClusterProcesses process = clusterRunner.run();
Config config = new Config();
config.useClusterServers()
.setSubscriptionMode(SubscriptionMode.MASTER)
.setLoadBalancer(new RandomLoadBalancer())
.addNodeAddress(process.getNodes().stream().findAny().get().getRedisServerAddressAndPort());
RedissonClient redisson = Redisson.create(config);
final AtomicBoolean executed = new AtomicBoolean(); final AtomicBoolean executed = new AtomicBoolean();
final AtomicInteger subscriptions = new AtomicInteger(); final AtomicInteger subscriptions = new AtomicInteger();
RTopic topic = redisson.getTopic("3"); RTopic topic = redisson.getTopic("3");
topic.addListener(new StatusListener() { topic.addListener(new StatusListener() {
@Override @Override
public void onUnsubscribe(String channel) { public void onUnsubscribe(String channel) {
} }
@Override @Override
public void onSubscribe(String channel) { public void onSubscribe(String channel) {
subscriptions.incrementAndGet(); subscriptions.incrementAndGet();
@ -1585,32 +1644,29 @@ public class RedissonTopicTest extends RedisDockerTest {
executed.set(true); executed.set(true);
} }
}); });
sendCommands(redisson, "3"); sendCommands(redisson, "3");
RedisCluster nodes = redisson.getRedisNodes(RedisNodes.CLUSTER); process.getNodes().stream().filter(x -> master1.getPort() == x.getRedisServerPort())
nodes.getMasters().forEach(m -> { .forEach(x -> {
RedisClientConfig cc = new RedisClientConfig(); try {
cc.setAddress("redis://" + m.getAddr().getHostString() + ":" + m.getAddr().getPort()); x.stop();
RedisClient c = RedisClient.create(cc); Thread.sleep(18000);
c.connect().async(RedisCommands.SHUTDOWN); } catch (InterruptedException e) {
c.shutdown(); // TODO Auto-generated catch block
try { e.printStackTrace();
Thread.sleep(18000); }
} catch (InterruptedException e) { });
throw new RuntimeException(e);
}
});
Thread.sleep(25000); Thread.sleep(25000);
redisson.getTopic("3").publish(1); redisson.getTopic("3").publish(1);
await().atMost(75, TimeUnit.SECONDS).until(() -> subscriptions.get() == 2); await().atMost(75, TimeUnit.SECONDS).until(() -> subscriptions.get() == 2);
assertThat(executed.get()).isTrue(); assertThat(executed.get()).isTrue();
redisson.shutdown(); redisson.shutdown();
redisCluster.stop(); process.shutdown();
} }
@Test @Test

Loading…
Cancel
Save