package com.sobey.cmop.mvc.web.operate; import java.util.Date; import java.util.List; import java.util.Map; import javax.servlet.ServletRequest; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import com.sobey.cmop.mvc.comm.BaseController; import com.sobey.cmop.mvc.constant.IpPoolConstant; import com.sobey.cmop.mvc.constant.RedmineConstant; import com.sobey.cmop.mvc.entity.ComputeItem; import com.sobey.cmop.mvc.entity.IpPool; import com.sobey.cmop.mvc.entity.NetworkEipItem; import com.sobey.cmop.mvc.entity.NetworkElbItem; import com.sobey.cmop.mvc.entity.RedmineIssue; import com.sobey.cmop.mvc.entity.StorageItem; import com.sobey.cmop.mvc.service.redmine.RedmineService; import com.sobey.framework.utils.Servlets; import com.taskadapter.redmineapi.bean.Issue; import com.taskadapter.redmineapi.bean.Project; import com.taskadapter.redmineapi.bean.User; /** * OperateController负责工单的管理 * * @author liukai * */ @Controller @RequestMapping(value = "/operate") public class OperateController extends BaseController { private static Logger logger = LoggerFactory.getLogger(OperateController.class); private static final String REDIRECT_SUCCESS_URL = "redirect:/operate/"; /** * 显示指派给自己的工单operate list */ @RequestMapping(value = { "list", "" }) public String assigned(@RequestParam(value = "page", defaultValue = "1") int pageNumber, @RequestParam(value = "page.size", defaultValue = PAGE_SIZE) int pageSize, Model model, ServletRequest request) { Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, REQUEST_PREFIX); model.addAttribute("page", comm.operateService.getAssignedIssuePageable(searchParams, pageNumber, pageSize)); // 将搜索条件编码成字符串,分页的URL model.addAttribute("searchParams", Servlets.encodeParameterStringWithPrefix(searchParams, REQUEST_PREFIX)); // 跳转到reported model.addAttribute("toReported", "toReported"); return "operate/operateList"; } /** * 显示所有的工单operate list */ @RequestMapping(value = "reported") public String reported(@RequestParam(value = "page", defaultValue = "1") int pageNumber, @RequestParam(value = "page.size", defaultValue = PAGE_SIZE) int pageSize, Model model, ServletRequest request) { Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, REQUEST_PREFIX); model.addAttribute("page", comm.operateService.getReportedIssuePageable(searchParams, pageNumber, pageSize)); // 将搜索条件编码成字符串,分页的URL model.addAttribute("searchParams", Servlets.encodeParameterStringWithPrefix(searchParams, REQUEST_PREFIX)); return "operate/operateList"; } /** * 跳转到更新页面,并替换掉redmine文本中的ip.(100%流程后无法替换.) * * @param id * @param model * @param redirectAttributes * @return */ @RequestMapping(value = "update/{id}") public String update(@PathVariable("id") Integer id, Model model, RedirectAttributes redirectAttributes) { logger.info("--->工单处理...issueId=" + id); Issue issue = RedmineService.getIssue(id); model.addAttribute("issue", issue); model.addAttribute("user", comm.accountService.getCurrentUser()); RedmineIssue redmineIssue = comm.operateService.findByIssueId(id); model.addAttribute("redmineIssue", redmineIssue); if (issue != null) { String desc = issue.getDescription(); desc = desc.replaceAll("\\*服务申请的详细信息\\*", ""); desc = desc.replaceAll("\\*服务变更的详细信息\\*", ""); if (desc.indexOf("# 基本信息") >= 0) { desc = desc.replaceAll("# 基本信息", "<br># 基本信息"); } else { desc = "<br>" + desc; } // 更新写入Redmine的IP List list = comm.operateService.getComputeStorageElbEip(redmineIssue); List<ComputeItem> computeList = (List) list.get(0); List<StorageItem> storageList = (List) list.get(1); List<NetworkElbItem> networkElbList = (List) list.get(2); List<NetworkEipItem> networkEipList = (List) list.get(3); // oldIP替换分配的IP. logger.info("--->更新写入Redmine的IP(计算资源)..." + computeList.size()); desc = this.replaceComputeTextFromOldIpToInnerIp(desc, computeList); logger.info("--->更新写入Redmine的IP(EIP)..." + networkEipList.size()); desc = this.replaceEIPTextFromOldIpToInnerIp(desc, networkEipList); logger.info("--->更新写入Redmine的IP(ELB)..." + networkElbList.size()); desc = this.replaceELBTextFromOldIpToInnerIp(desc, networkElbList); model.addAttribute("description", desc); if (!computeList.isEmpty()) { model.addAttribute("computeList", computeList); int poolType = 0; logger.info("--->has compute: " + computeList.size() + ",poolType=" + poolType); model.addAttribute("server", comm.operateService.findHostMapByServerType(2)); // 物理机 model.addAttribute("hostServer", comm.operateService.findHostMapByServerType(1)); model.addAttribute("osStorage", comm.oneCmdbUtilService.getOsStorageFromOnecmdb()); } if (!storageList.isEmpty()) { model.addAttribute("storageList", storageList); model.addAttribute("fimasController", comm.oneCmdbUtilService.getFimasHardWareFromOnecmdb()); model.addAttribute("netappController", comm.oneCmdbUtilService.getNfsHardWareFromOnecmdb()); } if (!networkEipList.isEmpty()) { model.addAttribute("eipList", networkEipList); logger.info("--->has eip: " + networkEipList.size()); List<IpPool> ipPools = comm.ipPoolService.getIpPoolByPoolTypeAndStatus( IpPoolConstant.PoolType.互联网IP池.toInteger(), IpPoolConstant.IpStatus.未使用.toInteger()); for (NetworkEipItem networkEipItem : networkEipList) { IpPool ipPool = comm.ipPoolService.findIpPoolByIpAddress(networkEipItem.getIpAddress()); ipPools.add(ipPool); } model.addAttribute("internetIpPool", ipPools); } if (!networkElbList.isEmpty()) { model.addAttribute("elbList", networkElbList); // 暂不处理ELB的虚拟IP池 } model.addAttribute("location", comm.operateService.getLocationFromOnecmdb()); model.addAttribute("vlan", comm.operateService.getVlanFromOnecmdb()); return "operate/operateForm"; } else { // 查询Redmine中的Issue信息失败 redirectAttributes.addFlashAttribute("message", "查询工单信息失败,请稍后重试!"); return "redirect:/operate"; } } /** * 将redmine文本中Compute的oldIP替换成已经分配的IP. * * @param desc * @param computeList * @return */ private String replaceComputeTextFromOldIpToInnerIp(String desc, List<ComputeItem> computeList) { int size = computeList.size(); String[] searchList = new String[size]; String[] replacementList = new String[size]; for (int i = 0; i < computeList.size(); i++) { searchList[i] = computeList.get(i).getIdentifier() + "(" + computeList.get(i).getRemark() + " - " + computeList.get(i).getOldIp() + ")"; replacementList[i] = computeList.get(i).getIdentifier() + "(" + computeList.get(i).getRemark() + " - " + computeList.get(i).getInnerIp() + ")"; } return StringUtils.replaceEach(desc, searchList, replacementList); } /** * 将redmine文本中EIP的oldIP替换成已经分配的IP. * * @param desc * @param networkEipList * @return */ private String replaceEIPTextFromOldIpToInnerIp(String desc, List<NetworkEipItem> networkEipList) { int size = networkEipList.size(); String[] searchList = new String[size]; String[] replacementList = new String[size]; for (int i = 0; i < networkEipList.size(); i++) { searchList[i] = networkEipList.get(i).getIdentifier() + "(" + networkEipList.get(i).getOldIp() + ")"; replacementList[i] = networkEipList.get(i).getIdentifier() + "(" + networkEipList.get(i).getIpAddress() + ")"; } return StringUtils.replaceEach(desc, searchList, replacementList); } /** * 将redmine文本中ELB的oldIP替换成已经分配的IP. * * @param desc * @param networkElbList * @return */ private String replaceELBTextFromOldIpToInnerIp(String desc, List<NetworkElbItem> networkElbList) { int size = networkElbList.size(); String[] searchList = new String[size]; String[] replacementList = new String[size]; for (int i = 0; i < networkElbList.size(); i++) { searchList[i] = networkElbList.get(i).getIdentifier() + "(" + networkElbList.get(i).getOldIp() + ")"; replacementList[i] = networkElbList.get(i).getIdentifier() + "(" + networkElbList.get(i).getVirtualIp() + ")"; } return StringUtils.replaceEach(desc, searchList, replacementList); } /** * 更新工单 * * @param id * @param authorId * @param priority * @param assignTo * @param projectId * @param doneRatio * @param estimatedHours * @param dueDate * @param note * @param redirectAttributes * @return */ @RequestMapping(value = "update") public String updateForm(@RequestParam(value = "issueId") int issueId, @RequestParam("projectId") int projectId, @RequestParam("note") String note, @RequestParam("priority") int priority, @RequestParam("authorId") int authorId, @RequestParam("assignTo") int assignTo, @RequestParam("dueDate") String dueDate, @RequestParam("estimatedHours") float estimatedHours, @RequestParam("doneRatio") int doneRatio, @RequestParam("computes") String computes, @RequestParam("storages") String storages, @RequestParam("hostNames") String hostNames, @RequestParam("serverAlias") String serverAlias, @RequestParam("osStorageAlias") String osStorageAlias, @RequestParam("controllerAlias") String controllerAlias, @RequestParam("volumes") String volumes, @RequestParam("innerIps") String innerIps, @RequestParam(value = "eipIds", required = false) String[] eipIds, @RequestParam(value = "eipAddress", required = false) String[] eipAddress, @RequestParam("locationAlias") String locationAlias, @RequestParam("elbIds") String elbIds, @RequestParam("virtualIps") String virtualIps, RedirectAttributes redirectAttributes) { logger.info("[issueId,projectId,priority,assignTo,dueDate,estimatedHours,doneRatio,note]:" + issueId + "," + projectId + "," + priority + "," + assignTo + "," + dueDate + "," + estimatedHours + "," + doneRatio + "," + note); logger.info("[computes,storages,hostNames,serverAlias,osStorageAlias,controllerAlias, volumes]:" + computes + "|" + storages + "|" + hostNames + "|" + serverAlias + "|" + osStorageAlias + "|" + controllerAlias + "|" + volumes); logger.info("[innerIps,eipIds,eipAddresss,locationAlias,elbIds,virtualIps]:" + innerIps + "|" + eipIds + "|" + eipAddress + "|" + locationAlias + "|" + elbIds + "|" + virtualIps); Issue issue = RedmineService.getIssue(issueId); // 此处的User是redmine中的User对象. User assignee = new User(); assignee.setId(assignTo); User author = new User(); author.setId(authorId); Project project = new Project(); project.setId(projectId); // 当完成度为100时,设置状态 statusId 为 5.关闭; 其它完成度则为 2.处理中. Integer statusId = RedmineConstant.MAX_DONERATIO.equals(doneRatio) ? RedmineConstant.Status.关闭.toInteger() : RedmineConstant.Status.处理中.toInteger(); issue.setAssignee(assignee);// 指派给 issue.setDoneRatio(doneRatio);// 完成率 issue.setStatusId(statusId); // 设置状态 issue.setStatusName(RedmineConstant.Status.get(statusId)); // 设置状态名称 issue.setDueDate(new Date()); // 完成期限 issue.setEstimatedHours(new Float(estimatedHours)); // 耗费时间 issue.setNotes(note); // 描述 issue.setPriorityId(priority); // 优先级 issue.setProject(project); // 所属项目 issue.setAuthor(author); // issue作者 // TODO 还有IP分配等功能,待以后完成. boolean result = comm.operateService.updateOperate(issue, computes, storages, hostNames, serverAlias, osStorageAlias, controllerAlias, volumes, innerIps, eipIds, eipAddress, locationAlias, elbIds, virtualIps); String message = result ? "工单更新成功!" : "工单更新失败,请稍后重试或联系管理员!"; redirectAttributes.addFlashAttribute("message", message); return REDIRECT_SUCCESS_URL; } }