Skip to content

Commit

Permalink
fix: Remove the loop condition in the test code to fix CI (#3)
Browse files Browse the repository at this point in the history
* [NEW] Added maven-ci.yml
[NEW] Added WatcherConstant.java
[NEW] Added LettuceRedisWatcher.java
[NEW] Added LettuceSubscriber.java
[NEW] Added LettuceSubThread.java
[NEW] Added LettuceRedisWatcherTest.java
[UPDATE] Updated .gitignore
[NEW] Added .releaserc.json
[NEW] Added maven-settings.xml
[NEW] Added pom.xml
[UPDATE] Updated README.md

* Refactor LettuceRedisWatcherTest.java to use local IP address instead of remote IP address for testing.

* Update LettuceRedisWatcherTest.java to simplify watcher initialization and update logic.

* Refactor Redis connection initialization and add support for Redis Cluster.

- Add Redis URI constants.
- Update Redis connection initialization in LettuceRedisWatcher.
- Add constructors for different Redis connection types.
- Add support for Redis Cluster in LettuceRedisWatcher.
- Update LettuceRedisWatcherTest to test Redis Cluster connection.

* Update LettuceRedisWatcherTest.java to use localhost as the redis server instead of the specific IP address.

* Update node version from 16 to 18 in maven-ci.yml and add new semantic.yml.

* Refactor semantic.yml to disable validation for the PR title and all the commits.
  • Loading branch information
ShingmoYeung authored Aug 8, 2023
1 parent 178bebf commit bef8318
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 46 deletions.
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);
}
}

0 comments on commit bef8318

Please sign in to comment.