This is an automated email from the ASF dual-hosted git repository.

Aias00 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 7d14ed80ba [fix] expose prestodb auth parameters and wire 
authorization into all metrics (#4188)
7d14ed80ba is described below

commit 7d14ed80ba8cf1be61ec660e88571a11de0ccf2f
Author: NekoPunch <[email protected]>
AuthorDate: Sun Jul 12 23:46:00 2026 -0700

    [fix] expose prestodb auth parameters and wire authorization into all 
metrics (#4188)
    
    Co-authored-by: Duansg <[email protected]>
---
 .../collect/basic/http/PrestodbMonitorE2eTest.java | 183 +++++++++++++++++++++
 .../src/main/resources/define/app-prestodb.yml     |  42 +++++
 home/docs/help/prestodb.md                         |   4 +
 .../current/help/prestodb.md                       |   4 +
 4 files changed, 233 insertions(+)

diff --git 
a/hertzbeat-e2e/hertzbeat-collector-basic-e2e/src/test/java/org/apache/hertzbeat/collector/collect/basic/http/PrestodbMonitorE2eTest.java
 
b/hertzbeat-e2e/hertzbeat-collector-basic-e2e/src/test/java/org/apache/hertzbeat/collector/collect/basic/http/PrestodbMonitorE2eTest.java
new file mode 100644
index 0000000000..04a821c0cc
--- /dev/null
+++ 
b/hertzbeat-e2e/hertzbeat-collector-basic-e2e/src/test/java/org/apache/hertzbeat/collector/collect/basic/http/PrestodbMonitorE2eTest.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.basic.http;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpServer;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.hertzbeat.collector.collect.AbstractCollectE2eTest;
+import org.apache.hertzbeat.collector.collect.http.HttpCollectImpl;
+import org.apache.hertzbeat.collector.util.CollectUtil;
+import org.apache.hertzbeat.common.entity.job.Configmap;
+import org.apache.hertzbeat.common.entity.job.Job;
+import org.apache.hertzbeat.common.entity.job.Metrics;
+import org.apache.hertzbeat.common.entity.job.protocol.Protocol;
+import org.apache.hertzbeat.common.entity.message.CollectRep;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * E2E test for PrestoDB monitor with HTTP Basic Auth enabled (issue #2838).
+ * Unlike other http monitor tests, the protocol is taken from the template 
definition
+ * after placeholder replacement (mirroring WheelTimerTask#initJobMetrics), so 
a metric
+ * whose http section lacks the authorization wiring fails this test with a 
401.
+ */
+@Slf4j
+@ExtendWith(MockitoExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class PrestodbMonitorE2eTest extends AbstractCollectE2eTest {
+
+    private static final int MOCK_SERVER_PORT = 52390;
+    private static final String LOCALHOST = "127.0.0.1";
+    private static final String USERNAME = "presto-admin";
+    private static final String PASSWORD = "presto-secret";
+    private static final Gson GSON = new Gson();
+    private static HttpServer mockServer;
+
+    private static final String CLUSTER_JSON = """
+            {"activeWorkers": 3, "runningQueries": 2, "queuedQueries": 1,
+             "blockedQueries": 0, "runningDrivers": 12, "runningTasks": 5}""";
+
+    private static final String NODE_JSON = """
+            [{"uri": "http://127.0.0.1:8080";, "recentRequests": 25.3, 
"recentFailures": 0.0,
+              "recentSuccesses": 25.3, "lastRequestTime": 
"2026-07-08T10:00:00.000Z",
+              "lastResponseTime": "2026-07-08T10:00:00.100Z", "age": "5.20d", 
"recentFailureRatio": 0.0}]""";
+
+    private static final String STATUS_JSON = """
+            {"nodeId": "coordinator-1", "nodeVersion": {"version": "0.289"}, 
"environment": "production",
+             "coordinator": true, "uptime": "5.20d", "externalAddress": 
"127.0.0.1",
+             "internalAddress": "127.0.0.1", "processors": 8, 
"processCpuLoad": 0.35,
+             "systemCpuLoad": 0.42, "heapUsed": 1073741824, "heapAvailable": 
4294967296, "nonHeapUsed": 268435456}""";
+
+    private static final String TASK_JSON = """
+            [{"taskId": "20260708_100000_00001_abcde.1.0.0", "version": 42, 
"state": "RUNNING",
+              "self": 
"http://127.0.0.1:8080/v1/task/20260708_100000_00001_abcde.1.0.0";,
+              "lastHeartbeat": "2026-07-08T10:00:00.000Z"}]""";
+
+    @AfterEach
+    public void tearDown() {
+        if (mockServer != null) {
+            mockServer.stop(0);
+        }
+    }
+
+    @BeforeEach
+    public void setUp() throws Exception {
+        super.setUp();
+        collect = new HttpCollectImpl();
+
+        mockServer = HttpServer.create(new 
InetSocketAddress(MOCK_SERVER_PORT), 0);
+        mockServer.setExecutor(null);
+        mockServer.start();
+        mockServer.createContext("/v1/cluster", exchange -> 
sendAuthenticatedJson(exchange, CLUSTER_JSON));
+        mockServer.createContext("/v1/node", exchange -> 
sendAuthenticatedJson(exchange, NODE_JSON));
+        mockServer.createContext("/v1/status", exchange -> 
sendAuthenticatedJson(exchange, STATUS_JSON));
+        mockServer.createContext("/v1/task", exchange -> 
sendAuthenticatedJson(exchange, TASK_JSON));
+    }
+
+    private void sendAuthenticatedJson(HttpExchange exchange, String response) 
throws IOException {
+        String expected = "Basic " + Base64.getEncoder()
+                .encodeToString((USERNAME + ":" + 
PASSWORD).getBytes(StandardCharsets.UTF_8));
+        if 
(!expected.equals(exchange.getRequestHeaders().getFirst("Authorization"))) {
+            exchange.getResponseHeaders().set("WWW-Authenticate", "Basic 
realm=\"presto\"");
+            exchange.sendResponseHeaders(401, -1);
+            exchange.close();
+            return;
+        }
+        exchange.getResponseHeaders().set("Content-Type", "application/json");
+        final byte[] array = response.getBytes(StandardCharsets.UTF_8);
+        exchange.sendResponseHeaders(200, array.length);
+        try (OutputStream os = exchange.getResponseBody()) {
+            os.write(array);
+        }
+    }
+
+    @Test
+    public void testPrestodbMonitorWithBasicAuth() {
+        Job prestodbJob = appService.getAppDefine("prestodb");
+        Map<String, Configmap> configmap = buildParamConfigmap(true);
+        for (Metrics metricsDef : prestodbJob.getMetrics()) {
+            metricsDef = replaceJobPlaceholder(metricsDef, configmap);
+            validateMetricsCollection(metricsDef, metricsDef.getName());
+        }
+    }
+
+    @Test
+    public void testPrestodbMonitorWithoutAuthIsRejected() {
+        Job prestodbJob = appService.getAppDefine("prestodb");
+        Map<String, Configmap> configmap = buildParamConfigmap(false);
+        Metrics availabilityMetric = prestodbJob.getMetrics().stream()
+                .filter(m -> "cluster".equals(m.getName()))
+                .findFirst()
+                .orElseThrow(() -> new IllegalStateException("prestodb 
template has no cluster metric"));
+        availabilityMetric = replaceJobPlaceholder(availabilityMetric, 
configmap);
+        CollectRep.MetricsData.Builder metricsData = 
collectMetrics(availabilityMetric);
+        Assertions.assertNotEquals(CollectRep.Code.SUCCESS, 
metricsData.getCode(),
+                "collection against an auth-protected endpoint must fail when 
no credentials are configured");
+    }
+
+    private Map<String, Configmap> buildParamConfigmap(boolean withAuth) {
+        Map<String, Configmap> configmap = new HashMap<>();
+        configmap.put("host", new Configmap("host", LOCALHOST, (byte) 1));
+        configmap.put("port", new Configmap("port", 
String.valueOf(MOCK_SERVER_PORT), (byte) 1));
+        configmap.put("ssl", new Configmap("ssl", "false", (byte) 1));
+        configmap.put("timeout", new Configmap("timeout", "6000", (byte) 1));
+        if (withAuth) {
+            configmap.put("authType", new Configmap("authType", "Basic Auth", 
(byte) 1));
+            configmap.put("username", new Configmap("username", USERNAME, 
(byte) 1));
+            configmap.put("password", new Configmap("password", PASSWORD, 
(byte) 1));
+        }
+        return configmap;
+    }
+
+    /**
+     * Mirrors WheelTimerTask#initJobMetrics: replace ^_^param^_^ placeholders
+     * in the whole metric definition, keeping the template's http 
authorization wiring.
+     */
+    private Metrics replaceJobPlaceholder(Metrics metricsDef, Map<String, 
Configmap> configmap) {
+        JsonElement jsonElement = GSON.toJsonTree(metricsDef);
+        CollectUtil.replaceSmilingPlaceholder(jsonElement, configmap);
+        return GSON.fromJson(jsonElement, Metrics.class);
+    }
+
+    @Override
+    protected Protocol buildProtocol(Metrics metricsDef) {
+        return metricsDef.getHttp();
+    }
+
+    @Override
+    protected CollectRep.MetricsData.Builder collectMetrics(Metrics 
metricsDef) {
+        metrics.setHttp(metricsDef.getHttp());
+        return collectMetricsData(metrics, metricsDef);
+    }
+}
diff --git a/hertzbeat-manager/src/main/resources/define/app-prestodb.yml 
b/hertzbeat-manager/src/main/resources/define/app-prestodb.yml
index 120e92afb0..813681e009 100644
--- a/hertzbeat-manager/src/main/resources/define/app-prestodb.yml
+++ b/hertzbeat-manager/src/main/resources/define/app-prestodb.yml
@@ -53,6 +53,36 @@ params:
       ja-JP: HTTPS
     type: boolean
     required: true
+  - field: authType
+    name:
+      zh-CN: 认证方式
+      en-US: Auth Type
+      ja-JP: 認証方法
+    type: radio
+    required: false
+    hide: true
+    options:
+      - label: Basic Auth
+        value: Basic Auth
+      - label: Digest Auth
+        value: Digest Auth
+  - field: username
+    name:
+      zh-CN: 用户名
+      en-US: Username
+      ja-JP: ユーザー名
+    type: text
+    limit: 50
+    required: false
+    hide: true
+  - field: password
+    name:
+      zh-CN: 密码
+      en-US: Password
+      ja-JP: パスワード
+    type: password
+    required: false
+    hide: true
   - field: timeout
     name:
       zh-CN: 超时时间(ms)
@@ -115,6 +145,12 @@ metrics:
       timeout: ^_^timeout^_^
       method: GET
       ssl: ^_^ssl^_^
+      authorization:
+        type: ^_^authType^_^
+        basicAuthUsername: ^_^username^_^
+        basicAuthPassword: ^_^password^_^
+        digestAuthUsername: ^_^username^_^
+        digestAuthPassword: ^_^password^_^
       parseType: jsonPath
       parseScript: '$'
 
@@ -182,6 +218,12 @@ metrics:
       timeout: ^_^timeout^_^
       method: GET
       ssl: ^_^ssl^_^
+      authorization:
+        type: ^_^authType^_^
+        basicAuthUsername: ^_^username^_^
+        basicAuthPassword: ^_^password^_^
+        digestAuthUsername: ^_^username^_^
+        digestAuthPassword: ^_^password^_^
       parseType: jsonPath
       parseScript: '$[*]'
 
diff --git a/home/docs/help/prestodb.md b/home/docs/help/prestodb.md
index 2ebe19fcf8..58081d1ded 100644
--- a/home/docs/help/prestodb.md
+++ b/home/docs/help/prestodb.md
@@ -13,6 +13,10 @@ keywords: [ open source monitoring system, open source 
database monitoring, pres
 
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
 | Target Host         | The IP address, IPv4, IPv6, or domain name of the 
target to be monitored. Note: ⚠️ Do not include protocol headers (e.g., 
https://, http://). |
 | port                | Port                                                   
                                                                                
       |
+| HTTPS               | Whether to enable HTTPS for the PrestoDB API endpoint. 
                                                                                
       |
+| Auth Type           | Optional HTTP authentication mode. Supported values 
are `Basic Auth` and `Digest Auth`.                                             
         |
+| Username            | Username used when `Basic Auth` or `Digest Auth` is 
enabled.                                                                        
          |
+| Password            | Password used when `Basic Auth` or `Digest Auth` is 
enabled.                                                                        
          |
 | Task Name           | The name identifying this monitor, which must be 
unique.                                                                         
             |
 | Connection Timeout  | Timeout for PrestoDB connection when no response is 
received, in milliseconds (ms). Default is 6000 ms.                             
          |
 | Collection Interval | Interval for periodic data collection, in seconds. The 
minimum interval is 30 seconds.                                                 
       |
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/prestodb.md 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/prestodb.md
index 423f35f49f..a2216cdcbd 100644
--- a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/prestodb.md
+++ b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/prestodb.md
@@ -14,6 +14,10 @@ keywords: [ 开源监控系统, 开源数据库监控, Presto数据库监控 ]
 | 目标Host | 被监控的对端IPV4,IPV6或域名。注意⚠️不带协议头(eg: https://, http://)。 |
 | 任务名称   | 标识此监控的名称,名称需要保证唯一性。                                  |
 | 端口     | 被监控的平台端口。                                            |
+| 启用HTTPS  | 是否启用 PrestoDB API 的 HTTPS 访问。                      |
+| 认证方式   | 可选的 HTTP 认证方式,支持 `Basic Auth` 和 `Digest Auth`。      |
+| 用户名    | 启用 `Basic Auth` 或 `Digest Auth` 后使用的用户名。            |
+| 密码     | 启用 `Basic Auth` 或 `Digest Auth` 后使用的密码。             |
 | 连接超时时间 | 设置连接PrestoDB未响应数据时的超时时间,单位ms毫秒,默认6000毫秒。             |
 | 采集间隔   | 监控周期性采集数据间隔时间,单位秒,可设置的最小间隔为30秒。                      |
 | 绑定标签   | 用于对监控资源进行分类管理。                                       |


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to