diff --git a/admin/admin-biz/pom.xml b/admin/admin-biz/pom.xml
index 1009c38f9937d4e4307797f7415b588e02dc5acf..9e5fd40f27890e1f1df9c441c277ecb713e7624b 100644
--- a/admin/admin-biz/pom.xml
+++ b/admin/admin-biz/pom.xml
@@ -40,6 +40,10 @@
org.mapstruct
mapstruct
+
+ io.netty
+ netty-all
+
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/event/dict/DictEventListener.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/event/dict/DictEventListener.java
index eb7ee96ec5d7b63faedcd5619c30116e63d8108d..48d20b444c46ebb0cdb0500abf9748511902f692 100644
--- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/event/dict/DictEventListener.java
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/event/dict/DictEventListener.java
@@ -1,18 +1,38 @@
package cn.icanci.loopstack.ddk.admin.biz.event.dict;
+import cn.icanci.loopstack.ddk.admin.biz.service.AppConfigService;
+import cn.icanci.loopstack.ddk.admin.biz.service.RegisterService;
+import cn.icanci.loopstack.ddk.common.model.config.AppConfigVO;
import cn.icanci.loopstack.lsi.event.BaseEventListener;
+import javax.annotation.Resource;
+
+import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
/**
+ * 字典键发布
+ *
* @author icanci
* @since 1.0 Created in 2023/01/09 22:41
*/
@Service
public class DictEventListener extends BaseEventListener {
+ @Resource
+ private AppConfigService appConfigService;
+ @Resource
+ private RegisterService registerService;
+
@Override
protected void event(DictEvent event) {
-
+ String uuid = event.getUuid();
+ if (StringUtils.isBlank(uuid)) {
+ return;
+ }
+ AppConfigVO appConfig = appConfigService.queryByUuid(uuid);
+ if (appConfig == null){
+ return;
+ }
}
}
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/event/resource/ResourceEventListener.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/event/resource/ResourceEventListener.java
index bca9f72ed2f4d6d987a593fbe7867831186bb9d1..ae50447b74aedcabf4ed0f63b91a2a54f7408a1e 100644
--- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/event/resource/ResourceEventListener.java
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/event/resource/ResourceEventListener.java
@@ -5,6 +5,8 @@ import cn.icanci.loopstack.lsi.event.BaseEventListener;
import org.springframework.stereotype.Service;
/**
+ * 资源刷新
+ *
* @author icanci
* @since 1.0 Created in 2023/01/09 22:41
*/
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/AppConfigService.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/AppConfigService.java
index b819ef6199e10071cab82d332d6a5a940773dc6d..8355c8404f9d27036f31abf7fb66ac0def4799cc 100644
--- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/AppConfigService.java
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/AppConfigService.java
@@ -21,4 +21,6 @@ public interface AppConfigService {
List loadSelector();
List queryByAppUuid(String appUuid);
+
+ AppConfigVO queryByUuid(String uuid);
}
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/LockService.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/LockService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1c9c6f6f194d9beeb30770f12f3c6da482e68a5
--- /dev/null
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/LockService.java
@@ -0,0 +1,24 @@
+package cn.icanci.loopstack.ddk.admin.biz.service;
+
+/**
+ * MySQL实现分布式锁
+ *
+ * Tips: 分布式锁的实现是必要的,因为客户端不知道有多少;服务端也不知道有多少
+ * 所以在进行心跳检测的时候,需要这样进行处理,否则会消耗无所谓的带宽
+ *
+ * @author icanci
+ * @since 1.0 Created in 2023/01/12 08:35
+ */
+public interface LockService {
+
+ /**
+ * 加锁
+ *
+ * @param key key
+ * @return
+ */
+ Long acquire(String key);
+
+ boolean release(String key, Long lockId);
+
+}
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/RegisterService.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/RegisterService.java
index fd3ca41951651564112135076983452901e8d525..942f308e6e197348ed2d5a1b51019d66e9a504be 100644
--- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/RegisterService.java
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/RegisterService.java
@@ -2,9 +2,12 @@ package cn.icanci.loopstack.ddk.admin.biz.service;
import cn.icanci.loopstack.ddk.admin.biz.model.RegisterModel;
import cn.icanci.loopstack.ddk.common.model.PageList;
+import cn.icanci.loopstack.ddk.common.model.config.RegisterVO;
import cn.icanci.loopstack.ddk.common.socket.load.ResourceLoadResponseDTO;
import cn.icanci.loopstack.ddk.common.socket.publish.RegisterDTO;
+import java.util.List;
+
/**
* @author icanci
* @since 1.0 Created in 2023/01/06 21:07
@@ -52,4 +55,18 @@ public interface RegisterService {
*/
ResourceLoadResponseDTO loadByAppId(String appId);
+ /**
+ * 查询所有注册信息
+ *
+ * @return 返回注册信息
+ */
+ List queryAll();
+
+ /**
+ * 更新注册信息
+ *
+ * @param register register
+ */
+ void update(RegisterVO register);
+
}
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/AppConfigServiceImpl.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/AppConfigServiceImpl.java
index 1ac21efdbe43bae29453794f663d8c2f241da987..048d387bfce77eec644ec6f5528fcb1f57fb7788 100644
--- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/AppConfigServiceImpl.java
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/AppConfigServiceImpl.java
@@ -103,4 +103,10 @@ public class AppConfigServiceImpl extends BaseService implements Ap
List apps = appConfigMapper.selectList(appConfigDO);
return appConfigMapping.dos2vos(apps);
}
+
+ @Override
+ public AppConfigVO queryByUuid(String uuid) {
+ AppConfigDO app = appConfigMapper.queryByUuid(getEnv(), uuid);
+ return appConfigMapping.do2vo(app);
+ }
}
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/LockServiceImpl.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/LockServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..13c5c277bddea6492a81d354e02a015902e85bd2
--- /dev/null
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/LockServiceImpl.java
@@ -0,0 +1,46 @@
+package cn.icanci.loopstack.ddk.admin.biz.service.impl;
+
+import cn.icanci.loopstack.ddk.admin.biz.service.LockService;
+import cn.icanci.loopstack.ddk.admin.biz.utils.EnvUtils;
+import cn.icanci.loopstack.ddk.admin.dal.mapper.entity.LockDO;
+import cn.icanci.loopstack.ddk.admin.dal.mapper.mapper.LockMapper;
+import io.netty.util.internal.ThrowableUtil;
+
+import javax.annotation.Resource;
+
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author icanci
+ * @since 1.0 Created in 2023/01/12 08:36
+ */
+@Service
+public class LockServiceImpl implements LockService {
+
+ private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LockServiceImpl.class);
+
+ @Resource
+ private LockMapper lockMapper;
+
+ @Override
+ public Long acquire(String key) {
+ try {
+ LockDO lockDO = new LockDO();
+ lockDO.setResource(key);
+ lockDO.setDesc(key);
+ lockDO.setEnv(EnvUtils.getEnv());
+ lockMapper.insert(lockDO);
+ return lockDO.getId();
+ } catch (DuplicateKeyException ex) {
+ LOGGER.warn("[LockService][acquire] lock acquire error:{}", ThrowableUtil.stackTraceToString(ex));
+ }
+ return null;
+ }
+
+ @Override
+ public boolean release(String key, Long lockId) {
+ return lockMapper.delete(lockId, key, EnvUtils.getEnv()) > 0;
+ }
+}
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/RegisterServiceImpl.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/RegisterServiceImpl.java
index 8114452e1a27cbf9a35369c37666f4e1cdaa1a4f..0e0c079d9cf2be325f618db579f5b625bddf6cb4 100644
--- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/RegisterServiceImpl.java
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/RegisterServiceImpl.java
@@ -163,6 +163,16 @@ public class RegisterServiceImpl implements RegisterService {
return response;
}
+ @Override
+ public List queryAll() {
+ return registerMapping.dos2vos(registerMapper.selectAll(EnvUtils.getEnv()));
+ }
+
+ @Override
+ public void update(RegisterVO register) {
+ registerMapper.update(registerMapping.vo2do(register));
+ }
+
private RegisterDO buildRequest(RegisterDTO register) {
RegisterDO registerDO = new RegisterDO();
registerDO.setUuid(IDHolder.generateNoBySnowFlake("REG"));
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/thread/TriggerThread.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/thread/TriggerThread.java
index 8588ec04f86d7c5f43b954e4b34d2db4e669cd08..285f4aaa51401cfb5a679922df5edc0d6cbd58e1 100644
--- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/thread/TriggerThread.java
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/thread/TriggerThread.java
@@ -1,5 +1,25 @@
package cn.icanci.loopstack.ddk.admin.biz.thread;
+import cn.hutool.core.collection.ConcurrentHashSet;
+import cn.hutool.http.Method;
+import cn.icanci.loopstack.api.client.Client;
+import cn.icanci.loopstack.api.client.RemoteException;
+import cn.icanci.loopstack.api.client.http.HttpClientImpl;
+import cn.icanci.loopstack.ddk.admin.biz.service.LockService;
+import cn.icanci.loopstack.ddk.admin.biz.service.RegisterService;
+import cn.icanci.loopstack.ddk.common.enums.BooleanEnum;
+import cn.icanci.loopstack.ddk.common.model.config.RegisterVO;
+import cn.icanci.loopstack.ddk.common.socket.SocketMessage;
+import cn.icanci.loopstack.ddk.common.socket.UriConstant;
+import cn.icanci.loopstack.ddk.common.socket.publish.PublishMethodInvokeDTO;
+import cn.icanci.loopstack.ddk.common.socket.publish.PublishTypeEnum;
+import cn.icanci.loopstack.ddk.common.socket.publish.PublishValueRefreshDTO;
+import cn.icanci.loopstack.ddk.common.socket.trigger.MethodInvokeTriggerDTO;
+import cn.icanci.loopstack.ddk.common.socket.trigger.TriggerDTO;
+import cn.icanci.loopstack.ddk.common.socket.trigger.ValueRefreshTriggerDTO;
+import cn.icanci.loopstack.ddk.common.utils.GenRegisterKeyUtils;
+import io.netty.util.internal.ThrowableUtil;
+
import java.util.Date;
import java.util.List;
import java.util.Set;
@@ -10,26 +30,14 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import cn.hutool.core.collection.ConcurrentHashSet;
-import cn.hutool.http.Method;
-import cn.icanci.loopstack.api.client.Client;
-import cn.icanci.loopstack.api.client.http.HttpClientImpl;
-import cn.icanci.loopstack.ddk.admin.biz.service.RegisterService;
-import cn.icanci.loopstack.ddk.common.model.config.RegisterVO;
-import cn.icanci.loopstack.ddk.common.socket.SocketMessage;
-import cn.icanci.loopstack.ddk.common.socket.UriConstant;
-import cn.icanci.loopstack.ddk.common.socket.publish.PublishDTO;
/**
* 触发器线程,定时向所有客户端发送心跳,维护连接
- *
+ *
* @author icanci
* @since 1.0 Created in 2022/11/22 22:11
*/
@@ -69,7 +77,7 @@ public class TriggerThread {
private static final ScheduledThreadPoolExecutor timeoutPool = new ScheduledThreadPoolExecutor(CORE_SIZE);
- private static LinkedBlockingQueue triggerQueue = new LinkedBlockingQueue<>();;
+ private static LinkedBlockingQueue triggerQueue = new LinkedBlockingQueue<>();;
private static Set urlRefreshed = new ConcurrentHashSet<>();
@@ -83,14 +91,14 @@ public class TriggerThread {
/**
* 触发刷新缓存
- *
+ *
* @param registers registers
*/
- public static void trigger(List registers) {
- if (CollectionUtils.isEmpty(registers)) {
+ public static void trigger(List triggers) {
+ if (CollectionUtils.isEmpty(triggers)) {
return;
}
- triggerQueue.addAll(registers);
+ triggerQueue.addAll(triggers);
}
/** 启动 */
@@ -109,33 +117,90 @@ public class TriggerThread {
while (triggerQueue.size() > 0) {
- final RegisterVO register = triggerQueue.poll();
+ final TriggerDTO triggerDTO = triggerQueue.poll();
+
+ PublishTypeEnum publishType = triggerDTO.getPublishType();
+
+ final List registers = triggerDTO.getRegisters();
+
+ if (publishType == null || CollectionUtils.isEmpty(registers)) {
+ continue;
+ }
+
+ for (RegisterVO register : registers) {
+ commonPool.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ trigger();
+ } catch (Throwable ex) {
+ logger.error("[TriggerThread][Run][Throwable] error message:{}", ex.getMessage());
+ }
+ }
+
+ /**
+ * 触发器
+ */
+ private void trigger() {
+ switch (publishType) {
+ case VALUE_REFRESH:
+ triggerValueRefresh();
+ break;
+ case METHOD_INVOKE:
+ triggerMethodInvoke();
+ break;
+ default:
+ // no op
+ }
+ }
+
+ /**
+ * 值刷新
+ */
+ private void triggerValueRefresh() {
+ ValueRefreshTriggerDTO valueRefreshTrigger = (ValueRefreshTriggerDTO) triggerDTO;
- commonPool.execute(new Runnable() {
- @Override
- public void run() {
- try {
String reqUrl = String.format(REFRESH_REQUEST_FORMAT, register.getClientAddress(), register.getClientPort());
- PublishDTO publishDTO = new PublishDTO();
+ PublishValueRefreshDTO valueRefresh = valueRefreshTrigger.getValueRefresh();
- publishDTO.setDomainCodes(Sets.newHashSet(register.getDomain()));
+ Client.RpcRequest rpcRequest = new Client.RpcRequest(reqUrl, valueRefresh, Maps.newHashMap(), Method.POST, 3, TimeUnit.SECONDS, 0);
- Client.RpcRequest rpcRequest = new Client.RpcRequest(reqUrl, publishDTO, Maps.newHashMap(), Method.POST, 3, TimeUnit.SECONDS, 0);
+ SocketMessage call = CLIENT.call(rpcRequest, SocketMessage.class);
+ if (call.isSuccess()) {
+ register.setIsDelete(0);
+ register.setLastUpdateTime(new Date());
+ registerService.update(register);
+ } else {
+ logger.warn("[TriggerThread][start][triggerValueRefresh] error message:{}", call.getContent());
+ }
+ }
+
+ /**
+ * 方法调用
+ */
+ private void triggerMethodInvoke() {
+
+ MethodInvokeTriggerDTO methodInvokeTrigger = (MethodInvokeTriggerDTO) triggerDTO;
+
+ String reqUrl = String.format(INVOKE_REQUEST_FORMAT, register.getClientAddress(), register.getClientPort());
+
+ PublishMethodInvokeDTO methodInvoke = methodInvokeTrigger.getMethodInvoke();
+
+ Client.RpcRequest rpcRequest = new Client.RpcRequest(reqUrl, methodInvoke, Maps.newHashMap(), Method.POST, 3, TimeUnit.SECONDS, 0);
SocketMessage call = CLIENT.call(rpcRequest, SocketMessage.class);
if (call.isSuccess()) {
register.setIsDelete(0);
register.setLastUpdateTime(new Date());
- registerService.save(register);
+ registerService.update(register);
} else {
- logger.warn("[TriggerThread][start][refresh] error message:{}", call.getContent());
+ logger.warn("[TriggerThread][start][triggerMethodInvoke] error message:{}", call.getContent());
}
- } catch (Throwable ex) {
- logger.error("[TriggerThread][Run][Throwable] error message:{}", ex.getMessage());
}
- }
- });
+
+ });
+ }
}
} catch (Throwable e) {
logger.warn("[TriggerThread][start][Throwable] error message:{}", e.getMessage());
@@ -179,10 +244,11 @@ public class TriggerThread {
public void run() {
// 加锁
String key = GenRegisterKeyUtils.generateKey(register);
- String token = lockService.acquire(key, 3000);
+
+ Long lockId = lockService.acquire(key);
try {
- if (StringUtils.isBlank(token)) {
+ if (lockId == null) {
return;
}
@@ -201,7 +267,7 @@ public class TriggerThread {
if (call.isSuccess()) {
register.setIsDelete(0);
register.setLastUpdateTime(new Date());
- registerService.save(register);
+ registerService.update(register);
} else {
logger.error("[HeartbeatRunner][run] error message:{}", call.getContent());
}
@@ -212,7 +278,7 @@ public class TriggerThread {
// no op
logger.error("[HeartbeatRunner][Throwable] error message:{}", ThrowableUtil.stackTraceToString(ex));
} finally {
- lockService.release(key, token);
+ lockService.release(key, lockId);
}
}
}
@@ -232,13 +298,18 @@ public class TriggerThread {
}
}
+ /**
+ * 尝试remove
+ *
+ * @param register register
+ */
private void tryRemove(RegisterVO register) {
try {
boolean isDelay = (System.currentTimeMillis() - register.getLastUpdateTime().getTime()) / 1000 > REGISTER_TIME_OUT;
if (isDelay) {
- register.setIsDelete(1);
+ register.setIsDelete(BooleanEnum.YES.getCode());
register.setLastUpdateTime(new Date());
- registerService.save(register);
+ registerService.update(register);
}
} catch (Throwable ex) {
// no op
diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/thread/TriggerThreadStart.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/thread/TriggerThreadStart.java
index 4b5afc97197f866a905dc8cade4c78d5659763e8..ea66b986e69ac9f589d4a7b10dfc5cd5d37bba02 100644
--- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/thread/TriggerThreadStart.java
+++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/thread/TriggerThreadStart.java
@@ -1,14 +1,16 @@
package cn.icanci.loopstack.ddk.admin.biz.thread;
+import cn.icanci.loopstack.ddk.admin.biz.service.LockService;
+import cn.icanci.loopstack.ddk.admin.biz.service.RegisterService;
+
import javax.annotation.Resource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
-import cn.icanci.loopstack.rec.admin.biz.service.LockService;
-import cn.icanci.loopstack.rec.admin.biz.service.RegisterService;
-
/**
+ * 触发器启动器
+ *
* @author icanci
* @since 1.0 Created in 2022/11/26 17:34
*/
diff --git a/admin/admin-dal/config/gen.properties b/admin/admin-dal/config/gen.properties
index f0e5ac26868693fc4f087bad95ff9bb79724f4a7..869ace726aaadb96eee6dfde01b400869c023547 100644
--- a/admin/admin-dal/config/gen.properties
+++ b/admin/admin-dal/config/gen.properties
@@ -13,7 +13,7 @@ removePreTable=ddk_
# \u6570\u636E\u6A21\u5757\uFF0C\u591A\u6570\u636E\u6E90\u53EF\u914D\u7F6E\u4E0D\u540C\u7684dbModule\uFF0C\u4F1A\u81EA\u52A8\u5206\u5305
dbModule=
# \u9700\u8981\u652F\u6301\u9006\u5411\u7684\u6570\u636E\u8868\uFF0C\u5168\u90E8\u5219\u586B\u5199*; \u975E\u5168\u90E8\u5219\u4F7F\u7528;\u53F7\u9694\u79BB\u6BD4\u5982: a;b;c;d;
-include=ddk_log;
+include=ddk_lock;
# \u9700\u8981\u751F\u6210\u7684\u5305\u540D\u5B57
packageName=cn.icanci.loopstack.ddk.admin.dal.mapper
# \u751F\u6210\u6587\u4EF6\u7684\u4F5C\u8005
diff --git a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/entity/LockDO.java b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/entity/LockDO.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c35034cd8669ea4c0bdecbbd3c8de679de0bfef
--- /dev/null
+++ b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/entity/LockDO.java
@@ -0,0 +1,70 @@
+package cn.icanci.loopstack.ddk.admin.dal.mapper.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import java.math.BigDecimal;
+
+/**
+* DdkLock
+* ⚠️ 修改之后请勿使用生成器再次生成,否则会覆盖修改
+*
+* @author icanci
+* @since 1.0 Created in 2023/01/12 23:27
+*/
+public class LockDO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * id
+ */
+ private Long id;
+
+ /**
+ * resource 锁定的资源
+ */
+ private String resource;
+
+ /**
+ * desc 描述
+ */
+ private String desc;
+
+ /**
+ * env 环境
+ */
+ private String env;
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ public String getResource() {
+ return this.resource;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ public String getDesc() {
+ return this.desc;
+ }
+
+ public void setEnv(String env) {
+ this.env = env;
+ }
+
+ public String getEnv() {
+ return this.env;
+ }
+}
\ No newline at end of file
diff --git a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/AppConfigMapper.java b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/AppConfigMapper.java
index b0c4269e111d308fb5c79639d4af3510676709ba..b0b716a6aa16d91db1a03397846e7abef035caa9 100644
--- a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/AppConfigMapper.java
+++ b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/AppConfigMapper.java
@@ -62,4 +62,6 @@ public interface AppConfigMapper {
* @return AppConfigDO
*/
AppConfigDO queryByAppConfigName(@Param("appConfigName") String appConfigName, @Param("env") String env);
+
+ AppConfigDO queryByUuid(@Param("env") String env, @Param("uuid") String uuid);
}
diff --git a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/LockMapper.java b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/LockMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..61be5ebdf3d8593d247f2d8dd90ebe45ace59ba0
--- /dev/null
+++ b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/LockMapper.java
@@ -0,0 +1,32 @@
+package cn.icanci.loopstack.ddk.admin.dal.mapper.mapper;
+
+import cn.icanci.loopstack.ddk.admin.dal.mapper.entity.LockDO;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+* DdkLockMapper
+* ⚠️ 修改之后请勿使用生成器再次生成,否则会覆盖修改
+*
+* @author icanci
+* @since 1.0 Created in 2023/01/12 23:27
+*/
+@Mapper
+public interface LockMapper {
+
+ /**
+ * 新增一条记录
+ *
+ * @param ddkLock 新增数据
+ **/
+ int insert(LockDO ddkLock);
+
+ /**
+ * 根据id删除一条记录
+ *
+ * @param key 主键
+ * @param resource 资源
+ **/
+ int delete(@Param("key") Object key, @Param("resource") String resource, @Param("env") String env);
+}
diff --git a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/RegisterMapper.java b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/RegisterMapper.java
index 5b126dd6a0ee6b95527ad91128596848042f445f..753f6401b715c4659d6628ac43ebb71832926b7d 100644
--- a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/RegisterMapper.java
+++ b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/RegisterMapper.java
@@ -60,4 +60,12 @@ public interface RegisterMapper {
* @param ddkRegister 查询条件
**/
int total(RegisterDO ddkRegister);
+
+ /**
+ * 查询所有注册信息
+ *
+ * @param env 环境
+ * @return 返回所有注册信息
+ */
+ List selectAll(@Param("env") String env);
}
diff --git a/admin/admin-dal/src/main/resources/DataSource.md b/admin/admin-dal/src/main/resources/DataSource.md
index 73f9834a58f8aec43e356cfa33741a98367cc830..adceb12666d1e95a0ae2b493cf782157be5bc662 100644
--- a/admin/admin-dal/src/main/resources/DataSource.md
+++ b/admin/admin-dal/src/main/resources/DataSource.md
@@ -5,16 +5,13 @@
| 作者 | icanci |
| 数据库名 | ddk |
-## ddk_log表结构说明
+## ddk_lock表结构说明
| 代码字段名 | 字段名 | 数据类型(代码) | 数据类型 | 长度 | NullAble | 注释 |
| :--------- | ------ | ---------------- | -------- | ---- | -------------- | ---- |
-| id | id | Long | bigint | 19 | NO | 主键 |
-| module | module | String | varchar | 40 | NO | 模块 |
-| targetId | target_id | String | varchar | 40 | NO | 对象编号,取uuid |
-| operatorType | operator_type | String | varchar | 40 | NO | 操作类型 |
-| content | content | String | text | 65535 | NO | 操作数据 |
-| createTime | create_time | Date | datetime | | NO | 创建时间 |
-| env | env | String | varchar | 16 | NO | 操作环境 |
+| id | id | Long | bigint | 19 | NO | |
+| resource | resource | String | varchar | 80 | NO | 锁定的资源 |
+| desc | desc | String | varchar | 40 | NO | 描述 |
+| env | env | String | varchar | 16 | NO | 环境 |
diff --git a/admin/admin-dal/src/main/resources/mybatis/mapper/AppConfigMapper.xml b/admin/admin-dal/src/main/resources/mybatis/mapper/AppConfigMapper.xml
index fbba21d0d96bd83fe589601508a758340d1f9cb9..da67e4b33c333a5493374d5763bd9d72959818d7 100644
--- a/admin/admin-dal/src/main/resources/mybatis/mapper/AppConfigMapper.xml
+++ b/admin/admin-dal/src/main/resources/mybatis/mapper/AppConfigMapper.xml
@@ -257,4 +257,11 @@
FROM ddk_app_config
WHERE `app_config_name` = #{appConfigName} and `env` = #{env}
+
+
\ No newline at end of file
diff --git a/admin/admin-dal/src/main/resources/mybatis/mapper/LockMapper.xml b/admin/admin-dal/src/main/resources/mybatis/mapper/LockMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e0d170d6cd79c873f06480f937a28228ed2e5e2e
--- /dev/null
+++ b/admin/admin-dal/src/main/resources/mybatis/mapper/LockMapper.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `id`
+ ,
+ `resource`,
+ `desc`,
+ `env`
+
+
+
+
+ INSERT INTO ddk_lock
+
+
+ `id`,
+
+
+ `resource`,
+
+
+ `desc`,
+
+
+ `env`
+
+
+
+
+ #{id},
+
+
+ #{resource},
+
+
+ #{desc},
+
+
+ #{env}
+
+
+
+
+
+
+ DELETE
+ FROM ddk_lock
+ WHERE `id` = #{key}
+ and `env` = #{env}
+ and `resource` = #{resource}
+
+
+
\ No newline at end of file
diff --git a/admin/admin-dal/src/main/resources/mybatis/mapper/RegisterMapper.xml b/admin/admin-dal/src/main/resources/mybatis/mapper/RegisterMapper.xml
index 7e80a026a5c17e5738e9a77f73b96207ce2fc960..2b62058b4ca83804792d476d27bd3a7c3f1363fd 100644
--- a/admin/admin-dal/src/main/resources/mybatis/mapper/RegisterMapper.xml
+++ b/admin/admin-dal/src/main/resources/mybatis/mapper/RegisterMapper.xml
@@ -250,4 +250,10 @@
limit 1
+
\ No newline at end of file
diff --git a/admin/admin-web/src/main/java/cn/icanci/loopstack/ddk/web/controller/register/RegisterController.java b/admin/admin-web/src/main/java/cn/icanci/loopstack/ddk/web/controller/register/RegisterController.java
index 3945066b876e0108c6df8f0b8f289916408db64e..8b101de1f629016b631eda4af59639803f75ce2e 100644
--- a/admin/admin-web/src/main/java/cn/icanci/loopstack/ddk/web/controller/register/RegisterController.java
+++ b/admin/admin-web/src/main/java/cn/icanci/loopstack/ddk/web/controller/register/RegisterController.java
@@ -8,7 +8,6 @@ import cn.icanci.loopstack.ddk.common.socket.load.ResourceLoadRequestDTO;
import cn.icanci.loopstack.ddk.common.socket.load.ResourceLoadResponseDTO;
import cn.icanci.loopstack.ddk.common.socket.publish.RegisterDTO;
import cn.icanci.loopstack.ddk.web.form.PublishDictForm;
-import cn.icanci.loopstack.ddk.web.form.PublishResourceForm;
import cn.icanci.loopstack.ddk.web.form.RegisterQueryForm;
import cn.icanci.loopstack.ddk.web.mapping.RegisterWebMapping;
@@ -45,12 +44,6 @@ public class RegisterController {
return R.builderOk().build();
}
- @PostMapping("publishResource")
- public R publishResource(@RequestBody PublishResourceForm publish) {
- registerService.publishResource(publish.getResource(), publish.getValue());
- return R.builderOk().build();
- }
-
/**
* 注册
*
diff --git a/admin/admin-web/src/main/java/cn/icanci/loopstack/ddk/web/webapi/DdkWebApiFacade.java b/admin/admin-web/src/main/java/cn/icanci/loopstack/ddk/web/webapi/DdkWebApiFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..c707090387ea98ceed848dcb5fa5dc5472ac4d98
--- /dev/null
+++ b/admin/admin-web/src/main/java/cn/icanci/loopstack/ddk/web/webapi/DdkWebApiFacade.java
@@ -0,0 +1,33 @@
+package cn.icanci.loopstack.ddk.web.webapi;
+
+import cn.icanci.loopstack.ddk.admin.biz.service.RegisterService;
+import cn.icanci.loopstack.ddk.common.result.R;
+import cn.icanci.loopstack.ddk.web.form.PublishResourceForm;
+
+import javax.annotation.Resource;
+
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 对外部系统提供服务
+ * - 对notice的通知功能
+ *
+ * @author icanci
+ * @since 1.0 Created in 2023/01/12 23:36
+ */
+@RestController
+@RequestMapping("/ddk/webapi")
+public class DdkWebApiFacade {
+ @Resource
+ private RegisterService registerService;
+
+ @PostMapping("publish")
+ public R publishResource(@RequestBody PublishResourceForm publish) {
+ registerService.publishResource(publish.getResource(), publish.getValue());
+ return R.builderOk().build();
+ }
+
+}
diff --git a/client/src/main/java/cn/icanci/loopstack/ddk/client/repository/DdkRepositoryHolder.java b/client/src/main/java/cn/icanci/loopstack/ddk/client/repository/DdkRepositoryHolder.java
index 0f6e3cae14cd13eba41ce73dd15f34af711be8dc..368161dd2d38ba462b006b1b67b8d535100fcf92 100644
--- a/client/src/main/java/cn/icanci/loopstack/ddk/client/repository/DdkRepositoryHolder.java
+++ b/client/src/main/java/cn/icanci/loopstack/ddk/client/repository/DdkRepositoryHolder.java
@@ -2,7 +2,7 @@ package cn.icanci.loopstack.ddk.client.repository;
import cn.icanci.loopstack.ddk.common.client.Client;
import cn.icanci.loopstack.ddk.common.client.http.HttpClientImpl;
-import cn.icanci.loopstack.ddk.common.socket.publish.PublishDTO;
+import cn.icanci.loopstack.ddk.common.socket.publish.PublishValueRefreshDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,7 +46,7 @@ public class DdkRepositoryHolder implements InitializingBean {
*
* @param publish publish
*/
- public synchronized void refresh(PublishDTO publish) {
+ public synchronized void refresh(PublishValueRefreshDTO publish) {
}
/**
@@ -54,7 +54,7 @@ public class DdkRepositoryHolder implements InitializingBean {
*
* @param publish publish
*/
- public synchronized void invoke(PublishDTO publish) {
+ public synchronized void invoke(PublishValueRefreshDTO publish) {
}
}
diff --git a/client/src/main/java/cn/icanci/loopstack/ddk/client/server/NamedNettyServerHandler.java b/client/src/main/java/cn/icanci/loopstack/ddk/client/server/NamedNettyServerHandler.java
index 36ce9d18815a47dd2623d2c3156bbcda302308df..b152201bc871ef4fe50eb882feb304fbee576da6 100644
--- a/client/src/main/java/cn/icanci/loopstack/ddk/client/server/NamedNettyServerHandler.java
+++ b/client/src/main/java/cn/icanci/loopstack/ddk/client/server/NamedNettyServerHandler.java
@@ -2,7 +2,7 @@ package cn.icanci.loopstack.ddk.client.server;
import cn.hutool.json.JSONUtil;
import cn.icanci.loopstack.ddk.client.repository.DdkRepositoryHolder;
-import cn.icanci.loopstack.ddk.common.socket.publish.PublishDTO;
+import cn.icanci.loopstack.ddk.common.socket.publish.PublishValueRefreshDTO;
import cn.icanci.loopstack.ddk.common.socket.SocketMessage;
import cn.icanci.loopstack.ddk.common.socket.UriConstant;
import io.netty.buffer.Unpooled;
@@ -87,11 +87,11 @@ public class NamedNettyServerHandler extends SimpleChannelInboundHandler registers;
+
+ public PublishTypeEnum getPublishType() {
+ return publishType;
+ }
+
+ public void setPublishType(PublishTypeEnum publishType) {
+ this.publishType = publishType;
+ }
+
+ public List getRegisters() {
+ return registers;
+ }
+
+ public void setRegisters(List registers) {
+ this.registers = registers;
+ }
+}
diff --git a/common/src/main/java/cn/icanci/loopstack/ddk/common/socket/trigger/ValueRefreshTriggerDTO.java b/common/src/main/java/cn/icanci/loopstack/ddk/common/socket/trigger/ValueRefreshTriggerDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..4094bd51483e8f5b6b84d32c2ec80e5371faa710
--- /dev/null
+++ b/common/src/main/java/cn/icanci/loopstack/ddk/common/socket/trigger/ValueRefreshTriggerDTO.java
@@ -0,0 +1,44 @@
+package cn.icanci.loopstack.ddk.common.socket.trigger;
+
+import cn.icanci.loopstack.ddk.common.socket.publish.PublishValueRefreshDTO;
+
+import java.util.Objects;
+import java.util.StringJoiner;
+
+/**
+ * App 配置
+ * @author icanci
+ * @since 1.0 Created in 2023/01/12 08:42
+ */
+public class ValueRefreshTriggerDTO extends TriggerDTO {
+
+ private PublishValueRefreshDTO valueRefresh;
+
+ public PublishValueRefreshDTO getValueRefresh() {
+ return valueRefresh;
+ }
+
+ public void setValueRefresh(PublishValueRefreshDTO valueRefresh) {
+ this.valueRefresh = valueRefresh;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ ValueRefreshTriggerDTO that = (ValueRefreshTriggerDTO) o;
+ return Objects.equals(valueRefresh, that.valueRefresh);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(valueRefresh);
+ }
+
+ @Override
+ public String toString() {
+ return new StringJoiner(",").add("valueRefresh=" + valueRefresh).toString();
+ }
+}
diff --git a/common/src/main/java/cn/icanci/loopstack/ddk/common/utils/GenRegisterKeyUtils.java b/common/src/main/java/cn/icanci/loopstack/ddk/common/utils/GenRegisterKeyUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..f48c2c1340ae088a0d08b3450a45df78f8c6b59b
--- /dev/null
+++ b/common/src/main/java/cn/icanci/loopstack/ddk/common/utils/GenRegisterKeyUtils.java
@@ -0,0 +1,16 @@
+package cn.icanci.loopstack.ddk.common.utils;
+
+import cn.icanci.loopstack.ddk.common.model.config.RegisterVO;
+
+/**
+ * @author icanci
+ * @since 1.0 Created in 2022/11/26 17:38
+ */
+public class GenRegisterKeyUtils {
+
+ private static final String FORMAT = "%s#%s#%s#%s";
+
+ public static String generateKey(RegisterVO register) {
+ return String.format(FORMAT, register.getAppId(), register.getClientAddress(), register.getClientPort(), register.getEnv());
+ }
+}