mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 17:50:29 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8c48991b8 | ||
|
|
dc8ae844c1 | ||
|
|
91a7593b87 | ||
|
|
4442a52adf | ||
|
|
f009629c8b | ||
|
|
60e3437e82 | ||
|
|
a9d0ad9af6 | ||
|
|
78ae893271 |
+12
-1
@@ -31,6 +31,8 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Send alarm information through Server
|
||||
*/
|
||||
@@ -54,7 +56,16 @@ public class ServerChanAlertNotifyHandlerImpl extends AbstractAlertNotifyHandler
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<ServerChanAlertNotifyHandlerImpl.ServerChanWebHookDto> httpEntity = new HttpEntity<>(serverChanWebHookDto, headers);
|
||||
String webHookUrl = String.format(alerterProperties.getServerChanWebhookUrl(), receiver.getServerChanToken());
|
||||
String sanitizedToken = receiver.getServerChanToken().replaceAll("[^a-zA-Z0-9_-]", "");
|
||||
String webHookUrl = String.format(alerterProperties.getServerChanWebhookUrl(), sanitizedToken);
|
||||
|
||||
// Validate the constructed URL against a whitelist
|
||||
List<String> allowedBaseUrls = List.of("https://api.serverchan.com", "https://serverchan.example.com");
|
||||
boolean isValidUrl = allowedBaseUrls.stream().anyMatch(webHookUrl::startsWith);
|
||||
if (!isValidUrl) {
|
||||
throw new AlertNoticeException("Invalid webhook URL: " + webHookUrl);
|
||||
}
|
||||
|
||||
ResponseEntity<CommonRobotNotifyResp> responseEntity = restTemplate.postForEntity(webHookUrl,
|
||||
httpEntity, CommonRobotNotifyResp.class);
|
||||
if (responseEntity.getStatusCode() == HttpStatus.OK) {
|
||||
|
||||
+24
-1
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.notice.impl;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Objects;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -52,7 +53,12 @@ final class SlackAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<SlackNotifyDTO> slackNotifyEntity = new HttpEntity<>(slackNotify, headers);
|
||||
var entity = restTemplate.postForEntity(receiver.getSlackWebHookUrl(), slackNotifyEntity, String.class);
|
||||
String slackWebHookUrl = receiver.getSlackWebHookUrl();
|
||||
if (!isValidSlackWebHookUrl(slackWebHookUrl)) {
|
||||
log.warn("Invalid Slack Webhook URL: {}", slackWebHookUrl);
|
||||
throw new AlertNoticeException("Invalid Slack Webhook URL");
|
||||
}
|
||||
var entity = restTemplate.postForEntity(slackWebHookUrl, slackNotifyEntity, String.class);
|
||||
if (entity.getStatusCode() == HttpStatus.OK && entity.getBody() != null) {
|
||||
var body = entity.getBody();
|
||||
if (Objects.equals(SUCCESS, body)) {
|
||||
@@ -81,4 +87,21 @@ final class SlackAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl {
|
||||
private String text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate if the Slack Webhook URL belongs to an allowed domain.
|
||||
*
|
||||
* @param url the Slack Webhook URL to validate
|
||||
* @return true if the URL is valid, false otherwise
|
||||
*/
|
||||
private boolean isValidSlackWebHookUrl(String url) {
|
||||
try {
|
||||
URI uri = new URI(url);
|
||||
String host = uri.getHost();
|
||||
return "hooks.slack.com".equals(host);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error validating Slack Webhook URL: {}", url, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-3
@@ -42,9 +42,14 @@ import org.springframework.stereotype.Component;
|
||||
final class TelegramBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl {
|
||||
|
||||
@Override
|
||||
public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, GroupAlert alert) throws AlertNoticeException {
|
||||
public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, GroupAlert alert)
|
||||
throws AlertNoticeException {
|
||||
try {
|
||||
String url = String.format(alerterProperties.getTelegramWebhookUrl(), receiver.getTgBotToken());
|
||||
String token = receiver.getTgBotToken();
|
||||
if (!isValidTelegramToken(token)) {
|
||||
throw new AlertNoticeException("Invalid Telegram Bot Token");
|
||||
}
|
||||
String url = String.format(alerterProperties.getTelegramWebhookUrl(), token);
|
||||
TelegramBotNotifyDTO notifyBody = TelegramBotNotifyDTO.builder()
|
||||
.chatId(receiver.getTgUserId())
|
||||
.text(renderContent(noticeTemplate, alert))
|
||||
@@ -54,7 +59,8 @@ final class TelegramBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandler
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<TelegramBotNotifyDTO> telegramEntity = new HttpEntity<>(notifyBody, headers);
|
||||
ResponseEntity<TelegramBotNotifyResponse> entity = restTemplate.postForEntity(url, telegramEntity, TelegramBotNotifyResponse.class);
|
||||
ResponseEntity<TelegramBotNotifyResponse> entity = restTemplate.postForEntity(url, telegramEntity,
|
||||
TelegramBotNotifyResponse.class);
|
||||
if (entity.getStatusCode() == HttpStatus.OK && entity.getBody() != null) {
|
||||
TelegramBotNotifyResponse body = entity.getBody();
|
||||
if (body.ok) {
|
||||
@@ -99,4 +105,10 @@ final class TelegramBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandler
|
||||
private String description;
|
||||
}
|
||||
|
||||
private boolean isValidTelegramToken(String token) {
|
||||
// Adjusted pattern to match real Telegram Bot tokens like
|
||||
// 110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw
|
||||
String tokenPattern = "^[0-9]+:[a-zA-Z0-9_-]+$";
|
||||
return token != null && token.matches(tokenPattern);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-1
@@ -57,7 +57,12 @@ final class WeComRobotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerI
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<WeWorkWebHookDto> httpEntity = new HttpEntity<>(weWorkWebHookDTO, headers);
|
||||
String webHookUrl = alerterProperties.getWeWorkWebhookUrl() + receiver.getWechatId();
|
||||
String wechatId = receiver.getWechatId();
|
||||
if (!isValidWechatId(wechatId)) {
|
||||
log.warn("Invalid WeChat ID: {}", wechatId);
|
||||
throw new AlertNoticeException("Invalid WeChat ID provided.");
|
||||
}
|
||||
String webHookUrl = alerterProperties.getWeWorkWebhookUrl() + wechatId;
|
||||
ResponseEntity<CommonRobotNotifyResp> entity = restTemplate.postForEntity(webHookUrl, httpEntity, CommonRobotNotifyResp.class);
|
||||
if (entity.getStatusCode() == HttpStatus.OK) {
|
||||
assert entity.getBody() != null;
|
||||
@@ -170,4 +175,15 @@ final class WeComRobotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerI
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the WeChat ID to ensure it meets the expected format.
|
||||
*
|
||||
* @param wechatId the WeChat ID to validate
|
||||
* @return true if valid, false otherwise
|
||||
*/
|
||||
private boolean isValidWechatId(String wechatId) {
|
||||
// Example validation: ensure the ID is alphanumeric and non-empty
|
||||
return StringUtils.isNotBlank(wechatId) && wechatId.matches("^[a-zA-Z0-9_-]+$");
|
||||
}
|
||||
}
|
||||
|
||||
+16
-26
@@ -20,6 +20,7 @@ package org.apache.hertzbeat.alert.notice.impl;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.hertzbeat.alert.AlerterProperties;
|
||||
@@ -48,7 +49,7 @@ import java.util.ResourceBundle;
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ServerChanAlertNotifyHandlerImplTest {
|
||||
|
||||
|
||||
@Mock
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@@ -57,20 +58,21 @@ class ServerChanAlertNotifyHandlerImplTest {
|
||||
|
||||
@Mock
|
||||
private ResourceBundle bundle;
|
||||
|
||||
|
||||
@InjectMocks
|
||||
private ServerChanAlertNotifyHandlerImpl serverChanAlertNotifyHandler;
|
||||
|
||||
|
||||
private NoticeReceiver receiver;
|
||||
private GroupAlert groupAlert;
|
||||
private NoticeTemplate template;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
receiver = new NoticeReceiver();
|
||||
receiver.setId(1L);
|
||||
receiver.setName("test-receiver");
|
||||
receiver.setAccessToken("test-token");
|
||||
receiver.setServerChanToken("SCT193569TSNm6xIabdjqeZPtOGOWcvU1e");
|
||||
|
||||
groupAlert = new GroupAlert();
|
||||
SingleAlert singleAlert = new SingleAlert();
|
||||
@@ -87,43 +89,31 @@ class ServerChanAlertNotifyHandlerImplTest {
|
||||
template.setName("test-template");
|
||||
template.setContent("test content");
|
||||
|
||||
when(alerterProperties.getServerChanWebhookUrl()).thenReturn("http://test.url/");
|
||||
when(bundle.getString("alerter.notify.title")).thenReturn("Alert Notification");
|
||||
lenient().when(alerterProperties.getServerChanWebhookUrl())
|
||||
.thenReturn("https://api.serverchan.com/send/%s");
|
||||
lenient().when(bundle.getString("alerter.notify.title")).thenReturn("Alert Notification");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNotifyAlertSuccess() {
|
||||
CommonRobotNotifyResp successResp = new CommonRobotNotifyResp();
|
||||
successResp.setErrCode(0);
|
||||
successResp.setMsg("success");
|
||||
ResponseEntity<CommonRobotNotifyResp> responseEntity =
|
||||
new ResponseEntity<>(successResp, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<CommonRobotNotifyResp> responseEntity = new ResponseEntity<>(successResp, HttpStatus.OK);
|
||||
|
||||
when(restTemplate.postForEntity(
|
||||
any(String.class),
|
||||
any(),
|
||||
eq(CommonRobotNotifyResp.class)
|
||||
)).thenReturn(responseEntity);
|
||||
eq(CommonRobotNotifyResp.class))).thenReturn(responseEntity);
|
||||
|
||||
serverChanAlertNotifyHandler.send(receiver, template, groupAlert);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNotifyAlertFailure() {
|
||||
CommonRobotNotifyResp failResp = new CommonRobotNotifyResp();
|
||||
failResp.setCode(1);
|
||||
failResp.setErrMsg("Test Error");
|
||||
ResponseEntity<CommonRobotNotifyResp> responseEntity =
|
||||
new ResponseEntity<>(failResp, HttpStatus.BAD_REQUEST);
|
||||
|
||||
when(restTemplate.postForEntity(
|
||||
any(String.class),
|
||||
any(),
|
||||
eq(CommonRobotNotifyResp.class)
|
||||
)).thenReturn(responseEntity);
|
||||
public void testNotifyAlertWithInvalidUrl() {
|
||||
when(alerterProperties.getServerChanWebhookUrl()).thenReturn("http://invalid-url.com/%s");
|
||||
|
||||
assertThrows(AlertNoticeException.class,
|
||||
assertThrows(AlertNoticeException.class,
|
||||
() -> serverChanAlertNotifyHandler.send(receiver, template, groupAlert));
|
||||
}
|
||||
}
|
||||
|
||||
+11
-15
@@ -51,7 +51,7 @@ class SlackAlertNotifyHandlerImplTest {
|
||||
|
||||
@Mock
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
|
||||
@Mock
|
||||
private ResourceBundle bundle;
|
||||
|
||||
@@ -68,18 +68,18 @@ class SlackAlertNotifyHandlerImplTest {
|
||||
receiver.setId(1L);
|
||||
receiver.setName("test-receiver");
|
||||
receiver.setAccessToken("test-token");
|
||||
receiver.setSlackWebHookUrl("http://localhost:8080");
|
||||
|
||||
receiver.setSlackWebHookUrl("https://hooks.slack.com/services/ABCDEF/GHIJKL/mnopqrstuvwxyz");
|
||||
|
||||
groupAlert = new GroupAlert();
|
||||
SingleAlert singleAlert = new SingleAlert();
|
||||
singleAlert.setLabels(new HashMap<>());
|
||||
singleAlert.getLabels().put("severity", "critical");
|
||||
singleAlert.getLabels().put("alertname", "Test Alert");
|
||||
|
||||
|
||||
List<SingleAlert> alerts = new ArrayList<>();
|
||||
alerts.add(singleAlert);
|
||||
groupAlert.setAlerts(alerts);
|
||||
|
||||
|
||||
template = new NoticeTemplate();
|
||||
template.setId(1L);
|
||||
template.setName("test-template");
|
||||
@@ -90,22 +90,18 @@ class SlackAlertNotifyHandlerImplTest {
|
||||
|
||||
@Test
|
||||
public void testNotifyAlertSuccess() {
|
||||
ResponseEntity<String> responseEntity =
|
||||
new ResponseEntity<>("ok", HttpStatus.OK);
|
||||
|
||||
ResponseEntity<String> responseEntity = new ResponseEntity<>("ok", HttpStatus.OK);
|
||||
|
||||
when(restTemplate.postForEntity(any(String.class), any(), eq(String.class))).thenReturn(responseEntity);
|
||||
|
||||
|
||||
slackAlertNotifyHandler.send(receiver, template, groupAlert);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyAlertFailure() {
|
||||
ResponseEntity<String> responseEntity =
|
||||
new ResponseEntity<>("invalid_payload", HttpStatus.BAD_REQUEST);
|
||||
public void testNotifyAlertWithInvalidUrl() {
|
||||
receiver.setSlackWebHookUrl("http://localhost:8080");
|
||||
|
||||
when(restTemplate.postForEntity(any(String.class), any(), eq(String.class))).thenReturn(responseEntity);
|
||||
|
||||
assertThrows(AlertNoticeException.class,
|
||||
assertThrows(AlertNoticeException.class,
|
||||
() -> slackAlertNotifyHandler.send(receiver, template, groupAlert));
|
||||
}
|
||||
}
|
||||
|
||||
+25
-25
@@ -20,6 +20,7 @@ package org.apache.hertzbeat.alert.notice.impl;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.hertzbeat.alert.AlerterProperties;
|
||||
@@ -51,10 +52,10 @@ class TelegramBotAlertNotifyHandlerImplTest {
|
||||
|
||||
@Mock
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
|
||||
@Mock
|
||||
private AlerterProperties alerterProperties;
|
||||
|
||||
|
||||
@Mock
|
||||
private ResourceBundle bundle;
|
||||
|
||||
@@ -70,58 +71,57 @@ class TelegramBotAlertNotifyHandlerImplTest {
|
||||
receiver = new NoticeReceiver();
|
||||
receiver.setId(1L);
|
||||
receiver.setName("test-receiver");
|
||||
receiver.setAccessToken("test-token");
|
||||
receiver.setTgBotToken("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11");
|
||||
receiver.setTgUserId("123456789"); // Telegram specific - chat ID
|
||||
|
||||
|
||||
groupAlert = new GroupAlert();
|
||||
SingleAlert singleAlert = new SingleAlert();
|
||||
singleAlert.setLabels(new HashMap<>());
|
||||
singleAlert.getLabels().put("severity", "critical");
|
||||
singleAlert.getLabels().put("alertname", "Test Alert");
|
||||
|
||||
|
||||
List<SingleAlert> alerts = new ArrayList<>();
|
||||
alerts.add(singleAlert);
|
||||
groupAlert.setAlerts(alerts);
|
||||
|
||||
|
||||
template = new NoticeTemplate();
|
||||
template.setId(1L);
|
||||
template.setName("test-template");
|
||||
template.setContent("test content");
|
||||
|
||||
when(alerterProperties.getTelegramWebhookUrl()).thenReturn("https://api.telegram.org/bot%s/sendMessage");
|
||||
when(bundle.getString("alerter.notify.title")).thenReturn("Alert Notification");
|
||||
|
||||
lenient().when(alerterProperties.getTelegramWebhookUrl())
|
||||
.thenReturn("https://api.telegram.org/bot%s/sendMessage");
|
||||
lenient().when(bundle.getString("alerter.notify.title")).thenReturn("Alert Notification");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyAlertSuccess() {
|
||||
TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse successResp =
|
||||
new TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse();
|
||||
TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse successResp = new TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse();
|
||||
successResp.setOk(true);
|
||||
successResp.setDescription("Test Success");
|
||||
|
||||
ResponseEntity<TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse> responseEntity =
|
||||
new ResponseEntity<>(successResp, HttpStatus.OK);
|
||||
|
||||
when(restTemplate.postForEntity(any(String.class), any(),
|
||||
|
||||
ResponseEntity<TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse> responseEntity = new ResponseEntity<>(
|
||||
successResp, HttpStatus.OK);
|
||||
|
||||
when(restTemplate.postForEntity(any(String.class), any(),
|
||||
eq(TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse.class))).thenReturn(responseEntity);
|
||||
|
||||
|
||||
telegramBotAlertNotifyHandler.send(receiver, template, groupAlert);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyAlertFailure() {
|
||||
TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse successResp =
|
||||
new TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse();
|
||||
successResp.setOk(false);
|
||||
successResp.setDescription("Test failed");
|
||||
TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse failureResp = new TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse();
|
||||
failureResp.setOk(false);
|
||||
failureResp.setDescription("Test failed");
|
||||
|
||||
ResponseEntity<TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse> responseEntity =
|
||||
new ResponseEntity<>(successResp, HttpStatus.BAD_REQUEST);
|
||||
ResponseEntity<TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse> responseEntity = new ResponseEntity<>(
|
||||
failureResp, HttpStatus.OK);
|
||||
|
||||
when(restTemplate.postForEntity(any(String.class), any(),
|
||||
eq(TelegramBotAlertNotifyHandlerImpl.TelegramBotNotifyResponse.class))).thenReturn(responseEntity);
|
||||
|
||||
assertThrows(AlertNoticeException.class,
|
||||
|
||||
assertThrows(AlertNoticeException.class,
|
||||
() -> telegramBotAlertNotifyHandler.send(receiver, template, groupAlert));
|
||||
}
|
||||
}
|
||||
|
||||
+13
-16
@@ -48,7 +48,7 @@ import java.util.ResourceBundle;
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class WeComRobotAlertNotifyHandlerImplTest {
|
||||
|
||||
|
||||
@Mock
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@@ -57,20 +57,21 @@ class WeComRobotAlertNotifyHandlerImplTest {
|
||||
|
||||
@Mock
|
||||
private ResourceBundle bundle;
|
||||
|
||||
|
||||
@InjectMocks
|
||||
private WeComRobotAlertNotifyHandlerImpl weComRobotAlertNotifyHandler;
|
||||
|
||||
|
||||
private NoticeReceiver receiver;
|
||||
private GroupAlert groupAlert;
|
||||
private NoticeTemplate template;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
receiver = new NoticeReceiver();
|
||||
receiver.setId(1L);
|
||||
receiver.setName("test-receiver");
|
||||
receiver.setAccessToken("test-token");
|
||||
receiver.setWechatId("test-wechat-id");
|
||||
|
||||
groupAlert = new GroupAlert();
|
||||
SingleAlert singleAlert = new SingleAlert();
|
||||
@@ -95,33 +96,29 @@ class WeComRobotAlertNotifyHandlerImplTest {
|
||||
public void testNotifyAlertSuccess() {
|
||||
CommonRobotNotifyResp successResp = new CommonRobotNotifyResp();
|
||||
successResp.setErrCode(0);
|
||||
ResponseEntity<CommonRobotNotifyResp> responseEntity =
|
||||
new ResponseEntity<>(successResp, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<CommonRobotNotifyResp> responseEntity = new ResponseEntity<>(successResp, HttpStatus.OK);
|
||||
|
||||
when(restTemplate.postForEntity(
|
||||
any(String.class),
|
||||
any(),
|
||||
eq(CommonRobotNotifyResp.class)
|
||||
)).thenReturn(responseEntity);
|
||||
eq(CommonRobotNotifyResp.class))).thenReturn(responseEntity);
|
||||
|
||||
weComRobotAlertNotifyHandler.send(receiver, template, groupAlert);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNotifyAlertFailure() {
|
||||
CommonRobotNotifyResp failResp = new CommonRobotNotifyResp();
|
||||
failResp.setCode(1);
|
||||
failResp.setErrMsg("Test Error");
|
||||
ResponseEntity<CommonRobotNotifyResp> responseEntity =
|
||||
new ResponseEntity<>(failResp, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<CommonRobotNotifyResp> responseEntity = new ResponseEntity<>(failResp, HttpStatus.OK);
|
||||
|
||||
when(restTemplate.postForEntity(
|
||||
any(String.class),
|
||||
any(),
|
||||
eq(CommonRobotNotifyResp.class)
|
||||
)).thenReturn(responseEntity);
|
||||
eq(CommonRobotNotifyResp.class))).thenReturn(responseEntity);
|
||||
|
||||
assertThrows(AlertNoticeException.class,
|
||||
assertThrows(AlertNoticeException.class,
|
||||
() -> weComRobotAlertNotifyHandler.send(receiver, template, groupAlert));
|
||||
}
|
||||
}
|
||||
|
||||
+20
@@ -150,6 +150,7 @@ public abstract class PromqlQueryExecutor implements QueryExecutor {
|
||||
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
|
||||
URI uri;
|
||||
if (datasourceQuery.getTimeType().equals(RANGE)) {
|
||||
validateDatasourceQuery(datasourceQuery);
|
||||
uri = UriComponentsBuilder.fromHttpUrl(httpPromqlProperties.url() + QUERY_RANGE_PATH)
|
||||
.queryParam(HTTP_QUERY_PARAM, datasourceQuery.getExpr())
|
||||
.queryParam(HTTP_START_PARAM, datasourceQuery.getStart())
|
||||
@@ -157,12 +158,14 @@ public abstract class PromqlQueryExecutor implements QueryExecutor {
|
||||
.queryParam(HTTP_STEP_PARAM, datasourceQuery.getStep())
|
||||
.build().toUri();
|
||||
} else if (datasourceQuery.getTimeType().equals(INSTANT)) {
|
||||
validateDatasourceQuery(datasourceQuery);
|
||||
uri = UriComponentsBuilder.fromHttpUrl(httpPromqlProperties.url() + QUERY_PATH)
|
||||
.queryParam(HTTP_QUERY_PARAM, datasourceQuery.getExpr())
|
||||
.build().toUri();
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format("no such time type for query id {}.", datasourceQuery.getRefId()));
|
||||
}
|
||||
validateUri(uri);
|
||||
ResponseEntity<PromQlQueryContent> responseEntity = restTemplate.exchange(uri, HttpMethod.GET, httpEntity,
|
||||
PromQlQueryContent.class);
|
||||
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||
@@ -214,4 +217,21 @@ public abstract class PromqlQueryExecutor implements QueryExecutor {
|
||||
return StringUtils.hasText(queryLanguage) && queryLanguage.equalsIgnoreCase(supportQueryLanguage);
|
||||
}
|
||||
|
||||
private void validateDatasourceQuery(DatasourceQuery datasourceQuery) {
|
||||
if (!StringUtils.hasText(datasourceQuery.getExpr()) || datasourceQuery.getExpr().length() > 1000) {
|
||||
throw new IllegalArgumentException("Invalid query expression");
|
||||
}
|
||||
if (datasourceQuery.getTimeType().equals(RANGE)) {
|
||||
if (datasourceQuery.getStart() == null || datasourceQuery.getEnd() == null || datasourceQuery.getStep() == null) {
|
||||
throw new IllegalArgumentException("Missing required parameters for range query");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateUri(URI uri) {
|
||||
String host = uri.getHost();
|
||||
if (host == null || !host.equals(httpPromqlProperties.url().replace("http://", "").replace("https://", ""))) {
|
||||
throw new IllegalArgumentException("Invalid URI host");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user