You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2014/11/27 14:16:22 UTC
svn commit: r1642141 - in /lucene/dev/trunk/solr: ./
core/src/java/org/apache/solr/cloud/ core/src/java/org/apache/solr/core/
core/src/java/org/apache/solr/handler/ core/src/java/org/apache/solr/util/
core/src/test/org/apache/solr/core/ core/src/test/o...
Author: noble
Date: Thu Nov 27 13:16:22 2014
New Revision: 1642141
URL: http://svn.apache.org/r1642141
Log:
SOLR-6607 Managing requesthandlers through API
Added:
lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerCloud.java (with props)
Modified:
lucene/dev/trunk/solr/CHANGES.txt
lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/PluginInfo.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrConfig.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/CommandOperation.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerConcurrent.java
Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Thu Nov 27 13:16:22 2014
@@ -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
----------------------
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java Thu Nov 27 13:16:22 2014
@@ -2235,17 +2235,19 @@ 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();
}
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java Thu Nov 27 13:16:22 2014
@@ -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 Ma
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 Ma
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;
+
+ }
}
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/PluginInfo.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/PluginInfo.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/PluginInfo.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/PluginInfo.java Thu Nov 27 13:16:22 2014
@@ -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 MapSe
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 MapSe
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,11 +148,11 @@ public class PluginInfo implements MapSe
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",
- "bool",
- "str",
- "int","long",
- "float","double"));
+ (asList("lst", "arr",
+ "bool",
+ "str",
+ "int", "long",
+ "float", "double"));
public static final String DEFAULTS = "defaults";
public static final String APPENDS = "appends";
public static final String INVARIANTS = "invariants";
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/RequestHandlers.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/RequestHandlers.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/RequestHandlers.java Thu Nov 27 13:16:22 2014
@@ -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 {
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrConfig.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrConfig.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrConfig.java Thu Nov 27 13:16:22 2014
@@ -334,13 +334,14 @@ public class SolrConfig extends Config i
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);
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java Thu Nov 27 13:16:22 2014
@@ -51,6 +51,7 @@ import org.apache.solr.request.LocalSolr
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.fo
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 R
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 R
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 R
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 R
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 R
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);
@@ -246,6 +256,50 @@ public class SolrConfigHandler extends R
}
+ 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) {
Map<String, Object> m = op.getDataMap();
if(op.hasError()) return overlay;
@@ -351,7 +405,8 @@ public class SolrConfigHandler extends R
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";
}
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/CommandOperation.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/CommandOperation.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/CommandOperation.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/CommandOperation.java Thu Nov 27 13:16:22 2014
@@ -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;
+
+ }
+ }
}
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java Thu Nov 27 13:16:22 2014
@@ -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 exten
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 exten
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 exten
}
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 exten
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);
- return (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
+ try {
+ return (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
+ } catch (JSONParser.ParseException e) {
+ return Collections.emptyMap();
+ }
}
}
Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerCloud.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerCloud.java?rev=1642141&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerCloud.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerCloud.java Thu Nov 27 13:16:22 2014
@@ -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);
+ }
+}
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerConcurrent.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerConcurrent.java?rev=1642141&r1=1642140&r2=1642141&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerConcurrent.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSolrConfigHandlerConcurrent.java Thu Nov 27 13:16:22 2014
@@ -33,6 +33,7 @@ import org.apache.http.client.methods.Ht
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 TestSolrConfigHandlerConcur
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 TestSolrConfigHandlerConcur
}
- 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 {
Re: svn commit: r1642141 - in /lucene/dev/trunk/solr: ./ core/src/java/org/apache/solr/cloud/ core/src/java/org/apache/solr/core/ core/src/java/org/apache/solr/handler/ core/src/java/org/apache/solr/util/ core/src/test/org/apache/solr/core/ core/src/test/o...
Posted by Mark Miller <ma...@gmail.com>.
> On Nov 27, 2014, at 8:16 AM, noble@apache.org wrote:
>
> SOLR-6607 Managing requesthandlers through API
You do see that you are the only one that doesn’t use a colon after the issue id right? As you were the only one that was just using the issue name only for a while?
Would you mind at least trying to be consistent with the rest of us?
- Mark
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lucene.apache.org
For additional commands, e-mail: dev-help@lucene.apache.org