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/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 00901f3c72 fix(register): track all HTTP registrations (#7143)
00901f3c72 is described below

commit 00901f3c722d3140dc1063e18d13b995477da1ba
Author: Liming Deng <[email protected]>
AuthorDate: Mon Sep 21 16:42:54 2026 +0800

    fix(register): track all HTTP registrations (#7143)
    
    Co-authored-by: shown <[email protected]>
    Co-authored-by: aias00 <[email protected]>
---
 .../client/http/HttpClientRegisterRepository.java  | 40 +++++++++-----
 .../http/HttpClientRegisterRepositoryTest.java     | 63 ++++++++++++++--------
 2 files changed, 69 insertions(+), 34 deletions(-)

diff --git 
a/shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepository.java
 
b/shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepository.java
index 88ae116051..288f9e1690 100644
--- 
a/shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepository.java
+++ 
b/shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepository.java
@@ -44,8 +44,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -56,9 +58,9 @@ public class HttpClientRegisterRepository extends 
FailbackRegistryRepository {
     
     private static final Logger LOGGER = 
LoggerFactory.getLogger(HttpClientRegisterRepository.class);
 
-    private static URIRegisterDTO uriRegisterDTO;
+    private final Map<String, URIRegisterDTO> uriRegisterDTOs = new 
ConcurrentHashMap<>();
 
-    private static ApiDocRegisterDTO apiDocRegisterDTO;
+    private final Map<String, ApiDocRegisterDTO> apiDocRegisterDTOs = new 
ConcurrentHashMap<>();
 
     private String username;
     
@@ -124,7 +126,7 @@ public class HttpClientRegisterRepository extends 
FailbackRegistryRepository {
             return;
         }
         doRegister(registerDTO, Constants.URI_PATH, Constants.URI);
-        uriRegisterDTO = registerDTO;
+        uriRegisterDTOs.put(uriIdentity(registerDTO), registerDTO);
     }
     
     @Override
@@ -154,7 +156,7 @@ public class HttpClientRegisterRepository extends 
FailbackRegistryRepository {
     @Override
     protected void doPersistApiDoc(final ApiDocRegisterDTO registerDTO) {
         doRegister(registerDTO, Constants.API_DOC_PATH, 
Constants.API_DOC_TYPE);
-        apiDocRegisterDTO = registerDTO;
+        apiDocRegisterDTOs.put(apiDocIdentity(registerDTO), registerDTO);
     }
     
     @Override
@@ -169,14 +171,28 @@ public class HttpClientRegisterRepository extends 
FailbackRegistryRepository {
 
     @Override
     public void closeRepository() {
-        if (Objects.nonNull(uriRegisterDTO)) {
-            uriRegisterDTO.setEventType(EventType.DELETED);
-            doRegister(uriRegisterDTO, Constants.URI_PATH, Constants.URI);
-        }
-        if (Objects.nonNull(apiDocRegisterDTO)) {
-            apiDocRegisterDTO.setEventType(EventType.OFFLINE);
-            doRegister(apiDocRegisterDTO, Constants.API_DOC_PATH, 
Constants.API_DOC_TYPE);
-        }
+        uriRegisterDTOs.values().forEach(registerDTO -> {
+            registerDTO.setEventType(EventType.DELETED);
+            doRegister(registerDTO, Constants.URI_PATH, Constants.URI);
+        });
+        apiDocRegisterDTOs.values().forEach(registerDTO -> {
+            registerDTO.setEventType(EventType.OFFLINE);
+            doRegister(registerDTO, Constants.API_DOC_PATH, 
Constants.API_DOC_TYPE);
+        });
+    }
+
+    private static String uriIdentity(final URIRegisterDTO registerDTO) {
+        return String.join(":", value(registerDTO.getNamespaceId()), 
value(registerDTO.getProtocol()), value(registerDTO.getAppName()),
+                value(registerDTO.getContextPath()), 
value(registerDTO.getRpcType()), value(registerDTO.getHost()), 
value(registerDTO.getPort()));
+    }
+
+    private static String apiDocIdentity(final ApiDocRegisterDTO registerDTO) {
+        return String.join(":", value(registerDTO.getContextPath()), 
value(registerDTO.getApiPath()), value(registerDTO.getHttpMethod()),
+                value(registerDTO.getRpcType()), 
value(registerDTO.getVersion()));
+    }
+
+    private static String value(final Object value) {
+        return Objects.toString(value, "");
     }
 
     /**
diff --git 
a/shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/test/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepositoryTest.java
 
b/shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/test/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepositoryTest.java
index e10db3a70b..38a2ce3474 100644
--- 
a/shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/test/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepositoryTest.java
+++ 
b/shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/test/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepositoryTest.java
@@ -18,6 +18,7 @@
 package org.apache.shenyu.register.client.http;
 
 import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.utils.GsonUtils;
 import org.apache.shenyu.register.client.http.utils.RegisterUtils;
 import org.apache.shenyu.register.client.http.utils.RuntimeUtils;
 import org.apache.shenyu.register.common.config.ShenyuRegisterCenterConfig;
@@ -26,13 +27,12 @@ import 
org.apache.shenyu.register.common.dto.DiscoveryConfigRegisterDTO;
 import org.apache.shenyu.register.common.dto.McpToolsRegisterDTO;
 import org.apache.shenyu.register.common.dto.MetaDataRegisterDTO;
 import org.apache.shenyu.register.common.dto.URIRegisterDTO;
-import org.junit.jupiter.api.AfterEach;
+import org.apache.shenyu.register.common.enums.EventType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.MockedStatic;
 
 import java.io.IOException;
-import java.lang.reflect.Field;
 import java.util.Optional;
 import java.util.Properties;
 
@@ -60,16 +60,10 @@ public final class HttpClientRegisterRepositoryTest {
     private HttpClientRegisterRepository repository;
 
     @BeforeEach
-    public void setUp() throws Exception {
-        resetStatics();
+    public void setUp() {
         repository = new HttpClientRegisterRepository(config(FIRST_SERVER));
     }
 
-    @AfterEach
-    public void tearDown() throws Exception {
-        resetStatics();
-    }
-
     @Test
     public void persistUriShouldRegisterToEveryServer() {
         HttpClientRegisterRepository multiServerRepository = new 
HttpClientRegisterRepository(config(
@@ -176,21 +170,54 @@ public final class HttpClientRegisterRepositoryTest {
     }
 
     @Test
-    public void closeRepositoryShouldUnregisterLastUriAndApiDoc() {
+    public void closeRepositoryShouldUnregisterEveryUriAndApiDoc() {
         try (MockedStatic<RegisterUtils> registerUtils = 
mockStatic(RegisterUtils.class);
              MockedStatic<RuntimeUtils> runtimeUtils = 
mockStatic(RuntimeUtils.class)) {
             runtimeUtils.when(() -> 
RuntimeUtils.listenByOther(anyInt())).thenReturn(false);
             registerUtils.when(() -> RegisterUtils.doLogin(anyString(), 
anyString(), anyString()))
                     .thenReturn(Optional.of(TOKEN));
 
-            repository.persistURI(uriRegisterDTO());
-            
repository.persistApiDoc(ApiDocRegisterDTO.builder().apiPath("/hello").build());
+            URIRegisterDTO firstUri = uriRegisterDTO();
+            URIRegisterDTO secondUri = 
URIRegisterDTO.builder().appName("demo").rpcType("http")
+                    .host("127.0.0.1").port(18081).build();
+            ApiDocRegisterDTO firstApiDoc = 
ApiDocRegisterDTO.builder().apiPath("/hello").build();
+            ApiDocRegisterDTO secondApiDoc = 
ApiDocRegisterDTO.builder().apiPath("/goodbye").build();
+            repository.persistURI(firstUri);
+            repository.persistURI(secondUri);
+            repository.persistApiDoc(firstApiDoc);
+            repository.persistApiDoc(secondApiDoc);
             repository.closeRepository();
 
             registerUtils.verify(() -> RegisterUtils.doRegister(anyString(),
-                    eq(FIRST_SERVER + Constants.URI_PATH), eq(Constants.URI), 
eq(TOKEN)), times(2));
+                    eq(FIRST_SERVER + Constants.URI_PATH), eq(Constants.URI), 
eq(TOKEN)), times(4));
             registerUtils.verify(() -> RegisterUtils.doRegister(anyString(),
-                    eq(FIRST_SERVER + Constants.API_DOC_PATH), 
eq(Constants.API_DOC_TYPE), eq(TOKEN)), times(2));
+                    eq(FIRST_SERVER + Constants.API_DOC_PATH), 
eq(Constants.API_DOC_TYPE), eq(TOKEN)), times(4));
+        }
+    }
+
+    @Test
+    public void repositoriesShouldTrackRegistrationsIndependently() {
+        HttpClientRegisterRepository secondRepository = new 
HttpClientRegisterRepository(config(FIRST_SERVER));
+        URIRegisterDTO firstUri = uriRegisterDTO();
+        URIRegisterDTO secondUri = 
URIRegisterDTO.builder().appName("demo").rpcType("http")
+                .host("127.0.0.1").port(18081).build();
+
+        try (MockedStatic<RegisterUtils> registerUtils = 
mockStatic(RegisterUtils.class);
+             MockedStatic<RuntimeUtils> runtimeUtils = 
mockStatic(RuntimeUtils.class)) {
+            runtimeUtils.when(() -> 
RuntimeUtils.listenByOther(anyInt())).thenReturn(false);
+            registerUtils.when(() -> RegisterUtils.doLogin(anyString(), 
anyString(), anyString()))
+                    .thenReturn(Optional.of(TOKEN));
+            repository.persistURI(firstUri);
+            secondRepository.persistURI(secondUri);
+            registerUtils.clearInvocations();
+
+            repository.closeRepository();
+
+            firstUri.setEventType(EventType.DELETED);
+            registerUtils.verify(() -> 
RegisterUtils.doRegister(eq(GsonUtils.getInstance().toJson(firstUri)),
+                    eq(FIRST_SERVER + Constants.URI_PATH), eq(Constants.URI), 
eq(TOKEN)));
+            registerUtils.verify(() -> 
RegisterUtils.doRegister(eq(GsonUtils.getInstance().toJson(secondUri)),
+                    eq(FIRST_SERVER + Constants.URI_PATH), eq(Constants.URI), 
eq(TOKEN)), never());
         }
     }
 
@@ -254,12 +281,4 @@ public final class HttpClientRegisterRepositoryTest {
         return metaDataRegisterDTO;
     }
 
-    private void resetStatics() throws Exception {
-        Field uriField = 
HttpClientRegisterRepository.class.getDeclaredField("uriRegisterDTO");
-        uriField.setAccessible(true);
-        uriField.set(null, null);
-        Field apiDocField = 
HttpClientRegisterRepository.class.getDeclaredField("apiDocRegisterDTO");
-        apiDocField.setAccessible(true);
-        apiDocField.set(null, null);
-    }
 }

Reply via email to