From 1123afae94f36027bcb7b2dc40b089653ed4d1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Fri, 2 Aug 2019 13:01:20 +0200 Subject: [PATCH] SOLR-13672: Cloud -> Zk Status page now parses response from Zookeeper 3.5.5 correctly --- solr/CHANGES.txt | 2 + .../handler/admin/ZookeeperStatusHandler.java | 40 +++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 03279b7a3e8..b6dd4401db2 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -126,6 +126,8 @@ Bug Fixes * SOLR-13664: Fixed SolrTestCaseJ4.deleteCore() to properly reset the dataDir used by initCore() (hossman) +* SOLR-13672: Cloud -> Zk Status page now parses response from Zookeeper 3.5.5 correctly (Jörn Franke, janhoy) + Other Changes ---------------------- 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 7afd6bf6dc1..fc42f18f9ee 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 @@ -99,6 +99,9 @@ public final class ZookeeperStatusHandler extends RequestHandlerBase { for (String zk : zookeepers) { try { Map stat = monitorZookeeper(zk); + if (stat.containsKey("errors")) { + errors.addAll((List)stat.get("errors")); + } details.add(stat); if ("true".equals(String.valueOf(stat.get("ok")))) { numOk++; @@ -115,13 +118,12 @@ public final class ZookeeperStatusHandler extends RequestHandlerBase { } catch (SolrException se) { log.warn("Failed talking to zookeeper" + zk, se); errors.add(se.getMessage()); - zkStatus.put("errors", errors); Map stat = new HashMap<>(); stat.put("host", zk); stat.put("ok", false); - zkStatus.put("status", STATUS_YELLOW); - return zkStatus; - } + status = STATUS_YELLOW; + details.add(stat); + } } zkStatus.put("details", details); if (followers+leaders > 0 && standalone > 0) { @@ -180,36 +182,34 @@ public final class ZookeeperStatusHandler extends RequestHandlerBase { private Map monitorZookeeper(String zkHostPort) throws SolrException { Map obj = new HashMap<>(); + List errors = new ArrayList<>(); obj.put("host", zkHostPort); List lines = getZkRawResponse(zkHostPort, "ruok"); boolean ok = "imok".equals(lines.get(0)); - if (ok == false) { - log.warn("Check 4lw.commands.whitelist setting in zookeeper configuration file, ZK response {}", lines.get(0)); - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, lines.get(0) + " Check 4lw.commands.whitelist setting in zookeeper configuration file."); - } obj.put("ok", ok); lines = getZkRawResponse(zkHostPort, "mntr"); - String[] parts; for (String line : lines) { - parts = line.split("\t"); + String[] parts = line.split("\t"); if (parts.length >= 2) { obj.put(parts[0], parts[1]); } else { - log.warn("Check 4lw.commands.whitelist setting in zookeeper configuration file, ZK response {}", line); - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, line + " Check 4lw.commands.whitelist setting in zookeeper configuration file."); + String err = String.format("Unexpected line in 'mntr' response from Zookeeper %s: %s", zkHostPort, line); + log.warn(err); + errors.add(err); } } lines = getZkRawResponse(zkHostPort, "conf"); - for (String line : lines) { - parts = line.split("="); + String[] parts = line.split("="); if (parts.length >= 2) { obj.put(parts[0], parts[1]); - } else { - log.warn("Check 4lw.commands.whitelist setting in zookeeper configuration file, ZK response {}", line); - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, line + " Check 4lw.commands.whitelist setting in zookeeper configuration file."); + } else if (!line.startsWith("membership:")) { + String err = String.format("Unexpected line in 'conf' response from Zookeeper %s: %s", zkHostPort, line); + log.warn(err); + errors.add(err); } } + obj.put("errors", errors); return obj; } @@ -238,6 +238,12 @@ public final class ZookeeperStatusHandler extends RequestHandlerBase { if (response == null || response.isEmpty()) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Empty response from Zookeeper " + zkHostPort); } + if (response.size() == 1 && response.get(0).contains("not in the whitelist")) { + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Could not execute " + fourLetterWordCommand + + " towards ZK host " + zkHostPort + ". Add this line to the 'zoo.cfg' " + + "configuration file on each zookeeper node: '4lw.commands.whitelist=mntr,conf,ruok'. See also chapter " + + "'Setting Up an External ZooKeeper Ensemble' in the Solr Reference Guide."); + } return response; } catch (IOException e) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Failed talking to Zookeeper " + zkHostPort, e);