From 6971244134b57e82e922b3bcbfb24b3462bace20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 12 May 2020 10:57:33 +0200 Subject: [PATCH] SOLR-14463: Solr Admin ZkStatus page now works with ZK 3.6 (#1499) --- solr/CHANGES.txt | 2 ++ .../handler/admin/ZookeeperStatusHandler.java | 5 ++- .../admin/ZookeeperStatusHandlerTest.java | 35 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3cfab7bb406..620ef35f7a0 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -161,6 +161,8 @@ Bug Fixes * SOLR-14431: SegmentsInfoRequestHandler does not release IndexWriter (Tiziano Degaetano, ab) +* SOLR-14463: Solr Admin ZkStatus page now works with ZK 3.6, without 'For input string: "null"' error (janhoy, Bernd Wahlen) + Other Changes --------------------- * SOLR-14197: SolrResourceLoader: marked many methods as deprecated, and in some cases rerouted exiting logic to avoid diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperStatusHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperStatusHandler.java index dd1833b3a75..65c737d7df9 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperStatusHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperStatusHandler.java @@ -147,7 +147,10 @@ public class ZookeeperStatusHandler extends RequestHandlerBase { followers++; } else if ("leader".equals(state)) { leaders++; - reportedFollowers = Integer.parseInt(String.valueOf(stat.get("zk_followers"))); + reportedFollowers = Math.max( + Integer.parseInt((String) stat.getOrDefault("zk_followers", "0")), + Integer.parseInt((String) stat.getOrDefault("zk_synced_followers", "0")) + ); } else if ("standalone".equals(state)) { standalone++; } diff --git a/solr/core/src/test/org/apache/solr/handler/admin/ZookeeperStatusHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/ZookeeperStatusHandlerTest.java index 693accf93cc..1363048ad33 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/ZookeeperStatusHandlerTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/ZookeeperStatusHandlerTest.java @@ -165,4 +165,39 @@ public class ZookeeperStatusHandlerTest extends SolrCloudTestCase { public void validateEmptyResponse() { new ZookeeperStatusHandler(null).validateZkRawResponse(Collections.emptyList(), "zoo1:2181", "mntr"); } + + @Test + public void testMntrBugZk36Solr14463() { + assumeWorkingMockito(); + ZookeeperStatusHandler zkStatusHandler = mock(ZookeeperStatusHandler.class); + when(zkStatusHandler.getZkRawResponse("zoo1:2181", "ruok")).thenReturn(Arrays.asList("imok")); + when(zkStatusHandler.getZkRawResponse("zoo1:2181", "mntr")).thenReturn( + Arrays.asList("zk_version\t3.5.5-390fe37ea45dee01bf87dc1c042b5e3dcce88653, built on 05/03/2019 12:07 GMT", + "zk_avg_latency\t1", + "zk_server_state\tleader", + "zk_synced_followers\t2")); + when(zkStatusHandler.getZkRawResponse("zoo1:2181", "conf")).thenReturn( + Arrays.asList("clientPort=2181")); + when(zkStatusHandler.getZkStatus(anyString(), any())).thenCallRealMethod(); + when(zkStatusHandler.monitorZookeeper(anyString())).thenCallRealMethod(); + when(zkStatusHandler.validateZkRawResponse(ArgumentMatchers.any(), any(), any())).thenAnswer(Answers.CALLS_REAL_METHODS); + + Map mockStatus = zkStatusHandler.getZkStatus("zoo1:2181", ZkDynamicConfig.fromZkConnectString("zoo1:2181")); + String expected = "{\n" + + " \"mode\":\"ensemble\",\n" + + " \"dynamicReconfig\":true,\n" + + " \"ensembleSize\":1,\n" + + " \"details\":[{\n" + + " \"zk_synced_followers\":\"2\",\n" + + " \"zk_version\":\"3.5.5-390fe37ea45dee01bf87dc1c042b5e3dcce88653, built on 05/03/2019 12:07 GMT\",\n" + + " \"zk_avg_latency\":\"1\",\n" + + " \"host\":\"zoo1:2181\",\n" + + " \"clientPort\":\"2181\",\n" + + " \"ok\":true,\n" + + " \"zk_server_state\":\"leader\"}],\n" + + " \"zkHost\":\"zoo1:2181\",\n" + + " \"errors\":[\"Leader reports 2 followers, but we only found 0. Please check zkHost configuration\"],\n" + + " \"status\":\"red\"}"; + assertEquals(expected, JSONUtil.toJSON(mockStatus)); + } } \ No newline at end of file