Skip to content

Commit

Permalink
Merge pull request #232 from yaming116/add-wechat
Browse files Browse the repository at this point in the history
feat: 添加微信机器人和补充单测
  • Loading branch information
ZhouYixun authored Jul 10, 2022
2 parents 76db789 + eedad20 commit 4ac564e
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 27 deletions.
6 changes: 6 additions & 0 deletions sonic-server-controller/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class Projects implements Serializable, TypeConverter<Projects, ProjectsD
private String projectName;

@TableField
@Column(value = "robot_secret", isNull = false, comment = "机器人秘钥")
@Column(value = "robot_secret", isNull = true, comment = "机器人秘钥")
private String robotSecret;

@TableField
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class ProjectsDTO implements Serializable, TypeConverter<ProjectsDTO, Pro
@ApiModelProperty(value = "机器人token", required = true, example = "http://dingTalk.com?token=*****")
String robotToken;

@ApiModelProperty(value = "机器人加签密钥", required = true, example = "qwe***")
@ApiModelProperty(value = "机器人加签密钥", required = false, example = "qwe***")
String robotSecret;

@ApiModelProperty(value = "项目图标", required = true, example = "http://img.jpg")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ public void sendDayReport() {
break;
}
}
if (projects.getRobotType() != 0 && projects.getRobotToken().length() > 0 && projects.getRobotSecret().length() > 0) {
if (projects.getRobotType() != 0 && projects.getRobotToken().length() > 0 ) {
robotMsgTool.sendDayReportMessage(projects.getRobotToken(), projects.getRobotSecret(), projects.getId()
, projects.getProjectName(), sf.format(yesterday), sf.format(today), suc, warn, fail, projects.getRobotType());
}
Expand Down Expand Up @@ -266,7 +266,7 @@ public void sendWeekReport() {
break;
}
}
if (projects.getRobotType() != 0 && projects.getRobotToken().length() > 0 && projects.getRobotSecret().length() > 0) {
if (projects.getRobotType() != 0 && projects.getRobotToken().length() > 0 ) {
robotMsgTool.sendWeekReportMessage(projects.getRobotToken(), projects.getRobotSecret(), projects.getId()
, projects.getProjectName(), sf.format(lastWeek), sf.format(today), suc, warn, fail, count, projects.getRobotType());
}
Expand Down Expand Up @@ -330,7 +330,7 @@ public void setStatus(Results results) {
results.setEndTime(new Date());
save(results);
Projects projects = projectsService.findById(results.getProjectId());
if (projects != null && projects.getRobotType() != 0 && projects.getRobotToken().length() > 0 && projects.getRobotSecret().length() > 0) {
if (projects != null && projects.getRobotType() != 0 && projects.getRobotToken().length() > 0) {
robotMsgTool.sendResultFinishReport(projects.getRobotToken(), projects.getRobotSecret(),
results.getSuiteName(), sucCount, warnCount, failCount, projects.getId(), results.getId(), projects.getRobotType());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.crypto.Mac;
Expand Down Expand Up @@ -72,34 +73,43 @@ private void signAndSend(String token, String secret, int type, JSONObject jsonO
try {
switch (type) {
case RobotType.DingTalk: {
Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64Utils.encode(signData)), "UTF-8");
String path = "";
if (!StringUtils.isEmpty(secret)) {
Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64Utils.encode(signData)), "UTF-8");
path = "&timestamp=" + timestamp + "&sign=" + sign;
}

ResponseEntity<JSONObject> responseEntity =
restTemplate.postForEntity(token + "&timestamp=" + timestamp + "&sign=" + sign
restTemplate.postForEntity(token + path
, jsonObject, JSONObject.class);
logger.info("robot result: " + responseEntity.getBody());
break;
}
case RobotType.WeChat: {
ResponseEntity<JSONObject> responseEntity =
restTemplate.postForEntity(token + "?key=" + secret
, jsonObject, JSONObject.class);
restTemplate.postForEntity(token , jsonObject, JSONObject.class);
logger.info("robot result: " + responseEntity.getBody());
break;
}

break;
case RobotType.FeiShu: {
String timestamp = String.valueOf(System.currentTimeMillis()).substring(0, 10);
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] signData = mac.doFinal(new byte[]{});
String sign = new String(Base64Utils.encode(signData));
jsonObject.put("timestamp", timestamp);
jsonObject.put("sign", sign);

if (!StringUtils.isEmpty(secret)) {
String timestamp = String.valueOf(System.currentTimeMillis()).substring(0, 10);
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] signData = mac.doFinal(new byte[]{});
String sign = new String(Base64Utils.encode(signData));
jsonObject.put("timestamp", timestamp);
jsonObject.put("sign", sign);
}

ResponseEntity<JSONObject> responseEntity =
restTemplate.postForEntity(token, jsonObject, JSONObject.class);
logger.info("robot result: " + responseEntity.getBody());
Expand Down Expand Up @@ -148,6 +158,17 @@ public void sendResultFinishReport(String token, String secret, String suiteName
jsonObject.put("msgtype", "link");
jsonObject.put("link", link);
}
if (type == RobotType.WeChat) {
jsonObject.put("msgtype", "markdown");
JSONObject markdown = new JSONObject();
markdown.put("content", "**测试套件: " + suiteName + " 运行完毕!**\n" +
"通过数:" + pass + " \n" +
"异常数:" + warn + " \n" +
"失败数:" + fail + "\n" +
"测试报告:[点击查看](" + clientHost + "/Home/" + projectId + "/ResultDetail/" + resultId + ")");
jsonObject.put("markdown", markdown);

}
if (type == RobotType.FeiShu) {
jsonObject.put("msg_type", "interactive");
JSONObject card = new JSONObject();
Expand Down Expand Up @@ -252,6 +273,33 @@ public void sendDayReportMessage(String token, String secret, int projectId, Str
jsonObject.put("msgtype", "markdown");
jsonObject.put("markdown", markdown);
}
if (type == RobotType.WeChat) {
String warnColorString;
if (warnCount == 0) {
warnColorString = "<font color=\"info\">" + warnCount + "</font>";
} else {
warnColorString = "<font color=\"warning\">" + warnCount + "</font>";
}
String failColorString;
if (failCount == 0) {
failColorString = "<font color=\"info\">" + failCount + "</font>";
} else {
failColorString = "<font color=\"warning\">" + failCount + "</font>";
}
int total = passCount + warnCount + failCount;
jsonObject.put("msgtype", "markdown");
JSONObject markdown = new JSONObject();
markdown.put("content", "### Sonic云真机测试平台日报 \n" +
"> ###### 项目:" + projectName + " \n" +
"> ###### 时间:" + yesterday + " ~ " + today + " \n" +
"> ###### 通过数:<font color=\"info\">" + passCount + "</font> \n" +
"> ###### 异常数:" + warnColorString + " \n" +
"> ###### 失败数:" + failColorString + " \n" +
"> ###### 测试通过率:" + (total > 0 ?
new BigDecimal((float) passCount / total).setScale(2, RoundingMode.HALF_UP).doubleValue() : 0) + "% \n" +
"> ###### 详细统计:[点击查看](" + clientHost + "/Home/" + projectId + ")");
jsonObject.put("markdown", markdown);
}
if (type == RobotType.FeiShu) {
jsonObject.put("msg_type", "interactive");
JSONObject card = new JSONObject();
Expand Down Expand Up @@ -283,18 +331,34 @@ public void sendErrorDevice(String token, String secret, int type, int errorType
if (type == RobotType.DingTalk) {
JSONObject markdown = new JSONObject();
if (errorType == 1) {
markdown.put("text", "### 设备高温预警 \n" +
markdown.put("text", "### Sonic设备高温预警 \n" +
"> ###### 设备序列号:" + udId + " \n" +
"> ###### 电池温度:<font color=#F56C6C>" + (tem / 10) + " ℃</font>");
} else {
markdown.put("text", "### 设备高温超时,已关机! \n" +
markdown.put("text", "### Sonic设备高温超时,已关机! \n" +
"> ###### 设备序列号:" + udId + " \n" +
"> ###### 电池温度:<font color=#F56C6C>" + (tem / 10) + " ℃</font>");
}
markdown.put("title", "设备温度异常通知");
jsonObject.put("msgtype", "markdown");
jsonObject.put("markdown", markdown);
}

if (type == RobotType.WeChat) {
JSONObject markdown = new JSONObject();
if (errorType == 1) {
markdown.put("content", "### Sonic设备高温预警 \n" +
"> ###### 设备序列号:" + udId + " \n" +
"> ###### 电池温度:<font color=\"warning\">" + (tem / 10) + " ℃</font>");
} else {
markdown.put("content", "### Sonic设备高温超时,已关机! \n" +
"> ###### 设备序列号:" + udId + " \n" +
"> ###### 电池温度:<font color=\"warning\">" + (tem / 10) + " ℃</font>");
}
jsonObject.put("msgtype", "markdown");
jsonObject.put("markdown", markdown);
}

if (type == RobotType.FeiShu) {
jsonObject.put("msg_type", "interactive");
JSONObject card = new JSONObject();
Expand All @@ -304,19 +368,21 @@ public void sendErrorDevice(String token, String secret, int type, int errorType
JSONObject element = new JSONObject();
element.put("tag", "markdown");
List<JSONObject> elementList = new ArrayList<>();

if (errorType == 1) {
element.put("content", "**设备高温预警**\n" +
element.put("content", "**Sonic设备高温预警** \n" +
"设备序列号:" + udId + " \n" +
"电池温度:" + (tem / 10) + " ℃");
} else {
element.put("content", "**设备高温超时,已关机!**\n" +
element.put("content", "**Sonic设备高温超时,已关机!** \n" +
"设备序列号:" + udId + " \n" +
"电池温度:" + (tem / 10) + " ℃");
}
elementList.add(element);
card.put("elements", elementList);
jsonObject.put("card", card);
}

signAndSend(token, secret, type, jsonObject);
}

Expand Down Expand Up @@ -353,6 +419,35 @@ public void sendWeekReportMessage(String token, String secret, int projectId, St
jsonObject.put("msgtype", "markdown");
jsonObject.put("markdown", markdown);
}
if (type == RobotType.WeChat) {
String warnColorString;
if (warnCount == 0) {
warnColorString = "<font color=\"info\">" + warnCount + "</font>";
} else {
warnColorString = "<font color=\"warning\">" + warnCount + "</font>";
}
String failColorString;
if (failCount == 0) {
failColorString = "<font color=\"info\">" + failCount + "</font>";
} else {
failColorString = "<font color=\"warning\">" + failCount + "</font>";
}
int total = passCount + warnCount + failCount;
jsonObject.put("msgtype", "markdown");
JSONObject markdown = new JSONObject();
markdown.put("content", "### Sonic云真机测试平台周报 \n" +
"> ###### 项目:" + projectName + " \n" +
"> ###### 时间:" + yesterday + " ~ " + today + " \n" +
"> ###### 共测试:" + count + " 次\n" +
"> ###### 通过数:<font color=\"info\">" + passCount + "</font> \n" +
"> ###### 异常数:" + warnColorString + " \n" +
"> ###### 失败数:" + failColorString + " \n" +
"> ###### 测试通过率:" + (total > 0 ?
new BigDecimal((float) passCount / total).setScale(2, RoundingMode.HALF_UP).doubleValue() : 0) + "% \n" +
"> ###### 详细统计:[点击查看](" + clientHost + "/Home/" + projectId + ")");
jsonObject.put("markdown", markdown);
}

if (type == RobotType.FeiShu) {
jsonObject.put("msg_type", "interactive");
JSONObject card = new JSONObject();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.cloud.sonic.controller;

import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

@SpringBootTest(classes = ControllerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
// 单元测试读取dev配置文件
@ActiveProfiles
public class BaseUnit {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.cloud.sonic.controller.tools;

import org.cloud.sonic.controller.BaseUnit;
import org.cloud.sonic.controller.models.interfaces.RobotType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

public class RobotTest extends BaseUnit {

@Autowired
RobotMsgTool robotMsgTool;

private String wechatToken = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx";

private String feishuToken = "https://open.feishu.cn/open-apis/bot/v2/hook/xxx";
@Test
public void sendDayReportMessage() {
robotMsgTool.sendDayReportMessage(wechatToken, "" ,1, "2",
"1", "2" , 1,2,3, RobotType.WeChat);
}

@Test
public void sendDayReportMessage2() {
robotMsgTool.sendDayReportMessage(wechatToken, "" ,1, "2",
"1", "2" , 1,0,0, RobotType.WeChat);
}

@Test
public void testSendErrorDevice1() {
robotMsgTool.sendErrorDevice(wechatToken, "", RobotType.WeChat, 1, 80,"111");
}


@Test
public void testSendErrorDevice2() {
robotMsgTool.sendErrorDevice(wechatToken, "", RobotType.WeChat, 2, 80,"111");
}

@Test
public void testSendErrorDeviceFeishu() {
robotMsgTool.sendErrorDevice(feishuToken, "", RobotType.FeiShu, 1, 80,"测试");
}

@Test
public void testSendErrorDeviceFeishu2() {
robotMsgTool.sendErrorDevice(feishuToken, "", RobotType.FeiShu, 2, 80,"测试");
}


@Test
public void sendWeekReportMessage() {
robotMsgTool.sendWeekReportMessage(wechatToken, "" ,1, "2",
"1", "2" , 1,0,0,100, RobotType.WeChat);
}

@Test
public void sendResultFinishReport() {
robotMsgTool.sendResultFinishReport(wechatToken, "","111", 1,1,1,1,
1,RobotType.WeChat);
}
}

0 comments on commit 4ac564e

Please sign in to comment.