Skip to content

Commit 873ea6b

Browse files
committed
refactor email builder
1 parent f144fe0 commit 873ea6b

File tree

8 files changed

+73
-27
lines changed

8 files changed

+73
-27
lines changed

apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/components/emailbuilder/ConfigPublishEmailBuilder.java

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package com.ctrip.framework.apollo.portal.components.emailbuilder;
22

33

4+
import com.google.common.collect.Lists;
5+
46
import com.ctrip.framework.apollo.common.constants.ReleaseOperation;
57
import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
68
import com.ctrip.framework.apollo.common.entity.AppNamespace;
9+
import com.ctrip.framework.apollo.common.utils.BeanUtils;
710
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
811
import com.ctrip.framework.apollo.core.enums.Env;
912
import com.ctrip.framework.apollo.portal.constant.RoleType;
@@ -16,15 +19,20 @@
1619
import com.ctrip.framework.apollo.portal.service.ReleaseService;
1720
import com.ctrip.framework.apollo.portal.service.RolePermissionService;
1821
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
22+
import com.ctrip.framework.apollo.portal.spi.UserService;
1923
import com.ctrip.framework.apollo.portal.util.RoleUtils;
2024

2125
import org.apache.commons.lang.time.FastDateFormat;
2226
import org.springframework.beans.factory.annotation.Autowired;
2327
import org.springframework.beans.factory.annotation.Value;
28+
import org.springframework.util.CollectionUtils;
2429

2530
import java.util.ArrayList;
31+
import java.util.Collections;
32+
import java.util.HashSet;
2633
import java.util.List;
2734
import java.util.Set;
35+
import java.util.regex.Matcher;
2836

2937
import javax.annotation.PostConstruct;
3038

@@ -62,7 +70,6 @@ public abstract class ConfigPublishEmailBuilder {
6270
private FastDateFormat dateFormat = FastDateFormat.getInstance("yyyy-MM-dd hh:mm:ss");
6371

6472

65-
private String emailAddressSuffix;
6673
private String emailSender;
6774

6875
@Autowired
@@ -73,10 +80,11 @@ public abstract class ConfigPublishEmailBuilder {
7380
private ReleaseService releaseService;
7481
@Autowired
7582
private AppNamespaceService appNamespaceService;
83+
@Autowired
84+
private UserService userService;
7685

7786
@PostConstruct
7887
public void init() {
79-
emailAddressSuffix = serverConfigService.getValue("email.address.suffix");
8088
emailSender = serverConfigService.getValue("email.sender");
8189
}
8290

@@ -103,15 +111,31 @@ private List<String> recipients(String appId, String namespaceName) {
103111
Set<UserInfo> releaseRoleUsers =
104112
rolePermissionService
105113
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.RELEASE_NAMESPACE));
114+
Set<UserInfo> owners = rolePermissionService.queryUsersWithRole(RoleUtils.buildAppMasterRoleName(appId));
106115

107-
List<String> recipients = new ArrayList<>(modifyRoleUsers.size() + releaseRoleUsers.size());
116+
Set<String> userIds = new HashSet<>(modifyRoleUsers.size() + releaseRoleUsers.size() + owners.size());
108117

109118
for (UserInfo userInfo : modifyRoleUsers) {
110-
recipients.add(userInfo.getUserId() + emailAddressSuffix);
119+
userIds.add(userInfo.getUserId());
111120
}
112121

113122
for (UserInfo userInfo : releaseRoleUsers) {
114-
recipients.add(userInfo.getUserId() + emailAddressSuffix);
123+
userIds.add(userInfo.getUserId());
124+
}
125+
126+
for (UserInfo userInfo : owners) {
127+
userIds.add(userInfo.getUserId());
128+
}
129+
130+
List<UserInfo> userInfos = userService.findByUserIds(Lists.newArrayList(userIds));
131+
132+
if (CollectionUtils.isEmpty(userInfos)){
133+
return Collections.emptyList();
134+
}
135+
136+
List<String> recipients = new ArrayList<>(userInfos.size());
137+
for (UserInfo userInfo: userInfos){
138+
recipients.add(userInfo.getEmail());
115139
}
116140

117141
return recipients;
@@ -124,15 +148,15 @@ protected String renderEmailCommonContent(String template, Env env, ReleaseHisto
124148
}
125149

126150
private String renderReleaseBasicInfo(String template, Env env, ReleaseHistoryBO releaseHistory) {
127-
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_APPID, releaseHistory.getAppId());
128-
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_ENV, env.toString());
129-
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_CLUSTER, releaseHistory.getClusterName());
130-
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_NAMESPACE, releaseHistory.getNamespaceName());
131-
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_OPERATOR, releaseHistory.getOperator());
132-
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_TITLE, releaseHistory.getReleaseTitle());
151+
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_APPID, Matcher.quoteReplacement(releaseHistory.getAppId()));
152+
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_ENV, Matcher.quoteReplacement(env.toString()));
153+
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_CLUSTER, Matcher.quoteReplacement(releaseHistory.getClusterName()));
154+
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_NAMESPACE, Matcher.quoteReplacement(releaseHistory.getNamespaceName()));
155+
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_OPERATOR, Matcher.quoteReplacement(releaseHistory.getOperator()));
156+
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_TITLE, Matcher.quoteReplacement(releaseHistory.getReleaseTitle()));
133157
renderResult =
134158
renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_ID, String.valueOf(releaseHistory.getReleaseId()));
135-
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_COMMENT, releaseHistory.getReleaseComment());
159+
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_COMMENT, Matcher.quoteReplacement(releaseHistory.getReleaseComment()));
136160
renderResult = renderResult.replaceAll(EMAIL_CONTENT_FIELD_APOLLO_SERVER_ADDRESS, getApolloPortalAddress());
137161
return renderResult
138162
.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_TIME, dateFormat.format(releaseHistory.getReleaseTime()));
@@ -150,7 +174,8 @@ private String renderDiffContent(String template, Env env, ReleaseHistoryBO rele
150174
//don't show diff content if namespace's format is file
151175
if (appNamespace == null ||
152176
!appNamespace.getFormat().equals(ConfigFileFormat.Properties.getValue())) {
153-
return template;
177+
178+
return template.replaceAll(EMAIL_CONTENT_FIELD_DIFF, "请点击链接到Apollo上查看");
154179
}
155180

156181
ReleaseCompareResult result = getReleaseCompareResult(env, releaseHistory);
@@ -177,7 +202,8 @@ private String renderDiffContent(String template, Env env, ReleaseHistoryBO rele
177202
changesHtmlBuilder.append("</tr>");
178203
}
179204

180-
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_DIFF, changesHtmlBuilder.toString());
205+
String diffContent = Matcher.quoteReplacement(changesHtmlBuilder.toString());
206+
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_DIFF, diffContent);
181207
return renderResult.replaceAll(EMAIL_CONTENT_DIFF_HAS_CONTENT_SWITCH, "");
182208
}
183209

@@ -214,5 +240,4 @@ private String cutOffString(String source) {
214240
return source;
215241
}
216242

217-
218243
}

apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/components/emailbuilder/GrayPublishEmailBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.List;
1414
import java.util.Map;
1515
import java.util.Set;
16+
import java.util.regex.Matcher;
1617

1718
@Component
1819
public class GrayPublishEmailBuilder extends ConfigPublishEmailBuilder {
@@ -59,7 +60,7 @@ private String renderGrayReleaseRuleContent(String template, ReleaseHistoryBO re
5960
}
6061
}
6162

62-
return result.replaceAll(EMAIL_CONTENT_FIELD_RULE, rulesHtmlBuilder.toString());
63+
return result.replaceAll(EMAIL_CONTENT_FIELD_RULE, Matcher.quoteReplacement(rulesHtmlBuilder.toString()));
6364

6465
}
6566
}

apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/ConfigPublishListener.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import com.ctrip.framework.apollo.portal.spi.EmailService;
1414
import com.ctrip.framework.apollo.tracer.Tracer;
1515

16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
1618
import org.springframework.beans.factory.annotation.Autowired;
1719
import org.springframework.context.event.EventListener;
1820
import org.springframework.stereotype.Component;
@@ -24,6 +26,7 @@
2426

2527
@Component
2628
public class ConfigPublishListener {
29+
private static final Logger logger = LoggerFactory.getLogger(ConfigPublishListener.class);
2730

2831
@Autowired
2932
private ServerConfigService serverConfigService;
@@ -53,6 +56,7 @@ public void init() {
5356
emailSupportedEnvs.add(Env.fromString(env.trim()));
5457
}
5558
} catch (Exception e) {
59+
logger.error("init email supported envs failed.", e);
5660
Tracer.logError("init email supported envs failed.", e);
5761
}
5862

@@ -75,12 +79,16 @@ public void onConfigPublish(ConfigPublishEvent event) {
7579

7680
int realOperation = releaseHistory.getOperation();
7781

78-
Email email = buildEmail(env, releaseHistory, realOperation);
82+
Email email = null;
83+
try {
84+
email = buildEmail(env, releaseHistory, realOperation);
85+
} catch (Throwable e) {
86+
Tracer.logError("build email failed.", e);
87+
}
7988

8089
if (email != null) {
8190
emailService.send(email);
8291
}
83-
8492
}
8593

8694
private ReleaseHistoryBO getReleaseHistory(ConfigPublishEvent event) {
@@ -99,7 +107,7 @@ private ReleaseHistoryBO getReleaseHistory(ConfigPublishEvent event) {
99107
if (info.isRollbackEvent()) {
100108
return releaseHistoryService
101109
.findLatestByPreviousReleaseIdAndOperation(env, info.getPreviousReleaseId(), operation);
102-
}else {
110+
} else {
103111
return releaseHistoryService.findLatestByReleaseIdAndOperation(env, info.getReleaseId(), operation);
104112
}
105113

apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/UserService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.ctrip.framework.apollo.portal.entity.bo.UserInfo;
44

55
import java.util.List;
6+
import java.util.Set;
67

78
/**
89
* @author Jason Song(song_s@ctrip.com)
@@ -13,4 +14,5 @@ public interface UserService {
1314
UserInfo findByUserId(String userId);
1415

1516
List<UserInfo> findByUserIds(List<String> userIds);
17+
1618
}

apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/ctrip/CtripUserService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
import org.springframework.web.client.RestTemplate;
1919

2020
import java.util.Collections;
21+
import java.util.HashSet;
2122
import java.util.List;
2223
import java.util.Map;
24+
import java.util.Set;
2325
import java.util.stream.Collectors;
2426

2527
/**
@@ -31,6 +33,7 @@ public class CtripUserService implements UserService {
3133
private List<String> searchUserMatchFields;
3234
private ParameterizedTypeReference<Map<String, List<UserServiceResponse>>> responseType;
3335

36+
3437
public CtripUserService(ServerConfigService serverConfigService) {
3538
this.serverConfigService = serverConfigService;
3639
this.restTemplate = new RestTemplate(clientHttpRequestFactory());

apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultUserService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55
import com.ctrip.framework.apollo.portal.entity.bo.UserInfo;
66
import com.ctrip.framework.apollo.portal.spi.UserService;
77

8+
import org.springframework.util.CollectionUtils;
9+
810
import java.util.Arrays;
11+
import java.util.Collections;
12+
import java.util.HashSet;
913
import java.util.List;
14+
import java.util.Set;
1015

1116
/**
1217
* @author Jason Song(song_s@ctrip.com)

apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
4040
ALL: 'all'
4141
};
4242

43-
var MIN_ROW_SIZE = 10;
4443

4544
var operate_branch_storage_key = 'OperateBranch';
4645

@@ -642,7 +641,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
642641
function parseModel2Text(namespace) {
643642

644643
if (namespace.items.length == 0) {
645-
namespace.itemCnt = MIN_ROW_SIZE;
644+
namespace.itemCnt = 0;
646645
return "";
647646
}
648647

@@ -658,7 +657,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
658657
function parseNotPropertiesText(namespace) {
659658
var text = namespace.items[0].item.value;
660659
var lineNum = text.split("\n").length;
661-
namespace.itemCnt = lineNum < MIN_ROW_SIZE ? MIN_ROW_SIZE : lineNum;
660+
namespace.itemCnt = lineNum;
662661
return text;
663662
}
664663

@@ -682,10 +681,10 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
682681
itemCnt++;
683682
});
684683

685-
namespace.itemCnt = itemCnt < MIN_ROW_SIZE ? MIN_ROW_SIZE : itemCnt;
684+
namespace.itemCnt = itemCnt;
686685
return result;
687686
}
688-
687+
689688
function toggleItemSearchInput(namespace) {
690689
namespace.showSearchInput = !namespace.showSearchInput;
691690
}

apollo-portal/src/main/resources/static/views/component/namespace-panel.html

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,15 @@
295295
</div>
296296
<!--text view-->
297297
<!--只读模式下的文本内容,不替换换行符-->
298-
<textarea class="form-control no-radius" rows="{{namespace.itemCnt}}"
298+
<textarea class="form-control no-radius"
299+
rows="{{namespace.itemCnt < 10 ? 10: namespace.itemCnt>20 ? 20:namespace.itemCnt}}"
299300
ng-show="namespace.viewType == 'text' && !namespace.isTextEditing"
300301
ng-disabled="!namespace.isTextEditing"
301302
ng-bind="namespace.text">
302303
</textarea>
303304
<!--编辑状态下的文本内容,会过滤掉换行符-->
304-
<textarea class="form-control" rows="{{namespace.itemCnt}}" style="border-radius: 0px"
305+
<textarea class="form-control no-radius"
306+
rows="{{namespace.itemCnt < 10 ? 10: namespace.itemCnt>20 ? 20:namespace.itemCnt}}"
305307
ng-show="namespace.viewType == 'text' && namespace.isTextEditing"
306308
ng-disabled="!namespace.isTextEditing" ng-model="namespace.editText">
307309
</textarea>
@@ -874,7 +876,8 @@
874876
<!--gray rules-->
875877
<div class="rules-manage-view row" ng-show="namespace.branch.viewType == 'rule'">
876878

877-
<div class="alert alert-warning no-radius" ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission">
879+
<div class="alert alert-warning no-radius"
880+
ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission">
878881
<strong>Tips:</strong>
879882
您没有权限编辑灰度规则, 具有namespace修改权或者发布权的人员才可以编辑灰度规则. 如需要编辑灰度规则,请找项目管理员申请权限.
880883
</div>

0 commit comments

Comments
 (0)