Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Remove the loop condition in the test code to fix CI #3

Merged
merged 8 commits into from
Aug 8, 2023
2 changes: 2 additions & 0 deletions .github/semantic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Always validate the PR title AND all the commits
titleAndCommits: false
2 changes: 1 addition & 1 deletion .github/workflows/maven-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18

- name: Sematic Release
run: |
Expand Down
86 changes: 59 additions & 27 deletions src/main/java/org/casbin/watcher/lettuce/LettuceRedisWatcher.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
package org.casbin.watcher.lettuce;

import io.lettuce.core.AbstractRedisClient;
import io.lettuce.core.ClientOptions;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.*;
import io.lettuce.core.cluster.ClusterClientOptions;
import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.RedisClusterURIUtil;
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.resource.DefaultClientResources;
import org.apache.commons.lang3.StringUtils;
import org.casbin.jcasbin.persist.Watcher;
import org.casbin.watcher.lettuce.constants.WatcherConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.UUID;
import java.util.function.Consumer;

public class LettuceRedisWatcher implements Watcher {
private static final Logger logger = LoggerFactory.getLogger(LettuceRedisWatcher.class);
private final String localId;
private final String redisChannelName;
private final AbstractRedisClient abstractRedisClient;
Expand All @@ -33,10 +37,9 @@ public class LettuceRedisWatcher implements Watcher {
* @param redisChannelName Redis Channel
* @param timeout Redis Timeout
* @param password Redis Password
* @param type Redis Type (standalone | cluster)
*/
public LettuceRedisWatcher(String redisIp, int redisPort, String redisChannelName, int timeout, String password, String type) {
this.abstractRedisClient = this.getLettuceRedisClient(redisIp, redisPort, password, timeout, type);
public LettuceRedisWatcher(String redisIp, Integer redisPort, String redisChannelName, int timeout, String password) {
this.abstractRedisClient = this.getLettuceRedisClient(redisIp, redisPort, null, password, timeout, WatcherConstant.LETTUCE_REDIS_TYPE_STANDALONE);
this.localId = UUID.randomUUID().toString();
this.redisChannelName = redisChannelName;
this.startSub();
Expand All @@ -48,10 +51,24 @@ public LettuceRedisWatcher(String redisIp, int redisPort, String redisChannelNam
* @param redisIp Redis IP
* @param redisPort Redis Port
* @param redisChannelName Redis Channel
* @param type Redis Type (standalone | cluster)
*/
public LettuceRedisWatcher(String redisIp, int redisPort, String redisChannelName, String type) {
this(redisIp, redisPort, redisChannelName, 2000, null, type);
public LettuceRedisWatcher(String redisIp, Integer redisPort, String redisChannelName) {
this(redisIp, redisPort, redisChannelName, 2000, null);
}

/**
* Constructor
*
* @param nodes Redis Nodes
* @param redisChannelName Redis Channel
* @param timeout Redis Timeout
* @param password Redis Password
*/
public LettuceRedisWatcher(String nodes, String redisChannelName, Integer timeout, String password) {
this.abstractRedisClient = this.getLettuceRedisClient(null, null, nodes, password, timeout, WatcherConstant.LETTUCE_REDIS_TYPE_CLUSTER);
this.localId = UUID.randomUUID().toString();
this.redisChannelName = redisChannelName;
this.startSub();
}

@Override
Expand Down Expand Up @@ -86,37 +103,38 @@ private void startSub() {
*
* @param host Redis Host
* @param port Redis Port
* @param nodes Redis Nodes
* @param password Redis Password
* @param timeout Redis Timeout
* @param type Redis Type (standalone | cluster) default:standalone
* @return AbstractRedisClient
*/
private AbstractRedisClient getLettuceRedisClient(String host, int port, String password, int timeout, String type) {
private AbstractRedisClient getLettuceRedisClient(String host, Integer port, String nodes, String password, int timeout, String type) {
// todo default standalone ?
// type = StringUtils.isEmpty(type) ? WatcherConstant.LETTUCE_REDIS_TYPE_STANDALONE : type;
if (StringUtils.isNotEmpty(type) && StringUtils.equalsAnyIgnoreCase(type,
WatcherConstant.LETTUCE_REDIS_TYPE_STANDALONE, WatcherConstant.LETTUCE_REDIS_TYPE_CLUSTER)) {
RedisURI redisUri = null;
if (StringUtils.isNotEmpty(password)) {
redisUri = RedisURI.builder()
.withHost(host)
.withPort(port)
.withPassword(password.toCharArray())
.withTimeout(Duration.of(timeout, ChronoUnit.SECONDS))
.build();
} else {
redisUri = RedisURI.builder()
.withHost(host)
.withPort(port)
.withTimeout(Duration.of(timeout, ChronoUnit.SECONDS))
.build();
}
ClientResources clientResources = DefaultClientResources.builder()
.ioThreadPoolSize(4)
.computationThreadPoolSize(4)
.build();
if (StringUtils.equalsIgnoreCase(type, WatcherConstant.LETTUCE_REDIS_TYPE_STANDALONE)) {
// standalone
RedisURI redisUri = null;
if (StringUtils.isNotEmpty(password)) {
redisUri = RedisURI.builder()
.withHost(host)
.withPort(port)
.withPassword(password.toCharArray())
.withTimeout(Duration.of(timeout, ChronoUnit.SECONDS))
.build();
} else {
redisUri = RedisURI.builder()
.withHost(host)
.withPort(port)
.withTimeout(Duration.of(timeout, ChronoUnit.SECONDS))
.build();
}
ClientOptions clientOptions = ClientOptions.builder()
.autoReconnect(true)
.pingBeforeActivateConnection(true)
Expand All @@ -126,12 +144,26 @@ private AbstractRedisClient getLettuceRedisClient(String host, int port, String
return redisClient;
} else {
// cluster
TimeoutOptions timeoutOptions = TimeoutOptions.builder().fixedTimeout(Duration.of(timeout, ChronoUnit.SECONDS)).build();
ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
.enablePeriodicRefresh(Duration.of(10, ChronoUnit.MINUTES))
.enableAdaptiveRefreshTrigger(ClusterTopologyRefreshOptions.RefreshTrigger.MOVED_REDIRECT, ClusterTopologyRefreshOptions.RefreshTrigger.PERSISTENT_RECONNECTS)
.adaptiveRefreshTriggersTimeout(Duration.of(30, ChronoUnit.SECONDS))
.build();
ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()
.autoReconnect(true)
.timeoutOptions(timeoutOptions)
.topologyRefreshOptions(topologyRefreshOptions)
.pingBeforeActivateConnection(true)
.validateClusterNodeMembership(true)
.build();
RedisClusterClient redisClusterClient = RedisClusterClient.create(clientResources, redisUri);
// Redis Cluster Node
String redisUri = StringUtils.isNotEmpty(password) ?
WatcherConstant.REDIS_URI_PREFIX.concat(password).concat(WatcherConstant.REDIS_URI_PASSWORD_SPLIT).concat(nodes) :
WatcherConstant.REDIS_URI_PREFIX.concat(nodes);
logger.info("Redis Cluster Uri: {}", redisUri);
List<RedisURI> redisURIList = RedisClusterURIUtil.toRedisURIs(URI.create(redisUri));
RedisClusterClient redisClusterClient = RedisClusterClient.create(clientResources, redisURIList);
redisClusterClient.setOptions(clusterClientOptions);
return redisClusterClient;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@ public class WatcherConstant {
*/
public static final String LETTUCE_REDIS_TYPE_STANDALONE = "standalone";
public static final String LETTUCE_REDIS_TYPE_CLUSTER = "cluster";

/**
* Redis URI
*/
public static final String REDIS_URI_PREFIX = "redis://";
public static final String REDIS_URI_PASSWORD_SPLIT = "@";
}
37 changes: 19 additions & 18 deletions src/test/java/org/casbin/test/LettuceRedisWatcherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,46 +18,47 @@ public class LettuceRedisWatcherTest {
@Before
public void initWatcher() {
String redisTopic = "jcasbin-topic";
this.lettuceRedisWatcher = new LettuceRedisWatcher("127.0.0.1", 6379, redisTopic, 2000, "foobared", "standalone");
this.lettuceRedisWatcher = new LettuceRedisWatcher("127.0.0.1", 6379, redisTopic, 2000, "foobared");
Enforcer enforcer = new Enforcer();
enforcer.setWatcher(this.lettuceRedisWatcher);
}

public void initClusterWatcher() {
String redisTopic = "jcasbin-topic";
// modify your cluster nodes
this.lettuceRedisWatcher = new LettuceRedisWatcher("192.168.1.234:6380,192.168.1.234:6381,192.168.1.234:6382", redisTopic, 2000, "123456");
Enforcer enforcer = new Enforcer();
enforcer.setWatcher(this.lettuceRedisWatcher);
}

@Test
public void testUpdate() throws InterruptedException {
this.initWatcher();
// this.initClusterWatcher();
this.lettuceRedisWatcher.update();
Thread.sleep(100);
}

@Test
public void testConsumerCallback() throws InterruptedException {
this.initWatcher();
while (true) {
this.lettuceRedisWatcher.setUpdateCallback((s) -> System.out.println(s));
this.lettuceRedisWatcher.update();
Thread.sleep(500);
}
// this.initClusterWatcher();
// while (true) {
this.lettuceRedisWatcher.setUpdateCallback((s) -> System.out.println(s));
this.lettuceRedisWatcher.update();
Thread.sleep(100);
// }
}

@Test
public void testConnectWatcherWithoutPassword() {
String redisTopic = "jcasbin-topic";
LettuceRedisWatcher lettuceRedisWatcherWithoutPassword = new LettuceRedisWatcher("127.0.0.1", 6378, redisTopic, "standalone");
LettuceRedisWatcher lettuceRedisWatcherWithoutPassword = new LettuceRedisWatcher("127.0.0.1", 6378, redisTopic);
Assert.assertNotNull(lettuceRedisWatcherWithoutPassword);
}

@Test
public void testConnectWatcherWithType() {
public void testConnectWatcherCluster() {
String redisTopic = "jcasbin-topic";
Assert.assertThrows(IllegalArgumentException.class, () -> {
new LettuceRedisWatcher("127.0.0.1", 6378, redisTopic, "sentinel");
});

LettuceRedisWatcher lettuceRedisWatcherStandalone = new LettuceRedisWatcher("127.0.0.1", 6378, redisTopic, "standalone");
Assert.assertNotNull(lettuceRedisWatcherStandalone);

LettuceRedisWatcher lettuceRedisWatcherCluster = new LettuceRedisWatcher("127.0.0.1", 6378, redisTopic, "cluster");
LettuceRedisWatcher lettuceRedisWatcherCluster = new LettuceRedisWatcher("127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382", redisTopic, 2000, null);
Assert.assertNotNull(lettuceRedisWatcherCluster);
}
}
Loading