package com.sobey.cmop.mvc.service.redmine; import java.util.Date; import java.util.List; import java.util.Map; import org.hibernate.bytecode.buildtime.spi.ExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.google.common.collect.Maps; import com.sobey.cmop.mvc.comm.BaseSevcie; import com.sobey.cmop.mvc.constant.RedmineConstant; import com.taskadapter.redmineapi.RedmineException; import com.taskadapter.redmineapi.RedmineManager; import com.taskadapter.redmineapi.RedmineManager.INCLUDE; import com.taskadapter.redmineapi.bean.Issue; import com.taskadapter.redmineapi.bean.User; /** * 通过redmine-java-api操作Redmine 相关的管理类. * * @author liukai */ @Service @Transactional(readOnly = true) public class RedmineService extends BaseSevcie { private static Logger logger = LoggerFactory.getLogger(RedmineService.class); /** * 重置次数 */ private static int COUNT = 0; /** * 解析redmine.properties 获得redmine api 配置信息 */ public static String HOST = CONFIG_LOADER.getProperty("redmineHost"); /** * redmine第一接收人 */ public static Integer FIRST_REDMINE_ASSIGNEE = RedmineConstant.Assignee.艾磊.toInteger(); /** * redmine第一接收人的RedmineManager */ public static RedmineManager FIRST_REDMINE_ASSIGNEE_REDMINEMANAGER = new RedmineManager(HOST, RedmineConstant.REDMINE_ASSIGNEE_KEY_MAP.get(FIRST_REDMINE_ASSIGNEE)); /** * MDN接收人 */ public static Integer MDN_REDMINE_ASSIGNEE = RedmineConstant.Assignee.李乾星.toInteger(); /** * MDN接收人的RedmineManager */ public static RedmineManager MDN_REDMINE_ASSIGNEE_REDMINEMANAGER = new RedmineManager(HOST, RedmineConstant.REDMINE_ASSIGNEE_KEY_MAP.get(MDN_REDMINE_ASSIGNEE)); /** * 云生产接收人 */ public static Integer CP_REDMINE_ASSIGNEE = RedmineConstant.Assignee.苏颖.toInteger(); /** * 云生产接收人的RedmineManager */ public static RedmineManager CP_REDMINE_ASSIGNEE_REDMINEMANAGER = new RedmineManager(HOST, RedmineConstant.REDMINE_ASSIGNEE_KEY_MAP.get(CP_REDMINE_ASSIGNEE)); /** * 监控接收人 */ public static Integer MONITOR_REDMINE_ASSIGNEE = RedmineConstant.Assignee.陆俊.toInteger(); /** * 监控接收人的RedmineManager */ public static RedmineManager MONITOR_REDMINE_ASSIGNEE_REDMINEMANAGER = new RedmineManager(HOST, RedmineConstant.REDMINE_ASSIGNEE_KEY_MAP.get(MONITOR_REDMINE_ASSIGNEE)); /** * 根据issueId 获得redmine中的Issue对象. * * @param issueId * @return */ public static Issue getIssue(Integer issueId) { // 此处若更新了Issue,则保存时将起作用. Issue issue = getIssueById(issueId, FIRST_REDMINE_ASSIGNEE_REDMINEMANAGER); return issue; } /** * 创建Issue * * @param mgr * @throws RedmineException */ @Transactional(readOnly = false) public static boolean createIssue(Issue issue, String projectId, RedmineManager mgr) { boolean result = false; try { Integer default_doneratio = 0; issue.setStatusName("新建"); // 默认:新建 issue.setDoneRatio(default_doneratio); issue.setAssignee(mgr.getCurrentUser()); // 默认:登录者 issue.setAuthor(mgr.getCurrentUser()); // 默认:登录者 issue.setStartDate(new Date()); issue.setDueDate(new Date()); issue.setCreatedOn(new Date()); mgr.createIssue(projectId, issue); result = true; logger.info("--->创建Issue成功!"); } catch (RedmineException e) { e.printStackTrace(); COUNT++; // 重新连接 repeatConnect(mgr); if (COUNT <= 3) { result = createIssue(issue, projectId, mgr); } else { logger.info("--->创建Issue失败!"); throw new ExecutionException("创建Issue失败!"); } } COUNT = 0; // 重置次数 return result; } /** * 更新Issue. * * 如果没有更新成功,用递归算法重复4次 * * @param issue * @param mgr * @return 成功返回true,失败返回false. */ @Transactional(readOnly = false) public static boolean changeIssue(Issue issue, RedmineManager mgr) { boolean result = false; try { logger.info("issueId--->" + issue.getId()); issue.setUpdatedOn(new Date()); mgr.update(issue); // 已关闭的更新会出错 result = true; logger.info("--->更新Issue成功!"); } catch (RedmineException e) { e.printStackTrace(); COUNT++; repeatConnect(mgr); if (COUNT <= 3) { result = changeIssue(issue, mgr); } else { logger.info("--->更新Issue失败!"); } } COUNT = 0; // 重置次数 return result; } /** * 根据issueId获取Issue * * 如果没有值,用递归算法重复4次, * * @param issueId * @param mgr * @return */ public static Issue getIssueById(int issueId, RedmineManager mgr) { Issue issue = null; try { issue = mgr.getIssueById(issueId, INCLUDE.journals); logger.info("--->获取Issue成功!"); } catch (RedmineException e) { e.printStackTrace(); COUNT++; repeatConnect(mgr); if (COUNT <= 3) { issue = getIssueById(issueId, mgr); } else { logger.info("--->获取Issue失败!"); } } COUNT = 0; // 重置次数 return issue; } /** * 根据subject获得Issue. * * 如果没有值,用递归算法重复4次,如果最后还是获取不了值,则返回Null. * * @param subject * @param mgr * @return */ @SuppressWarnings("unchecked") public static Issue getIssueBySubject(String subject, RedmineManager mgr) { List<Issue> list = null; try { Map<String, String> paraMap = Maps.newHashMap(); paraMap.put("subject", subject); list = mgr.getIssues(paraMap); } catch (RedmineException e) { e.printStackTrace(); COUNT++; repeatConnect(mgr); if (COUNT <= 3) { list = (List<Issue>) getIssueBySubject(subject, mgr); } else { logger.info("--->获取Issue失败!"); } } COUNT = 0; // 重置次数 if (list != null && list.size() > 0) { logger.info("--->获取Issue成功!"); return list.get(0); } return null; } /** * 解决连接Redmine失败的情况,每隔2秒钟重连3次 * * @return */ private static boolean repeatConnect(RedmineManager mgr) { logger.info("--->RedmineException..." + COUNT); try { // 延时2秒 Thread.sleep(2000); User user = mgr.getCurrentUser(); logger.info("--->重新连接Redmine成功!" + user.getFirstName()); return true; } catch (Exception e) { e.printStackTrace(); logger.info("--->重新连接Redmine失败!"); } return false; } }