Skip to content

Commit

Permalink
add cat restapi transaction & fix email windows outlook bug
Browse files Browse the repository at this point in the history
  • Loading branch information
lepdou committed Dec 23, 2016
1 parent 66c2002 commit 561ad08
Show file tree
Hide file tree
Showing 16 changed files with 258 additions and 158 deletions.
Expand Up @@ -76,6 +76,11 @@ public List<Env> getActiveEnvs() {
return activeEnvs;
}

public boolean isEnvActive(Env env) {
Boolean mark = envStatusMark.get(env);
return mark == null ? false : mark;
}

private class HealthCheckTask implements Runnable {

private static final int ENV_DOWN_THRESHOLD = 2;
Expand Down
Expand Up @@ -85,6 +85,7 @@ private <T> T execute(HttpMethod method, Env env, String path, Object request, C

String uri = uriTemplateHandler.expand(path, uriVariables).getPath();
Transaction ct = Tracer.newTransaction("AdminAPI", uri);
ct.addData("Env", env);

List<ServiceDTO> services = getAdminServices(env, ct);

Expand Down Expand Up @@ -126,6 +127,7 @@ private <T> ResponseEntity<T> exchangeGet(Env env, String path, ParameterizedTyp

String uri = uriTemplateHandler.expand(path, uriVariables).getPath();
Transaction ct = Tracer.newTransaction("AdminAPI", uri);
ct.addData("Env", env);

List<ServiceDTO> services = getAdminServices(env, ct);

Expand Down
Expand Up @@ -101,6 +101,21 @@ public String portalAddress() {
/***
* Level: low
**/
public Set<Env> publishTipsSupportedEnvs() {
String[] configurations = getArrayProperty("namespace.publish.tips.supported.envs", null);

Set<Env> result = Sets.newHashSet();
if (configurations == null || configurations.length == 0) {
return result;
}

for (String env : configurations) {
result.add(Env.fromString(env));
}

return result;
}

public String consumerTokenSalt() {
return getValue("consumer.token.salt", "apollo-portal");
}
Expand All @@ -109,12 +124,20 @@ public String emailSender() {
return getValue("email.sender");
}

public String publishEmailBodyTemplate() {
return getValue("email.template.release.v2", "");
public String emailTemplateFramework() {
return getValue("email.template.framework", "");
}

public String emailReleaseDiffModuleTemplate() {
return getValue("email.template.release.module.diff", "");
}

public String rollbackEmailBodyTemplate() {
return getValue("email.template.rollback.v2", "");
public String emailRollbackDiffModuleTemplate() {
return getValue("email.template.rollback.module.diff", "");
}

public String emailGrayRulesModuleTemplate() {
return getValue("email.template.release.module.rules", "");
}

/***
Expand All @@ -139,6 +162,10 @@ public int survivalDuration() {
return getIntProperty("ctrip.email.survival.duration", 5);
}

public boolean isSendEmailAsync() {
return getBooleanProperty("email.send.async", true);
}

public String portalServerName() {
return getValue("serverName");
}
Expand Down
Expand Up @@ -47,15 +47,13 @@ public abstract class ConfigPublishEmailBuilder {
private static final String EMAIL_CONTENT_FIELD_RELEASE_TITLE = "#\\{releaseTitle}";
private static final String EMAIL_CONTENT_FIELD_RELEASE_COMMENT = "#\\{releaseComment}";
private static final String EMAIL_CONTENT_FIELD_APOLLO_SERVER_ADDRESS = "#\\{apollo.portal.address}";
private static final String EMAIL_CONTENT_FIELD_DIFF = "#\\{diff}";
private static final String EMAIL_CONTENT_FIELD_DIFF_CONTENT = "#\\{diffContent}";

//email content special field placeholder
protected static final String EMAIL_CONTENT_FIELD_RULE = "#\\{rules}";
private static final String EMAIL_CONTENT_DIFF_MODULE = "#\\{diffModule}";
protected static final String EMAIL_CONTENT_GRAY_RULES_MODULE = "#\\{rulesModule}";

//email content module switch
private static final String EMAIL_CONTENT_DIFF_HAS_CONTENT_SWITCH = "diff-hidden";
private static final String EMAIL_CONTENT_DIFF_HAS_NOT_CONTENT_SWITCH = "diff-empty-hidden";
protected static final String EMAIL_CONTENT_RULE_SWITCH = "rule-hidden";
//email content special field placeholder
protected static final String EMAIL_CONTENT_GRAY_RULES_CONTENT = "#\\{rulesContent}";

//set config's value max length to protect email.
protected static final int VALUE_MAX_LENGTH = 100;
Expand All @@ -72,65 +70,50 @@ public abstract class ConfigPublishEmailBuilder {
@Autowired
private UserService userService;
@Autowired
private PortalConfig portalConfig;


public Email build(Env env, ReleaseHistoryBO releaseHistory) {

Email email = new Email();

email.setSubject(subject());
email.setSenderEmailAddress(portalConfig.emailSender());
email.setBody(emailContent(env, releaseHistory));
email.setRecipients(recipients(releaseHistory.getAppId(), releaseHistory.getNamespaceName()));

return email;
}
protected PortalConfig portalConfig;

/**
* email subject
*/
protected abstract String subject();

/**
* email body content
*/
protected abstract String emailContent(Env env, ReleaseHistoryBO releaseHistory);

private List<String> recipients(String appId, String namespaceName) {
Set<UserInfo> modifyRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.MODIFY_NAMESPACE));
Set<UserInfo> releaseRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.RELEASE_NAMESPACE));
Set<UserInfo> owners = rolePermissionService.queryUsersWithRole(RoleUtils.buildAppMasterRoleName(appId));
/**
* email body template framework
*/
protected abstract String getTemplateFramework();

Set<String> userIds = new HashSet<>(modifyRoleUsers.size() + releaseRoleUsers.size() + owners.size());
/**
* email body diff module template
*/
protected abstract String getDiffModuleTemplate();

for (UserInfo userInfo : modifyRoleUsers) {
userIds.add(userInfo.getUserId());
}

for (UserInfo userInfo : releaseRoleUsers) {
userIds.add(userInfo.getUserId());
}

for (UserInfo userInfo : owners) {
userIds.add(userInfo.getUserId());
}
public Email build(Env env, ReleaseHistoryBO releaseHistory) {

List<UserInfo> userInfos = userService.findByUserIds(Lists.newArrayList(userIds));
Email email = new Email();

if (CollectionUtils.isEmpty(userInfos)){
return Collections.emptyList();
}
email.setSubject(subject());
email.setSenderEmailAddress(portalConfig.emailSender());
email.setRecipients(recipients(releaseHistory.getAppId(), releaseHistory.getNamespaceName()));

List<String> recipients = new ArrayList<>(userInfos.size());
for (UserInfo userInfo: userInfos){
recipients.add(userInfo.getEmail());
}
String emailBody = emailContent(env, releaseHistory);
//clear not used module
emailBody = emailBody.replaceAll(EMAIL_CONTENT_DIFF_MODULE, "");
emailBody = emailBody.replaceAll(EMAIL_CONTENT_GRAY_RULES_MODULE, "");
email.setBody(emailBody);

return recipients;
return email;
}

protected String renderEmailCommonContent(String template, Env env, ReleaseHistoryBO releaseHistory) {
protected String renderEmailCommonContent(Env env, ReleaseHistoryBO releaseHistory) {
String template = getTemplateFramework();
String renderResult = renderReleaseBasicInfo(template, env, releaseHistory);
renderResult = renderDiffContent(renderResult, env, releaseHistory);
renderResult = renderDiffModule(renderResult, env, releaseHistory);
return renderResult;
}

Expand All @@ -142,16 +125,16 @@ private String renderReleaseBasicInfo(String template, Env env, ReleaseHistoryBO
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.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_ID, String.valueOf(releaseHistory.getReleaseId()));
renderResult =
renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_HISTORY_ID, String.valueOf(releaseHistory.getId()));
renderResult.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_HISTORY_ID, String.valueOf(releaseHistory.getId()));
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()));
.replaceAll(EMAIL_CONTENT_FIELD_RELEASE_TIME, dateFormat.format(releaseHistory.getReleaseTime()));
}

private String renderDiffContent(String template, Env env, ReleaseHistoryBO releaseHistory) {
private String renderDiffModule(String bodyTemplate, Env env, ReleaseHistoryBO releaseHistory) {
String appId = releaseHistory.getAppId();
String namespaceName = releaseHistory.getNamespaceName();

Expand All @@ -162,16 +145,15 @@ private String renderDiffContent(String template, Env env, ReleaseHistoryBO rele

//don't show diff content if namespace's format is file
if (appNamespace == null ||
!appNamespace.getFormat().equals(ConfigFileFormat.Properties.getValue())) {
!appNamespace.getFormat().equals(ConfigFileFormat.Properties.getValue())) {

return template.replaceAll(EMAIL_CONTENT_FIELD_DIFF, "请点击链接到Apollo上查看");
return bodyTemplate.replaceAll(EMAIL_CONTENT_DIFF_MODULE, "<br><h4>变更内容请点击链接到Apollo上查看</h4>");
}

ReleaseCompareResult result = getReleaseCompareResult(env, releaseHistory);

if (!result.hasContent()) {
String renderResult = template.replaceAll(EMAIL_CONTENT_DIFF_HAS_NOT_CONTENT_SWITCH, "");
return renderResult.replaceAll(EMAIL_CONTENT_FIELD_DIFF, "");
return bodyTemplate.replaceAll(EMAIL_CONTENT_DIFF_MODULE, "<br><h4>无配置变更</h4>");
}

List<Change> changes = result.getChanges();
Expand All @@ -184,23 +166,24 @@ private String renderDiffContent(String template, Env env, ReleaseHistoryBO rele

changesHtmlBuilder.append("<tr>");
changesHtmlBuilder.append("<td width=\"10%\">").append(change.getType().toString()).append("</td>");
changesHtmlBuilder.append("<td width=\"10%\">").append(cutOffString(key)).append("</td>");
changesHtmlBuilder.append("<td width=\"10%\">").append(cutOffString(oldValue)).append("</td>");
changesHtmlBuilder.append("<td width=\"10%\">").append(cutOffString(newValue)).append("</td>");
changesHtmlBuilder.append("<td width=\"20%\">").append(cutOffString(key)).append("</td>");
changesHtmlBuilder.append("<td width=\"35%\">").append(cutOffString(oldValue)).append("</td>");
changesHtmlBuilder.append("<td width=\"35%\">").append(cutOffString(newValue)).append("</td>");

changesHtmlBuilder.append("</tr>");
}

String diffContent = Matcher.quoteReplacement(changesHtmlBuilder.toString());
String renderResult = template.replaceAll(EMAIL_CONTENT_FIELD_DIFF, diffContent);
return renderResult.replaceAll(EMAIL_CONTENT_DIFF_HAS_CONTENT_SWITCH, "");
String diffModuleTemplate = getDiffModuleTemplate();
String diffModuleRenderResult = diffModuleTemplate.replaceAll(EMAIL_CONTENT_FIELD_DIFF_CONTENT, diffContent);
return bodyTemplate.replaceAll(EMAIL_CONTENT_DIFF_MODULE, diffModuleRenderResult);
}

private ReleaseCompareResult getReleaseCompareResult(Env env, ReleaseHistoryBO releaseHistory) {
if (releaseHistory.getOperation() == ReleaseOperation.GRAY_RELEASE
&& releaseHistory.getPreviousReleaseId() == 0) {
&& releaseHistory.getPreviousReleaseId() == 0) {
ReleaseDTO masterLatestActiveRelease = releaseService.loadLatestRelease(
releaseHistory.getAppId(), env, releaseHistory.getClusterName(), releaseHistory.getNamespaceName());
releaseHistory.getAppId(), env, releaseHistory.getClusterName(), releaseHistory.getNamespaceName());
ReleaseDTO branchLatestActiveRelease = releaseService.findReleaseById(env, releaseHistory.getReleaseId());

return releaseService.compare(masterLatestActiveRelease, branchLatestActiveRelease);
Expand All @@ -209,13 +192,41 @@ private ReleaseCompareResult getReleaseCompareResult(Env env, ReleaseHistoryBO r
return releaseService.compare(env, releaseHistory.getPreviousReleaseId(), releaseHistory.getReleaseId());
}

private List<String> recipients(String appId, String namespaceName) {
Set<UserInfo> modifyRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.MODIFY_NAMESPACE));
Set<UserInfo> releaseRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.RELEASE_NAMESPACE));
Set<UserInfo> owners = rolePermissionService.queryUsersWithRole(RoleUtils.buildAppMasterRoleName(appId));

Set<String> userIds = new HashSet<>(modifyRoleUsers.size() + releaseRoleUsers.size() + owners.size());

protected String getReleaseTemplate() {
return portalConfig.publishEmailBodyTemplate();
}
for (UserInfo userInfo : modifyRoleUsers) {
userIds.add(userInfo.getUserId());
}

protected String getRollbackTemplate() {
return portalConfig.rollbackEmailBodyTemplate();
for (UserInfo userInfo : releaseRoleUsers) {
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;
}

protected String getApolloPortalAddress() {
Expand Down
Expand Up @@ -31,36 +31,48 @@ protected String subject() {

@Override
public String emailContent(Env env, ReleaseHistoryBO releaseHistory) {
String result = renderEmailCommonContent(getReleaseTemplate(), env, releaseHistory);
String result = renderEmailCommonContent(env, releaseHistory);
return renderGrayReleaseRuleContent(result, releaseHistory);
}

private String renderGrayReleaseRuleContent(String template, ReleaseHistoryBO releaseHistory) {
String result = template.replaceAll(EMAIL_CONTENT_RULE_SWITCH, "");
@Override
protected String getTemplateFramework() {
return portalConfig.emailTemplateFramework();
}

@Override
protected String getDiffModuleTemplate() {
return portalConfig.emailReleaseDiffModuleTemplate();
}

private String renderGrayReleaseRuleContent(String bodyTemplate, ReleaseHistoryBO releaseHistory) {

Map<String, Object> context = releaseHistory.getOperationContext();
Object rules = context.get("rules");
List<GrayReleaseRuleItemDTO>
ruleItems = rules == null ?
null : gson.fromJson(rules.toString(), GsonType.RULE_ITEMS);
ruleItems = rules == null ?
null : gson.fromJson(rules.toString(), GsonType.RULE_ITEMS);


StringBuilder rulesHtmlBuilder = new StringBuilder();
if (CollectionUtils.isEmpty(ruleItems)) {
rulesHtmlBuilder.append("无灰度规则");
return bodyTemplate.replaceAll(EMAIL_CONTENT_GRAY_RULES_MODULE, "<br><h4>无灰度规则</h4>");
} else {
StringBuilder rulesHtmlBuilder = new StringBuilder();
for (GrayReleaseRuleItemDTO ruleItem : ruleItems) {
String clientAppId = ruleItem.getClientAppId();
Set<String> ips = ruleItem.getClientIpList();

rulesHtmlBuilder.append("<b>AppId:&nbsp;</b>")
.append(clientAppId)
.append("&nbsp;&nbsp; <b>IP:&nbsp;</b>");
.append(clientAppId)
.append("&nbsp;&nbsp; <b>IP:&nbsp;</b>");

IP_JOINER.appendTo(rulesHtmlBuilder, ips);
}
}
String grayRulesModuleContent = portalConfig.emailGrayRulesModuleTemplate().replaceAll(EMAIL_CONTENT_GRAY_RULES_CONTENT,
Matcher.quoteReplacement(rulesHtmlBuilder.toString()));

return result.replaceAll(EMAIL_CONTENT_FIELD_RULE, Matcher.quoteReplacement(rulesHtmlBuilder.toString()));
return bodyTemplate.replaceAll(EMAIL_CONTENT_GRAY_RULES_MODULE, Matcher.quoteReplacement(grayRulesModuleContent));
}

}
}

0 comments on commit 561ad08

Please sign in to comment.