This is an automated email from the ASF dual-hosted git repository.
zhaoqingran 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 6d459957fb feat(nacos-sd): add auth and filtering parameters for Nacos
service d… (#4099)
6d459957fb is described below
commit 6d459957fba38383784cdedad47af3d9733f209a
Author: pentium100 <[email protected]>
AuthorDate: Sun Mar 29 22:33:33 2026 +0800
feat(nacos-sd): add auth and filtering parameters for Nacos service d…
(#4099)
Co-authored-by: Logic <[email protected]>
---
.../registry/discovery/entity/ConnectConfig.java | 5 +
.../discovery/impl/NacosDiscoveryClient.java | 80 ++++++++++----
.../collector/collect/sd/NacosSdCollectImpl.java | 5 +
.../discovery/impl/NacosDiscoveryClientTest.java | 116 +++++++++++++++++++--
.../entity/job/protocol/NacosSdProtocol.java | 13 ++-
.../entity/job/protocol/RegistryProtocol.java | 6 ++
.../src/main/resources/define/app-nacos_sd.yml | 42 +++++++-
script/helm/hertzbeat-helm-chart | 2 +-
8 files changed, 240 insertions(+), 29 deletions(-)
diff --git
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/registry/discovery/entity/ConnectConfig.java
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/registry/discovery/entity/ConnectConfig.java
index 3040155c3b..48ac9c1598 100644
---
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/registry/discovery/entity/ConnectConfig.java
+++
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/registry/discovery/entity/ConnectConfig.java
@@ -32,4 +32,9 @@ import lombok.Data;
public class ConnectConfig {
private String host;
private int port;
+ private String username;
+ private String password;
+ private String namespace;
+ private String serviceName;
+ private String groupName;
}
diff --git
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/registry/discovery/impl/NacosDiscoveryClient.java
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/registry/discovery/impl/NacosDiscoveryClient.java
index 906de99803..d560bd72a8 100644
---
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/registry/discovery/impl/NacosDiscoveryClient.java
+++
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/registry/discovery/impl/NacosDiscoveryClient.java
@@ -22,10 +22,14 @@ package
org.apache.hertzbeat.collector.collect.registry.discovery.impl;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.api.naming.pojo.Instance;
import com.google.common.collect.Lists;
+
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Properties;
+
import lombok.extern.slf4j.Slf4j;
import
org.apache.hertzbeat.collector.collect.registry.constant.DiscoveryClientHealthStatus;
import
org.apache.hertzbeat.collector.collect.registry.discovery.DiscoveryClient;
@@ -33,6 +37,7 @@ import
org.apache.hertzbeat.collector.collect.registry.discovery.entity.ConnectC
import
org.apache.hertzbeat.collector.collect.registry.discovery.entity.ServerInfo;
import
org.apache.hertzbeat.collector.collect.registry.discovery.entity.ServiceInstance;
import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
+import org.springframework.util.StringUtils;
/**
* DiscoveryClient impl of Nacos
@@ -45,9 +50,14 @@ public class NacosDiscoveryClient implements DiscoveryClient
{
@Override
public ConnectConfig buildConnectConfig(RegistryProtocol registryProtocol)
{
return ConnectConfig.builder()
- .host(registryProtocol.getHost())
- .port(Integer.parseInt(registryProtocol.getPort()))
- .build();
+ .host(registryProtocol.getHost())
+ .port(Integer.parseInt(registryProtocol.getPort()))
+ .username(registryProtocol.getUsername())
+ .password(registryProtocol.getPassword())
+ .namespace(registryProtocol.getNamespace())
+ .serviceName(registryProtocol.getServiceName())
+ .groupName(registryProtocol.getGroupName())
+ .build();
}
@Override
@@ -55,7 +65,20 @@ public class NacosDiscoveryClient implements DiscoveryClient
{
try {
localConnectConfig = connectConfig;
- namingService =
NamingFactory.createNamingService(connectConfig.getHost() + ":" +
connectConfig.getPort());
+ Properties properties = new Properties();
+ properties.put("serverAddr", connectConfig.getHost() + ":" +
connectConfig.getPort());
+
+ if (StringUtils.hasText(connectConfig.getUsername())) {
+ properties.put("username", connectConfig.getUsername());
+ }
+ if (StringUtils.hasText(connectConfig.getPassword())) {
+ properties.put("password", connectConfig.getPassword());
+ }
+ if (StringUtils.hasText(connectConfig.getNamespace())) {
+ properties.put("namespace", connectConfig.getNamespace());
+ }
+
+ namingService = NamingFactory.createNamingService(properties);
// Perform a synchronous probe to verify connectivity eagerly,
// because NamingFactory.createNamingService() establishes the TCP
@@ -75,9 +98,9 @@ public class NacosDiscoveryClient implements DiscoveryClient {
ServerInfo serverInfo;
if (healthCheck()) {
serverInfo = ServerInfo.builder()
- .address(localConnectConfig.getHost())
- .port(String.valueOf(localConnectConfig.getPort()))
- .build();
+ .address(localConnectConfig.getHost())
+ .port(String.valueOf(localConnectConfig.getPort()))
+ .build();
} else {
throw new RuntimeException("NamingService is not healthy");
}
@@ -97,19 +120,36 @@ public class NacosDiscoveryClient implements
DiscoveryClient {
}
List<ServiceInstance> serviceInstanceList = Lists.newArrayList();
try {
- for (String serviceName : namingService.getServicesOfServer(0,
9999).getData()) {
- namingService.getAllInstances(serviceName).forEach(instance ->
- serviceInstanceList.add(ServiceInstance.builder()
- .serviceId(instance.getInstanceId())
- .serviceName(instance.getServiceName())
- .address(instance.getIp())
- .weight(instance.getWeight())
- .metadata(instance.getMetadata())
- .port(instance.getPort())
- .healthStatus(instance.isHealthy()
- ? DiscoveryClientHealthStatus.UP
- : DiscoveryClientHealthStatus.DOWN)
- .build()));
+ List<String> services;
+
+ if (StringUtils.hasText(localConnectConfig.getServiceName())) {
+ services = List.of(localConnectConfig.getServiceName());
+ } else if (StringUtils.hasText(localConnectConfig.getGroupName()))
{
+ services = namingService.getServicesOfServer(0, 9999,
localConnectConfig.getGroupName()).getData();
+ } else {
+ services = namingService.getServicesOfServer(0,
9999).getData();
+ }
+
+ for (String serviceName : services) {
+ List<Instance> instances;
+ if (StringUtils.hasText(localConnectConfig.getGroupName())) {
+ instances = namingService.getAllInstances(serviceName,
localConnectConfig.getGroupName());
+ } else {
+ instances = namingService.getAllInstances(serviceName);
+ }
+
+ instances.forEach(instance ->
+ serviceInstanceList.add(ServiceInstance.builder()
+ .serviceId(instance.getInstanceId())
+ .serviceName(instance.getServiceName())
+ .address(instance.getIp())
+ .weight(instance.getWeight())
+ .metadata(instance.getMetadata())
+ .port(instance.getPort())
+ .healthStatus(instance.isHealthy()
+ ? DiscoveryClientHealthStatus.UP
+ : DiscoveryClientHealthStatus.DOWN)
+ .build()));
}
} catch (NacosException e) {
throw new RuntimeException("Failed to fetch instance info");
diff --git
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/sd/NacosSdCollectImpl.java
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/sd/NacosSdCollectImpl.java
index c553a09265..4ba07ced61 100644
---
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/sd/NacosSdCollectImpl.java
+++
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/sd/NacosSdCollectImpl.java
@@ -62,6 +62,11 @@ public class NacosSdCollectImpl extends AbstractCollect {
RegistryProtocol registryProtocol = RegistryProtocol.builder()
.host(metrics.getNacos_sd().getHost())
.port(metrics.getNacos_sd().getPort())
+ .username(metrics.getNacos_sd().getUsername())
+ .password(metrics.getNacos_sd().getPassword())
+ .namespace(metrics.getNacos_sd().getNamespace())
+ .groupName(metrics.getNacos_sd().getGroupName())
+ .serviceName(metrics.getNacos_sd().getServiceName())
.discoveryClientTypeName(DiscoveryClientInstance.NACOS.name())
.build();
diff --git
a/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/registry/discovery/impl/NacosDiscoveryClientTest.java
b/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/registry/discovery/impl/NacosDiscoveryClientTest.java
index 71978cdac8..71a005d82a 100644
---
a/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/registry/discovery/impl/NacosDiscoveryClientTest.java
+++
b/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/registry/discovery/impl/NacosDiscoveryClientTest.java
@@ -24,9 +24,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
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.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -39,6 +41,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import
org.apache.hertzbeat.collector.collect.registry.constant.DiscoveryClientHealthStatus;
import
org.apache.hertzbeat.collector.collect.registry.discovery.entity.ConnectConfig;
import
org.apache.hertzbeat.collector.collect.registry.discovery.entity.ServerInfo;
@@ -77,6 +80,11 @@ class NacosDiscoveryClientTest {
RegistryProtocol protocol = RegistryProtocol.builder()
.host(HOST)
.port(String.valueOf(PORT))
+ .username("test-user")
+ .password("test-pass")
+ .namespace("test-namespace")
+ .serviceName("test-service")
+ .groupName("test-group")
.build();
ConnectConfig config =
nacosDiscoveryClient.buildConnectConfig(protocol);
@@ -84,6 +92,11 @@ class NacosDiscoveryClientTest {
assertNotNull(config);
assertEquals(HOST, config.getHost());
assertEquals(PORT, config.getPort());
+ assertEquals("test-user", config.getUsername());
+ assertEquals("test-pass", config.getPassword());
+ assertEquals("test-namespace", config.getNamespace());
+ assertEquals("test-service", config.getServiceName());
+ assertEquals("test-group", config.getGroupName());
}
@Test
@@ -91,7 +104,7 @@ class NacosDiscoveryClientTest {
ConnectConfig config =
ConnectConfig.builder().host(HOST).port(PORT).build();
try (MockedStatic<NamingFactory> mockedFactory =
Mockito.mockStatic(NamingFactory.class)) {
- mockedFactory.when(() -> NamingFactory.createNamingService(HOST +
":" + PORT))
+ mockedFactory.when(() ->
NamingFactory.createNamingService(any(Properties.class)))
.thenReturn(namingService);
ListView<String> emptyView = new ListView<>();
emptyView.setData(Collections.emptyList());
@@ -99,17 +112,17 @@ class NacosDiscoveryClientTest {
nacosDiscoveryClient.initClient(config);
- mockedFactory.verify(() -> NamingFactory.createNamingService(HOST
+ ":" + PORT));
+ mockedFactory.verify(() ->
NamingFactory.createNamingService(any(Properties.class)));
verify(namingService).getServicesOfServer(0, 1);
}
}
@Test
- void testInitClientFailedOnCreate() throws NacosException {
+ void testInitClientFailedOnCreate() {
ConnectConfig config =
ConnectConfig.builder().host(HOST).port(PORT).build();
try (MockedStatic<NamingFactory> mockedFactory =
Mockito.mockStatic(NamingFactory.class)) {
- mockedFactory.when(() ->
NamingFactory.createNamingService(anyString()))
+ mockedFactory.when(() ->
NamingFactory.createNamingService(any(Properties.class)))
.thenThrow(new NacosException(500, "connection refused"));
assertThrows(RuntimeException.class, () ->
nacosDiscoveryClient.initClient(config));
@@ -121,7 +134,7 @@ class NacosDiscoveryClientTest {
ConnectConfig config =
ConnectConfig.builder().host(HOST).port(PORT).build();
try (MockedStatic<NamingFactory> mockedFactory =
Mockito.mockStatic(NamingFactory.class)) {
- mockedFactory.when(() ->
NamingFactory.createNamingService(anyString()))
+ mockedFactory.when(() ->
NamingFactory.createNamingService(any(Properties.class)))
.thenReturn(namingService);
when(namingService.getServicesOfServer(0, 1))
.thenThrow(new NacosException(500, "host unreachable"));
@@ -244,6 +257,94 @@ class NacosDiscoveryClientTest {
assertThrows(RuntimeException.class, () ->
nacosDiscoveryClient.getServices());
}
+ @Test
+ void testGetServicesWithGroupNameOnly() throws NacosException {
+ ConnectConfig config =
ConnectConfig.builder().host(HOST).port(PORT).groupName("test-group").build();
+ injectNamingServiceAndConfig(config);
+
when(namingService.getServerStatus()).thenReturn(DiscoveryClientHealthStatus.UP);
+
+ ListView<String> serviceNames = new ListView<>();
+ serviceNames.setData(Collections.singletonList("test-service"));
+ when(namingService.getServicesOfServer(0, 9999,
"test-group")).thenReturn(serviceNames);
+
+ Instance instance = new Instance();
+ instance.setInstanceId("inst-2");
+ instance.setServiceName("test-service");
+ instance.setIp("192.168.1.2");
+ instance.setPort(9090);
+ instance.setWeight(1.0);
+ instance.setHealthy(true);
+
+ when(namingService.getAllInstances("test-service",
"test-group")).thenReturn(Collections.singletonList(instance));
+
+ List<ServiceInstance> result = nacosDiscoveryClient.getServices();
+
+ assertNotNull(result);
+ assertEquals(1, result.size());
+ assertEquals("inst-2", result.get(0).getServiceId());
+
+ verify(namingService).getServicesOfServer(0, 9999, "test-group");
+ verify(namingService).getAllInstances("test-service", "test-group");
+ }
+
+ @Test
+ void testGetServicesWithServiceNameOnly() throws NacosException {
+ ConnectConfig config =
ConnectConfig.builder().host(HOST).port(PORT).serviceName("test-service-only").build();
+ injectNamingServiceAndConfig(config);
+
when(namingService.getServerStatus()).thenReturn(DiscoveryClientHealthStatus.UP);
+
+ Instance instance = new Instance();
+ instance.setInstanceId("inst-3");
+ instance.setServiceName("test-service-only");
+ instance.setIp("192.168.1.3");
+ instance.setPort(9090);
+ instance.setWeight(1.0);
+ instance.setHealthy(true);
+
+
when(namingService.getAllInstances("test-service-only")).thenReturn(Collections.singletonList(instance));
+
+ List<ServiceInstance> result = nacosDiscoveryClient.getServices();
+
+ assertNotNull(result);
+ assertEquals(1, result.size());
+ assertEquals("inst-3", result.get(0).getServiceId());
+
+ // Assert getServicesOfServer is NOT called
+ verify(namingService, never()).getServicesOfServer(anyInt(), anyInt());
+ verify(namingService, never()).getServicesOfServer(anyInt(), anyInt(),
anyString());
+
+ verify(namingService).getAllInstances("test-service-only");
+ }
+
+ @Test
+ void testGetServicesWithGroupAndServiceName() throws NacosException {
+ ConnectConfig config =
ConnectConfig.builder().host(HOST).port(PORT).groupName("test-group").serviceName("target-service").build();
+ injectNamingServiceAndConfig(config);
+
when(namingService.getServerStatus()).thenReturn(DiscoveryClientHealthStatus.UP);
+
+ Instance instance = new Instance();
+ instance.setInstanceId("inst-4");
+ instance.setServiceName("target-service");
+ instance.setIp("192.168.1.4");
+ instance.setPort(9090);
+ instance.setWeight(1.0);
+ instance.setHealthy(true);
+
+ when(namingService.getAllInstances("target-service",
"test-group")).thenReturn(Collections.singletonList(instance));
+
+ List<ServiceInstance> result = nacosDiscoveryClient.getServices();
+
+ assertNotNull(result);
+ assertEquals(1, result.size());
+ assertEquals("inst-4", result.get(0).getServiceId());
+
+ // Assert getServicesOfServer is NOT called
+ verify(namingService, never()).getServicesOfServer(anyInt(), anyInt());
+ verify(namingService, never()).getServicesOfServer(anyInt(), anyInt(),
anyString());
+
+ verify(namingService).getAllInstances("target-service", "test-group");
+ }
+
@Test
void testHealthCheckReturnsTrue() {
injectNamingServiceAndConfig();
@@ -285,8 +386,11 @@ class NacosDiscoveryClientTest {
}
private void injectNamingServiceAndConfig() {
+
injectNamingServiceAndConfig(ConnectConfig.builder().host(HOST).port(PORT).build());
+ }
+
+ private void injectNamingServiceAndConfig(ConnectConfig config) {
ReflectionTestUtils.setField(nacosDiscoveryClient, "namingService",
namingService);
- ConnectConfig config =
ConnectConfig.builder().host(HOST).port(PORT).build();
ReflectionTestUtils.setField(nacosDiscoveryClient,
"localConnectConfig", config);
}
}
diff --git
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/NacosSdProtocol.java
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/NacosSdProtocol.java
index 148b3e328a..5e7c0117c5 100644
---
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/NacosSdProtocol.java
+++
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/NacosSdProtocol.java
@@ -52,7 +52,18 @@ public class NacosSdProtocol implements Protocol {
* Nacos password for authentication
*/
private String password;
-
+
+ /**
+ * Nacos Service Name
+ */
+ private String serviceName;
+
+ /**
+ * Nacos Group Name
+ */
+
+ private String groupName;
+
/**
* Check if the essential protocol parameters are invalid
* @return true if essential parameters are missing
diff --git
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/RegistryProtocol.java
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/RegistryProtocol.java
index a33f5cfd75..aaa63161e3 100644
---
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/RegistryProtocol.java
+++
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/RegistryProtocol.java
@@ -40,6 +40,12 @@ public class RegistryProtocol implements
CommonRequestProtocol, Protocol {
private String port;
private String discoveryClientTypeName;
+ private String username;
+ private String password;
+ private String namespace;
+ private String serviceName;
+ private String groupName;
+
@Override
public boolean isInvalid() {
diff --git a/hertzbeat-manager/src/main/resources/define/app-nacos_sd.yml
b/hertzbeat-manager/src/main/resources/define/app-nacos_sd.yml
index 82a82e38f7..e79a4e8fcb 100644
--- a/hertzbeat-manager/src/main/resources/define/app-nacos_sd.yml
+++ b/hertzbeat-manager/src/main/resources/define/app-nacos_sd.yml
@@ -42,6 +42,41 @@ params:
ja-JP: ポート
type: number
required: true
+ - field: __nacos_sd_username__
+ name:
+ zh-CN: Nacos 服务发现 Username
+ en-US: Nacos Service Discovery User Name
+ ja-JP: ユーザー名
+ type: text
+ required: false
+ - field: __nacos_sd_password__
+ name:
+ zh-CN: Nacos 服务发现 Password
+ en-US: Nacos Service Discovery Password
+ ja-JP: パスワード
+ type: password
+ required: false
+ - field: __nacos_sd_namespace__
+ name:
+ zh-CN: Nacos 服务发现 Namespace
+ en-US: Nacos Service Discovery Namespace
+ ja-JP: 名前空間
+ type: text
+ required: false
+ - field: __nacos_sd_groupName__
+ name:
+ zh-CN: Nacos 服务发现 Group Name
+ en-US: Nacos Service Discovery Group Name
+ ja-JP: グループ名
+ type: text
+ required: false
+ - field: __nacos_sd_serviceName__
+ name:
+ zh-CN: Nacos 服务发现 Service Name
+ en-US: Nacos Service Discovery Service Name
+ ja-JP: サービス名
+ type: text
+ required: false
metrics:
- name: target
@@ -72,4 +107,9 @@ metrics:
# the config content when protocol is nacos_sd
nacos_sd:
host: ^_^__nacos_sd_host__^_^
- port: ^_^__nacos_sd_port__^_^
\ No newline at end of file
+ port: ^_^__nacos_sd_port__^_^
+ namespace: ^_^__nacos_sd_namespace__^_^
+ username: ^_^__nacos_sd_username__^_^
+ password: ^_^__nacos_sd_password__^_^
+ groupName: ^_^__nacos_sd_groupName__^_^
+ serviceName: ^_^__nacos_sd_serviceName__^_^
diff --git a/script/helm/hertzbeat-helm-chart b/script/helm/hertzbeat-helm-chart
index 4a4fbb796e..89cfa4ee21 160000
--- a/script/helm/hertzbeat-helm-chart
+++ b/script/helm/hertzbeat-helm-chart
@@ -1 +1 @@
-Subproject commit 4a4fbb796e9485862c10e38b28a43e604d02284f
+Subproject commit 89cfa4ee219a99619f64a201d7abfa5f071417d0
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]