mirror of https://github.com/apache/lucene.git
Support for customizing the QueryResponseWriter per request - SOLR-16
git-svn-id: https://svn.apache.org/repos/asf/incubator/solr/trunk@409560 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
15e77d2ef4
commit
2d04fecca2
|
@ -12,7 +12,8 @@ New Features
|
|||
6. The default search field may now be overridden by requests to the
|
||||
standard request handler using the df query parameter. (Erik Hatcher)
|
||||
7. Added DisMaxRequestHandler and SolrPluginUtils. (Chris Hostetter)
|
||||
|
||||
8. Support for customizing the QueryResponseWriter per request
|
||||
(Mike Baranczak / SOLR-16 / hossman)
|
||||
|
||||
Changes in runtime behavior
|
||||
1. classes reorganized into different packages, package names changed to Apache
|
||||
|
|
|
@ -218,6 +218,17 @@
|
|||
</str>
|
||||
</requestHandler>
|
||||
|
||||
<!-- queryResponseWriter plugins... query responses will be written using the
|
||||
writer specified by the 'wt' request parameter matching the name of a registered
|
||||
writer.
|
||||
The "standard" writer is the default and will be used if 'wt' is not specified
|
||||
in the request. XMLResponseWriter will be used if nothing specified here.
|
||||
|
||||
<queryResponseWriter name="standard" class="org.apache.solr.request.XMLResponseWriter"/>
|
||||
<queryResponseWriter name="custom" class="com.example.MyResponseWriter"/>
|
||||
-->
|
||||
|
||||
|
||||
<!-- config for the admin interface -->
|
||||
<admin>
|
||||
<defaultQuery>solr</defaultQuery>
|
||||
|
|
|
@ -16,13 +16,17 @@
|
|||
|
||||
package org.apache.solr.core;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.FSDirectory;
|
||||
import org.apache.solr.request.QueryResponseWriter;
|
||||
import org.apache.solr.request.SolrRequestHandler;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.request.SolrQueryResponse;
|
||||
import org.apache.solr.request.XMLResponseWriter;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.update.*;
|
||||
|
@ -30,6 +34,7 @@ import org.apache.solr.util.DOMUtil;
|
|||
import org.apache.solr.util.RefCounted;
|
||||
import org.apache.solr.util.StrUtils;
|
||||
import org.apache.solr.util.XML;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
@ -52,6 +57,7 @@ import java.util.logging.Logger;
|
|||
|
||||
/**
|
||||
* @author yonik
|
||||
* @author <a href='mailto:mbaranczak@epublishing.com'> Mike Baranczak </a>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
@ -197,6 +203,8 @@ public final class SolrCore {
|
|||
|
||||
initIndex();
|
||||
|
||||
initWriters();
|
||||
|
||||
try {
|
||||
// Open the searcher *before* the handler so we don't end up opening
|
||||
// one in the middle.
|
||||
|
@ -939,6 +947,61 @@ public final class SolrCore {
|
|||
}
|
||||
|
||||
|
||||
|
||||
private QueryResponseWriter defaultResponseWriter;
|
||||
private Map<String, QueryResponseWriter> responseWriters
|
||||
= new TreeMap<String, QueryResponseWriter>();
|
||||
|
||||
/** Configure the query response writers. There will always be a default writer; additional
|
||||
* writers may also be configured. */
|
||||
private void initWriters() {
|
||||
String xpath = "queryResponseWriter";
|
||||
NodeList nodes = (NodeList) SolrConfig.config.evaluate(xpath, XPathConstants.NODESET);
|
||||
int length = nodes.getLength();
|
||||
for (int i=0; i<length; i++) {
|
||||
Element elm = (Element) nodes.item(i);
|
||||
|
||||
try {
|
||||
String name = DOMUtil.getAttr(elm,"name", xpath+" config");
|
||||
String className = DOMUtil.getAttr(elm,"class", xpath+" config");
|
||||
log.info("adding queryResponseWriter "+name+"="+className);
|
||||
|
||||
QueryResponseWriter writer = (QueryResponseWriter) Config.newInstance(className);
|
||||
responseWriters.put(name, writer);
|
||||
} catch (Exception ex) {
|
||||
SolrException.logOnce(log,null, ex);
|
||||
// if a writer can't be created, skip it and continue
|
||||
}
|
||||
}
|
||||
|
||||
// configure the default response writer; this one should never be null
|
||||
if (responseWriters.containsKey("standard")) {
|
||||
defaultResponseWriter = responseWriters.get("standard");
|
||||
}
|
||||
if (defaultResponseWriter == null) {
|
||||
defaultResponseWriter = new XMLResponseWriter();
|
||||
}
|
||||
}
|
||||
|
||||
/** Finds a writer by name, or returns the default writer if not found. */
|
||||
public final QueryResponseWriter getQueryResponseWriter(String writerName) {
|
||||
if (writerName != null) {
|
||||
QueryResponseWriter writer = responseWriters.get(writerName);
|
||||
if (writer != null) {
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
return defaultResponseWriter;
|
||||
}
|
||||
|
||||
/** Returns the appropriate writer for a request. If the request specifies a writer via the
|
||||
* 'wt' parameter, attempts to find that one; otherwise return the default writer.
|
||||
*/
|
||||
public final QueryResponseWriter getQueryResponseWriter(SolrQueryRequest request) {
|
||||
return getQueryResponseWriter(request.getParam("wt"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@ import java.util.*;
|
|||
public class TestHarness {
|
||||
|
||||
private SolrCore core;
|
||||
private XMLResponseWriter xmlwriter = new XMLResponseWriter();
|
||||
private XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
private DocumentBuilder builder;
|
||||
|
||||
|
@ -183,12 +182,13 @@ public class TestHarness {
|
|||
throw rsp.getException();
|
||||
}
|
||||
|
||||
StringWriter writer = new StringWriter(32000);
|
||||
xmlwriter.write(writer,req,rsp);
|
||||
StringWriter sw = new StringWriter(32000);
|
||||
QueryResponseWriter responseWriter = core.getQueryResponseWriter(req);
|
||||
responseWriter.write(sw,req,rsp);
|
||||
|
||||
req.close();
|
||||
|
||||
return writer.toString();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* Copyright 2006 The Apache Software Foundation
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
package org.apache.solr;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import org.apache.solr.request.QueryResponseWriter;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.request.SolrQueryResponse;
|
||||
import org.apache.solr.util.AbstractSolrTestCase;
|
||||
import org.apache.solr.util.TestHarness;
|
||||
|
||||
/** Tests the ability to configure multiple query output writers, and select those
|
||||
* at query time.
|
||||
*
|
||||
* @author <a href='mailto:mbaranczak@epublishing.com'> Mike Baranczak </a>
|
||||
*/
|
||||
public class OutputWriterTest extends AbstractSolrTestCase {
|
||||
|
||||
/** The XML string that's output for testing purposes. */
|
||||
public static final String USELESS_OUTPUT = "useless output";
|
||||
|
||||
|
||||
public String getSchemaFile() { return "solr/crazy-path-to-schema.xml"; }
|
||||
|
||||
public String getSolrConfigFile() { return "solr/crazy-path-to-config.xml"; }
|
||||
|
||||
|
||||
public void testOriginalSolrWriter() {
|
||||
lrf.args.put("wt", "standard");
|
||||
assertQ(req("foo"), "//response/responseHeader/status");
|
||||
|
||||
lrf.args.remove("wt");
|
||||
assertQ(req("foo"), "//response/responseHeader/status");
|
||||
}
|
||||
|
||||
public void testUselessWriter() throws Exception {
|
||||
lrf.args.put("wt", "useless");
|
||||
String out = h.query(req("foo"));
|
||||
assertEquals(USELESS_OUTPUT, out);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
/** An output writer that doesn't do anything useful. */
|
||||
|
||||
public static class UselessOutputWriter implements QueryResponseWriter {
|
||||
|
||||
public UselessOutputWriter() {}
|
||||
|
||||
public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response)
|
||||
throws IOException {
|
||||
|
||||
writer.write(USELESS_OUTPUT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -40,9 +40,14 @@
|
|||
<HashDocSet maxSize="3000" loadFactor="0.75"/>
|
||||
<boolTofilterOptimizer enabled="true" cacheSize="32" threshold=".05"/>
|
||||
</query>
|
||||
|
||||
<requestHandler name="standard" class="solr.StandardRequestHandler" />
|
||||
<requestHandler name="crazy_custom_qt" class="solr.StandardRequestHandler" />
|
||||
|
||||
<queryResponseWriter name="standard" class="org.apache.solr.request.XMLResponseWriter"/>
|
||||
<queryResponseWriter name="useless" class="org.apache.solr.OutputWriterTest$UselessOutputWriter"/>
|
||||
|
||||
|
||||
<admin>
|
||||
<defaultQuery>solr</defaultQuery>
|
||||
<gettableFiles>solrconfig.xml scheam.xml</gettableFiles>
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.apache.solr.core.Config;
|
|||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.core.SolrException;
|
||||
import org.apache.solr.request.SolrQueryResponse;
|
||||
import org.apache.solr.request.XMLResponseWriter;
|
||||
import org.apache.solr.request.QueryResponseWriter;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
|
@ -36,17 +36,17 @@ import java.util.logging.Logger;
|
|||
|
||||
/**
|
||||
* @author yonik
|
||||
* @author <a href='mailto:mbaranczak@epublishing.com'> Mike Baranczak </a>
|
||||
*/
|
||||
|
||||
public class SolrServlet extends HttpServlet {
|
||||
|
||||
final Logger log = Logger.getLogger(SolrServlet.class.getName());
|
||||
SolrCore core;
|
||||
private static String CONTENT_TYPE="text/xml;charset=UTF-8";
|
||||
|
||||
XMLResponseWriter xmlResponseWriter;
|
||||
|
||||
public void init() throws ServletException
|
||||
{
|
||||
public void init() throws ServletException {
|
||||
log.info("SolrServlet.init()");
|
||||
try {
|
||||
Context c = new InitialContext();
|
||||
|
@ -71,7 +71,7 @@ public class SolrServlet extends HttpServlet {
|
|||
|
||||
log.info("user.dir=" + System.getProperty("user.dir"));
|
||||
core = SolrCore.getSolrCore();
|
||||
xmlResponseWriter=new XMLResponseWriter();
|
||||
|
||||
log.info("SolrServlet.init() done");
|
||||
}
|
||||
|
||||
|
@ -94,14 +94,15 @@ public class SolrServlet extends HttpServlet {
|
|||
core.execute(solrReq, solrRsp);
|
||||
if (solrRsp.getException() == null) {
|
||||
response.setContentType(CONTENT_TYPE);
|
||||
PrintWriter writer = response.getWriter();
|
||||
// if (solrReq.getStrParam("version","2").charAt(0) == '1')
|
||||
xmlResponseWriter.write(writer, solrReq, solrRsp);
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
QueryResponseWriter responseWriter = core.getQueryResponseWriter(solrReq);
|
||||
responseWriter.write(out, solrReq, solrRsp);
|
||||
} else {
|
||||
Exception e = solrRsp.getException();
|
||||
int rc=500;
|
||||
if (e instanceof SolrException) {
|
||||
rc=((SolrException)e).code();
|
||||
rc=((SolrException)e).code();
|
||||
}
|
||||
sendErr(rc, SolrException.toStr(e), request, response);
|
||||
}
|
||||
|
@ -115,7 +116,6 @@ public class SolrServlet extends HttpServlet {
|
|||
// This releases the IndexReader associated with the request
|
||||
solrReq.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final void sendErr(int rc, String msg, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
|
Loading…
Reference in New Issue