diff --git a/ContentGrabbingJi-CacheStore-redis/pom.xml b/ContentGrabbingJi-CacheStore-redis/pom.xml index 87e71b9..2ef58db 100644 --- a/ContentGrabbingJi-CacheStore-redis/pom.xml +++ b/ContentGrabbingJi-CacheStore-redis/pom.xml @@ -52,6 +52,12 @@ jedis 3.3.0 + + + com.google.code.gson + gson + 2.8.6 + \ No newline at end of file diff --git a/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisCacheStoreFactory.java b/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisCacheStoreFactory.java index 142496e..2489c5e 100644 --- a/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisCacheStoreFactory.java +++ b/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisCacheStoreFactory.java @@ -17,7 +17,7 @@ package net.lamgc.cgj.bot.cache.redis; -import com.google.common.base.Strings; +import com.google.gson.Gson; import net.lamgc.cgj.bot.cache.*; import net.lamgc.cgj.bot.cache.convert.StringConverter; import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException; @@ -25,10 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; -import java.net.MalformedURLException; -import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.Properties; /** * @@ -39,19 +36,11 @@ public class RedisCacheStoreFactory implements CacheStoreFactory { private final static Logger log = LoggerFactory.getLogger(RedisCacheStoreFactory.class); - private final static String PROP_HOST = "redis.host"; - private final static String PROP_PORT = "redis.port"; - private final static String PROP_USE_SSL = "redis.useSSL"; - private final static String PROP_USERNAME = "redis.username"; - private final static String PROP_PASSWORD = "redis.password"; - private final static String PROP_DATABASE = "redis.databaseId"; - private final static String PROP_CLIENT_NAME = "redis.clientName"; - private final RedisConnectionPool connectionPool = new RedisConnectionPool(); @Override public void initial(File dataDirectory) { - final File propertiesFile = new File(dataDirectory, "redis.properties"); + final File propertiesFile = new File(dataDirectory, RedisUtils.PROPERTIES_FILE_NAME); if (!propertiesFile.exists()) { log.warn("未找到 Redis 配置文件, 使用默认配置."); return; @@ -59,27 +48,14 @@ public class RedisCacheStoreFactory implements CacheStoreFactory { log.warn("Redis 配置文件不是一个文件, 使用默认配置."); return; } - Properties properties = new Properties(); try (Reader propertiesReader = new BufferedReader( new InputStreamReader(new FileInputStream(propertiesFile), StandardCharsets.UTF_8))) { - properties.load(propertiesReader); + RedisConnectionProperties properties = new Gson() + .fromJson(propertiesReader, RedisConnectionProperties.class); + connectionPool.setConnectionProperties(properties); + log.debug("Redis 配置文件已成功读取: {}", properties); } catch (IOException e) { - log.error("读取 Redis 配置文件时发生异常", e); - } - try { - String queryString = "/?" + "ssl=" + properties.getProperty(PROP_USE_SSL, "false") + '&' + - "user=" + Strings.nullToEmpty(properties.getProperty(PROP_USERNAME)) + '&' + - "passwd=" + Strings.nullToEmpty(properties.getProperty(PROP_PASSWORD)) + '&' + - "database=" + properties.getProperty(PROP_DATABASE, "0") + '&' + - "clientName=" + Strings.nullToEmpty(properties.getProperty(PROP_CLIENT_NAME)); - URL url = new URL("redis", - properties.getProperty(PROP_HOST, "localhost"), - Integer.parseInt(properties.getProperty(PROP_PORT, "6379")), - queryString); - - connectionPool.setConnectionUrl(url); - } catch (MalformedURLException e) { - log.error("构造连接 URL 时发生异常", e); + log.error("读取 Redis 配置文件时发生异常, 将使用默认配置连接 Redis.", e); } } diff --git a/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisConnectionPool.java b/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisConnectionPool.java index 8a582de..05b85bd 100644 --- a/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisConnectionPool.java +++ b/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisConnectionPool.java @@ -17,17 +17,14 @@ package net.lamgc.cgj.bot.cache.redis; +import com.google.common.base.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; +import java.io.*; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.atomic.AtomicReference; @@ -42,13 +39,18 @@ class RedisConnectionPool { private final static Logger log = LoggerFactory.getLogger(RedisConnectionPool.class); private final AtomicReference POOL = new AtomicReference<>(); - private final AtomicReference CONNECTION_URL = new AtomicReference<>(); + private final AtomicReference connectionProperties = new AtomicReference<>(); private final Map scriptMap = new HashMap<>(); - public synchronized void setConnectionUrl(URL connectionUrl) { - if(CONNECTION_URL.get() != null) { - CONNECTION_URL.set(connectionUrl); + public RedisConnectionPool() { + Runtime.getRuntime().addShutdownHook(new Thread(this::close, + "Shutdown-RedisConnectionPool@" + Integer.toHexString(this.hashCode()))); + } + + public synchronized void setConnectionProperties(RedisConnectionProperties properties) { + if(connectionProperties.get() != null) { + connectionProperties.set(properties); } } @@ -60,12 +62,35 @@ class RedisConnectionPool { JedisPoolConfig config = new JedisPoolConfig(); config.setTestOnBorrow(true); config.setTestOnReturn(true); - URL connectionUrl = CONNECTION_URL.get(); - if (connectionUrl == null) { + RedisConnectionProperties properties = connectionProperties.get(); + if (properties == null) { jedisPool = new JedisPool(config); } else { - jedisPool = new JedisPool(config, connectionUrl.getHost(), connectionUrl.getPort(), - connectionUrl.getPath().toLowerCase().contains("ssl=true")); + String userName = properties.getUserName(); + if (Strings.isNullOrEmpty(userName)) { + jedisPool = new JedisPool(config, + properties.getHost(), + properties.getPort(), + properties.getConnectionTimeout(), + properties.getSocketTimeout(), + properties.getPassword(), + properties.getDatabaseId(), + properties.getClientName(), + properties.enableSsl() + ); + } else { + jedisPool = new JedisPool(config, + properties.getHost(), + properties.getPort(), + properties.getConnectionTimeout(), + properties.getSocketTimeout(), + userName, + properties.getPassword(), + properties.getDatabaseId(), + properties.getClientName(), + properties.enableSsl() + ); + } } POOL.set(jedisPool); loadScript(); @@ -198,4 +223,10 @@ class RedisConnectionPool { } + public void close() { + JedisPool jedisPool = POOL.get(); + if (jedisPool != null && !jedisPool.isClosed()) { + jedisPool.close(); + } + } } diff --git a/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisConnectionProperties.java b/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisConnectionProperties.java new file mode 100644 index 0000000..53de47c --- /dev/null +++ b/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisConnectionProperties.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2021 LamGC + * + * ContentGrabbingJi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * ContentGrabbingJi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package net.lamgc.cgj.bot.cache.redis; + +import com.google.common.base.Strings; +import redis.clients.jedis.Protocol; + +/** + * Redis 连接配置对象. + * @author LamGC + */ +@SuppressWarnings({"FieldCanBeLocal", "unused"}) +public class RedisConnectionProperties { + + private int connectionTimeout = Protocol.DEFAULT_TIMEOUT; + private int socketTimeout = Protocol.DEFAULT_TIMEOUT; + private String host = Protocol.DEFAULT_HOST; + private int port = Protocol.DEFAULT_PORT; + private boolean ssl = false; + private String userName = null; + private String password = null; + private int databaseId = Protocol.DEFAULT_DATABASE; + private String clientName = null; + + @Override + public String toString() { + int showPasswordLength = password.length() / 4; + return "RedisConnectionProperties{" + + "connectionTimeout=" + connectionTimeout + + ", socketTimeout=" + socketTimeout + + ", host='" + host + '\'' + + ", port=" + port + + ", ssl=" + ssl + + ", userName='" + userName + '\'' + + ", password='" + password.substring(0, showPasswordLength) + + Strings.repeat("*", password.length() - showPasswordLength) + '\'' + + ", databaseId=" + databaseId + + ", clientName='" + clientName + '\'' + + '}'; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public int getSocketTimeout() { + return socketTimeout; + } + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public boolean enableSsl() { + return ssl; + } + + public String getUserName() { + return userName; + } + + public String getPassword() { + return password; + } + + public int getDatabaseId() { + return databaseId; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public void setDatabaseId(int databaseId) { + this.databaseId = databaseId; + } + + public void setHost(String host) { + this.host = host; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setPort(int port) { + this.port = port; + } + + public void setSocketTimeout(int socketTimeout) { + this.socketTimeout = socketTimeout; + } + + public void setEnableSsl(boolean ssl) { + this.ssl = ssl; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisUtils.java b/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisUtils.java index cf7e06b..470e3f1 100644 --- a/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisUtils.java +++ b/ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisUtils.java @@ -49,6 +49,11 @@ public class RedisUtils { */ public final static String KEY_SEPARATOR = ":"; + /** + * Redis 组件配置文件名. + */ + public final static String PROPERTIES_FILE_NAME = "redis.properties.json"; + /** * 检查字符串返回结果是否为操作成功. * @param result 字符串返回结果.