summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nz-admin/pom.xml16
-rw-r--r--nz-admin/src/main/java/com/nis/common/config/RedisConfig.java42
-rw-r--r--nz-admin/src/main/java/com/nis/common/config/SetupRunner.java8
-rw-r--r--nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java5
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/backend/DbSyncRedisThread.java569
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisManager.java92
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/shiro/WorkAloneRedisManager.java157
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/util/RedisSearchUtil.java433
-rw-r--r--pom.xml2
9 files changed, 1300 insertions, 24 deletions
diff --git a/nz-admin/pom.xml b/nz-admin/pom.xml
index cecbba23..1d356138 100644
--- a/nz-admin/pom.xml
+++ b/nz-admin/pom.xml
@@ -146,6 +146,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
+ <version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
@@ -343,6 +344,21 @@
<artifactId>jsoup</artifactId>
<version>1.14.1</version>
</dependency>
+
+ <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-pool2</artifactId>
+ <version>2.11.1</version>
+ </dependency>
+
+ <!--mysql-binlog-connector-java-->
+ <dependency>
+ <groupId>com.zendesk</groupId>
+ <artifactId>mysql-binlog-connector-java</artifactId>
+ <version>0.25.0</version>
+ </dependency>
+
</dependencies>
<build>
diff --git a/nz-admin/src/main/java/com/nis/common/config/RedisConfig.java b/nz-admin/src/main/java/com/nis/common/config/RedisConfig.java
index 0b642fa4..e917ab70 100644
--- a/nz-admin/src/main/java/com/nis/common/config/RedisConfig.java
+++ b/nz-admin/src/main/java/com/nis/common/config/RedisConfig.java
@@ -1,9 +1,8 @@
package com.nis.common.config;
-import java.net.UnknownHostException;
-import java.time.Duration;
-
-import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+import cn.hutool.log.Log;
+import com.nis.common.utils.Tool;
+import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -16,12 +15,11 @@ import org.springframework.data.redis.connection.lettuce.LettucePoolingClientCon
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
-
-import com.nis.common.utils.Tool;
-
-import cn.hutool.log.Log;
-import lombok.Data;
import org.springframework.data.redis.serializer.StringRedisSerializer;
+import redis.clients.jedis.JedisPoolConfig;
+
+import java.net.UnknownHostException;
+import java.time.Duration;
/**
* redis 初始化配置
@@ -72,19 +70,21 @@ public class RedisConfig {
if(Tool.StrUtil.isNotBlank(this.getRedisPin())) {
configuration.setPassword(this.getRedisPin());
}
- GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
- poolConfig.setMinIdle(this.getMinIdle());
- poolConfig.setMaxIdle(this.getMaxIdle());
- poolConfig.setMaxTotal(this.getMaxActive());
- poolConfig.setMaxWaitMillis(this.getMaxWait());
+ JedisPoolConfig poolConfig = new JedisPoolConfig();
+ poolConfig.setMinIdle(this.getMinIdle());
+ poolConfig.setMaxIdle(this.getMaxIdle());
+ poolConfig.setMaxTotal(this.getMaxActive());
+ poolConfig.setMaxWait(Duration.ofMillis(this.getMaxWait()));
+
+ LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder()
+ .commandTimeout(Duration.ofMillis(this.getRedisTimeout()))
+ .shutdownTimeout(Duration.ZERO)
+ .poolConfig(poolConfig)
+ .build();
- LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder()
- .commandTimeout(Duration.ofMillis(this.getRedisTimeout()))
- .shutdownTimeout(Duration.ZERO)
- .poolConfig(poolConfig)
- .build();
-
- RedisConnectionFactory factory = new LettuceConnectionFactory(configuration, lettucePoolingClientConfiguration);
+ RedisConnectionFactory factory = new LettuceConnectionFactory(configuration, lettucePoolingClientConfiguration);
+ // setValidateConnection
+ //((LettuceConnectionFactory) factory).setValidateConnection(true);
return factory;
}
diff --git a/nz-admin/src/main/java/com/nis/common/config/SetupRunner.java b/nz-admin/src/main/java/com/nis/common/config/SetupRunner.java
index 2370284a..ca78e6a0 100644
--- a/nz-admin/src/main/java/com/nis/common/config/SetupRunner.java
+++ b/nz-admin/src/main/java/com/nis/common/config/SetupRunner.java
@@ -14,6 +14,7 @@ import com.nis.modules.panel.entity.VisualPanel;
import com.nis.modules.panel.service.VisualPanelService;
import com.nis.modules.panel.utils.DashboardConstant;
import com.nis.modules.report.job.ReportJobManager;
+import com.nis.modules.sys.backend.DbSyncRedisThread;
import com.nis.modules.sys.entity.SysUserEntity;
import com.nis.modules.sys.job.SysBackJobManager;
import com.nis.modules.sys.service.LicenseService;
@@ -73,6 +74,9 @@ public class SetupRunner implements CommandLineRunner{
@Autowired
private VsysTaskConfigThread vsysTaskConfigThread;
+
+ @Autowired
+ private DbSyncRedisThread dbSyncRedisThread;
@@ -115,6 +119,10 @@ public class SetupRunner implements CommandLineRunner{
Tool.ThreadUtil.execute(vsysTaskConfigThread);
log.info("启动 {} 成功", "VsysTaskConfigThread");
+ // 启动 Resis & Mysql 数据同步线程
+ Tool.ThreadUtil.execute(dbSyncRedisThread);
+ log.info("启动 {} 成功", "DbSyncRedisThread");
+
if (inited == 2) {
log.info(" inited = {} ,skip init setup", inited);
return;
diff --git a/nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java b/nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java
index 910991f0..67359bf4 100644
--- a/nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java
+++ b/nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java
@@ -8,6 +8,7 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
+import com.nis.modules.sys.shiro.MyRedisManager;
import org.apache.catalina.connector.Connector;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
@@ -218,8 +219,8 @@ public class ShiroConfig {
*
* @return
*/
- public RedisManager redisManager() {
- RedisManager redisManager = new RedisManager();
+ public MyRedisManager redisManager() {
+ MyRedisManager redisManager = new MyRedisManager();
redisManager.setHost(config.getRedisHost() + ":" + config.getRedisPort());
redisManager.setTimeout(Tool.NumberUtil.parseInt(Tool.StrUtil.toString(config.getRedisTimeout())));
redisManager.setDatabase(config.getRedisDatabase());
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/backend/DbSyncRedisThread.java b/nz-admin/src/main/java/com/nis/modules/sys/backend/DbSyncRedisThread.java
new file mode 100644
index 00000000..27bb62b6
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/sys/backend/DbSyncRedisThread.java
@@ -0,0 +1,569 @@
+package com.nis.modules.sys.backend;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.log.Log;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
+import com.github.shyiko.mysql.binlog.BinaryLogClient;
+import com.github.shyiko.mysql.binlog.event.*;
+import com.google.gson.Gson;
+import com.nis.common.utils.Constant;
+import com.nis.common.utils.RedisLock;
+import com.nis.common.utils.Tool;
+import com.nis.modules.alert.entity.AlertRuleEntity;
+import com.nis.modules.alert.service.AlertRuleService;
+import com.nis.modules.asset.entity.AssetAsset;
+import com.nis.modules.asset.entity.AssetModel;
+import com.nis.modules.asset.entity.Dc;
+import com.nis.modules.asset.service.AssetAssetService;
+import com.nis.modules.asset.service.AssetModelService;
+import com.nis.modules.asset.service.DcService;
+import com.nis.modules.endpoint.entity.MonitorEndpoint;
+import com.nis.modules.endpoint.service.MonitorEndpointService;
+import com.nis.modules.module.entity.MonitorModule;
+import com.nis.modules.module.service.MonitorModuleService;
+import com.nis.modules.project.entity.MonitorProject;
+import com.nis.modules.project.service.MonitorProjectService;
+import com.nis.modules.sys.util.RedisSearchUtil;
+import org.apache.commons.lang3.time.StopWatch;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import redis.clients.jedis.JedisPooled;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * DbSyncRedisThread
+ * 通过监听 binlog,将 mysql 数据同步到 redis
+ *
+ * @author shizhendong
+ * @date 2023-02-03
+ */
+@Component
+public class DbSyncRedisThread implements Runnable {
+
+ private static final Log log = Log.get();
+
+ @Value("${database.host}")
+ private String databaseHost;
+ @Value("${database.port:3306}")
+ private int databasePort;
+ @Value("${database.user}")
+ private String databaseUser;
+ @Value("${database.pin}")
+ private String databasePin;
+
+ @Value("${redis.host}")
+ private String redisHost;
+ @Value("${redis.port:6379}")
+ private int redisPort;
+ @Value("${redis.database:0}")
+ private int redisDatabase;
+ @Value("${redis.pin}")
+ private String redisPin;
+ @Value("${spring.redis.jedis.pool.max-idle:10}")
+ private int maxIdle;
+ @Value("${spring.redis.jedis.pool.min-idle:3}")
+ private int minIdle;
+ @Value("${spring.redis.jedis.pool.max-wait:100000}")
+ private int maxWait;
+ @Value("${spring.redis.jedis.pool.max-active:100}")
+ private int maxActive;
+ @Value("${spring.redis.timeout:100000}")
+ private int redisTimeout;
+
+ /**
+ * table_columns_map
+ * key: table_name
+ * value: table columns info. include ordinal_position and column_name.
+ */
+ private static Map<String, Object> TABLE_COLUMNS_MAP;
+
+ /**
+ * redis key
+ * sync binlog position
+ */
+ private static final String REDIS_KEY_BINLOG_POSITION = "sync_binlog_position";
+
+ /**
+ * sync_table_names
+ * 数据同步的表名称
+ */
+ private static List<String> SYNC_TABLE_NAMES = Tool.ListUtil.of(
+ "dc", "asset_asset", "asset_model",
+ "monitor_project", "monitor_module", "monitor_endpoint",
+ "alert_rule", "alert_message_active", "alert_message_history", "alert_message_silence"
+ );
+
+ private JedisPooled jedisClient;
+
+ private static final Gson GSON = new Gson();
+
+ @Autowired
+ private RedisLock redisLock;
+
+ @Autowired
+ private DcService dcService;
+
+ @Autowired
+ private AssetAssetService assetService;
+
+ @Autowired
+ private AssetModelService assetModelService;
+
+ @Autowired
+ private MonitorProjectService projectService;
+
+ @Autowired
+ private MonitorModuleService moduleService;
+
+ @Autowired
+ private MonitorEndpointService endpointService;
+
+ @Autowired
+ private AlertRuleService alertRuleService;
+
+ @Autowired
+ private RedisTemplate<String, String> redisTemplate;
+
+ /**
+ * init Columns Mapping
+ */
+ private void initTableCloumnsMapping() {
+ log.info("[initTableCloumnsMapping] [init table columns info begin]");
+
+ TABLE_COLUMNS_MAP = Tool.MapUtil.newHashMap();
+ String querySqlStr = StrUtil.concat(true, "SELECT ",
+ "TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION ",
+ "FROM ",
+ "INFORMATION_SCHEMA.COLUMNS ",
+ "WHERE TABLE_SCHEMA = DATABASE();");
+ List<Map<String, Object>> selectList = SqlRunner.db().selectList(querySqlStr);
+ Map<String, List<Map<String, Object>>> tMap = selectList.stream()
+ .filter(map -> SYNC_TABLE_NAMES.contains(StrUtil.toString(map.get("TABLE_NAME"))))
+ .collect(Collectors.groupingBy(map -> StrUtil.toString(map.get("TABLE_NAME"))));
+
+ for (Map.Entry<String, List<Map<String, Object>>> entry : tMap.entrySet()) {
+ String tableName = entry.getKey();
+ List<Map<String, Object>> value = entry.getValue();
+
+ Map<Integer, String> positionWithNameMapping = value.stream()
+ .collect(Collectors.toMap(
+ map -> {
+ String ordinalPosition = map.get("ORDINAL_POSITION").toString();
+ return Integer.valueOf(ordinalPosition);
+ },
+ map -> {
+ String columnName = map.get("COLUMN_NAME").toString();
+ return StringUtils.underlineToCamel(columnName);
+ }));
+ TABLE_COLUMNS_MAP.put(tableName, positionWithNameMapping);
+ }
+
+ log.info("[initTableCloumnsMapping] [table columns map size: {}]", TABLE_COLUMNS_MAP.size());
+ }
+
+ @Override
+ public void run() {
+ Thread.currentThread().setName("Db Sync Redis Thread");
+ log.info("DbSyncRedisThread start...");
+
+ // init Table Cloumns Mapping
+ this.initTableCloumnsMapping();
+
+ // jedis client
+ this.jedisClient = this.buildJedisPool(redisHost, redisPort, redisTimeout, redisPin, redisDatabase, maxIdle, minIdle, maxWait, maxActive);
+
+ BinaryLogClient binaryLogClient = null;
+ try {
+ binaryLogClient = this.buildBinaryLogClient(this.databaseHost, this.databasePort, this.databaseUser, this.databasePin);
+
+ // binaryLogClient.setEventDeserializer();
+
+ // Lifecycle Listener
+ binaryLogClient.registerLifecycleListener(this.buildLifecycleListener());
+
+ // Event Listener
+ binaryLogClient.registerEventListener(this.buildEventListener());
+
+ try {
+ // connect
+ binaryLogClient.connect();
+ } catch (IOException e) {
+ log.error(e, "[DbSyncRedisThread] [BinaryLogClient connect error]");
+ }
+ } finally {
+ // disconnect
+ try {
+ if (binaryLogClient != null) {
+ binaryLogClient.disconnect();
+ }
+ } catch (IOException e) {
+ log.error(e, "[DbSyncRedisThread] [disconnect BinaryLogClient error]");
+ }
+
+ // close
+ Tool.IoUtil.close(this.jedisClient);
+ }
+ }
+
+
+ /**
+ * build Jedis Pool
+ *
+ * @param redisHost
+ * @param redisPort
+ * @param redisTimeout
+ * @param redisPin
+ * @param redisDatabase
+ * @param maxIdle
+ * @param minIdle
+ * @param maxWait
+ * @param maxActive
+ * @return
+ */
+ private JedisPooled buildJedisPool(String redisHost, int redisPort, int redisTimeout, String redisPin, int redisDatabase, int maxIdle, int minIdle, int maxWait, int maxActive) {
+ log.info("[buildJedisPool] [begin]");
+ log.info("[buildJedisPool] [redisHost: {}] [redisPort: {}] [redisDatabase: {}]", redisHost, redisPort, redisDatabase);
+
+ GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
+ poolConfig.setMaxIdle(maxIdle);
+ poolConfig.setMinIdle(minIdle);
+ poolConfig.setMaxTotal(maxActive);
+ poolConfig.setMaxWait(Duration.ofMillis(maxWait));
+
+ JedisPooled jedisPooled = new JedisPooled(poolConfig, redisHost, redisPort, redisTimeout, StrUtil.emptyToNull(redisPin), redisDatabase);
+ log.info("[buildJedisPool] [finshed]");
+ return jedisPooled;
+ }
+
+ /**
+ * build Binary Log Client
+ *
+ * @param databaseHost
+ * @param databasePort
+ * @param databaseUser
+ * @param databasePin
+ * @return
+ */
+ private BinaryLogClient buildBinaryLogClient(String databaseHost, int databasePort, String databaseUser, String databasePin) {
+ log.info("[buildBinaryLogClient] [begin]");
+ log.info("[buildBinaryLogClient] [databaseHost: {}] [databasePort: {}] [databaseUser: {}]", databaseHost, databasePort, databaseUser);
+
+ // 数据库密码解密
+ databasePin = Tool.AesUtil.decrypt(databasePin, Constant.AES_SECRET_KEY);
+
+ // Binary Log Client
+ BinaryLogClient client = new BinaryLogClient(databaseHost, databasePort, databaseUser, databasePin);
+
+ log.info("[buildBinaryLogClient] [finshed]");
+ return client;
+ }
+
+ /**
+ * build Lifecycle Listener
+ * 1. create Redis Search Index
+ * 2. update full data
+ *
+ * @return
+ */
+ private BinaryLogClient.AbstractLifecycleListener buildLifecycleListener() {
+ log.info("[buildLifecycleListener] [begin]");
+ BinaryLogClient.AbstractLifecycleListener lifecycleListener = new BinaryLogClient.AbstractLifecycleListener() {
+ @Override
+ public void onConnect(BinaryLogClient client) {
+ super.onConnect(client);
+
+ // HA
+ try {
+ boolean lock = redisLock.lock("lock_db_sync_redis", Constant.SERVER_ID, 5L);
+ log.info("[onConnect] [Get sync lock from redis] [result: {}]", lock);
+ if (lock) {
+ // create Redis Search Index
+ // TODO https://github.com/RediSearch/RediSearch/issues/367
+ RedisSearchUtil redisSearchUtil = RedisSearchUtil.RedisSearchUtilBuilder.builder()
+ .jedisPooled(jedisClient)
+ .build();
+ // create Redis Search Index
+ redisSearchUtil.createRedisSearchIndex();
+
+ // db
+ long currentBinlogPosition = client.getBinlogPosition();
+ // redis
+ String binlogPositionInRedis = redisTemplate.opsForValue().get(REDIS_KEY_BINLOG_POSITION);
+ log.info("[onConnect] [binlog position] [db: {}] [redis: {}]", currentBinlogPosition, binlogPositionInRedis);
+
+ if (!StrUtil.equals(StrUtil.toString(currentBinlogPosition), binlogPositionInRedis)) {
+ log.info("[onConnect] [binlog position is updated. full update cache data]");
+ // 全量更新-同步
+ updateAll();
+ // update position
+ redisTemplate.opsForValue().set(REDIS_KEY_BINLOG_POSITION, StrUtil.toString(currentBinlogPosition));
+ } else {
+ log.info("[onConnect] [binlog position not updated. do not update cached data]");
+ }
+ } else {
+ log.warn("[DbSyncRedisThread] [did not get the sync lock, do not update cached data]");
+ }
+ } finally {
+ redisLock.unlock("lock_db_sync_redis", Constant.SERVER_ID);
+ }
+ }
+ };
+ log.info("[buildLifecycleListener] [finshed]");
+ return lifecycleListener;
+ }
+
+ /**
+ * build Event Listener
+ *
+ * @return
+ */
+ private BinaryLogClient.EventListener buildEventListener() {
+ log.info("[buildEventListener] [begin]");
+ BinaryLogClient.EventListener eventListener = new BinaryLogClient.EventListener() {
+ @Override
+ public void onEvent(Event event) {
+ // 检查 HA mode
+ String serverId = redisTemplate.opsForValue().get(Constant.SYS_HA_LOCK);
+ if (!Tool.StrUtil.equals(serverId, Constant.SERVER_ID)) {
+ return;
+ }
+
+ EventHeader eventHeader = event.getHeader();
+ EventType eventType = eventHeader.getEventType();
+ EventData eventData = event.getData();
+
+ // table
+ if (Tool.ObjectUtil.equal(0, EventType.TABLE_MAP.compareTo(eventType))) {
+ TableMapEventData tableMapEventData = (TableMapEventData) eventData;
+ String tableName = tableMapEventData.getTable();
+ if (SYNC_TABLE_NAMES.contains(tableName)) {
+ long tableId = tableMapEventData.getTableId();
+ if (Tool.ObjectUtil.isNotNull(TABLE_COLUMNS_MAP.get(StrUtil.toString(tableId)))) {
+ return;
+ }
+ // TABLE_MAP 可监听到内容包含 table_id & table_name
+ // 其他 EVENT 只能获取到 table_id,table_id 只在监听时可获得,于是在 TABLE_MAP 事件做对应
+ // TABLE_COLUMNS_MAP.put(StrUtil.toString(tableId), TABLE_COLUMNS_MAP.get(tableName));
+ TABLE_COLUMNS_MAP.put(StrUtil.concat(true, StrUtil.toString(tableId), "_table_name"), tableName);
+ }
+ }
+
+ // Insert
+ if (Tool.ObjectUtil.equal(0, EventType.WRITE_ROWS.compareTo(eventType))) {
+ WriteRowsEventData writeRowsEventData = (WriteRowsEventData) eventData;
+ String tableName = (String) TABLE_COLUMNS_MAP.get(StrUtil.toString(writeRowsEventData.getTableId()) + "_table_name");
+ if (Tool.ObjectUtil.isNull(tableName)) return;
+
+ Map<Integer, String> columnsInfo = (Map) TABLE_COLUMNS_MAP.get(tableName);
+ for (Serializable[] row : writeRowsEventData.getRows()) {
+ Map<Object, Object> insertEntityMap = Tool.MapUtil.builder().map();
+ for (int i = 0; i < row.length; i++) {
+ insertEntityMap.put(columnsInfo.get(i + 1), row[i]);
+ }
+ // set
+ jedisClient.jsonSet(getKey(tableName, insertEntityMap.get("id")), GSON.toJson(insertEntityMap));
+ }
+ }
+
+ // Update
+ if (Tool.ObjectUtil.equal(0, EventType.UPDATE_ROWS.compareTo(eventType))) {
+ UpdateRowsEventData updateRowsEventData = (UpdateRowsEventData) eventData;
+ String tableName = (String) TABLE_COLUMNS_MAP.get(StrUtil.toString(updateRowsEventData.getTableId()) + "_table_name");
+ if (Tool.ObjectUtil.isNull(tableName)) return;
+
+ Map<Integer, String> columnsInfo = (Map) TABLE_COLUMNS_MAP.get(tableName);
+ for (Map.Entry<Serializable[], Serializable[]> entry : updateRowsEventData.getRows()) {
+ Serializable[] after = entry.getValue();
+ Map<Object, Object> updateEntityMap = Tool.MapUtil.builder().map();
+ for (int i = 0; i < after.length; i++) {
+ updateEntityMap.put(columnsInfo.get(i + 1), after[i]);
+ }
+ // set
+ jedisClient.jsonSet(getKey(tableName, updateEntityMap.get("id")), GSON.toJson(updateEntityMap));
+ }
+ }
+
+ // Delete
+ if (Tool.ObjectUtil.equal(0, EventType.DELETE_ROWS.compareTo(eventType))) {
+ DeleteRowsEventData deleteRowsEventData = (DeleteRowsEventData) eventData;
+ String tableName = (String) TABLE_COLUMNS_MAP.get(StrUtil.toString(deleteRowsEventData.getTableId()) + "_table_name");
+ if (Tool.ObjectUtil.isNull(tableName)) return;
+
+ Map<Integer, String> columnsInfo = (Map) TABLE_COLUMNS_MAP.get(tableName);
+ for (Serializable[] row : deleteRowsEventData.getRows()) {
+ for (int i = 0; i < row.length; i++) {
+ String fieldName = columnsInfo.get(i + 1);
+ if (StrUtil.equals("id", fieldName)) {
+ // del
+ jedisClient.del(getKey(tableName, row[i]));
+ }
+ }
+ }
+ }
+
+ // XID
+ if (Tool.ObjectUtil.equal(0, EventType.XID.compareTo(eventType))) {
+ EventHeaderV4 header = (EventHeaderV4) eventHeader;
+ redisTemplate.opsForValue().set(REDIS_KEY_BINLOG_POSITION, StrUtil.toString(header.getNextPosition()));
+ }
+ }
+ };
+ log.info("[buildEventListener] [finshed]");
+ return eventListener;
+ }
+
+ /**
+ * 全量更新 asset & endpoint 内容
+ * 先删除后增
+ */
+ private void updateAll() {
+ log.info("[updateAll] [begin]");
+
+ StopWatch sw = new StopWatch();
+ sw.start();
+ try {
+ // remove
+ this.removeTablesCache();
+
+ // push
+ this.pushTablesCache();
+ } catch (Exception e) {
+ log.error(e, "[updateAll] [error]");
+ // 同步失败,停止服务
+ Tool.RuntimeUtil.exec("systemctl stop nz-web.service");
+ } finally {
+ sw.stop();
+ }
+ log.info("[updateAll] [finshed] [Run Time: {}]", sw.toString());
+ }
+
+ /**
+ * remove Tables Cache
+ */
+ private void removeTablesCache() {
+ log.info("[removeTableCache] [begin]");
+ StopWatch sw = new StopWatch();
+ sw.start();
+
+ Set<String> dcRemoveKeys = redisTemplate.keys("dc:*");
+ if (Tool.CollUtil.isNotEmpty(dcRemoveKeys)) redisTemplate.delete(dcRemoveKeys);
+
+ Set<String> assetRemoveKeys = redisTemplate.keys("asset_asset:*");
+ if (Tool.CollUtil.isNotEmpty(assetRemoveKeys)) redisTemplate.delete(assetRemoveKeys);
+
+ Set<String> assetModelRemoveKeys = redisTemplate.keys("asset_model:*");
+ if (Tool.CollUtil.isNotEmpty(assetModelRemoveKeys)) redisTemplate.delete(assetModelRemoveKeys);
+
+ Set<String> projectRemoveKeys = redisTemplate.keys("monitor_project:*");
+ if (Tool.CollUtil.isNotEmpty(projectRemoveKeys)) redisTemplate.delete(projectRemoveKeys);
+
+ Set<String> moduleRemoveKeys = redisTemplate.keys("monitor_module:*");
+ if (Tool.CollUtil.isNotEmpty(moduleRemoveKeys)) redisTemplate.delete(moduleRemoveKeys);
+
+ Set<String> endpointRemoveKeys = redisTemplate.keys("monitor_endpoint:*");
+ if (Tool.CollUtil.isNotEmpty(endpointRemoveKeys)) redisTemplate.delete(endpointRemoveKeys);
+
+ Set<String> ruleRemoveKeys = redisTemplate.keys("alert_rule:*");
+ if (Tool.CollUtil.isNotEmpty(ruleRemoveKeys)) redisTemplate.delete(ruleRemoveKeys);
+
+ Set<String> alertMsgActiveRemoveKeys = redisTemplate.keys("alert_message_active:*");
+ if (Tool.CollUtil.isNotEmpty(alertMsgActiveRemoveKeys)) redisTemplate.delete(alertMsgActiveRemoveKeys);
+
+ Set<String> alertMsgHistoryRemoveKeys = redisTemplate.keys("alert_message_history:*");
+ if (Tool.CollUtil.isNotEmpty(alertMsgHistoryRemoveKeys)) redisTemplate.delete(alertMsgHistoryRemoveKeys);
+
+ Set<String> alertMsgSilenceruleRemoveKeys = redisTemplate.keys("alert_message_silence:*");
+ if (Tool.CollUtil.isNotEmpty(alertMsgSilenceruleRemoveKeys))
+ redisTemplate.delete(alertMsgSilenceruleRemoveKeys);
+
+ sw.stop();
+ log.info("[removeTableCache] [finshed] [Run Time: {}]", sw.toString());
+ }
+
+ /**
+ * push Tables Cache
+ */
+ private void pushTablesCache() {
+ log.info("[pushTablesCache] [begin]");
+ StopWatch sw = new StopWatch();
+ sw.start();
+
+ List<Dc> dcList = dcService.list();
+ for (Dc dc : dcList) {
+ this.jedisClient.jsonSet(this.getKey("dc", dc.getId()), GSON.toJson(dc));
+ }
+
+ List<AssetAsset> assetList = assetService.list();
+ for (AssetAsset asset : assetList) {
+ this.jedisClient.jsonSet(this.getKey("asset_asset", asset.getId()), GSON.toJson(asset));
+ }
+
+ List<AssetModel> modelList = assetModelService.list();
+ for (AssetModel model : modelList) {
+ this.jedisClient.jsonSet(this.getKey("asset_model", model.getId()), GSON.toJson(model));
+ }
+
+ List<MonitorProject> projectList = projectService.list();
+ for (MonitorProject project : projectList) {
+ this.jedisClient.jsonSet(this.getKey("monitor_project", project.getId()), GSON.toJson(project));
+ }
+
+ List<MonitorModule> moduleList = moduleService.list();
+ for (MonitorModule module : moduleList) {
+ this.jedisClient.jsonSet(this.getKey("monitor_module", module.getId()), GSON.toJson(module));
+ }
+
+ List<MonitorEndpoint> endpointList = endpointService.list();
+ for (MonitorEndpoint endpoint : endpointList) {
+ this.jedisClient.jsonSet(this.getKey("monitor_endpoint", endpoint.getId()), GSON.toJson(endpoint));
+ }
+
+ List<AlertRuleEntity> alertRuleList = alertRuleService.list();
+ for (AlertRuleEntity alertRule : alertRuleList) {
+ this.jedisClient.jsonSet(this.getKey("alert_rule", alertRule.getId()), GSON.toJson(alertRule));
+ }
+
+ List<Map<String, Object>> alertMsgActiveList = SqlRunner.db().selectList("SELECT * FROM alert_message_active;");
+ for (Map<String, Object> msgEntity : alertMsgActiveList) {
+ Map<String, Object> tMap = msgEntity.entrySet().stream().collect(HashMap::new, (k, v) -> k.put(StringUtils.underlineToCamel(v.getKey()), v.getValue()), HashMap::putAll);
+ this.jedisClient.jsonSet(this.getKey("alert_message_active", Tool.MapUtil.getStr(msgEntity, "id")), GSON.toJson(tMap));
+ }
+
+ List<Map<String, Object>> alertMsgHistoryList = SqlRunner.db().selectList("SELECT * FROM alert_message_history;");
+ for (Map<String, Object> msgEntity : alertMsgHistoryList) {
+ Map<String, Object> tMap = msgEntity.entrySet().stream().collect(HashMap::new, (k, v) -> k.put(StringUtils.underlineToCamel(v.getKey()), v.getValue()), HashMap::putAll);
+ this.jedisClient.jsonSet(this.getKey("alert_message_history", Tool.MapUtil.getStr(msgEntity, "id")), GSON.toJson(tMap));
+ }
+
+ List<Map<String, Object>> alertMsgSilenceList = SqlRunner.db().selectList("SELECT * FROM alert_message_silence;");
+ for (Map<String, Object> msgEntity : alertMsgSilenceList) {
+ Map<String, Object> tMap = msgEntity.entrySet().stream().collect(HashMap::new, (k, v) -> k.put(StringUtils.underlineToCamel(v.getKey()), v.getValue()), HashMap::putAll);
+ this.jedisClient.jsonSet(this.getKey("alert_message_silence", Tool.MapUtil.getStr(msgEntity, "id")), GSON.toJson(tMap));
+ }
+ sw.stop();
+ log.info("[pushTablesCache] [finshed] [Run Time: {}]", sw.toString());
+ }
+
+ /**
+ * get Key
+ *
+ * @param prefix table name
+ * @param id
+ * @return
+ */
+ private String getKey(String prefix, Object id) {
+ return StrUtil.concat(true, prefix, ":", StrUtil.toString(id));
+ }
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisManager.java b/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisManager.java
new file mode 100644
index 00000000..d7659f21
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisManager.java
@@ -0,0 +1,92 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package com.nis.modules.sys.shiro;
+
+import org.crazycake.shiro.IRedisManager;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+
+/**
+ * MyRedisManager
+ * 重写自 org.crazycake.shiro.RedisManager
+ * 重写原因:shiro-redis 最高版本仅支持 Jedis 3.3.0,重写该类解决 jedis api 调用报错问题
+ *
+ * @author shizhendong
+ * @date 2023-02-13
+ */
+public class MyRedisManager extends WorkAloneRedisManager implements IRedisManager {
+ private static final String DEFAULT_HOST = "127.0.0.1:6379";
+ private String host = "127.0.0.1:6379";
+ private int timeout = 2000;
+ private String password;
+ private int database = 0;
+ private JedisPool jedisPool;
+
+ public MyRedisManager() {
+ }
+
+ private void init() {
+ if (this.jedisPool == null) {
+ Class var1 = org.crazycake.shiro.RedisManager.class;
+ synchronized (org.crazycake.shiro.RedisManager.class) {
+ if (this.jedisPool == null) {
+ String[] hostAndPort = this.host.split(":");
+ this.jedisPool = new JedisPool(this.getJedisPoolConfig(), hostAndPort[0], Integer.parseInt(hostAndPort[1]), this.timeout, this.password, this.database);
+ }
+ }
+ }
+
+ }
+
+ @Override
+ protected Jedis getJedis() {
+ if (this.jedisPool == null) {
+ this.init();
+ }
+
+ return this.jedisPool.getResource();
+ }
+
+ public String getHost() {
+ return this.host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public int getTimeout() {
+ return this.timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public int getDatabase() {
+ return this.database;
+ }
+
+ public void setDatabase(int database) {
+ this.database = database;
+ }
+
+ public JedisPool getJedisPool() {
+ return this.jedisPool;
+ }
+
+ public void setJedisPool(JedisPool jedisPool) {
+ this.jedisPool = jedisPool;
+ }
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/shiro/WorkAloneRedisManager.java b/nz-admin/src/main/java/com/nis/modules/sys/shiro/WorkAloneRedisManager.java
new file mode 100644
index 00000000..bc833935
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/sys/shiro/WorkAloneRedisManager.java
@@ -0,0 +1,157 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package com.nis.modules.sys.shiro;
+
+import org.crazycake.shiro.IRedisManager;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPoolConfig;
+import redis.clients.jedis.params.ScanParams;
+import redis.clients.jedis.resps.ScanResult;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * WorkAloneRedisManager
+ * 重写自 org.crazycake.shiro.common.WorkAloneRedisManager
+ * 重写原因:shiro-redis 最高版本仅支持 Jedis 3.3.0,重写该类解决 jedis api 调用报错问题
+ *
+ * @author shizhendong
+ * @date 2023-02-13
+ */
+public abstract class WorkAloneRedisManager implements IRedisManager {
+ protected static final int DEFAULT_COUNT = 100;
+ private int count = 100;
+ private JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
+
+ public WorkAloneRedisManager() {
+ }
+
+ protected abstract Jedis getJedis();
+
+ @Override
+ public byte[] get(byte[] key) {
+ if (key == null) {
+ return null;
+ } else {
+ Jedis jedis = this.getJedis();
+
+ byte[] value;
+ try {
+ value = jedis.get(key);
+ } finally {
+ jedis.close();
+ }
+
+ return value;
+ }
+ }
+
+ @Override
+ public byte[] set(byte[] key, byte[] value, int expireTime) {
+ if (key == null) {
+ return null;
+ } else {
+ Jedis jedis = this.getJedis();
+
+ try {
+ jedis.set(key, value);
+ if (expireTime > 0) {
+ jedis.expire(key, (long) expireTime);
+ }
+ } finally {
+ jedis.close();
+ }
+
+ return value;
+ }
+ }
+
+ @Override
+ public void del(byte[] key) {
+ if (key != null) {
+ Jedis jedis = this.getJedis();
+
+ try {
+ jedis.del(key);
+ } finally {
+ jedis.close();
+ }
+
+ }
+ }
+
+ @Override
+ public Long dbSize(byte[] pattern) {
+ long dbSize = 0L;
+ Jedis jedis = this.getJedis();
+
+ try {
+ ScanParams params = new ScanParams();
+ params.count(this.count);
+ params.match(pattern);
+ byte[] cursor = ScanParams.SCAN_POINTER_START_BINARY;
+
+ ScanResult scanResult;
+ do {
+ scanResult = jedis.scan(cursor, params);
+ List<byte[]> results = scanResult.getResult();
+
+ for (Iterator var9 = results.iterator(); var9.hasNext(); ++dbSize) {
+ byte[] result = (byte[]) var9.next();
+ }
+
+ cursor = scanResult.getCursorAsBytes();
+ } while (scanResult.getCursor().compareTo(ScanParams.SCAN_POINTER_START) > 0);
+ } finally {
+ jedis.close();
+ }
+
+ return dbSize;
+ }
+
+ @Override
+ public Set<byte[]> keys(byte[] pattern) {
+ Set<byte[]> keys = new HashSet();
+ Jedis jedis = this.getJedis();
+
+ try {
+ ScanParams params = new ScanParams();
+ params.count(this.count);
+ params.match(pattern);
+ byte[] cursor = ScanParams.SCAN_POINTER_START_BINARY;
+
+ ScanResult scanResult;
+ do {
+ scanResult = jedis.scan(cursor, params);
+ keys.addAll(scanResult.getResult());
+ cursor = scanResult.getCursorAsBytes();
+ } while (scanResult.getCursor().compareTo(ScanParams.SCAN_POINTER_START) > 0);
+ } finally {
+ jedis.close();
+ }
+
+ return keys;
+ }
+
+ public int getCount() {
+ return this.count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+ public JedisPoolConfig getJedisPoolConfig() {
+ return this.jedisPoolConfig;
+ }
+
+ public void setJedisPoolConfig(JedisPoolConfig jedisPoolConfig) {
+ this.jedisPoolConfig = jedisPoolConfig;
+ }
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/util/RedisSearchUtil.java b/nz-admin/src/main/java/com/nis/modules/sys/util/RedisSearchUtil.java
new file mode 100644
index 00000000..1412ae89
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/sys/util/RedisSearchUtil.java
@@ -0,0 +1,433 @@
+package com.nis.modules.sys.util;
+
+import cn.hutool.log.Log;
+import com.nis.common.smartvalidate.ann.NotNull;
+import com.nis.common.utils.Tool;
+import lombok.Data;
+import org.apache.commons.lang3.time.StopWatch;
+import redis.clients.jedis.Connection;
+import redis.clients.jedis.JedisPooled;
+import redis.clients.jedis.commands.ProtocolCommand;
+import redis.clients.jedis.search.IndexDefinition;
+import redis.clients.jedis.search.IndexOptions;
+import redis.clients.jedis.search.Schema;
+import redis.clients.jedis.util.SafeEncoder;
+
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * RedisSearchUtil
+ * 创建 RedisSearch Index
+ * 用法 : RedisSearchUtil.RedisSearchUtilBuilder.builder().jedisPooled(jedisClient).build().createRedisSearchIndex();
+ *
+ * @author shizhendong
+ * @date 2023-02-03
+ */
+@Data
+public class RedisSearchUtil {
+
+ private final static Log log = Log.get();
+
+ @NotNull
+ private JedisPooled jedisClient;
+
+ /**
+ * query Existing Index List
+ * exec FT._LIST command by sendCommand() function
+ *
+ * @return
+ */
+ private List<String> queryExistingIndexList() {
+ Connection resource = this.jedisClient.getPool().getResource();
+ try {
+ ProtocolCommand protocolCommand = new ProtocolCommand() {
+ @Override
+ public byte[] getRaw() {
+ return SafeEncoder.encode("FT._LIST");
+ }
+ };
+ resource.sendCommand(protocolCommand);
+
+ List<String> respList = Tool.ListUtil.list(true);
+ Object response = resource.getOne();
+ if (response instanceof List) {
+ for (Object itemResp : ((List) response)) {
+ respList.add(new String((byte[]) itemResp));
+ }
+ } else {
+ respList = Collections.singletonList(new String((byte[]) response));
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("[queryExistingIndexList] [finshed] [exist index size: {}] [content: {}]", respList.size(), Tool.JSONUtil.toJsonStr(respList));
+ }
+ return respList;
+ } finally {
+ resource.close();
+ }
+ }
+
+ /**
+ * create Redis Search Index
+ */
+ public void createRedisSearchIndex() {
+ log.info("[createRedisSearchIndex] [begin]");
+ StopWatch sw = new StopWatch();
+ sw.start();
+
+ // dc
+ this.createDcIndex();
+
+ // asset_asset
+ this.createAssetIndex();
+
+ // asset_model
+ this.createModelIndex();
+
+ // monitor_project
+ this.createProjectIndex();
+
+ // monitor_module
+ this.createModuleIndex();
+
+ // monitor_endpoint
+ this.createEndpointIndex();
+
+ // alert_rule
+ this.createAlertRuleIndex();
+
+ // alert_message_active
+ this.createAlertMsgActiveIndex();
+
+ // alert_message_history
+ this.createAlertMsgHistoryIndex();
+
+ // alert_message_silence
+ this.createAlertMsgSilenceIndex();
+
+ sw.stop();
+ log.info("[createRedisSearchIndex] [finshed] [Run Time: {}]", sw.toString());
+ }
+
+ /**
+ * create Dc Index
+ */
+ private void createDcIndex() {
+ log.info("[createDcIndex] [begin]");
+
+ String indexName = "dcIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"dc:"})
+ );
+
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableTextField("$.name", 1).as("name")
+ .addSortableTextField("$.state", 1).as("state")
+ .addTextField("$.location", 1);
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createDcIndex] [finshed]");
+ }
+
+ /**
+ * create Asset Index
+ */
+ private void createAssetIndex() {
+ log.info("[createAssetIndex] [begin]");
+
+ String indexName = "assetIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"asset_asset:"})
+ );
+
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableTextField("$.name", 1).as("name")
+ .addSortableTextField("$.sn", 1).as("sn")
+ .addSortableTextField("$.manageIp", 1).as("manageIp")
+ .addSortableNumericField("$.stateId").as("stateId")
+ .addSortableNumericField("$.modelId").as("modelId")
+ .addSortableNumericField("$.typeId").as("typeId");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createAssetIndex] [finshed]");
+ }
+
+ /**
+ * create Model Index
+ */
+ private void createModelIndex() {
+ log.info("[createModelIndex] [begin]");
+
+ String indexName = "modelIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createModelIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"asset_model:"})
+ );
+
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableNumericField("$.brandId").as("brandId")
+ .addSortableTextField("$.name", 1).as("name");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createModelIndex] [finshed]");
+ }
+
+ /**
+ * create Project Index
+ */
+ private void createProjectIndex() {
+ log.info("[createProjectIndex] [begin]");
+
+ String indexName = "projectIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"monitor_project:"})
+ );
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableTextField("$.name", 1).as("name");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createProjectIndex] [finshed]");
+ }
+
+ /**
+ * create Module Index
+ */
+ private void createModuleIndex() {
+ log.info("[createModuleIndex] [begin]");
+
+ String indexName = "moduleIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"monitor_module:"})
+ );
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableTextField("$.name", 1).as("name");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createModuleIndex] [finshed]");
+ }
+
+ /**
+ * create Endpoint Index
+ */
+ private void createEndpointIndex() {
+ log.info("[createEndpointIndex] [begin]");
+
+ String indexName = "endpointIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"monitor_endpoint:"})
+ );
+
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableTextField("$.name", 1).as("name")
+ .addSortableNumericField("$.assetId").as("assetId")
+ .addSortableNumericField("$.moduleId").as("moduleId");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createEndpointIndex] [finshed]");
+ }
+
+ /**
+ * create AlertRule Index
+ */
+ private void createAlertRuleIndex() {
+ log.info("[createAlertRuleIndex] [begin]");
+
+ String indexName = "ruleIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"alert_rule:"})
+ );
+
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableTextField("$.name", 1).as("name")
+ .addSortableNumericField("$.severityId").as("severityId");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createAlertRuleIndex] [finshed]");
+ }
+
+
+ /**
+ * create Alert Msg Active Index
+ */
+ private void createAlertMsgActiveIndex() {
+ log.info("[createAlertMsgActiveIndex] [begin]");
+
+ String indexName = "activeAlertMsgIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"alert_message_active:"})
+ );
+
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableNumericField("$.ruleId").as("ruleId")
+ .addSortableNumericField("$.assetId").as("assetId")
+ .addSortableNumericField("$.endpointId").as("endpointId")
+ .addTextField("$.summary", 1).as("summary")
+ .addTextField("$.labels", 1).as("labels");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createAlertMsgActiveIndex] [finshed]");
+ }
+
+ /**
+ * create Alert Msg History Index
+ */
+ private void createAlertMsgHistoryIndex() {
+ log.info("[createAlertMsgHistoryIndex] [begin]");
+
+ String indexName = "historyAlertMsgIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"alert_message_history:"})
+ );
+
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableNumericField("$.ruleId").as("ruleId")
+ .addSortableNumericField("$.assetId").as("assetId")
+ .addSortableNumericField("$.endpointId").as("endpointId")
+ .addTextField("$.summary", 1).as("summary")
+ .addTextField("$.labels", 1).as("labels");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createAlertMsgHistoryIndex] [finshed]");
+ }
+
+ /**
+ * create Alert Msg Silence Index
+ */
+ private void createAlertMsgSilenceIndex() {
+ log.info("[createAlertMsgHistoryIndex] [begin]");
+
+ String indexName = "silenceAlertMsgIndex";
+
+ // query Existing Index List
+ List<String> existingIndexList = this.queryExistingIndexList();
+
+ boolean indexExist = existingIndexList.contains(indexName);
+ log.info("[createDcIndex] [index is exist: {}]", indexExist);
+ if (indexExist) this.jedisClient.ftDropIndex(indexName);
+
+ IndexOptions indexOptions = IndexOptions.defaultOptions().setDefinition(
+ new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes(new String[]{"alert_message_silence:"})
+ );
+
+ Schema schema = new Schema()
+ .addSortableNumericField("$.id").as("id")
+ .addSortableNumericField("$.ruleId").as("ruleId")
+ .addSortableNumericField("$.assetId").as("assetId")
+ .addSortableNumericField("$.endpointId").as("endpointId")
+ .addTextField("$.summary", 1).as("summary")
+ .addTextField("$.labels", 1).as("labels");
+ // create index
+ this.jedisClient.ftCreate(indexName, indexOptions, schema);
+
+ log.info("[createAlertMsgHistoryIndex] [finshed]");
+ }
+
+ public static class RedisSearchUtilBuilder {
+
+ private RedisSearchUtil redisSearchUtil = new RedisSearchUtil();
+
+ public static RedisSearchUtilBuilder builder() {
+ return new RedisSearchUtilBuilder();
+ }
+
+ public RedisSearchUtilBuilder jedisPooled(JedisPooled jedisClient) {
+ this.redisSearchUtil.setJedisClient(jedisClient);
+ return this;
+ }
+
+ public RedisSearchUtil build() {
+ return this.redisSearchUtil;
+ }
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 07971444..2fdd0ea2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<junit.version>4.12</junit.version>
- <jedis.version>2.9.0</jedis.version>
+ <jedis.version>4.3.1</jedis.version>
<druid.version>1.2.8</druid.version>
<mybatisplus.version>3.0.7.1</mybatisplus.version>
<mysql.version>8.0.27</mysql.version>