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]

Reply via email to