package com.sobey.cmop.mvc.service.redmine;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sobey.cmop.mvc.comm.BaseSevcie;
import com.sobey.cmop.mvc.constant.ApplyConstant;
import com.sobey.cmop.mvc.constant.FieldNameConstant;
import com.sobey.cmop.mvc.constant.FieldNameConstant.Compate;
import com.sobey.cmop.mvc.constant.FieldNameConstant.Dns;
import com.sobey.cmop.mvc.constant.FieldNameConstant.Eip;
import com.sobey.cmop.mvc.constant.FieldNameConstant.Elb;
import com.sobey.cmop.mvc.constant.FieldNameConstant.MdnLiveItem;
import com.sobey.cmop.mvc.constant.FieldNameConstant.MdnVodItem;
import com.sobey.cmop.mvc.constant.FieldNameConstant.Storage;
import com.sobey.cmop.mvc.constant.FieldNameConstant.monitorCompute;
import com.sobey.cmop.mvc.constant.FieldNameConstant.monitorElb;
import com.sobey.cmop.mvc.constant.IpPoolConstant;
import com.sobey.cmop.mvc.constant.RedmineConstant;
import com.sobey.cmop.mvc.constant.ResourcesConstant;
import com.sobey.cmop.mvc.entity.Apply;
import com.sobey.cmop.mvc.entity.Change;
import com.sobey.cmop.mvc.entity.ChangeItem;
import com.sobey.cmop.mvc.entity.ComputeItem;
import com.sobey.cmop.mvc.entity.CpItem;
import com.sobey.cmop.mvc.entity.Failure;
import com.sobey.cmop.mvc.entity.MdnItem;
import com.sobey.cmop.mvc.entity.MonitorCompute;
import com.sobey.cmop.mvc.entity.MonitorElb;
import com.sobey.cmop.mvc.entity.MonitorMail;
import com.sobey.cmop.mvc.entity.MonitorPhone;
import com.sobey.cmop.mvc.entity.NetworkDnsItem;
import com.sobey.cmop.mvc.entity.NetworkEipItem;
import com.sobey.cmop.mvc.entity.NetworkElbItem;
import com.sobey.cmop.mvc.entity.NetworkEsgItem;
import com.sobey.cmop.mvc.entity.Resources;
import com.sobey.cmop.mvc.entity.ServiceTag;
import com.sobey.cmop.mvc.entity.StorageItem;
import com.sobey.cmop.mvc.entity.User;
import com.sobey.framework.utils.DateUtil;
/**
* 生成满足 Redmine格式的文本(用于通过API插入redmine).
*
* @author liukai
*
*/
@Service
@Transactional(readOnly = true)
public class RedmineUtilService extends BaseSevcie {
private static Logger logger = LoggerFactory.getLogger(RedmineUtilService.class);
/**
* 换行
*/
private static final String NEWLINE = "\r\n";
/**
* 一个空格
*/
private static final String BLANK = " ";
/**
* 箭头.用于资源变更时旧值和新值的比较
*/
private static final String RARR = BLANK + "→" + BLANK;
/**
* 因为oneCMDB中的update方法,没有更改复杂对象的功能. 故只能通过redmine显示的方法通知管理人员手动修改变更对象在oneCMDB中的数据.
*/
private static final String CHANGE_ONECMDB_NOTIFICATION = "(提交后,请按工单手动修改oneCMDB中的数据)";
/**
* 生成满足redmine显示的服务申请Apply文本.
*/
public String applyRedmineDesc(Apply apply) {
try {
StringBuilder content = new StringBuilder();
content.append("*服务申请的详细信息*").append(NEWLINE + NEWLINE);
content.append("# +*基本信息*+").append(NEWLINE);
content.append("<pre>").append(NEWLINE);
content.append("申请标题: ").append(apply.getTitle()).append(NEWLINE);
content.append("服务标签: ").append(apply.getServiceTag()).append(NEWLINE);
content.append("优先级: ").append(RedmineConstant.Priority.get(apply.getPriority())).append(NEWLINE);
content.append("服务起止日期: ").append(apply.getServiceStart()).append(" 至 ").append(apply.getServiceEnd())
.append(NEWLINE);
content.append("用途描述: ").append(apply.getDescription()).append(NEWLINE);
content.append("申请人: ").append(apply.getUser().getName()).append(NEWLINE);
content.append("申请时间: ").append(DateUtil.formatDate(apply.getCreateTime())).append(NEWLINE);
content.append("</pre>");
content.append(NEWLINE);
// 拼装计算资源Compute信息
this.generateContentByLists(apply.getUser(), content, new ArrayList<ComputeItem>(apply.getComputeItems()),
new ArrayList<StorageItem>(apply.getStorageItems()),
new ArrayList<NetworkElbItem>(apply.getNetworkElbItems()),
new ArrayList<NetworkEipItem>(apply.getNetworkEipItems()),
new ArrayList<NetworkDnsItem>(apply.getNetworkDnsItems()),
new ArrayList<MonitorMail>(apply.getMonitorMails()),
new ArrayList<MonitorPhone>(apply.getMonitorPhones()),
new ArrayList<MonitorCompute>(apply.getMonitorComputes()),
new ArrayList<MonitorElb>(apply.getMonitorElbs()), new ArrayList<MdnItem>(apply.getMdnItems()),
new ArrayList<CpItem>(apply.getCpItems()));
return content.toString();
} catch (Exception e) {
logger.error("--->服务申请Apply拼装Redmine内容出错:" + e.getMessage());
return null;
}
}
/**
* 生成满足redmine显示的资源回收Resources文本.
*/
public String recycleResourcesRedmineDesc(User user, List<ComputeItem> computeItems,
List<StorageItem> storageItems, List<NetworkElbItem> elbItems, List<NetworkEipItem> eipItems,
List<NetworkDnsItem> dnsItems, List<MonitorMail> monitorMails, List<MonitorPhone> monitorPhones,
List<MonitorCompute> monitorComputes, List<MonitorElb> monitorElbs, List<MdnItem> mdnItems,
List<CpItem> cpItems) {
try {
StringBuilder content = new StringBuilder();
// 拼装资源信息
this.generateContentByLists(user, content, computeItems, storageItems, elbItems, eipItems, dnsItems,
monitorMails, monitorPhones, monitorComputes, monitorElbs, mdnItems, cpItems);
return content.toString();
} catch (Exception e) {
logger.error("--->资源变更Resources拼装Redmine内容出错:" + e.getMessage());
return null;
}
}
/**
* 生成满足redmine显示的故障申报Failure文本.
*/
public String failureResourcesRedmineDesc(Failure failure, List<ComputeItem> computeItems,
List<StorageItem> storageItems, List<NetworkElbItem> elbItems, List<NetworkEipItem> eipItems,
List<NetworkDnsItem> dnsItems, List<MonitorMail> monitorMails, List<MonitorPhone> monitorPhones,
List<MonitorCompute> monitorComputes, List<MonitorElb> monitorElbs, List<MdnItem> mdnItems,
List<CpItem> cpItems) {
try {
StringBuilder content = new StringBuilder();
content.append("# +*故障申报信息*+").append(NEWLINE);
content.append("<pre>").append(NEWLINE);
content.append("申报人:").append(failure.getUser().getName()).append(NEWLINE);
content.append("申报标题:").append(failure.getTitle()).append(NEWLINE);
content.append("申报时间:").append(failure.getCreateTime()).append(NEWLINE);
content.append("故障类型:").append(ApplyConstant.ServiceType.get(failure.getFaultType())).append(NEWLINE);
content.append("优先级:").append(RedmineConstant.Priority.get(failure.getLevel())).append(NEWLINE);
content.append("受理人:").append(RedmineConstant.Assignee.get(failure.getAssignee())).append(NEWLINE);
content.append("故障现象及描述:").append(failure.getDescription()).append(NEWLINE);
content.append("</pre>");
this.generateContentByLists(failure.getUser(), content, computeItems, storageItems, elbItems, eipItems,
dnsItems, monitorMails, monitorPhones, monitorComputes, monitorElbs, mdnItems, cpItems);
return content.toString();
} catch (Exception e) {
logger.error("--->故障申报Failure拼装Redmine内容出错:" + e.getMessage());
return null;
}
}
/**
* 将各个资源相关的参数生成符合redmine格式的文本.
*
* @param user
* 资源创建人
* @param content
* @param computeItems
* @param storageItems
* @param elbItems
* @param eipItems
* @param dnsItems
* @param monitorMails
* @param monitorPhones
* @param monitorComputes
* @param monitorElbs
* @param mdnItems
* @param cpItems
*/
private void generateContentByLists(User user, StringBuilder content, List<ComputeItem> computeItems,
List<StorageItem> storageItems, List<NetworkElbItem> elbItems, List<NetworkEipItem> eipItems,
List<NetworkDnsItem> dnsItems, List<MonitorMail> monitorMails, List<MonitorPhone> monitorPhones,
List<MonitorCompute> monitorComputes, List<MonitorElb> monitorElbs, List<MdnItem> mdnItems,
List<CpItem> cpItems) {
RedmineTextUtil.generateCompute(content, computeItems);
RedmineTextUtil.generateStorage(content, storageItems);
RedmineTextUtil.generateElb(content, elbItems);
RedmineTextUtil.generateEip(content, eipItems);
RedmineTextUtil.generateDNS(content, dnsItems);
RedmineTextUtil.generateMonitorMail(content, monitorMails);
RedmineTextUtil.generateMonitorPhone(content, monitorPhones);
RedmineTextUtil.generateMonitorCompute(content, monitorComputes);
RedmineTextUtil.generateMonitorElb(content, monitorElbs);
RedmineTextUtil.generateMdn(content, mdnItems);
RedmineTextUtil.generateCP(content, cpItems);
}
/**
* 将变更前和变更后的值拼装成StringBuilder content
*
* @param fieldName
* 变更项
* @param content
* redmine 文本
* @param changeItem
* changeItem对象
*/
private void saveChangeText(String fieldName, StringBuilder content, ChangeItem changeItem) {
content.append(fieldName + ":" + BLANK).append(changeItem.getOldString()).append(RARR)
.append(changeItem.getNewString()).append(NEWLINE);
}
private void saveESGChangeText(String fieldName, StringBuilder content, ChangeItem changeItem) {
String[] ids = StringUtils.split(changeItem.getNewValue(), ",");
List<NetworkEsgItem> networkEsgItems = new ArrayList<NetworkEsgItem>();
for (String id : ids) {
networkEsgItems.add(comm.esgService.getNetworkEsgItem(Integer.valueOf(id)));
}
content.append(fieldName + ":" + BLANK).append(changeItem.getOldString()).append(RARR)
.append(ComputeItem.extractDetailToString(networkEsgItems)).append(NEWLINE);
}
/**
* 将变更前和变更后的值拼装成StringBuilder content(包括换行)
*
* @param fieldName
* 变更项
* @param content
* redmine 文本
* @param changeItem
* changeItem对象
*/
private void saveChangeTextAndNEWLINE(String fieldName, StringBuilder content, ChangeItem changeItem) {
content.append(fieldName + ":" + BLANK).append(NEWLINE).append(changeItem.getOldString()).append(RARR)
.append(NEWLINE).append(changeItem.getNewString()).append(NEWLINE);
}
/**
* 生成满足redmine显示的资源变更Resources文本.
*/
public String resourcesRedmineDesc(ServiceTag serviceTag) {
try {
StringBuilder content = new StringBuilder();
content.append("*服务变更的详细信息*").append(NEWLINE + NEWLINE);
content.append("* +*服务标签基本信息*+").append(NEWLINE);
content.append("<pre>").append(NEWLINE);
content.append("标签名: ").append(serviceTag.getName()).append(NEWLINE);
content.append("优先级: ").append(RedmineConstant.Priority.get(serviceTag.getPriority())).append(NEWLINE);
content.append("服务起止日期: ").append(serviceTag.getServiceStart()).append(" 至 ")
.append(serviceTag.getServiceEnd()).append(NEWLINE);
content.append("用途描述: ").append(serviceTag.getDescription()).append(NEWLINE);
content.append("申请人: ").append(serviceTag.getUser().getName()).append(NEWLINE);
content.append("</pre>");
content.append(NEWLINE + NEWLINE);
content.append("* +*变更信息*+").append(NEWLINE);
content.append("<pre>").append(NEWLINE);
List<Resources> resourcesList = comm.resourcesService.getCommitedResourcesListByServiceTagId(serviceTag
.getId());
for (Resources resources : resourcesList) {
Integer serviceType = resources.getServiceType();
for (Change change : resources.getChanges()) {
// 资源标识符(标识符) + 变更说明
content.append("变更资源标识符:" + BLANK).append(resources.getServiceIdentifier());
// 只有当ip不为0.0.0.0时才插入IP(即资源本身有IP时,像DNS,ES3这些没有IP的资源将不显示ip)
if (!IpPoolConstant.DEFAULT_IPADDRESS.equals(resources.getIpAddress())) {
String remark = "";
// 增加ECS的备注,以便于工单IP的替换.
if (ResourcesConstant.ServiceType.ECS.toInteger().equals(serviceType)) {
ComputeItem computeItem = comm.computeService.getComputeItem(resources.getServiceId());
remark = computeItem.getRemark();
content.append("(" + remark + " - " + resources.getIpAddress() + ")");
} else {
content.append("(" + resources.getIpAddress() + ")");
}
}
content.append(BLANK + BLANK).append("变更描述:" + BLANK).append(change.getDescription())
.append(NEWLINE);
content.append(NEWLINE).append("变更项:");
if (change.getSubResourcesId() != null) {
content.append("(服务子项ID:" + change.getSubResourcesId() + ")");
}
content.append(BLANK + "旧值").append(RARR).append("新值").append(NEWLINE);
for (ChangeItem changeItem : change.getChangeItems()) {
String fieldName = changeItem.getFieldName();
if (serviceType.equals(ResourcesConstant.ServiceType.PCS.toInteger())
|| serviceType.equals(ResourcesConstant.ServiceType.ECS.toInteger())) {
// 计算资源Compute信息
for (Compate enumField : FieldNameConstant.Compate.values()) {
if (enumField.toString().equals(fieldName)) {
if (FieldNameConstant.Compate.应用信息.toString().equals(fieldName)) {
this.saveChangeTextAndNEWLINE(fieldName, content, changeItem);
} else if (FieldNameConstant.Compate.ESG.toString().equals(fieldName)) {
this.saveESGChangeText(fieldName + CHANGE_ONECMDB_NOTIFICATION, content,
changeItem);
} else {
this.saveChangeText(fieldName, content, changeItem);
}
}
}
} else if (serviceType.equals(ResourcesConstant.ServiceType.ES3.toInteger())) {
// 存储空间Storage信息
for (Storage enumField : FieldNameConstant.Storage.values()) {
if (enumField.toString().equals(fieldName)) {
if (FieldNameConstant.Storage.容量空间.toString().equals(fieldName)) {
this.saveChangeText(fieldName + "(GB)", content, changeItem);
} else {
this.saveChangeText(fieldName, content, changeItem);
}
}
}
} else if (serviceType.equals(ResourcesConstant.ServiceType.ELB.toInteger())) {
// 变更负载均衡器ELB
for (Elb enumField : FieldNameConstant.Elb.values()) {
if (enumField.toString().equals(fieldName)) {
if (FieldNameConstant.Elb.端口信息.toString().equals(fieldName)) {
this.saveChangeTextAndNEWLINE(fieldName, content, changeItem);
} else if (FieldNameConstant.Elb.关联实例.toString().equals(fieldName)) {
this.saveChangeTextAndNEWLINE(fieldName + CHANGE_ONECMDB_NOTIFICATION, content,
changeItem);
} else {
this.saveChangeText(fieldName, content, changeItem);
}
}
}
} else if (serviceType.equals(ResourcesConstant.ServiceType.EIP.toInteger())) {
// EIP
for (Eip enumField : FieldNameConstant.Eip.values()) {
if (enumField.toString().equals(fieldName)) {
if (FieldNameConstant.Eip.端口信息.toString().equals(fieldName)) {
this.saveChangeTextAndNEWLINE(fieldName, content, changeItem);
} else {
this.saveChangeText(fieldName, content, changeItem);
}
}
}
} else if (serviceType.equals(ResourcesConstant.ServiceType.DNS.toInteger())) {
// 拼装DNS信息
for (Dns enumField : FieldNameConstant.Dns.values()) {
if (enumField.toString().equals(fieldName)) {
this.saveChangeText(fieldName, content, changeItem);
}
}
} else if (serviceType.equals(ResourcesConstant.ServiceType.MONITOR_COMPUTE.toInteger())) {
// monitorCompute
for (monitorCompute enumField : FieldNameConstant.monitorCompute.values()) {
if (enumField.toString().equals(fieldName)) {
this.saveChangeText(fieldName, content, changeItem);
}
}
} else if (serviceType.equals(ResourcesConstant.ServiceType.MONITOR_ELB.toInteger())) {
// monitorElb
for (monitorElb enumField : FieldNameConstant.monitorElb.values()) {
if (enumField.toString().equals(fieldName)) {
this.saveChangeText(fieldName, content, changeItem);
}
}
} else if (serviceType.equals(ResourcesConstant.ServiceType.MDN.toInteger())) {
// MDN
for (com.sobey.cmop.mvc.constant.FieldNameConstant.MdnItem enumField : FieldNameConstant.MdnItem
.values()) {
if (enumField.toString().equals(fieldName)) {
this.saveChangeText(fieldName, content, changeItem);
}
}
// MDNVod
for (MdnVodItem enumField : FieldNameConstant.MdnVodItem.values()) {
if (enumField.toString().equals(fieldName)) {
this.saveChangeText(fieldName, content, changeItem);
}
}
// MDNLive
for (MdnLiveItem enumField : FieldNameConstant.MdnLiveItem.values()) {
if (enumField.toString().equals(fieldName)) {
this.saveChangeText(fieldName, content, changeItem);
}
}
} else if (serviceType.equals(ResourcesConstant.ServiceType.CP.toInteger())) {
// 云生产CP
for (com.sobey.cmop.mvc.constant.FieldNameConstant.CpItem enumField : FieldNameConstant.CpItem
.values()) {
if (enumField.toString().equals(fieldName)) {
this.saveChangeText(fieldName, content, changeItem);
}
}
}
}
}
content.append(NEWLINE);
}
content.append("</pre>").append(NEWLINE);
return content.toString();
} catch (Exception e) {
e.printStackTrace();
logger.error("--->拼装Redmine内容出错:" + e.getMessage());
return null;
}
}
}