Commit 873ea6bb by lepdou

refactor email builder

parent f144fe06
package com.ctrip.framework.apollo.portal.components.emailbuilder;
import com.google.common.collect.Lists;
import com.ctrip.framework.apollo.common.constants.ReleaseOperation;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.constant.RoleType;
......@@ -16,15 +19,20 @@ import com.ctrip.framework.apollo.portal.service.AppNamespaceService;
import com.ctrip.framework.apollo.portal.service.ReleaseService;
import com.ctrip.framework.apollo.portal.service.RolePermissionService;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.spi.UserService;
import com.ctrip.framework.apollo.portal.util.RoleUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import javax.annotation.PostConstruct;
......@@ -62,7 +70,6 @@ public abstract class ConfigPublishEmailBuilder {
private FastDateFormat dateFormat = FastDateFormat.getInstance("yyyy-MM-dd hh:mm:ss");
private String emailAddressSuffix;
private String emailSender;
@Autowired
......@@ -73,10 +80,11 @@ public abstract class ConfigPublishEmailBuilder {
private ReleaseService releaseService;
@Autowired
private AppNamespaceService appNamespaceService;
@Autowired
private UserService userService;
@PostConstruct
public void init() {
emailAddressSuffix = serverConfigService.getValue("email.address.suffix");
emailSender = serverConfigService.getValue("email.sender");
}
......@@ -103,15 +111,31 @@ public abstract class ConfigPublishEmailBuilder {
Set<UserInfo> releaseRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.RELEASE_NAMESPACE));
Set<UserInfo> owners = rolePermissionService.queryUsersWithRole(RoleUtils.buildAppMasterRoleName(appId));
List<String> recipients = new ArrayList<>(modifyRoleUsers.size() + releaseRoleUsers.size());
Set<String> userIds = new HashSet<>(modifyRoleUsers.size() + releaseRoleUsers.size() + owners.size());
for (UserInfo userInfo : modifyRoleUsers) {
recipients.add(userInfo.getUserId() + emailAddressSuffix);
userIds.add(userInfo.getUserId());
}
for (UserInfo userInfo : releaseRoleUsers) {
recipients.add(userInfo.getUserId() + emailAddressSuffix);
userIds.add(userInfo.getUserId());
}
for (UserInfo userInfo : owners) {
userIds.add(userInfo.getUserId());
}
List<UserInfo> userInfos = userService.findByUserIds(Lists.newArrayList(userIds));
if (CollectionUtils.isEmpty(userInfos)){
return Collections.emptyList();
}
List<String> recipients = new ArrayList<>(userInfos.size());
for (UserInfo userInfo: userInfos){
recipients.add(userInfo.getEmail());
}
return recipients;
......@@ -124,15 +148,15 @@ public abstract class ConfigPublishEmailBuilder {
}
private String renderReleaseBasicInfo(String template, Env env, ReleaseHistoryBO releaseHistory) {
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_APPID, releaseHistory.getAppId());
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_ENV, env.toString());
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_CLUSTER, releaseHistory.getClusterName());
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_NAMESPACE, releaseHistory.getNamespaceName());
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_OPERATOR, releaseHistory.getOperator());
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_TITLE, releaseHistory.getReleaseTitle());
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_APPID, Matcher.quoteReplacement(releaseHistory.getAppId()));
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_ENV, Matcher.quoteReplacement(env.toString()));
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_CLUSTER, Matcher.quoteReplacement(releaseHistory.getClusterName()));
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_NAMESPACE, Matcher.quoteReplacement(releaseHistory.getNamespaceName()));
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_OPERATOR, Matcher.quoteReplacement(releaseHistory.getOperator()));
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_TITLE, Matcher.quoteReplacement(releaseHistory.getReleaseTitle()));
renderResult =
renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_ID, String.valueOf(releaseHistory.getReleaseId()));
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_COMMENT, releaseHistory.getReleaseComment());
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_COMMENT, Matcher.quoteReplacement(releaseHistory.getReleaseComment()));
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_APOLLO_SERVER_ADDRESS, getApolloPortalAddress());
return renderResult
.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_TIME, dateFormat.format(releaseHistory.getReleaseTime()));
......@@ -150,7 +174,8 @@ public abstract class ConfigPublishEmailBuilder {
//don't show diff content if namespace's format is file
if (appNamespace == null ||
!appNamespace.getFormat().equals(ConfigFileFormat.Properties.getValue())) {
return template;
return template.replaceAll(EMAIL_CONTENT_FIELD_DIFF, "请点击链接到Apollo上查看");
}
ReleaseCompareResult result = getReleaseCompareResult(env, releaseHistory);
......@@ -177,7 +202,8 @@ public abstract class ConfigPublishEmailBuilder {
changesHtmlBuilder.append("</tr>");
}
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_DIFF, changesHtmlBuilder.toString());
String diffContent = Matcher.quoteReplacement(changesHtmlBuilder.toString());
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_DIFF, diffContent);
return renderResult.replaceAll(EMAIL_CONTENT_DIFF_HAS_CONTENT_SWITCH, "");
}
......@@ -214,5 +240,4 @@ public abstract class ConfigPublishEmailBuilder {
return source;
}
}
......@@ -13,6 +13,7 @@ import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
@Component
public class GrayPublishEmailBuilder extends ConfigPublishEmailBuilder {
......@@ -59,7 +60,7 @@ public class GrayPublishEmailBuilder extends ConfigPublishEmailBuilder {
}
}
return result.replaceAll(EMAIL_CONTENT_FIELD_RULE, rulesHtmlBuilder.toString());
return result.replaceAll(EMAIL_CONTENT_FIELD_RULE, Matcher.quoteReplacement(rulesHtmlBuilder.toString()));
}
}
......@@ -13,6 +13,8 @@ import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.spi.EmailService;
import com.ctrip.framework.apollo.tracer.Tracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
......@@ -24,6 +26,7 @@ import javax.annotation.PostConstruct;
@Component
public class ConfigPublishListener {
private static final Logger logger = LoggerFactory.getLogger(ConfigPublishListener.class);
@Autowired
private ServerConfigService serverConfigService;
......@@ -53,6 +56,7 @@ public class ConfigPublishListener {
emailSupportedEnvs.add(Env.fromString(env.trim()));
}
} catch (Exception e) {
logger.error("init email supported envs failed.", e);
Tracer.logError("init email supported envs failed.", e);
}
......@@ -75,12 +79,16 @@ public class ConfigPublishListener {
int realOperation = releaseHistory.getOperation();
Email email = buildEmail(env, releaseHistory, realOperation);
Email email = null;
try {
email = buildEmail(env, releaseHistory, realOperation);
} catch (Throwable e) {
Tracer.logError("build email failed.", e);
}
if (email != null) {
emailService.send(email);
}
}
private ReleaseHistoryBO getReleaseHistory(ConfigPublishEvent event) {
......@@ -99,7 +107,7 @@ public class ConfigPublishListener {
if (info.isRollbackEvent()) {
return releaseHistoryService
.findLatestByPreviousReleaseIdAndOperation(env, info.getPreviousReleaseId(), operation);
}else {
} else {
return releaseHistoryService.findLatestByReleaseIdAndOperation(env, info.getReleaseId(), operation);
}
......
......@@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.portal.spi;
import com.ctrip.framework.apollo.portal.entity.bo.UserInfo;
import java.util.List;
import java.util.Set;
/**
* @author Jason Song(song_s@ctrip.com)
......@@ -13,4 +14,5 @@ public interface UserService {
UserInfo findByUserId(String userId);
List<UserInfo> findByUserIds(List<String> userIds);
}
......@@ -18,8 +18,10 @@ import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
......@@ -31,6 +33,7 @@ public class CtripUserService implements UserService {
private List<String> searchUserMatchFields;
private ParameterizedTypeReference<Map<String, List<UserServiceResponse>>> responseType;
public CtripUserService(ServerConfigService serverConfigService) {
this.serverConfigService = serverConfigService;
this.restTemplate = new RestTemplate(clientHttpRequestFactory());
......
......@@ -5,8 +5,13 @@ import com.google.common.collect.Lists;
import com.ctrip.framework.apollo.portal.entity.bo.UserInfo;
import com.ctrip.framework.apollo.portal.spi.UserService;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Jason Song(song_s@ctrip.com)
......
......@@ -40,7 +40,6 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
ALL: 'all'
};
var MIN_ROW_SIZE = 10;
var operate_branch_storage_key = 'OperateBranch';
......@@ -642,7 +641,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
function parseModel2Text(namespace) {
if (namespace.items.length == 0) {
namespace.itemCnt = MIN_ROW_SIZE;
namespace.itemCnt = 0;
return "";
}
......@@ -658,7 +657,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
function parseNotPropertiesText(namespace) {
var text = namespace.items[0].item.value;
var lineNum = text.split("\n").length;
namespace.itemCnt = lineNum < MIN_ROW_SIZE ? MIN_ROW_SIZE : lineNum;
namespace.itemCnt = lineNum;
return text;
}
......@@ -682,7 +681,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
itemCnt++;
});
namespace.itemCnt = itemCnt < MIN_ROW_SIZE ? MIN_ROW_SIZE : itemCnt;
namespace.itemCnt = itemCnt;
return result;
}
......
......@@ -295,13 +295,15 @@
</div>
<!--text view-->
<!--只读模式下的文本内容,不替换换行符-->
<textarea class="form-control no-radius" rows="{{namespace.itemCnt}}"
<textarea class="form-control no-radius"
rows="{{namespace.itemCnt < 10 ? 10: namespace.itemCnt>20 ? 20:namespace.itemCnt}}"
ng-show="namespace.viewType == 'text' && !namespace.isTextEditing"
ng-disabled="!namespace.isTextEditing"
ng-bind="namespace.text">
</textarea>
<!--编辑状态下的文本内容,会过滤掉换行符-->
<textarea class="form-control" rows="{{namespace.itemCnt}}" style="border-radius: 0px"
<textarea class="form-control no-radius"
rows="{{namespace.itemCnt < 10 ? 10: namespace.itemCnt>20 ? 20:namespace.itemCnt}}"
ng-show="namespace.viewType == 'text' && namespace.isTextEditing"
ng-disabled="!namespace.isTextEditing" ng-model="namespace.editText">
</textarea>
......@@ -874,7 +876,8 @@
<!--gray rules-->
<div class="rules-manage-view row" ng-show="namespace.branch.viewType == 'rule'">
<div class="alert alert-warning no-radius" ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission">
<div class="alert alert-warning no-radius"
ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission">
<strong>Tips:</strong>
您没有权限编辑灰度规则, 具有namespace修改权或者发布权的人员才可以编辑灰度规则. 如需要编辑灰度规则,请找项目管理员申请权限.
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment