需求
在大屏上显示出每个项目的构建情况,如果构建失败,大屏上项目颜色变红的同时要给最新构建这个项目的用户发送邮件,提醒他构建失败了。
准备知识
大屏上显示的项目构建情况,其实是通过Jenkins api 获取的,想要看Jenkins 每个页面的api内容,直接在网页地址后面加上api/json
就行了,如下图所示。对Jenkins api 不理解的可以去看:Jenkins API简单使用
效果
编码过程
pom.xml
添加好 jenkins api 、邮件、模板引擎的依赖
<!-- jenkins api -->
<dependency>
<groupId>com.cdancy</groupId>
<artifactId>jenkins-rest</artifactId>
<version>0.0.30</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
<!--freemarker-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 微软exchange 邮箱 -->
<dependency>
<groupId>com.surevine</groupId>
<artifactId>ews-java-api</artifactId>
<version>2.15</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.8</version>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>ldapbp</artifactId>
<version>1.0</version>
</dependency>
发送邮件定时任务RemindTask
@Slf4j
@Component("remindTask")
public class RemindTask {
@Autowired
private CiDashBoardMapper ciDashBoardMapper;
@Autowired
private JenkinsConfig jenkinsConfig;
@Autowired
private CiDashBoardService ciDashBoardService;
public void sendRemindEmail() {
log.info("sendRemindEmail start! ");
List<CiDashBoardVO> ciDashBoardVOList = ciDashBoardMapper.getCiDashBoardData();
ciDashBoardVOList.forEach(ciDashBoardVO -> {
String color=getColor(ciDashBoardVO.getColors());
//如果是红色就给对应责任人发邮件
if(Objects.equals( color, "red")){
List<remindTaskVO> remindTaskVOList= ciDashBoardMapper.getDashBoardJobUrl(ciDashBoardVO.getProjectName(),color);
if (CollUtil.isEmpty(remindTaskVOList)) {
log.info("remindTaskVOList列表是空的");
}
remindTaskVOList.forEach(remindTaskVO -> {
//创建jenkins连接,根据api一层层的找对应构建责任人
JobsApi jobApi = jenkinsConfig.connection().jobsApi();
String folderName=remindTaskVO.getFolderName();
String jobName=remindTaskVO.getJobName();
JobInfo jobInfo = jobApi.jobInfo(folderName, jobName);
int number=jobInfo.lastBuild().number();
BuildInfo buildInfo = jobApi.buildInfo(folderName, jobName,number);
// String userId=buildInfo.actions().get(1).causes().get(0).userId();
String userName=buildInfo.actions().get(1).causes().get(0).userName();
//找到后发邮件
try {
Boolean sendRemindEmail=ciDashBoardService.sendRemindEmail(folderName,jobName,userName);
if(sendRemindEmail){
log.info("给构建失败责任人{}发送提醒邮件成功",userName);
}else{
log.info("给构建失败责任人{}发送提醒邮件失败,请检查",userName);
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
});
}else{
log.info("项目没有报红");
}
});
log.info("sendRemindEmail end! ");
}
/**
* @Description: 计算构建的颜色
*/
private String getColor(String colors) {
if (StrUtil.isBlank(colors)) {
return JenkinsColorStatusEnum.UNKNOWN.getInfo();
}
if (colors.contains(JenkinsColorStatusEnum.RED.getInfo())) {
return JenkinsColorStatusEnum.RED.getInfo();
}
if (colors.contains(JenkinsColorStatusEnum.YELLOW.getInfo())) {
return JenkinsColorStatusEnum.YELLOW.getInfo();
}
return JenkinsColorStatusEnum.BLUE.getInfo();
}
}
remindTaskVO
/**
* @Description: 提醒任务vo
*/
@Data
public class remindTaskVO {
private String folderName;
private String jobName;
}
CiDashBoardMapper :获取展示在大屏上的所有项目以及对应job的projectName和urlName
public interface CiDashBoardMapper {
List<CiDashBoardVO> getCiDashBoardData();
/**
* @Description: 获取展示在大屏上的所有项目对应job的projectName和urlName
*/
List<remindTaskVO> getDashBoardJobUrl(String projectName, String color);
}
CiDashBoardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iov.rcs.ci.mapper.CiDashBoardMapper">
<resultMap id="ciDashBoardMap" type="com.iov.rcs.ci.domain.CiDashBoardVO">
<result property="projectName" column="project_name"/>
<result property="colors" column="colors"/>
</resultMap>
<resultMap id="remindTaskMap" type="com.iov.rcs.ci.domain.remindTaskVO">
<result property="folderName" column="folder_name"/>
<result property="jobName" column="job_name"/>
</resultMap>
<select id="getCiDashBoardData" resultMap="ciDashBoardMap">
SELECT project_name,
GROUP_CONCAT(color Separator ',') as colors
FROM (
SELECT b.*,
j.color
FROM jenkins_project_binding AS b
LEFT JOIN jenkins_data AS j ON j.jenkins_id = b.jenkins_id
and j.color not in ('aborted', 'notbuilt', 'disabled', 'blue_anime')
) as a
group by project_name
</select>
<select id="getDashBoardJobUrl" resultMap="remindTaskMap">
SELECT folder_name,job_name
FROM (
SELECT j.*,
b.project_name
FROM jenkins_project_binding AS b
LEFT JOIN jenkins_data AS j ON j.jenkins_id = b.jenkins_id
and j.color not in ('aborted', 'notbuilt', 'disabled', 'blue_anime')
) as a
where project_name= #{projectName}
and color=#{color}
</select>
</mapper>
CiDashBoardService
public interface CiDashBoardService {
AjaxResult getCiDashBoardData();
/**
* @Description: 发送邮件提醒功能
*/
public boolean sendRemindEmail(String folderName,String jobName,String username) throws ParseException;
}
CiDashBoardServiceImpl
@Slf4j
@Service
@AllArgsConstructor
public class CiDashBoardServiceImpl implements CiDashBoardService {
@Autowired
private CiDashBoardMapper ciDashBoardMapper;
private final Configuration configuration;
/**
* @Description: 动态获取构建大屏的数据
*/
@Override
public AjaxResult getCiDashBoardData() {
List<CiDashBoardVO> ciDashBoardVOList = ciDashBoardMapper.getCiDashBoardData();
if (CollUtil.isEmpty(ciDashBoardVOList)) {
return AjaxResult.error("ciDashBoardVOList列表是空的");
}
JSONArray jsonArray = new JSONArray();
ciDashBoardVOList.forEach(ciDashBoardVO -> {
JSONObject jsonObject = new JSONObject();
jsonObject.set("projectName", ciDashBoardVO.getProjectName());
jsonObject.set("color", getColor(ciDashBoardVO.getColors()));
jsonArray.put(jsonObject);
});
return AjaxResult.success(jsonArray);
}
/**
* @Description: 发送邮件提醒功能
*/
@Override
public boolean sendRemindEmail(String folderName,String jobName,String username) throws ParseException {
DesvMailUtil mailUtil = new DesvMailUtil(“这里写公司规定发邮件的邮箱”);
HashMap<String, Object> params = new HashMap<>();
Template template;
try {
template = configuration.getTemplate("SendRemindTask.ftl");
} catch (IOException e) {
log.error("configuration.getTemplate error:{}", e.getMessage());
return Boolean.FALSE;
}
initRemindEmailData(params, folderName,jobName,username);
try {
mailUtil.sendEmailByFreemarker(params, template);
} catch (Exception e) {
log.error("sendMail error:{}", e.getMessage());
return Boolean.FALSE;
}
return Boolean.TRUE;
}
/**
* @Description: 初始化邮件内容
*/
private void initRemindEmailData(HashMap<String, Object> params,String folderName,String jobName,String username) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
//params.put("to", appCpsp.getResponseEmail());
params.put("to", "");
params.put("title", "项目构建失败提醒");
params.put("ResponseName",username);
params.put("projectName",folderName);
params.put("jobName",jobName);
//当前日期
params.put("today", DateUtil.format(new Date(), DatePattern.CHINESE_DATE_PATTERN));
}
/**
* @Description: 计算构建的颜色
*/
private String getColor(String colors) {
if (StrUtil.isBlank(colors)) {
return JenkinsColorStatusEnum.UNKNOWN.getInfo();
}
if (colors.contains(JenkinsColorStatusEnum.RED.getInfo())) {
return JenkinsColorStatusEnum.RED.getInfo();
}
if (colors.contains(JenkinsColorStatusEnum.YELLOW.getInfo())) {
return JenkinsColorStatusEnum.YELLOW.getInfo();
}
return JenkinsColorStatusEnum.BLUE.getInfo();
}
}
DesvMailUtil 发送邮件工具
/**
* @Description: 发送邮件工具
*/
@Data
@Slf4j
public class DesvMailUtil {
private String username;
private String password;
private String domain;
private String uri;
public DesvMailUtil(String username, String password, String domain, String uri) {
this.username = username;
this.password = password;
this.domain = domain;
this.uri = uri;
}
public void sendEmailByFreemarker(Map<String, Object> params, Template template) throws Exception {
// 新建server版本
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
// 用户名,密码,域名
ExchangeCredentials credentials = new WebCredentials(username, password, domain);
service.setCredentials(credentials);
service.setUrl(new URI(uri));
String s = FreeMarkerTemplateUtils.processTemplateIntoString(template, params);
EmailMessage msg = new EmailMessage(service);
msg.setSubject(MapUtil.getStr(params, "title"));
msg.setBody(MessageBody.getMessageBodyFromText(s));
// 收件人
msg.getToRecipients().add(MapUtil.getStr(params, "to"));
// 发送
msg.send();
}
}
SendRemindTask.ftl
<!DOCTYPE html>
<html>
<head>
<meta http-equiv = Content-Type content="text/html; charset=utf-8"/>
</head>
<body>
<p class="lines title">
<span>Dear ${ResponseName}:</span>
</p>
<p class="lines">
<span> 您的 ${projectName}项目中的job: ${jobName}构建失败,请及时处理。</span>
</p>
<p class="lines">
<span>如您有任何疑问,可联系: </span>
</p>
<div class="lines">
<p>
<span>${today}</span>
</p>
</div>
</body>
<style>
.lines {
text-align: left;
font-size: 14px;
margin-bottom: 20px;
}
.lines.title {
font-size: 18px;
}
</style>
</html>