diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index 21cb891f8da..d56586c9a9f 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -142,17 +142,12 @@ public final class ZkController { TimeoutException, IOException { if (cc == null) throw new IllegalArgumentException("CoreContainer cannot be null."); this.cc = cc; - if (localHostContext.startsWith("/")) { - // be forgiving and strip this off - // this allows us to support users specifying hostContext="/" in - // solr.xml to indicate the root context, instead of hostContext="" - // which means the default of "solr" - localHostContext = localHostContext.substring(1); - } - if (localHostContext.endsWith("/")) { - // be extra nice - localHostContext = localHostContext.substring(0,localHostContext.length()-1); - } + + // be forgiving and strip this off leading/trailing slashes + // this allows us to support users specifying hostContext="/" in + // solr.xml to indicate the root context, instead of hostContext="" + // which means the default of "solr" + localHostContext = trimLeadingAndTrailingSlashes(localHostContext); updateShardHandler = new UpdateShardHandler(distribUpdateConnTimeout, distribUpdateSoTimeout); @@ -1313,9 +1308,9 @@ public final class ZkController { /** * Returns the nodeName that should be used based on the specified properties. * - * @param hostName - must not be the empty string - * @param hostPort - must consist only of digits, must not be the empty string - * @param hostContext - should not begin or end with a slash, may be the empty string to denote the root context + * @param hostName - must not be null or the empty string + * @param hostPort - must consist only of digits, must not be null or the empty string + * @param hostContext - should not begin or end with a slash (leading/trailin slashes will be ignored), must not be null, may be the empty string to denote the root context * @lucene.experimental * @see SolrZkClient#getBaseUrlForNodeName */ @@ -1324,9 +1319,27 @@ public final class ZkController { final String hostContext) { try { return hostName + ':' + hostPort + '_' + - URLEncoder.encode(hostContext, "UTF-8"); + URLEncoder.encode(trimLeadingAndTrailingSlashes(hostContext), "UTF-8"); } catch (UnsupportedEncodingException e) { throw new IllegalStateException("JVM Does not seem to support UTF-8", e); } } + + /** + * utilitiy method fro trimming and leading and/or trailing slashes from + * it's input. May return the empty string. May return null if and only + * if the input is null. + */ + private static String trimLeadingAndTrailingSlashes(final String in) { + if (null == in) return in; + + String out = in; + if (out.startsWith("/")) { + out = out.substring(1); + } + if (out.endsWith("/")) { + out = out.substring(0,out.length()-1); + } + return out; + } } diff --git a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java index a661fd48ec6..d59d31aa61d 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java @@ -53,10 +53,22 @@ public class ZkControllerTest extends SolrTestCaseJ4 { // nodeName from parts assertEquals("localhost:8888_solr", ZkController.generateNodeName("localhost", "8888", "solr")); - assertEquals("localhost:8888_", // root context + assertEquals("localhost:8888_solr", + ZkController.generateNodeName("localhost", "8888", "/solr")); + assertEquals("localhost:8888_solr", + ZkController.generateNodeName("localhost", "8888", "/solr/")); + // root context + assertEquals("localhost:8888_", ZkController.generateNodeName("localhost", "8888", "")); + assertEquals("localhost:8888_", + ZkController.generateNodeName("localhost", "8888", "/")); + // subdir assertEquals("foo-bar:77_solr%2Fsub_dir", ZkController.generateNodeName("foo-bar", "77", "solr/sub_dir")); + assertEquals("foo-bar:77_solr%2Fsub_dir", + ZkController.generateNodeName("foo-bar", "77", "/solr/sub_dir")); + assertEquals("foo-bar:77_solr%2Fsub_dir", + ZkController.generateNodeName("foo-bar", "77", "/solr/sub_dir/")); // setup a SolrZkClient to do some getBaseUrlForNodeName testing String zkDir = dataDir.getAbsolutePath() + File.separator @@ -75,27 +87,41 @@ public class ZkControllerTest extends SolrTestCaseJ4 { // getBaseUrlForNodeName assertEquals("http://zzz.xxx:1234/solr", zkClient.getBaseUrlForNodeName("zzz.xxx:1234_solr")); - assertEquals("http://xxx:99/", + assertEquals("http://xxx:99", zkClient.getBaseUrlForNodeName("xxx:99_")); assertEquals("http://foo-bar.baz.org:9999/some_dir", zkClient.getBaseUrlForNodeName("foo-bar.baz.org:9999_some_dir")); assertEquals("http://foo-bar.baz.org:9999/solr/sub_dir", zkClient.getBaseUrlForNodeName("foo-bar.baz.org:9999_solr%2Fsub_dir")); - // generateNodeName + getBaseUrlForNodeName assertEquals("http://foo:9876/solr", zkClient.getBaseUrlForNodeName (ZkController.generateNodeName("foo","9876","solr"))); + assertEquals("http://foo:9876/solr", + zkClient.getBaseUrlForNodeName + (ZkController.generateNodeName("foo","9876","/solr"))); + assertEquals("http://foo:9876/solr", + zkClient.getBaseUrlForNodeName + (ZkController.generateNodeName("foo","9876","/solr/"))); assertEquals("http://foo.bar.com:9876/solr/sub_dir", zkClient.getBaseUrlForNodeName (ZkController.generateNodeName("foo.bar.com","9876","solr/sub_dir"))); - assertEquals("http://foo-bar:9876/", + assertEquals("http://foo.bar.com:9876/solr/sub_dir", + zkClient.getBaseUrlForNodeName + (ZkController.generateNodeName("foo.bar.com","9876","/solr/sub_dir/"))); + assertEquals("http://foo-bar:9876", zkClient.getBaseUrlForNodeName (ZkController.generateNodeName("foo-bar","9876",""))); + assertEquals("http://foo-bar:9876", + zkClient.getBaseUrlForNodeName + (ZkController.generateNodeName("foo-bar","9876","/"))); assertEquals("http://foo-bar.com:80/some_dir", zkClient.getBaseUrlForNodeName (ZkController.generateNodeName("foo-bar.com","80","some_dir"))); + assertEquals("http://foo-bar.com:80/some_dir", + zkClient.getBaseUrlForNodeName + (ZkController.generateNodeName("foo-bar.com","80","/some_dir"))); } finally { zkClient.close(); } diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java b/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java index cb60ff09184..77df7bba026 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java @@ -484,7 +484,7 @@ public class SolrZkClient { try { final String path = URLDecoder.decode(nodeName.substring(1+_offset), "UTF-8"); - return "http://" + hostAndPort + "/" + path; + return "http://" + hostAndPort + (path.isEmpty() ? "" : ("/" + path)); } catch (UnsupportedEncodingException e) { throw new IllegalStateException("JVM Does not seem to support UTF-8", e); }