From fc8e42bb1dd42c3d1f826521c0960d23e199844e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87a=C4=9Flar=20Eker?= Date: Mon, 20 Apr 2026 00:38:36 +0300 Subject: [PATCH 1/3] fix(pd): set memberSize from RaftEngine members in IndexAPI --- .../src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java b/hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java index a0448965f1..c5ce282c4a 100644 --- a/hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java +++ b/hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java @@ -66,6 +66,7 @@ public BriefStatistics index() throws PDException, ExecutionException, Interrupt BriefStatistics statistics = new BriefStatistics(); statistics.leader = RaftEngine.getInstance().getLeaderGrpcAddress(); statistics.state = pdService.getStoreNodeService().getClusterStats().getState().toString(); + statistics.memberSize = RaftEngine.getInstance().getMembers().size(); statistics.storeSize = pdService.getStoreNodeService().getActiveStores().size(); statistics.graphSize = pdService.getPartitionService().getGraphs().size(); statistics.partitionSize = pdService.getStoreNodeService().getShardGroups().size(); From 4db9735bd5fcd2de8714d85e55515b0d62aea675 Mon Sep 17 00:00:00 2001 From: imbajin Date: Mon, 20 Apr 2026 21:18:00 +0800 Subject: [PATCH 2/3] fix(pd): complete GET / stats fix and add test coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use pdService.getMembers() for memberSize (consistent with cluster()) instead of RaftEngine directly, as suggested in issue #3002 discussion - Add dataState field to BriefStatistics: exposes worst partition health state across all graphs, the most useful missing operational indicator - Align graphSize to count only user-facing graphs (endsWith("/g")), matching the semantics of cluster() to avoid silent count discrepancy - Add testQueryIndexInfo() to both RestApiTest classes to assert state, leader, memberSize > 0, and storeSize > 0 — catches this class of bug --- .../apache/hugegraph/pd/rest/IndexAPI.java | 33 +++++++++++++++++-- .../apache/hugegraph/pd/rest/RestApiTest.java | 18 ++++++++++ .../hugegraph/pd/service/RestApiTest.java | 17 ++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java b/hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java index c5ce282c4a..bee39f23ed 100644 --- a/hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java +++ b/hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/IndexAPI.java @@ -66,10 +66,35 @@ public BriefStatistics index() throws PDException, ExecutionException, Interrupt BriefStatistics statistics = new BriefStatistics(); statistics.leader = RaftEngine.getInstance().getLeaderGrpcAddress(); statistics.state = pdService.getStoreNodeService().getClusterStats().getState().toString(); - statistics.memberSize = RaftEngine.getInstance().getMembers().size(); + + // Use pdService (consistent with cluster()) rather than RaftEngine directly + CallStreamObserverWrap membersResp = + new CallStreamObserverWrap<>(); + pdService.getMembers(Pdpb.GetMembersRequest.newBuilder().build(), membersResp); + statistics.memberSize = membersResp.get().get(0).getMembersList().size(); + statistics.storeSize = pdService.getStoreNodeService().getActiveStores().size(); - statistics.graphSize = pdService.getPartitionService().getGraphs().size(); + // Filter to user-facing graphs only (consistent with cluster()) + List graphs = pdRestService.getGraphs(); + statistics.graphSize = (int) graphs.stream() + .filter(g -> g.getGraphName() != null && + g.getGraphName().endsWith("/g")) + .count(); statistics.partitionSize = pdService.getStoreNodeService().getShardGroups().size(); + + // Derive worst partition health state across all graphs + Metapb.PartitionState dataState = Metapb.PartitionState.PState_Normal; + for (Metapb.Graph graph : graphs) { + if (graph.getState() == Metapb.PartitionState.UNRECOGNIZED) { + continue; + } + if (graph.getState() != null && + graph.getState().getNumber() > dataState.getNumber()) { + dataState = graph.getState(); + } + } + statistics.dataState = dataState.name(); + return statistics; } @@ -158,9 +183,13 @@ public RestApiResponse cluster() throws InterruptedException, ExecutionException class BriefStatistics { String state; + /** Worst partition health state across all graphs (mirrors cluster().dataState) */ + String dataState; String leader; int memberSize; + /** Active (online) store count only */ int storeSize; + /** User-facing graphs count (graphName ending with /g) */ int graphSize; int partitionSize; } diff --git a/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/rest/RestApiTest.java b/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/rest/RestApiTest.java index 2d6f4f054b..86846f218b 100644 --- a/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/rest/RestApiTest.java +++ b/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/rest/RestApiTest.java @@ -29,6 +29,24 @@ public class RestApiTest extends BaseServerTest { + @Test + public void testQueryIndexInfo() throws URISyntaxException, IOException, InterruptedException, + JSONException { + String url = pdRestAddr + "/"; + HttpRequest request = HttpRequest.newBuilder() + .uri(new URI(url)) + .header("Authorization", "Basic c3RvcmU6MTIz") + .GET() + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assert response.statusCode() == 200; + JSONObject obj = new JSONObject(response.body()); + assert obj.getString("state") != null; + assert obj.getString("leader") != null; + assert obj.getInt("memberSize") > 0 : "memberSize should be > 0 for a running cluster"; + assert obj.getInt("storeSize") > 0 : "storeSize should be > 0 for a running cluster"; + } + @Test public void testQueryClusterInfo() throws URISyntaxException, IOException, InterruptedException, JSONException { diff --git a/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/service/RestApiTest.java b/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/service/RestApiTest.java index d4c9cd121e..c1dcd26f18 100644 --- a/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/service/RestApiTest.java +++ b/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/service/RestApiTest.java @@ -29,6 +29,23 @@ public class RestApiTest extends BaseServerTest { + @Test + public void testQueryIndexInfo() throws URISyntaxException, IOException, InterruptedException, + JSONException { + String url = pdRestAddr + "/"; + HttpRequest request = HttpRequest.newBuilder() + .uri(new URI(url)).header(key, value) + .GET() + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assert response.statusCode() == 200; + JSONObject obj = new JSONObject(response.body()); + assert obj.getString("state") != null; + assert obj.getString("leader") != null; + assert obj.getInt("memberSize") > 0 : "memberSize should be > 0 for a running cluster"; + assert obj.getInt("storeSize") > 0 : "storeSize should be > 0 for a running cluster"; + } + @Test public void testQueryClusterInfo() throws URISyntaxException, IOException, InterruptedException, JSONException { From 839a3d2c59753e7494d8b264bf166ae5e52ddea6 Mon Sep 17 00:00:00 2001 From: imbajin Date: Mon, 20 Apr 2026 22:07:14 +0800 Subject: [PATCH 3/3] fix(pd): relax storeSize assertion in PD-only test environment --- .../main/java/org/apache/hugegraph/pd/rest/RestApiTest.java | 3 ++- .../main/java/org/apache/hugegraph/pd/service/RestApiTest.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/rest/RestApiTest.java b/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/rest/RestApiTest.java index 86846f218b..fb2b71d480 100644 --- a/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/rest/RestApiTest.java +++ b/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/rest/RestApiTest.java @@ -44,7 +44,8 @@ public void testQueryIndexInfo() throws URISyntaxException, IOException, Interru assert obj.getString("state") != null; assert obj.getString("leader") != null; assert obj.getInt("memberSize") > 0 : "memberSize should be > 0 for a running cluster"; - assert obj.getInt("storeSize") > 0 : "storeSize should be > 0 for a running cluster"; + // storeSize can be 0 in PD-only test environments with no store nodes registered + assert obj.getInt("storeSize") >= 0; } @Test diff --git a/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/service/RestApiTest.java b/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/service/RestApiTest.java index c1dcd26f18..b899c09194 100644 --- a/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/service/RestApiTest.java +++ b/hugegraph-pd/hg-pd-test/src/main/java/org/apache/hugegraph/pd/service/RestApiTest.java @@ -43,7 +43,8 @@ public void testQueryIndexInfo() throws URISyntaxException, IOException, Interru assert obj.getString("state") != null; assert obj.getString("leader") != null; assert obj.getInt("memberSize") > 0 : "memberSize should be > 0 for a running cluster"; - assert obj.getInt("storeSize") > 0 : "storeSize should be > 0 for a running cluster"; + // storeSize can be 0 in PD-only test environments with no store nodes registered + assert obj.getInt("storeSize") >= 0; } @Test