SOLR-6607 Managing requesthandlers through API

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1642141 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Noble Paul 2014-11-27 13:16:22 +00:00
parent 99b935a881
commit 4fab579c2a
11 changed files with 317 additions and 39 deletions

View File

@ -217,6 +217,8 @@ New Features
* SOLR-6533: Support editing common solrconfig.xml values (Noble Paul)
* SOLR-6607: Managing requesthandlers throuh API (Noble Paul)
Bug Fixes
----------------------

View File

@ -2235,18 +2235,20 @@ public final class ZkController {
log.info("Watcher on {} is removed ", zkDir);
return;
}
final Set<Runnable> listeners = confDirectoryListeners.get(zkDir);
Set<Runnable> listeners = confDirectoryListeners.get(zkDir);
if (listeners != null && !listeners.isEmpty()) {
final Set<Runnable> listenersCopy = new HashSet<>(listeners);
new Thread() {
//run these in a separate thread because this can be long running
public void run() {
for (final Runnable listener : listeners)
for (final Runnable listener : listenersCopy) {
try {
listener.run();
} catch (Exception e) {
log.warn("listener throws error", e);
}
}
}
}.start();
}

View File

@ -28,17 +28,22 @@ import java.util.Map;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.request.SolrRequestHandler;
import org.noggit.CharArr;
import org.noggit.JSONParser;
import org.noggit.JSONWriter;
import org.noggit.ObjectBuilder;
import static org.apache.solr.common.params.CoreAdminParams.NAME;
public class ConfigOverlay implements MapSerializable{
private final int znodeVersion ;
private Map<String, Object> data;
private Map<String,Object> props;
private Map<String,Object> userProps;
private Map<String, Map> reqHandlers;
public ConfigOverlay(Map<String,Object> jsonObj, int znodeVersion){
if(jsonObj == null) jsonObj= Collections.EMPTY_MAP;
@ -48,6 +53,8 @@ public class ConfigOverlay implements MapSerializable{
if(props == null) props= Collections.EMPTY_MAP;
userProps = (Map<String, Object>) data.get("userProps");
if(userProps == null) userProps= Collections.EMPTY_MAP;
reqHandlers = (Map<String, Map>) data.get(SolrRequestHandler.TYPE);
if(reqHandlers == null) reqHandlers = new LinkedHashMap<>();
}
public Object getXPathProperty(String xpath){
@ -255,4 +262,28 @@ public class ConfigOverlay implements MapSerializable{
result.putAll(data);
return result;
}
public Map<String, Map> getReqHandlers() {
return Collections.unmodifiableMap(reqHandlers);
}
public ConfigOverlay addReqHandler(Map<String, Object> info) {
ConfigOverlay copy = copyOverLayWithReqHandler();
copy.reqHandlers.put((String)info.get(NAME) , info);
return copy;
}
private ConfigOverlay copyOverLayWithReqHandler() {
LinkedHashMap<String, Object> newmap = new LinkedHashMap<>(data);
ConfigOverlay copy = new ConfigOverlay(newmap, znodeVersion);
newmap.put(SolrRequestHandler.TYPE, copy.reqHandlers = new LinkedHashMap<>(reqHandlers));
return copy;
}
public ConfigOverlay deleteHandler(String name) {
ConfigOverlay copy = copyOverLayWithReqHandler();
copy.reqHandlers.remove(name);
return copy;
}
}

View File

@ -22,8 +22,12 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.*;
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import static org.apache.solr.common.params.CoreAdminParams.NAME;
import static org.apache.solr.schema.FieldType.CLASS_NAME;
/**
* An Object which represents a Plugin of any type
@ -38,8 +42,8 @@ public class PluginInfo implements MapSerializable{
public PluginInfo(String type, Map<String, String> attrs ,NamedList initArgs, List<PluginInfo> children) {
this.type = type;
this.name = attrs.get("name");
this.className = attrs.get("class");
this.name = attrs.get(NAME);
this.className = attrs.get(CLASS_NAME);
this.initArgs = initArgs;
attributes = unmodifiableMap(attrs);
this.children = children == null ? Collections.<PluginInfo>emptyList(): unmodifiableList(children);
@ -49,14 +53,27 @@ public class PluginInfo implements MapSerializable{
public PluginInfo(Node node, String err, boolean requireName, boolean requireClass) {
type = node.getNodeName();
name = DOMUtil.getAttr(node, "name", requireName ? err : null);
className = DOMUtil.getAttr(node, "class", requireClass ? err : null);
name = DOMUtil.getAttr(node, NAME, requireName ? err : null);
className = DOMUtil.getAttr(node, CLASS_NAME, requireClass ? err : null);
initArgs = DOMUtil.childNodesToNamedList(node);
attributes = unmodifiableMap(DOMUtil.toMap(node.getAttributes()));
children = loadSubPlugins(node);
isFromSolrConfig = true;
}
public PluginInfo(String type, Map<String,Object> map) {
LinkedHashMap m = new LinkedHashMap<>(map);
NamedList nl = new NamedList();
for (String s : asList(DEFAULTS, APPENDS, INVARIANTS)) if (m.get(s) != null) nl.add(s, map.remove(s));
this.type = type;
this.name = (String) m.get(NAME);
this.className = (String) m.get(CLASS_NAME);
this.initArgs = nl;
attributes = unmodifiableMap(m);
this.children = Collections.<PluginInfo>emptyList();
isFromSolrConfig = true;
}
private List<PluginInfo> loadSubPlugins(Node node) {
List<PluginInfo> children = new ArrayList<>();
//if there is another sub tag with a non namedlist tag that has to be another plugin
@ -131,7 +148,7 @@ public class PluginInfo implements MapSerializable{
public static final PluginInfo EMPTY_INFO = new PluginInfo("",Collections.<String,String>emptyMap(), new NamedList(),Collections.<PluginInfo>emptyList());
private static final HashSet<String> NL_TAGS = new HashSet<>
(Arrays.asList("lst", "arr",
(asList("lst", "arr",
"bool",
"str",
"int", "long",

View File

@ -143,12 +143,15 @@ public final class RequestHandlers {
List<PluginInfo> implicits = PluginsRegistry.getHandlers(core);
// use link map so we iterate in the same order
Map<PluginInfo,SolrRequestHandler> handlers = new LinkedHashMap<>();
Map<String, PluginInfo> implicitInfoMap= new HashMap<>();
Map<String, PluginInfo> infoMap= new LinkedHashMap<>();
//deduping implicit and explicit requesthandlers
for (PluginInfo info : implicits) implicitInfoMap.put(info.name,info);
for (PluginInfo info : implicits) infoMap.put(info.name,info);
for (PluginInfo info : config.getPluginInfos(SolrRequestHandler.class.getName()))
if(implicitInfoMap.containsKey(info.name)) implicitInfoMap.remove(info.name);
ArrayList<PluginInfo> infos = new ArrayList<>(implicitInfoMap.values());
if(infoMap.containsKey(info.name)) infoMap.remove(info.name);
for (Map.Entry e : core.getSolrConfig().getOverlay().getReqHandlers().entrySet())
infoMap.put((String)e.getKey(), new PluginInfo(SolrRequestHandler.TYPE, (Map)e.getValue()));
ArrayList<PluginInfo> infos = new ArrayList<>(infoMap.values());
infos.addAll(config.getPluginInfos(SolrRequestHandler.class.getName()));
for (PluginInfo info : infos) {
try {

View File

@ -334,13 +334,14 @@ public class SolrConfig extends Config implements MapSerializable{
in = loader.openResource(ConfigOverlay.RESOURCE_NAME);
} catch (IOException e) {
//no problem no overlay.json file
return new ConfigOverlay(Collections.EMPTY_MAP,0);
return new ConfigOverlay(Collections.EMPTY_MAP,-1);
}
try {
int version = 0; //will be always 0 for file based resourceloader
if (in instanceof ZkSolrResourceLoader.ZkByteArrayInputStream) {
version = ((ZkSolrResourceLoader.ZkByteArrayInputStream) in).getStat().getVersion();
log.info("config overlay loaded . version : {} ", version);
}
Map m = (Map) ObjectBuilder.getVal(new JSONParser(new InputStreamReader(in, StandardCharsets.UTF_8)));
return new ConfigOverlay(m,version);

View File

@ -51,6 +51,7 @@ import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.SchemaManager;
import org.apache.solr.util.CommandOperation;
import org.apache.solr.util.plugin.SolrCoreAware;
@ -63,8 +64,10 @@ import static java.text.MessageFormat.format;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.apache.solr.common.cloud.ZkNodeProps.makeMap;
import static org.apache.solr.common.params.CoreAdminParams.NAME;
import static org.apache.solr.core.ConfigOverlay.NOT_EDITABLE;
import static org.apache.solr.core.PluginInfo.DEFAULTS;
import static org.apache.solr.schema.FieldType.CLASS_NAME;
public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAware{
public static final Logger log = LoggerFactory.getLogger(SolrConfigHandler.class);
@ -106,7 +109,7 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
return new Runnable() {
@Override
public void run() {
log.info("config update_listener called");
log.info("config update listener called for core {}", coreName);
SolrZkClient zkClient = cc.getZkController().getZkClient();
int solrConfigversion,overlayVersion;
try (SolrCore core = cc.getCore(coreName)) {
@ -117,7 +120,7 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
if (checkStale(zkClient, overlayPath, solrConfigversion) ||
checkStale(zkClient, solrConfigPath, overlayVersion)) {
log.info("core reload");
log.info("core reload {}",coreName);
cc.reload(coreName);
}
}
@ -128,7 +131,7 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
try {
Stat stat = zkClient.exists(zkPath, null, true);
if(stat == null){
if(currentVersion>0) return true;
if(currentVersion > -1) return true;
return false;
}
if (stat.getVersion() > currentVersion) {
@ -198,7 +201,7 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
for (CommandOperation op : ops) opsCopy.add(op.getCopy());
try {
handleCommands(opsCopy, overlay);
break;
break;//succeeded . so no need to go over the loop again
} catch (ZkController.ResourceModifiedInZkException e) {
//retry
log.info("Race condition, the node is modified in ZK by someone else " +e.getMessage());
@ -226,6 +229,13 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
case UNSET_USER_PROPERTY:
overlay = applyUnsetUserProp(op, overlay);
break;
case UPDATE_REQHANDLER:
case CREATE_REQHANDLER:
overlay = applyRequestHandler(op, overlay);
break;
case DELETE_REQHANDLER:
overlay = applyDeleteHandler(op,overlay);
break;
}
}
List errs = CommandOperation.captureErrors(ops);
@ -244,6 +254,50 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
req.getCore().getCoreDescriptor().getCoreContainer().reload(req.getCore().getName());
}
}
private ConfigOverlay applyDeleteHandler(CommandOperation op, ConfigOverlay overlay) {
String name = op.getStr(CommandOperation.ROOT_OBJ);
if(op.hasError()) return overlay;
if(overlay.getReqHandlers().containsKey(name)){
return overlay.deleteHandler(name);
} else {
op.addError(MessageFormat.format("NO such requestHandler ''{0}'' ",name));
return overlay;
}
}
private ConfigOverlay applyRequestHandler(CommandOperation op, ConfigOverlay overlay) {
String name=op.getStr(NAME);
op.getStr(CLASS_NAME);
op.getMap(PluginInfo.DEFAULTS, null);
op.getMap(PluginInfo.INVARIANTS,null);
op.getMap(PluginInfo.APPENDS,null);
if(op.hasError()) return overlay;
if(CREATE_REQHANDLER.equals(op.name)) {
if (overlay.getReqHandlers().containsKey(name)) {
op.addError(MessageFormat.format(" ''{0}'' already exists . Do an ''{1}'' , if you want to change it ", name, UPDATE_REQHANDLER));
return overlay;
} else {
return overlay.addReqHandler(op.getDataMap());
}
} else if(UPDATE_REQHANDLER.equals(op.name)){
if (!overlay.getReqHandlers().containsKey(name)) {
op.addError(MessageFormat.format(" ''{0}'' does not exist . Do an ''{1}'' , if you want to create it ", name, CREATE_REQHANDLER));
return overlay;
} else {
return overlay.addReqHandler(op.getDataMap());
}
}
return overlay;
}
private ConfigOverlay applySetUserProp(CommandOperation op, ConfigOverlay overlay) {
@ -351,7 +405,8 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
public static final String UNSET_PROPERTY = "unset-property";
public static final String SET_USER_PROPERTY = "set-user-property";
public static final String UNSET_USER_PROPERTY = "unset-user-property";
public static final String CREATE_REQHANDLER = "create-requesthandler";
public static final String DELETE_REQHANDLER = "delete-requesthandler";
public static final String UPDATE_REQHANDLER = "update-requesthandler";
}

View File

@ -214,4 +214,15 @@ public class CommandOperation {
return new CommandOperation(name,commandData);
}
public Map getMap(String key, Map def) {
Object o =getMapVal(key);
if(o==null) return def;
if ( !(o instanceof Map)) {
addError(MessageFormat.format("''{0}'' must be a map", key));
return def;
} else {
return (Map) o;
}
}
}

View File

@ -19,15 +19,25 @@ package org.apache.solr.core;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.ImmutableList;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.handler.TestSolrConfigHandlerConcurrent;
import org.apache.solr.util.RestTestBase;
import org.apache.solr.util.RestTestHarness;
import org.eclipse.jetty.servlet.ServletHolder;
@ -77,13 +87,11 @@ public class TestSolrConfigHandler extends RestTestBase {
public void testProperty() throws Exception{
RestTestHarness harness = restTestHarness;
String payload= "{\n" +
" 'set-property' : { 'updateHandler.autoCommit.maxDocs':100, 'updateHandler.autoCommit.maxTime':10 } \n" +
" }";
RestTestHarness harness = restTestHarness;
String response = harness.post("/config?wt=json", SolrTestCaseJ4.json(payload));
Map map = (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
assertNull(response, map.get("errors"));
runConfigCommand( harness,"/config?wt=json", payload);
Map m = (Map) getRespMap("/config/overlay?wt=json" ,harness).get("overlay");
Map props = (Map) m.get("props");
@ -99,9 +107,7 @@ public class TestSolrConfigHandler extends RestTestBase {
payload= "{\n" +
" 'unset-property' : 'updateHandler.autoCommit.maxDocs'} \n" +
" }";
response = harness.post("/config?wt=json", SolrTestCaseJ4.json(payload));
map = (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
assertNull(response, map.get("errors"));
runConfigCommand(harness, "/config?wt=json", payload);
m = (Map) getRespMap("/config/overlay?wt=json" ,harness).get("overlay");
props = (Map) m.get("props");
@ -111,14 +117,12 @@ public class TestSolrConfigHandler extends RestTestBase {
}
public void testUserProp() throws Exception{
RestTestHarness harness = restTestHarness;
String payload= "{\n" +
" 'set-user-property' : { 'my.custom.variable.a':'MODIFIEDA'," +
" 'my.custom.variable.b':'MODIFIEDB' } \n" +
" }";
RestTestHarness harness = restTestHarness;
String response = harness.post("/config?wt=json", SolrTestCaseJ4.json(payload));
Map map = (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
assertNull(response, map.get("errors"));
runConfigCommand(harness,"/config?wt=json", payload);
Map m = (Map) getRespMap("/config/overlay?wt=json" ,harness).get("overlay");
Map props = (Map) m.get("userProps");
@ -132,14 +136,93 @@ public class TestSolrConfigHandler extends RestTestBase {
assertEquals("MODIFIEDA", m.get("a"));
assertEquals("MODIFIEDB", m.get("b"));
}
public void testReqHandlerAPIs() throws Exception {
reqhandlertests(restTestHarness, null,null);
}
private static void runConfigCommand(RestTestHarness harness, String uri, String payload) throws IOException {
String response = harness.post(uri, SolrTestCaseJ4.json(payload));
Map map = (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
assertNull(response, map.get("errors"));
}
public static void reqhandlertests(RestTestHarness writeHarness,String testServerBaseUrl, CloudSolrServer cloudSolrServer) throws Exception {
String payload = "{\n" +
"'create-requesthandler' : { 'name' : '/x', 'class': 'org.apache.solr.handler.DumpRequestHandler' , 'startup' : 'lazy'}\n" +
"}";
runConfigCommand(writeHarness,"/config?wt=json", payload);
boolean success = false;
long startTime = System.nanoTime();
long maxTimeoutSeconds = 10;
while ( TimeUnit.SECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS) < maxTimeoutSeconds) {
String uri = "/config/overlay?wt=json";
Map m = testServerBaseUrl ==null? getRespMap(uri,writeHarness) : TestSolrConfigHandlerConcurrent.getAsMap(testServerBaseUrl+uri ,cloudSolrServer) ;
if("lazy".equals( ConfigOverlay.getObjectByPath(m, true, Arrays.asList("overlay", "requestHandler", "/x","startup")))) {
Map map = getRespMap("/x?wt=json",writeHarness);
if(map.containsKey("params")) {
success = true;
break;
}
}
Thread.sleep(100);
}
assertTrue( "Could not register requestHandler ", success);
payload = "{\n" +
"'update-requesthandler' : { 'name' : '/x', 'class': 'org.apache.solr.handler.DumpRequestHandler' , 'startup' : 'lazy' , 'a':'b'}\n" +
"}";
runConfigCommand(writeHarness,"/config?wt=json", payload);
success = false;
startTime = System.nanoTime();
maxTimeoutSeconds = 10;
while ( TimeUnit.SECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS) < maxTimeoutSeconds) {
String uri = "/config/overlay?wt=json";
Map m = testServerBaseUrl ==null? getRespMap(uri,writeHarness) : TestSolrConfigHandlerConcurrent.getAsMap(testServerBaseUrl+uri ,cloudSolrServer) ;
if("b".equals( ConfigOverlay.getObjectByPath(m, true, Arrays.asList("overlay", "requestHandler", "/x","a")))) {
success = true;
break;
}
Thread.sleep(100);
}
assertTrue( "Could not update requestHandler ", success);
payload = "{\n" +
"'delete-requesthandler' : '/x'" +
"}";
runConfigCommand(writeHarness,"/config?wt=json", payload);
success = false;
startTime = System.nanoTime();
maxTimeoutSeconds = 10;
while ( TimeUnit.SECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS) < maxTimeoutSeconds) {
String uri = "/config/overlay?wt=json";
Map m = testServerBaseUrl ==null? getRespMap(uri,writeHarness) : TestSolrConfigHandlerConcurrent.getAsMap(testServerBaseUrl+uri ,cloudSolrServer) ;
if(null == ConfigOverlay.getObjectByPath(m, true, Arrays.asList("overlay", "requestHandler", "/x","a"))) {
success = true;
break;
}
Thread.sleep(100);
}
assertTrue( "Could not delete requestHandler ", success);
}
public static Map getRespMap(String path, RestTestHarness restHarness) throws Exception {
String response = restHarness.query(path);
try {
return (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
} catch (JSONParser.ParseException e) {
return Collections.emptyMap();
}
}
}

View File

@ -0,0 +1,72 @@
package org.apache.solr.handler;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.core.TestSolrConfigHandler;
import org.apache.solr.util.RESTfulServerProvider;
import org.apache.solr.util.RestTestHarness;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestSolrConfigHandlerCloud extends AbstractFullDistribZkTestBase {
static final Logger log = LoggerFactory.getLogger(TestSolrConfigHandlerCloud.class);
private List<RestTestHarness> restTestHarnesses = new ArrayList<>();
private void setupHarnesses() {
for (final SolrServer client : clients) {
RestTestHarness harness = new RestTestHarness(new RESTfulServerProvider() {
@Override
public String getBaseURL() {
return ((HttpSolrServer)client).getBaseURL();
}
});
restTestHarnesses.add(harness);
}
}
@Override
public void doTest() throws Exception {
setupHarnesses();
testReqHandlerAPIs();
}
private void testReqHandlerAPIs() throws Exception {
DocCollection coll = cloudClient.getZkStateReader().getClusterState().getCollection("collection1");
List<String> urls = new ArrayList<>();
for (Slice slice : coll.getSlices()) {
for (Replica replica : slice.getReplicas())
urls.add(""+replica.get(ZkStateReader.BASE_URL_PROP) + "/"+replica.get(ZkStateReader.CORE_NAME_PROP));
}
RestTestHarness writeHarness = restTestHarnesses.get(random().nextInt(restTestHarnesses.size()));
String testServerBaseUrl = urls.get(random().nextInt(urls.size()));
TestSolrConfigHandler.reqhandlertests(writeHarness, testServerBaseUrl , cloudClient);
}
}

View File

@ -33,6 +33,7 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
import org.apache.solr.common.cloud.DocCollection;
@ -164,7 +165,7 @@ public class TestSolrConfigHandlerConcurrent extends AbstractFullDistribZkTestBa
while ( TimeUnit.SECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS) < maxTimeoutSeconds) {
Thread.sleep(100);
errmessages.clear();
Map respMap = getAsMap(url+"/config/overlay?wt=json");
Map respMap = getAsMap(url+"/config/overlay?wt=json", cloudClient);
Map m = (Map) respMap.get("overlay");
if(m!= null) m = (Map) m.get("props");
if(m == null) {
@ -191,7 +192,7 @@ public class TestSolrConfigHandlerConcurrent extends AbstractFullDistribZkTestBa
}
private Map getAsMap(String uri) throws Exception {
public static Map getAsMap(String uri, CloudSolrServer cloudClient) throws Exception {
HttpGet get = new HttpGet(uri) ;
HttpEntity entity = null;
try {