package com.sobey.cmop.mvc.service.email;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import com.google.common.collect.Maps;
import com.sobey.cmop.mvc.comm.BaseSevcie;
import com.sobey.cmop.mvc.constant.ApplyConstant;
import com.sobey.cmop.mvc.constant.AuditConstant;
import com.sobey.cmop.mvc.constant.CPConstant;
import com.sobey.cmop.mvc.constant.ComputeConstant;
import com.sobey.cmop.mvc.constant.IpPoolConstant;
import com.sobey.cmop.mvc.constant.MdnConstant;
import com.sobey.cmop.mvc.constant.MonitorConstant;
import com.sobey.cmop.mvc.constant.NetworkConstant;
import com.sobey.cmop.mvc.constant.RedmineConstant;
import com.sobey.cmop.mvc.constant.StorageConstant;
import com.sobey.cmop.mvc.entity.Apply;
import com.sobey.cmop.mvc.entity.Audit;
import com.sobey.cmop.mvc.entity.AuditFlow;
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.NetworkDnsItem;
import com.sobey.cmop.mvc.entity.NetworkEipItem;
import com.sobey.cmop.mvc.entity.NetworkElbItem;
import com.sobey.cmop.mvc.entity.ServiceTag;
import com.sobey.cmop.mvc.entity.StorageItem;
import com.sobey.cmop.mvc.entity.User;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
* MIME邮件服务类.
*
* 由Freemarker引擎生成的的html格式邮件, 并带有附件.
*
* @author liukai
*/
public class TemplateMailService extends BaseSevcie {
public static final String DEFAULT_ENCODING = "utf-8";
private static Logger logger = LoggerFactory.getLogger(TemplateMailService.class);
private JavaMailSender mailSender;
private Template detailTemplate;
private Template changeTemplate;
/**
* 根据freemarkerConfiguration的templateLoaderPath载入文件.
*
* <pre>
* 注入Freemarker引擎配置,构造Freemarker 邮件内容模板.
* 实现一个Template类,然后加载指定路劲(查看applicationContext-email.xml)的后缀为.ftl模板.
* 可实现多个不同的模板.
* </pre>
*
*/
public void setFreemarkerConfiguration(Configuration freemarkerConfiguration) throws IOException {
detailTemplate = freemarkerConfiguration.getTemplate("detailMailTemplate.ftl", DEFAULT_ENCODING);
changeTemplate = freemarkerConfiguration.getTemplate("changeMailTemplate.ftl", DEFAULT_ENCODING);
}
/**
* freemarker 中使用的常量的Map
*
* @return
*/
private Map<String, Object> freemarkerParameterMap() {
Map<String, Object> map = Maps.newHashMap();
map.put("osTypeMap", ComputeConstant.OS_TYPE_STRING_MAP);
map.put("osBitMap", ComputeConstant.OS_BIT_STRING_MAP);
map.put("priorityMap", RedmineConstant.Priority.mapKeyStr);
map.put("computeTypeMap", ComputeConstant.ComputeType.mapKeyStr);
map.put("pcsServerTypeMap", ComputeConstant.PCSServerType.mapKeyStr);
map.put("ecsServerTypeMap", ComputeConstant.ECSServerType.mapKeyStr);
map.put("applyServiceTypeMap", ApplyConstant.ServiceType.mapKeyStr);
map.put("storageTypeMap", StorageConstant.StorageType.mapKeyStr);
map.put("KeepSessionMap", NetworkConstant.KeepSession.mapKeyStr);
map.put("ispTypeMap", NetworkConstant.ISPType.mapKeyStr);
map.put("domainTypeMap", NetworkConstant.DomainType.mapKeyStr);
map.put("thresholdGtMap", MonitorConstant.THRESHOLD_GT_STRING_KEY);
map.put("thresholdLtMap", MonitorConstant.THRESHOLD_LT_STRING_KEY);
map.put("thresholdNetGtMap", MonitorConstant.THRESHOLD_NET_GT_STRING_KEY);
map.put("maxProcessMap", MonitorConstant.MAX_PROCESS_STRING_KEY);
map.put("encoderModeMap", MdnConstant.EncoderMode.mapKeyStr);
map.put("outputModeMap", MdnConstant.OutputMode.mapKeyStr);
map.put("bandwidthMap", MdnConstant.BANDWIDTH_MAP_STRING_KEY);
map.put("videoOutputWayMap", CPConstant.VideoOutputWay.mapKeyStr);
map.put("recordTypeMap", CPConstant.RecordType.mapKeyStr);
map.put("exportEncodeMap", CPConstant.EXPORTENCODE_MAP_STRING_KEY);
map.put("recordBitrateMap", CPConstant.RECORDBITRATE_MAP_STRING_KEY);
map.put("isPushCtpMap", CPConstant.IsPushCtp.mapKeyStr);
map.put("DEFAULT_IPADDRESS", IpPoolConstant.DEFAULT_IPADDRESS);
return map;
}
// ==========================//
// ========= Apply ==========//
// ==========================//
/**
* 发送MIME格式的服务申请审批通知邮件.
*/
public void sendApplyNotificationMail(Apply apply, AuditFlow auditFlow) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
// 服务申请Apply
map.put("apply", apply);
map.put("computes", apply.getComputeItems());
map.put("storages", apply.getStorageItems());
map.put("elbs", apply.getNetworkElbItems());
map.put("eips", apply.getNetworkEipItems());
map.put("dnses", apply.getNetworkDnsItems());
map.put("monitorComputes", apply.getMonitorComputes());
map.put("monitorElbs", apply.getMonitorElbs());
map.put("monitorMails", apply.getMonitorMails());
map.put("monitorPhones", apply.getMonitorPhones());
map.put("mdns", apply.getMdnItems());
map.put("cps", apply.getCpItems());
// 申请 审批Audit
String passUrl = CONFIG_LOADER.getProperty("APPLY_PASS_URL") + "?applyId=" + apply.getId() + "&userId="
+ auditFlow.getUser().getId() + "&result=" + AuditConstant.Result.同意;
String disagreeContinueUrl = CONFIG_LOADER.getProperty("APPLY_DISAGREE_URL") + "/" + apply.getId() + "?userId="
+ auditFlow.getUser().getId() + "&result=" + AuditConstant.Result.不同意但继续;
String disagreeReturnUrl = CONFIG_LOADER.getProperty("APPLY_DISAGREE_URL") + "/" + apply.getId() + "?userId="
+ auditFlow.getUser().getId() + "&result=" + AuditConstant.Result.不同意且退回;
map.put("sumCost", comm.costService.costPrice(apply));
map.put("passUrl", passUrl);
map.put("disagreeContinueUrl", disagreeContinueUrl);
map.put("disagreeReturnUrl", disagreeReturnUrl);
// 邮件标题
String sendSubject = "资源申请审批邮件";
this.sendMailConfig(detailTemplate, map, auditFlow.getUser(), sendSubject);
}
/**
* 发送工单处理邮件(服务申请Apply)
*/
public void sendApplyOperateNotificationMail(Apply apply, User assigneeUser) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
// 服务申请Apply
map.put("apply", apply);
map.put("computes", apply.getComputeItems());
map.put("storages", apply.getStorageItems());
map.put("elbs", apply.getNetworkElbItems());
map.put("eips", apply.getNetworkEipItems());
map.put("dnses", apply.getNetworkDnsItems());
map.put("monitorComputes", apply.getMonitorComputes());
map.put("monitorElbs", apply.getMonitorElbs());
map.put("monitorMails", apply.getMonitorMails());
map.put("monitorPhones", apply.getMonitorPhones());
map.put("mdns", apply.getMdnItems());
map.put("cps", apply.getCpItems());
// 工单处理URL
String operateUrl = "你有新的服务申请处理工单. <a href=\"" + CONFIG_LOADER.getProperty("OPERATE_URL")
+ "\">→点击进行处理</a><br>";
map.put("operateUrl", operateUrl);
// 邮件标题
String sendSubject = "工单处理邮件";
this.sendMailConfig(detailTemplate, map, assigneeUser, sendSubject);
}
/**
* 工单处理结束,通知申请人邮件(服务申请Apply)
*/
public void sendApplyOperateDoneNotificationMail(Apply apply) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
// 服务申请Apply
map.put("apply", apply);
map.put("computes", apply.getComputeItems());
map.put("storages", apply.getStorageItems());
map.put("elbs", apply.getNetworkElbItems());
map.put("eips", apply.getNetworkEipItems());
map.put("dnses", apply.getNetworkDnsItems());
map.put("monitorComputes", apply.getMonitorComputes());
map.put("monitorElbs", apply.getMonitorElbs());
map.put("monitorMails", apply.getMonitorMails());
map.put("monitorPhones", apply.getMonitorPhones());
map.put("mdns", apply.getMdnItems());
map.put("cps", apply.getCpItems());
// 工单处理完成提示文字
String operateDoneStr = "工单处理流程已完成.";
if (!apply.getComputeItems().isEmpty()) {
operateDoneStr += "为了账号安全,请尽快修改服务器初始密码.初始账号和密码:<br> Windows: <br> administrator/Newmed!@s0bey<br>Linux: <br> root/newmedia<br>";
}
operateDoneStr += "如果申请了VPN账号,请向申请资源负责人索取.<a href=\"" + CONFIG_LOADER.getProperty("RESOURCE_URL")
+ "\">→点击查看</a><br>";
map.put("operateDoneStr", operateDoneStr);
// 邮件标题
String sendSubject = "服务申请工单处理邮件";
this.sendMailConfig(detailTemplate, map, apply.getUser(), sendSubject);
}
// ==========================//
// ======= Resources ========//
// ==========================//
/**
* 发送MIME格式的资源变更审批通知邮件.
*/
public void sendResourcesNotificationMail(ServiceTag serviceTag, AuditFlow auditFlow, Audit audit) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
// 服务标签ServiceTag
map.put("serviceTag", serviceTag);
map.put("resourcesList", comm.resourcesService.getCommitedResourcesListByServiceTagId(serviceTag.getId()));
// 变更 审批Audit
String passUrl = CONFIG_LOADER.getProperty("RESOURCES_PASS_URL") + "?serviceTagId=" + serviceTag.getId()
+ "&userId=" + auditFlow.getUser().getId() + "&result=" + AuditConstant.Result.同意;
String disagreeContinueUrl = CONFIG_LOADER.getProperty("RESOURCES_DISAGREE_URL") + "/" + serviceTag.getId()
+ "?userId=" + auditFlow.getUser().getId() + "&result=" + AuditConstant.Result.不同意但继续 + "&auditId="
+ audit.getId();
String disagreeReturnUrl = CONFIG_LOADER.getProperty("RESOURCES_DISAGREE_URL") + "/" + serviceTag.getId()
+ "?userId=" + auditFlow.getUser().getId() + "&result=" + AuditConstant.Result.不同意且退回 + "&auditId="
+ audit.getId();
;
map.put("passUrl", passUrl);
map.put("disagreeContinueUrl", disagreeContinueUrl);
map.put("disagreeReturnUrl", disagreeReturnUrl);
// 邮件标题
String sendSubject = "资源变更审批邮件";
this.sendMailConfig(changeTemplate, map, auditFlow.getUser(), sendSubject);
}
/**
* 发送工单处理邮件(资源变更Resources)
*/
public void sendResourcesOperateNotificationMail(ServiceTag serviceTag, User assigneeUser) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
// 服务标签ServiceTag
map.put("serviceTag", serviceTag);
map.put("resourcesList", comm.resourcesService.getOperateResourcesListByServiceTagId(serviceTag.getId()));
// 工单处理URL
String operateUrl = "你有新的资源变更处理工单. <a href=\"" + CONFIG_LOADER.getProperty("OPERATE_URL")
+ "\">→点击进行处理</a><br>";
map.put("operateUrl", operateUrl);
// 邮件标题
String sendSubject = "工单处理邮件";
this.sendMailConfig(changeTemplate, map, assigneeUser, sendSubject);
}
/**
* 工单处理结束,通知申请人邮件(资源变更Resources)
*/
public void sendResourcesOperateDoneNotificationMail(ServiceTag serviceTag) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
// 服务标签ServiceTag
map.put("serviceTag", serviceTag);
map.put("resourcesList", comm.resourcesService.getOperateResourcesListByServiceTagId(serviceTag.getId()));
// 工单处理完成提示文字
String operateDoneStr = "工单处理流程已完成.如果申请了VPN账号,请向申请资源负责人索取.<a href=\""
+ CONFIG_LOADER.getProperty("RESOURCE_URL") + "\">→点击查看</a><br>";
map.put("operateDoneStr", operateDoneStr);
// 邮件标题
String sendSubject = "资源变更处理邮件";
this.sendMailConfig(changeTemplate, map, serviceTag.getUser(), sendSubject);
}
// ==========================//
// ========= Recycle ========//
// ==========================//
/**
* 发送工单处理邮件(资源回收)
*/
public void sendRecycleResourcesOperateNotificationMail(User user, List<ComputeItem> computeItems,
List<StorageItem> storageItems, List<NetworkElbItem> elbItems, List<NetworkEipItem> eipItems,
List<NetworkDnsItem> dnsItems, List<MonitorCompute> monitorComputes, List<MonitorElb> monitorElbs,
List<MdnItem> mdnItems, List<CpItem> cpItems, User assigneeUser) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
map.put("computes", computeItems);
map.put("storages", storageItems);
map.put("elbs", elbItems);
map.put("eips", eipItems);
map.put("dnses", dnsItems);
map.put("monitorComputes", monitorComputes);
map.put("monitorElbs", monitorElbs);
map.put("mdns", mdnItems);
map.put("cps", cpItems);
// 工单处理URL
String operateUrl = "你有新的资源回收工单处理. <a href=\"" + CONFIG_LOADER.getProperty("OPERATE_URL")
+ "\">→点击进行处理</a><br>";
map.put("operateUrl", operateUrl);
// 邮件标题
String sendSubject = "资源回收工单处理邮件";
this.sendMailConfig(detailTemplate, map, assigneeUser, sendSubject);
}
/**
* 工单处理结束,通知申请人邮件(资源回收)
*
* @param sendToUser
* 收件人.生成环境使用
*/
public void sendRecycleResourcesOperateDoneNotificationMail(User sendToUser) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
// 工单处理完成提示文字
String operateDoneStr = "资源回收工单处理流程已完成.<a href=\"" + CONFIG_LOADER.getProperty("RESOURCE_URL")
+ "\">→点击查看</a><br>";
map.put("operateDoneStr", operateDoneStr);
// 邮件标题
String sendSubject = "资源回收处理邮件";
this.sendMailConfig(detailTemplate, map, sendToUser, sendSubject);
}
// ==========================//
// ========= Failure ========//
// ==========================//
/**
* 发送MIME格式的工单处理邮件(故障申报Failure).
*/
public void sendFailureResourcesNotificationMail(Failure failure, List<ComputeItem> computeItems,
List<StorageItem> storageItems, List<NetworkElbItem> elbItems, List<NetworkEipItem> eipItems,
List<NetworkDnsItem> dnsItems, List<MonitorCompute> monitorComputes, List<MonitorElb> monitorElbs,
List<MdnItem> mdnItems, List<CpItem> cpItems, User assigneeUser) {
// 初始化数据,并将其放入一个HashMap中.
Map<String, Object> map = this.freemarkerParameterMap();
map.put("failure", failure);
map.put("computes", computeItems);
map.put("storages", storageItems);
map.put("elbs", elbItems);
map.put("eips", eipItems);
map.put("dnses", dnsItems);
map.put("monitorComputes", monitorComputes);
map.put("monitorElbs", monitorElbs);
map.put("mdns", mdnItems);
map.put("cps", cpItems);
// 工单处理URL
String operateUrl = "你有新的故障处理工单工单处理. <a href=\"" + CONFIG_LOADER.getProperty("OPERATE_URL")
+ "\">→点击进行处理</a><br>";
map.put("operateUrl", operateUrl);
// 邮件标题
String sendSubject = "故障申报工单处理邮件";
this.sendMailConfig(detailTemplate, map, assigneeUser, sendSubject);
}
/**
* 邮件发送配置的信息
*
* @param template
* 采用的邮件模板.
* @param map
* 初始化的数据map
* @param sendToUser
* 收件人
* @param sendSubject
* 邮件标题
*/
private void sendMailConfig(Template template, Map<String, Object> map, User sendToUser, String sendSubject) {
try {
/****************** Step.1 将初始化的数据Map通过freemarker模板生成HTML格式内容. ******************/
String content = this.generateMailContent(template, map);
/****************** Step.2 完成邮件发送的几个参数后发送邮件. ******************/
// 发件人.通过读取配置文件获得.
String sendFrom = CONFIG_LOADER.getProperty("SENDFROM_EMAIL");
// 收件人.生成环境使用
String sendTo = sendToUser.getEmail();
// 收件人.测试使用
String sendToTest = CONFIG_LOADER.getProperty("TEST_SENDTO_EMAIL");
MimeMessage msg = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(msg, true, DEFAULT_ENCODING);
helper.setFrom(sendFrom);
// TODO 测试环境使用.
helper.setTo(sendToTest);
// TODO 生产环境使用.
// helper.setTo(sendTo);
helper.setSubject(sendSubject);
helper.setText(content, true);
mailSender.send(msg);
logger.info("HTML版邮件已发送至 " + sendTo);
} catch (MessagingException e) {
logger.error("构造邮件失败", e);
} catch (Exception e) {
logger.error("发送邮件失败", e);
}
/****************** Step.3 完成邮件发送的几个参数后发送邮件. ******************/
}
/**
* 使用Freemarker生成html格式内容.
*
* @param template
* freemarker的模板
* @param map
* 传入freemarker的参数.Key为参数名,value为传入参数的对象.
*
* @return 通过模板得到的HTML内容
*
* @throws MessagingException
*/
private String generateMailContent(Template template, Map<String, Object> map) throws MessagingException {
try {
return FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
} catch (IOException e) {
logger.error("生成邮件内容失败, FreeMarker模板不存在", e);
throw new MessagingException("FreeMarker模板不存在", e);
} catch (TemplateException e) {
logger.error("生成邮件内容失败, FreeMarker处理失败", e);
throw new MessagingException("FreeMarker处理失败", e);
}
}
/**
* Spring的MailSender.
*/
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
}