This is an automated email from the ASF dual-hosted git repository.
liuhongyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
The following commit(s) were added to refs/heads/master by this push:
new 1c781d5bc [bugfix] webhook url query parameters missing (#3779)
1c781d5bc is described below
commit 1c781d5bc5be9d7dd8f99170bf3a3be742916721
Author: zhou yong kang <[email protected]>
AuthorDate: Tue Sep 23 09:31:47 2025 +0800
[bugfix] webhook url query parameters missing (#3779)
Co-authored-by: Calvin <[email protected]>
Co-authored-by: aias00 <[email protected]>
---
.../notice/impl/WebHookAlertNotifyHandlerImpl.java | 14 ++++-
.../apache/hertzbeat/alert/util/CryptoUtils.java | 18 +++++-
.../impl/WebHookAlertNotifyHandlerImplTest.java | 72 +++++++++++++++++++++-
.../common/entity/alerter/NoticeReceiver.java | 4 +-
4 files changed, 99 insertions(+), 9 deletions(-)
diff --git
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/WebHookAlertNotifyHandlerImpl.java
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/WebHookAlertNotifyHandlerImpl.java
index 54d56e532..cb90b4909 100644
---
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/WebHookAlertNotifyHandlerImpl.java
+++
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/WebHookAlertNotifyHandlerImpl.java
@@ -18,6 +18,7 @@
package org.apache.hertzbeat.alert.notice.impl;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import org.apache.hertzbeat.alert.notice.AlertNoticeException;
import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
import org.apache.hertzbeat.common.entity.alerter.NoticeReceiver;
@@ -39,6 +40,13 @@ final class WebHookAlertNotifyHandlerImpl extends
AbstractAlertNotifyHandlerImpl
@Override
public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate,
GroupAlert alert) {
try {
+ String hookUrl = receiver.getHookUrl();
+
+ // Basic URL validation
+ if (StringUtils.isBlank(hookUrl)) {
+ throw new AlertNoticeException("Webhook URL is null or empty");
+ }
+
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// alert.setContent(escapeJsonStr(alert.getContent()));
@@ -46,11 +54,11 @@ final class WebHookAlertNotifyHandlerImpl extends
AbstractAlertNotifyHandlerImpl
webhookJson = webhookJson.replace(",\n }", "\n }");
HttpEntity<String> alertHttpEntity = new HttpEntity<>(webhookJson,
headers);
- ResponseEntity<String> entity =
restTemplate.postForEntity(receiver.getHookUrl(), alertHttpEntity,
String.class);
+ ResponseEntity<String> entity =
restTemplate.postForEntity(hookUrl, alertHttpEntity, String.class);
if (entity.getStatusCode().value() <
HttpStatus.BAD_REQUEST.value()) {
- log.debug("Send WebHook: {} Success", receiver.getHookUrl());
+ log.debug("Send WebHook: {} Success", hookUrl);
} else {
- log.warn("Send WebHook: {} Failed: {}", receiver.getHookUrl(),
entity.getBody());
+ log.warn("Send WebHook: {} Failed: {}", hookUrl,
entity.getBody());
throw new AlertNoticeException("Http StatusCode " +
entity.getStatusCode());
}
} catch (Exception e) {
diff --git
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/util/CryptoUtils.java
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/util/CryptoUtils.java
index 6d5f2ce84..43684396b 100644
---
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/util/CryptoUtils.java
+++
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/util/CryptoUtils.java
@@ -21,7 +21,6 @@ import lombok.extern.slf4j.Slf4j;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
-import javax.xml.bind.DatatypeConverter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
@@ -64,7 +63,7 @@ public class CryptoUtils {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(data.getBytes(UTF8));
- return DatatypeConverter.printHexBinary(digest).toLowerCase();
+ return bytesToHex(digest).toLowerCase();
} catch (Exception e) {
log.error("Failed to calculate SHA256: {}", e.getMessage());
throw new RuntimeException("Failed to calculate SHA256", e);
@@ -101,6 +100,19 @@ public class CryptoUtils {
*/
public static String hmacSha256Hex(byte[] key, String data) {
byte[] hmacResult = hmac256(key, data);
- return DatatypeConverter.printHexBinary(hmacResult).toLowerCase();
+ return bytesToHex(hmacResult).toLowerCase();
+ }
+
+ /**
+ * Convert byte array to hexadecimal string
+ * @param bytes byte array to convert
+ * @return hexadecimal string representation
+ */
+ private static String bytesToHex(byte[] bytes) {
+ StringBuilder result = new StringBuilder();
+ for (byte byteValue : bytes) {
+ result.append(String.format("%02x", byteValue));
+ }
+ return result.toString();
}
}
\ No newline at end of file
diff --git
a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/WebHookAlertNotifyHandlerImplTest.java
b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/WebHookAlertNotifyHandlerImplTest.java
index 28dfb7c53..e38c38927 100644
---
a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/WebHookAlertNotifyHandlerImplTest.java
+++
b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/WebHookAlertNotifyHandlerImplTest.java
@@ -18,6 +18,7 @@
package org.apache.hertzbeat.alert.notice.impl;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
@@ -105,7 +106,76 @@ class WebHookAlertNotifyHandlerImplTest {
when(restTemplate.postForEntity(any(String.class), any(),
eq(String.class))).thenReturn(responseEntity);
- assertThrows(AlertNoticeException.class,
+ assertThrows(AlertNoticeException.class,
() -> webHookAlertNotifyHandler.send(receiver, template,
groupAlert));
}
+
+ @Test
+ public void testNotifyAlertWithQueryParametersSuccess() {
+
receiver.setHookUrl("https://prod-12.chinaeast2.logic.azure.cn:443/workflows/test/triggers/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=testSignature123");
+
+ ResponseEntity<String> responseEntity =
+ new ResponseEntity<>("null", HttpStatus.OK);
+
+ when(restTemplate.postForEntity(eq(receiver.getHookUrl()), any(),
eq(String.class))).thenReturn(responseEntity);
+
+ webHookAlertNotifyHandler.send(receiver, template, groupAlert);
+ }
+
+ @Test
+ public void testNotifyAlertWithNullOrEmptyUrl() {
+ // Test null URL
+ receiver.setHookUrl(null);
+ assertThrows(AlertNoticeException.class,
+ () -> webHookAlertNotifyHandler.send(receiver, template,
groupAlert));
+
+ // Test empty URL
+ receiver.setHookUrl("");
+ assertThrows(AlertNoticeException.class,
+ () -> webHookAlertNotifyHandler.send(receiver, template,
groupAlert));
+
+ // Test blank URL
+ receiver.setHookUrl(" ");
+ assertThrows(AlertNoticeException.class,
+ () -> webHookAlertNotifyHandler.send(receiver, template,
groupAlert));
+ }
+
+ @Test
+ public void testNotifyAlertWithValidUrls() {
+ ResponseEntity<String> responseEntity =
+ new ResponseEntity<>("null", HttpStatus.OK);
+
+ when(restTemplate.postForEntity(any(String.class), any(),
eq(String.class))).thenReturn(responseEntity);
+
+ // Test various valid URLs that should work
+
receiver.setHookUrl("https://hooks.slack.com/services/T123/B456/complete-token");
+ webHookAlertNotifyHandler.send(receiver, template, groupAlert);
+
+
receiver.setHookUrl("https://discord.com/api/webhooks/123456789/complete-token");
+ webHookAlertNotifyHandler.send(receiver, template, groupAlert);
+
+
receiver.setHookUrl("https://example.com/webhook?complete=true&valid=yes");
+ webHookAlertNotifyHandler.send(receiver, template, groupAlert);
+ }
+
+ @Test
+ public void testNotifyAlertWithLongUrlSuccess() {
+ // Test that long URLs (over 300 chars) can now be handled with the
increased field length
+ StringBuilder longUrl = new
StringBuilder("https://prod-12.chinaeast2.logic.azure.cn:443/workflows/test/triggers/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=");
+ for (int i = 0; i < 200; i++) {
+ longUrl.append("x");
+ }
+ receiver.setHookUrl(longUrl.toString());
+
+ ResponseEntity<String> responseEntity =
+ new ResponseEntity<>("null", HttpStatus.OK);
+
+ when(restTemplate.postForEntity(eq(receiver.getHookUrl()), any(),
eq(String.class))).thenReturn(responseEntity);
+
+ webHookAlertNotifyHandler.send(receiver, template, groupAlert);
+
+ // Verify the URL is longer than the old 300 char limit
+ assertTrue(receiver.getHookUrl().length() > 300,
+ "URL should be longer than old 300 char limit to test the field
length increase");
+ }
}
diff --git
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/alerter/NoticeReceiver.java
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/alerter/NoticeReceiver.java
index 53b063a43..328665e3f 100644
---
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/alerter/NoticeReceiver.java
+++
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/alerter/NoticeReceiver.java
@@ -94,8 +94,8 @@ public class NoticeReceiver {
@Schema(title = "URL address: The notification method is valid for
webhook",
description = "URL address: The notification method is valid for
webhook",
example = "https://www.tancloud.cn", accessMode = READ_WRITE)
- @Size(max = 300)
- @Column(length = 300)
+ @Size(max = 1000)
+ @Column(length = 1000)
private String hookUrl;
@Schema(title = "openId : The notification method is valid for WeChat
official account, enterprise WeChat robot or FlyBook robot",
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]