Skip to content

Commit 53ffca0

Browse files
authored
Merge branch 'master' into 0722-yuluo/optimize-collector
2 parents 5b47df7 + b00a50a commit 53ffca0

File tree

7 files changed

+232
-171
lines changed

7 files changed

+232
-171
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.hertzbeat.common.util;
19+
20+
import javax.naming.AuthenticationException;
21+
22+
import org.apache.hertzbeat.common.constants.CommonConstants;
23+
import org.apache.hertzbeat.common.entity.dto.Message;
24+
import org.springframework.http.ResponseEntity;
25+
26+
/**
27+
* A tool which make the restful response be easy to use
28+
*/
29+
public class ResponseUtil {
30+
public static <T, E extends Exception> ResponseEntity<Message<T>> handle(Supplier<T, E> supplier) {
31+
try {
32+
T result = supplier.get();
33+
return ResponseEntity.ok(Message.success(result));
34+
} catch (Exception e) {
35+
byte err = CommonConstants.FAIL_CODE;
36+
if (e.getClass().equals(AuthenticationException.class)) {
37+
err = CommonConstants.LOGIN_FAILED_CODE;
38+
}
39+
return ResponseEntity.ok(Message.fail(err, e.getMessage()));
40+
}
41+
}
42+
43+
public static <T, E extends Exception> ResponseEntity<Message<T>> handle(Runnable runner) {
44+
try {
45+
runner.run();
46+
return ResponseEntity.ok(Message.success());
47+
} catch (Exception e) {
48+
byte err = CommonConstants.FAIL_CODE;
49+
if (e.getClass().equals(AuthenticationException.class)) {
50+
err = CommonConstants.LOGIN_FAILED_CODE;
51+
}
52+
return ResponseEntity.ok(Message.fail(err, e.getMessage()));
53+
}
54+
}
55+
56+
/**
57+
* Supplier interface for getting result
58+
*/
59+
public interface Supplier<T, E extends Exception> {
60+
61+
/**
62+
* Gets a result.
63+
*
64+
* @return a result
65+
*/
66+
T get() throws E;
67+
}
68+
69+
}

manager/src/main/java/org/apache/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java

Lines changed: 134 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,15 @@
1717

1818
package org.apache.hertzbeat.manager.component.alerter.impl;
1919

20-
import com.fasterxml.jackson.annotation.JsonProperty;
21-
import java.util.ArrayList;
22-
import java.util.Collections;
23-
import java.util.List;
24-
import lombok.Data;
20+
import java.util.Arrays;
21+
import java.util.stream.Collectors;
2522
import lombok.RequiredArgsConstructor;
2623
import lombok.extern.slf4j.Slf4j;
24+
import org.apache.commons.lang3.StringUtils;
2725
import org.apache.hertzbeat.common.entity.alerter.Alert;
2826
import org.apache.hertzbeat.common.entity.manager.NoticeReceiver;
2927
import org.apache.hertzbeat.common.entity.manager.NoticeTemplate;
30-
import org.apache.hertzbeat.common.util.StrUtil;
28+
import org.apache.hertzbeat.common.util.JsonUtil;
3129
import org.apache.hertzbeat.manager.support.exception.AlertNoticeException;
3230
import org.springframework.http.HttpEntity;
3331
import org.springframework.http.HttpHeaders;
@@ -44,59 +42,23 @@
4442
@Slf4j
4543
final class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl {
4644

45+
/**
46+
* Title color corresponding to the alarm priority
47+
*/
48+
private static final String[] TITLE_COLOR = {"red", "yellow", "orange"};
49+
50+
4751
@Override
4852
public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) {
4953
try {
50-
FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto();
51-
flyBookWebHookDto.setMsgType("post");
52-
53-
Content content = new Content();
54-
flyBookWebHookDto.setContent(content);
55-
56-
Post post = new Post();
57-
content.setPost(post);
58-
59-
ZhCn zhCn = new ZhCn();
60-
post.setZhCn(zhCn);
61-
62-
zhCn.setTitle("[" + bundle.getString("alerter.notify.title") + "]");
63-
64-
List<FlyBookContent> contentList = new ArrayList<>();
65-
66-
FlyBookContent textContent = new FlyBookContent();
67-
textContent.setTag("text");
68-
textContent.setText(renderContent(noticeTemplate, alert));
69-
contentList.add(textContent);
70-
71-
FlyBookContent linkContent = new FlyBookContent();
72-
linkContent.setTag("a");
73-
linkContent.setText(bundle.getString("alerter.notify.console"));
74-
linkContent.setHref(alerterProperties.getConsoleUrl());
75-
contentList.add(linkContent);
76-
77-
String userId = receiver.getUserId();
78-
List<String> userIdList = StrUtil.analysisArgToList(userId);
79-
if (userIdList != null && !userIdList.isEmpty()) {
80-
List<FlyBookContent> atContents = userIdList.stream()
81-
.map(userID -> {
82-
FlyBookContent atContent = new FlyBookContent();
83-
atContent.setTag("at");
84-
atContent.setUserId(userID);
85-
return atContent;
86-
})
87-
.toList();
88-
contentList.addAll(atContents);
89-
}
90-
91-
List<List<FlyBookContent>> contents = Collections.singletonList(contentList);
92-
zhCn.setContent(contents);
93-
54+
String notificationContent = JsonUtil.toJson(renderContent(noticeTemplate, alert));
55+
String cardMessage = createLarkMessage(receiver.getUserId(), notificationContent, alert.getPriority());
9456
String webHookUrl = alerterProperties.getFlyBookWebhookUrl() + receiver.getAccessToken();
9557
HttpHeaders headers = new HttpHeaders();
9658
headers.setContentType(MediaType.APPLICATION_JSON);
97-
HttpEntity<FlyBookWebHookDto> flyEntity = new HttpEntity<>(flyBookWebHookDto, headers);
59+
HttpEntity<String> flyEntity = new HttpEntity<>(cardMessage, headers);
9860
ResponseEntity<CommonRobotNotifyResp> entity = restTemplate.postForEntity(webHookUrl,
99-
flyEntity, CommonRobotNotifyResp.class);
61+
flyEntity, CommonRobotNotifyResp.class);
10062
if (entity.getStatusCode() == HttpStatus.OK) {
10163
assert entity.getBody() != null;
10264
if (entity.getBody().getCode() == null || entity.getBody().getCode() == 0) {
@@ -114,77 +76,129 @@ public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert a
11476
}
11577
}
11678

117-
118-
@Override
119-
public byte type() {
120-
return 6;
121-
}
122-
123-
@Data
124-
private static class FlyBookWebHookDto {
125-
126-
private static final String DEFAULT_MSG_TYPE = "post";
127-
128-
/**
129-
* Message type
130-
*/
131-
@JsonProperty("msg_type")
132-
private String msgType = DEFAULT_MSG_TYPE;
133-
134-
135-
private Content content;
136-
137-
}
138-
13979
/**
140-
* Message content
80+
* create a lark notification card message
81+
*
82+
* @param userId at user id
83+
* @param notificationContent notification content
84+
* @param priority priority for alert
85+
* @return message
14186
*/
142-
@Data
143-
private static class Content {
144-
public Post post;
145-
}
146-
147-
@Data
148-
private static class FlyBookContent {
149-
/**
150-
* format currently supports text、hyperlink、@people function
151-
*/
152-
public String tag;
153-
154-
/**
155-
* text
156-
*/
157-
public String text;
158-
159-
/**
160-
* hyperlink address
161-
*/
162-
public String href;
163-
164-
@JsonProperty("user_id")
165-
public String userId;
166-
167-
@JsonProperty("user_name")
168-
public String userName;
169-
}
170-
171-
@Data
172-
private static class Post {
173-
@JsonProperty("zh_cn")
174-
public ZhCn zhCn;
87+
private String createLarkMessage(String userId, String notificationContent, byte priority) {
88+
String larkCardMessage = """
89+
{
90+
"msg_type": "interactive",
91+
"card": {
92+
"config": {
93+
"update_multi": true
94+
},
95+
"i18n_elements": {
96+
"zh_cn": [
97+
{
98+
"tag": "column_set",
99+
"flex_mode": "none",
100+
"horizontal_spacing": "default",
101+
"background_style": "default",
102+
"columns": [
103+
{
104+
"tag": "column",
105+
"elements": [
106+
{
107+
"tag": "div",
108+
"text": {
109+
"tag": "plain_text",
110+
"content": "",
111+
"text_size": "normal",
112+
"text_align": "left",
113+
"text_color": "default"
114+
}
115+
}
116+
],
117+
"width": "weighted",
118+
"weight": 1
119+
}
120+
]
121+
},
122+
{
123+
"tag": "column_set",
124+
"flex_mode": "none",
125+
"horizontal_spacing": "default",
126+
"background_style": "default",
127+
"columns": [
128+
{
129+
"tag": "column",
130+
"elements": [
131+
{
132+
"tag": "div",
133+
"text": {
134+
"tag": "plain_text",
135+
"content": %s,
136+
"text_size": "normal",
137+
"text_align": "left",
138+
"text_color": "default"
139+
}
140+
}
141+
],
142+
"width": "weighted",
143+
"weight": 1
144+
}
145+
]
146+
},
147+
%s
148+
{
149+
"tag": "action",
150+
"actions": [
151+
{
152+
"tag": "button",
153+
"text": {
154+
"tag": "plain_text",
155+
"content": "登入控制台"
156+
},
157+
"type": "default",
158+
"complex_interaction": true,
159+
"width": "default",
160+
"size": "medium",
161+
"multi_url": {
162+
"url": "%s"
163+
}
164+
}
165+
]
166+
}
167+
]
168+
},
169+
"i18n_header": {
170+
"zh_cn": {
171+
"title": {
172+
"tag": "plain_text",
173+
"content": "HertzBeat 告警"
174+
},
175+
"template": "%s"
176+
}
177+
}
178+
}
179+
}
180+
""";
181+
182+
String atUserElement = "";
183+
if (StringUtils.isNotBlank(userId)) {
184+
String atUserId = Arrays.stream(userId.split(","))
185+
.map(id -> "<at id=" + id + "></at>")
186+
.collect(Collectors.joining(" "));
187+
atUserElement = String.format("""
188+
{
189+
"tag": "div",
190+
"text": {
191+
"content": "%s",
192+
"tag": "lark_md"
193+
}
194+
},
195+
""", atUserId);
196+
}
197+
return String.format(larkCardMessage, notificationContent, atUserElement, alerterProperties.getConsoleUrl(), TITLE_COLOR[priority]);
175198
}
176199

177-
@Data
178-
private static class ZhCn {
179-
/**
180-
* Title
181-
*/
182-
public String title;
183-
184-
/**
185-
* Content
186-
*/
187-
public List<List<FlyBookContent>> content;
200+
@Override
201+
public byte type() {
202+
return 6;
188203
}
189-
190204
}

manager/src/main/java/org/apache/hertzbeat/manager/controller/AccountController.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import javax.naming.AuthenticationException;
3030
import lombok.extern.slf4j.Slf4j;
3131
import org.apache.hertzbeat.common.entity.dto.Message;
32+
import org.apache.hertzbeat.common.util.ResponseUtil;
3233
import org.apache.hertzbeat.manager.pojo.dto.LoginDto;
3334
import org.apache.hertzbeat.manager.pojo.dto.RefreshTokenResponse;
3435
import org.apache.hertzbeat.manager.service.AccountService;
@@ -56,11 +57,7 @@ public class AccountController {
5657
@PostMapping("/form")
5758
@Operation(summary = "Account password login to obtain associated user information", description = "Account password login to obtain associated user information")
5859
public ResponseEntity<Message<Map<String, String>>> authGetToken(@Valid @RequestBody LoginDto loginDto) {
59-
try {
60-
return ResponseEntity.ok(Message.success(accountService.authGetToken(loginDto)));
61-
} catch (AuthenticationException e) {
62-
return ResponseEntity.ok(Message.fail(LOGIN_FAILED_CODE, e.getMessage()));
63-
}
60+
return ResponseUtil.handle(() -> accountService.authGetToken(loginDto));
6461
}
6562

6663
@GetMapping("/refresh/{refreshToken}")

0 commit comments

Comments
 (0)