From d283176b2bc670e96c388233828aeed50d92a0f4 Mon Sep 17 00:00:00 2001 From: Zhujx Date: Wed, 6 Aug 2025 10:40:32 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat=EF=BC=9Apom=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 9 +++++---- xservice-message-starter/pom.xml | 2 +- xservice-schedule-starter/pom.xml | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index f0b3cda..5d1c4bc 100644 --- a/pom.xml +++ b/pom.xml @@ -105,10 +105,11 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.boot - spring-boot-starter-actuator - + + + + + commons-io commons-io diff --git a/xservice-message-starter/pom.xml b/xservice-message-starter/pom.xml index 91631df..4273555 100644 --- a/xservice-message-starter/pom.xml +++ b/xservice-message-starter/pom.xml @@ -22,7 +22,7 @@ com.xiang xservice-common - 1.0 + 1.2 diff --git a/xservice-schedule-starter/pom.xml b/xservice-schedule-starter/pom.xml index 55cf4e8..b5fb3ee 100644 --- a/xservice-schedule-starter/pom.xml +++ b/xservice-schedule-starter/pom.xml @@ -22,7 +22,7 @@ com.xiang xservice-common - 1.0 + 1.2 From 78df3b2062bc8fcf3500e7dacd5addd1ff79325a Mon Sep 17 00:00:00 2001 From: Zhujx Date: Fri, 8 Aug 2025 15:32:30 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat=EF=BC=9A=E9=92=89=E9=92=89=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E4=BC=98=E5=8C=962.0=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xservice-message-starter/pom.xml | 2 +- .../dingTalk/service/DingTalkService.java | 44 +++++++------------ 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/xservice-message-starter/pom.xml b/xservice-message-starter/pom.xml index 4273555..7ec39ba 100644 --- a/xservice-message-starter/pom.xml +++ b/xservice-message-starter/pom.xml @@ -10,7 +10,7 @@ xservice-message-starter - 1.1 + 2.0 17 diff --git a/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/service/DingTalkService.java b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/service/DingTalkService.java index 132dcb7..a24b972 100644 --- a/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/service/DingTalkService.java +++ b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/service/DingTalkService.java @@ -12,6 +12,7 @@ import com.dingtalk.api.response.OapiGettokenResponse; import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response; import com.dingtalk.api.response.OapiRobotSendResponse; import com.xiang.xservice.basic.xservice.dingTalk.enums.DingTalkUrlEnum; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -46,53 +47,40 @@ public class DingTalkService { private static final String CLIENT_SECRET = "wyapsH6y8P1K_wuTPKGKwG0mquj1uth9Dxn6HcRpta3sh8Syukl0C8nOmR1PeBzs"; - private static final String GRANT_TYPE = "client_credentials"; - - private static final String USER_ID = "450841600726084717"; - - private static final String MSG_TYPE = "text"; + private static final String MSG_TYPE_TEXT = "text"; /** - * 自定义机器人token - */ - private static final String CUSTOM_ROBOT_TOKEN = "4709b708d961846e0aee523c5abc3b67e8fa424ee292501d85efd4e504f15a8b"; - - /** - * 密钥 - */ - private static final String SECRET = "SEC768ed578c0fb31a9aec84b1c1db4f195f5aca203985bbb9d549e23e41c8874d1"; - - /** - * 发送机器人消息 - * @param msg + * 发送机器人消息到指定的群 + * @param robotSecret 机器人密钥 + * @param robotToken 机器人token + * @param userIds @对象 + * @param msg 消息内容 * @return * @throws Exception */ - public String sendRobotMessage(String msg) throws Exception { + public String sendRobotMessage(String robotSecret, String robotToken, List userIds, String msg) throws Exception { Long timestamp = System.currentTimeMillis(); - String stringToSign = timestamp + "\n" + SECRET; + String stringToSign = timestamp + "\n" + robotSecret; Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(new SecretKeySpec(SECRET.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + mac.init(new SecretKeySpec(robotSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8)); String sign = URLEncoder.encode(Base64.getEncoder().encodeToString(signData), StandardCharsets.UTF_8); //sign字段和timestamp字段必须拼接到请求URL上,否则会出现 310000 的错误信息 DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/robot/send?sign=" + sign + "×tamp=" + timestamp); OapiRobotSendRequest req = new OapiRobotSendRequest(); - /** - * 发送文本消息 - */ + //定义文本内容 OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text(); text.setContent(msg); //定义 @ 对象 OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); - at.setAtUserIds(List.of(USER_ID)); + at.setAtUserIds(userIds); //设置消息类型 - req.setMsgtype("text"); + req.setMsgtype(MSG_TYPE_TEXT); req.setText(text); req.setAt(at); - OapiRobotSendResponse rsp = client.execute(req, CUSTOM_ROBOT_TOKEN); + OapiRobotSendResponse rsp = client.execute(req, robotToken); return rsp.getBody(); } @@ -110,7 +98,7 @@ public class DingTalkService { OapiChatSendRequest.Text text = new OapiChatSendRequest.Text(); text.setContent(message); msg.setText(text); - msg.setMsgtype("text"); + msg.setMsgtype(MSG_TYPE_TEXT); req.setMsg(msg); OapiChatSendResponse rsp = client.execute(req, token); log.info("[DingTalk] send chat message, req:{}, token:{}, response:{}", JSONObject.toJSONString(req), token, JSONObject.toJSONString(rsp)); @@ -133,7 +121,7 @@ public class DingTalkService { req.setUseridList(userId); req.setToAllUser(false); OapiMessageCorpconversationAsyncsendV2Request.Msg obj1 = new OapiMessageCorpconversationAsyncsendV2Request.Msg(); - obj1.setMsgtype(MSG_TYPE); + obj1.setMsgtype(MSG_TYPE_TEXT); OapiMessageCorpconversationAsyncsendV2Request.Text obj2 = new OapiMessageCorpconversationAsyncsendV2Request.Text(); obj2.setContent(message); obj1.setText(obj2); From e5ef8bc3fdb4c901ab961f813d01a5e73a486b08 Mon Sep 17 00:00:00 2001 From: xiang Date: Sat, 23 Aug 2025 14:34:31 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:ssh=20=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 ++++ xservice-common/pom.xml | 2 +- .../xservice/basic/utils/SSHManager.java | 39 +++++++++++++++++++ xservice-mysql-starter/pom.xml | 10 ++++- .../mysql/config/DynamicDataSourceConfig.java | 2 +- .../mysql/entity/DataSourceProperty.java | 9 ++++- .../service/DynamicRoutingDataSource.java | 28 ++++++++++++- 7 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/utils/SSHManager.java diff --git a/pom.xml b/pom.xml index 5d1c4bc..62d0925 100644 --- a/pom.xml +++ b/pom.xml @@ -155,6 +155,13 @@ com.fasterxml.jackson.core jackson-databind + + + + com.jcraft + jsch + 0.1.55 + diff --git a/xservice-common/pom.xml b/xservice-common/pom.xml index 51b7a8a..b4676bd 100644 --- a/xservice-common/pom.xml +++ b/xservice-common/pom.xml @@ -8,7 +8,7 @@ xservice-basic 1.1 - 1.2 + 1.3 xservice-common diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/utils/SSHManager.java b/xservice-common/src/main/java/com/xiang/xservice/basic/utils/SSHManager.java new file mode 100644 index 0000000..b1bac91 --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/utils/SSHManager.java @@ -0,0 +1,39 @@ +package com.xiang.xservice.basic.utils; + +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Session; +import java.util.concurrent.ConcurrentHashMap; + +public class SSHManager { + private static final ConcurrentHashMap sessionMap = new ConcurrentHashMap<>(); + + public static void createTunnel(String key, String sshHost, int sshPort, + String sshUser, String sshPassword, + int localPort, String remoteHost, int remotePort) throws Exception { + if (sessionMap.containsKey(key) && sessionMap.get(key).isConnected()) { + return; // 已存在 + } + JSch jsch = new JSch(); + Session session = jsch.getSession(sshUser, sshHost, sshPort); + session.setPassword(sshPassword); + + java.util.Properties config = new java.util.Properties(); + config.put("StrictHostKeyChecking", "no"); + session.setConfig(config); + + session.connect(); + session.setPortForwardingL(localPort, remoteHost, remotePort); + + sessionMap.put(key, session); + System.out.println("SSH Tunnel for [" + key + "] established."); + } + + public static void closeTunnel(String key) { + Session session = sessionMap.get(key); + if (session != null && session.isConnected()) { + session.disconnect(); + sessionMap.remove(key); + System.out.println("SSH Tunnel for [" + key + "] closed."); + } + } +} diff --git a/xservice-mysql-starter/pom.xml b/xservice-mysql-starter/pom.xml index 0eebc0a..ca4504a 100644 --- a/xservice-mysql-starter/pom.xml +++ b/xservice-mysql-starter/pom.xml @@ -10,11 +10,19 @@ xservice-mysql-starter - 1.1 + 2.0-SNAPSHOT 17 17 UTF-8 + + + com.xiang + xservice-common + 1.3 + + + \ No newline at end of file diff --git a/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/config/DynamicDataSourceConfig.java b/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/config/DynamicDataSourceConfig.java index 1a99752..0f27f78 100644 --- a/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/config/DynamicDataSourceConfig.java +++ b/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/config/DynamicDataSourceConfig.java @@ -29,7 +29,7 @@ public class DynamicDataSourceConfig { targetDataSources.put(key, builder.build()); }); - DynamicRoutingDataSource routing = new DynamicRoutingDataSource(); + DynamicRoutingDataSource routing = new DynamicRoutingDataSource(props); routing.setDefaultTargetDataSource(targetDataSources.get(props.getPrimary())); routing.setTargetDataSources(targetDataSources); return routing; diff --git a/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/entity/DataSourceProperty.java b/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/entity/DataSourceProperty.java index 1eb20bd..36d95f3 100644 --- a/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/entity/DataSourceProperty.java +++ b/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/entity/DataSourceProperty.java @@ -12,5 +12,12 @@ public class DataSourceProperty { private String username; private String password; private String driverClassName = "com.mysql.cj.jdbc.Driver"; - + private Boolean sshConnect; + private String sshHost; + private Integer sshPort = 22; + private String sshUser; + private String sshPassword; + private Integer localPort; // 本地转发端口 + private String remoteHost; // 远端数据库 host + private Integer remotePort; // 远端数据库 port } diff --git a/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/service/DynamicRoutingDataSource.java b/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/service/DynamicRoutingDataSource.java index f058af8..ddff2ae 100644 --- a/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/service/DynamicRoutingDataSource.java +++ b/xservice-mysql-starter/src/main/java/com/xiang/xservice/mysql/service/DynamicRoutingDataSource.java @@ -1,11 +1,37 @@ package com.xiang.xservice.mysql.service; +import com.xiang.xservice.basic.utils.SSHManager; import com.xiang.xservice.mysql.config.DynamicDataSourceContext; +import com.xiang.xservice.mysql.entity.DataSourceProperty; +import lombok.RequiredArgsConstructor; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; +import com.xiang.xservice.mysql.entity.DynamicDataSourceProperties; +@RequiredArgsConstructor public class DynamicRoutingDataSource extends AbstractRoutingDataSource { + + private final DynamicDataSourceProperties dynamicDataSourceProperties; + @Override protected Object determineCurrentLookupKey() { - return DynamicDataSourceContext.get(); + String key = DynamicDataSourceContext.get(); + DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(key); + if (Boolean.TRUE.equals(dataSourceProperty.getSshConnect())) { + try { + SSHManager.createTunnel( + key, + dataSourceProperty.getSshHost(), + dataSourceProperty.getSshPort(), + dataSourceProperty.getSshUser(), + dataSourceProperty.getSshPassword(), + dataSourceProperty.getLocalPort(), + dataSourceProperty.getRemoteHost(), + dataSourceProperty.getRemotePort() + ); + } catch (Exception e) { + throw new RuntimeException("Failed to establish SSH tunnel for " + key, e); + } + } + return key; } } From 7204df97ffecc271963ea4d36c42b9702cd5aa6b Mon Sep 17 00:00:00 2001 From: xiang Date: Sat, 23 Aug 2025 14:37:11 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:pom=20=E7=89=88=E6=9C=AC=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xservice-mysql-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xservice-mysql-starter/pom.xml b/xservice-mysql-starter/pom.xml index ca4504a..9cdeee6 100644 --- a/xservice-mysql-starter/pom.xml +++ b/xservice-mysql-starter/pom.xml @@ -10,7 +10,7 @@ xservice-mysql-starter - 2.0-SNAPSHOT + 2.0 17 17