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 0dd517f5bf fix: handle null or invalid data in HttpSyncDataService 
long polling response (#6979)
0dd517f5bf is described below

commit 0dd517f5bf7438f08667a4c41afdf694728bb320
Author: Limbo <[email protected]>
AuthorDate: Sat Sep 5 14:56:13 2026 +0800

    fix: handle null or invalid data in HttpSyncDataService long polling 
response (#6979)
    
    Co-authored-by: aias00 <[email protected]>
---
 .../shenyu/sync/data/http/HttpSyncDataService.java | 11 ++++---
 .../sync/data/http/HttpSyncDataServiceTest.java    | 35 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git 
a/shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java
 
b/shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java
index ec1e36cd50..75ecd3520f 100644
--- 
a/shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java
+++ 
b/shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java
@@ -236,12 +236,15 @@ public class HttpSyncDataService implements 
SyncDataService {
             Assert.notNull(responseBody, "Resolve response body failed.");
             String json = responseBody.string();
             LOG.info("listener result: [{}]", json);
-            JsonObject responseFromServer = GsonUtils.getGson().fromJson(json, 
JsonObject.class);
-            JsonElement element = responseFromServer.get("data");
-            if (element.isJsonNull()) {
+            JsonElement responseFromServer = 
GsonUtils.getGson().fromJson(json, JsonElement.class);
+            if (Objects.isNull(responseFromServer) || 
responseFromServer.isJsonNull()) {
                 return;
             }
-            groupJson = responseFromServer.getAsJsonArray("data");
+            JsonElement element = 
responseFromServer.getAsJsonObject().get("data");
+            if (Objects.isNull(element) || element.isJsonNull()) {
+                return;
+            }
+            groupJson = element.getAsJsonArray();
         } catch (IOException e) {
             String message = String.format("listener configs fail, 
server:[%s], %s", server, e.getMessage());
             throw new ShenyuException(message, e);
diff --git 
a/shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java
 
b/shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java
index db14f2d93b..4f58d3677a 100644
--- 
a/shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java
+++ 
b/shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.sync.data.http;
 
 import com.github.tomakehurst.wiremock.WireMockServer;
 import 
com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
+import com.github.tomakehurst.wiremock.stubbing.StubMapping;
 import org.apache.shenyu.common.config.ShenyuConfig;
 import org.apache.shenyu.common.constant.HttpConstants;
 import org.apache.shenyu.common.dto.ConfigData;
@@ -33,6 +34,7 @@ import 
org.apache.shenyu.sync.data.api.ProxySelectorDataSubscriber;
 import org.apache.shenyu.sync.data.api.DiscoveryUpstreamDataSubscriber;
 import org.apache.shenyu.sync.data.api.AiProxyApiKeyDataSubscriber;
 import org.apache.shenyu.sync.data.http.config.HttpConfig;
+import org.apache.shenyu.sync.data.http.refresh.AbstractDataRefresh;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -58,6 +60,8 @@ import static 
com.github.tomakehurst.wiremock.client.WireMock.get;
 import static com.github.tomakehurst.wiremock.client.WireMock.post;
 import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
 import static 
com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.atLeastOnce;
@@ -90,6 +94,8 @@ public final class HttpSyncDataServiceTest {
 
     @BeforeEach
     public void before() {
+        Map<?, ?> groupCache = (Map<?, ?>) 
ReflectionTestUtils.getField(AbstractDataRefresh.class, "GROUP_CACHE");
+        Objects.requireNonNull(groupCache).clear();
         this.wireMockServer = new WireMockServer(
                 options()
                         .extensions(mock(ResponseTemplateTransformer.class))
@@ -165,6 +171,35 @@ public final class HttpSyncDataServiceTest {
         verify(proxySelectorDataSubscriber, atLeastOnce()).refresh();
     }
 
+    @Test
+    public void testDoLongPollingIgnoresResponseWithoutData() {
+        httpSyncDataService.close();
+        assertAll(
+                () -> 
assertLongPollingResponseIgnored("{\"code\":500,\"message\":\"error\"}"),
+                () -> assertLongPollingResponseIgnored("{\"data\":null}"),
+                () -> assertLongPollingResponseIgnored("null"),
+                () -> assertLongPollingResponseIgnored("")
+        );
+    }
+
+    private void assertLongPollingResponseIgnored(final String responseBody) {
+        StubMapping stubMapping = 
wireMockServer.stubFor(post(urlPathEqualTo("/configs/listener"))
+                .atPriority(1)
+                .willReturn(aResponse()
+                        .withHeader(HttpHeaders.CONTENT_TYPE, 
ContentType.APPLICATION_JSON.toString())
+                        .withBody(responseBody)
+                        .withStatus(200))
+        );
+
+        try {
+            assertDoesNotThrow(() -> {
+                ReflectionTestUtils.invokeMethod(httpSyncDataService, 
"doLongPolling", getMockServerUrl());
+            });
+        } finally {
+            wireMockServer.removeStub(stubMapping);
+        }
+    }
+
     private String getMockServerUrl() {
         return "http://127.0.0.1:"; + wireMockServer.port();
     }

Reply via email to