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,8 +12,9 @@ New Features
|
||||||
6. The default search field may now be overridden by requests to the
|
6. The default search field may now be overridden by requests to the
|
||||||
standard request handler using the df query parameter. (Erik Hatcher)
|
standard request handler using the df query parameter. (Erik Hatcher)
|
||||||
7. Added DisMaxRequestHandler and SolrPluginUtils. (Chris Hostetter)
|
7. Added DisMaxRequestHandler and SolrPluginUtils. (Chris Hostetter)
|
||||||
|
8. Support for customizing the QueryResponseWriter per request
|
||||||
|
(Mike Baranczak / SOLR-16 / hossman)
|
||||||
|
|
||||||
Changes in runtime behavior
|
Changes in runtime behavior
|
||||||
1. classes reorganized into different packages, package names changed to Apache
|
1. classes reorganized into different packages, package names changed to Apache
|
||||||
2. force read of document stored fields in QuerySenderListener
|
2. force read of document stored fields in QuerySenderListener
|
||||||
|
|
|
@ -218,6 +218,17 @@
|
||||||
</str>
|
</str>
|
||||||
</requestHandler>
|
</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 -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>solr</defaultQuery>
|
<defaultQuery>solr</defaultQuery>
|
||||||
|
|
|
@ -16,13 +16,17 @@
|
||||||
|
|
||||||
package org.apache.solr.core;
|
package org.apache.solr.core;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.store.FSDirectory;
|
import org.apache.lucene.store.FSDirectory;
|
||||||
|
import org.apache.solr.request.QueryResponseWriter;
|
||||||
import org.apache.solr.request.SolrRequestHandler;
|
import org.apache.solr.request.SolrRequestHandler;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
import org.apache.solr.request.SolrQueryResponse;
|
import org.apache.solr.request.SolrQueryResponse;
|
||||||
|
import org.apache.solr.request.XMLResponseWriter;
|
||||||
import org.apache.solr.schema.IndexSchema;
|
import org.apache.solr.schema.IndexSchema;
|
||||||
import org.apache.solr.search.SolrIndexSearcher;
|
import org.apache.solr.search.SolrIndexSearcher;
|
||||||
import org.apache.solr.update.*;
|
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.RefCounted;
|
||||||
import org.apache.solr.util.StrUtils;
|
import org.apache.solr.util.StrUtils;
|
||||||
import org.apache.solr.util.XML;
|
import org.apache.solr.util.XML;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
@ -52,6 +57,7 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yonik
|
* @author yonik
|
||||||
|
* @author <a href='mailto:mbaranczak@epublishing.com'> Mike Baranczak </a>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -196,6 +202,8 @@ public final class SolrCore {
|
||||||
parseListeners();
|
parseListeners();
|
||||||
|
|
||||||
initIndex();
|
initIndex();
|
||||||
|
|
||||||
|
initWriters();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Open the searcher *before* the handler so we don't end up opening
|
// Open the searcher *before* the handler so we don't end up opening
|
||||||
|
@ -937,6 +945,61 @@ public final class SolrCore {
|
||||||
log.severe("Error writing to putput stream: "+ee);
|
log.severe("Error writing to putput stream: "+ee);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
public class TestHarness {
|
||||||
|
|
||||||
private SolrCore core;
|
private SolrCore core;
|
||||||
private XMLResponseWriter xmlwriter = new XMLResponseWriter();
|
|
||||||
private XPath xpath = XPathFactory.newInstance().newXPath();
|
private XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
private DocumentBuilder builder;
|
private DocumentBuilder builder;
|
||||||
|
|
||||||
|
@ -183,12 +182,13 @@ public class TestHarness {
|
||||||
throw rsp.getException();
|
throw rsp.getException();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringWriter writer = new StringWriter(32000);
|
StringWriter sw = new StringWriter(32000);
|
||||||
xmlwriter.write(writer,req,rsp);
|
QueryResponseWriter responseWriter = core.getQueryResponseWriter(req);
|
||||||
|
responseWriter.write(sw,req,rsp);
|
||||||
|
|
||||||
req.close();
|
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,8 +40,13 @@
|
||||||
<HashDocSet maxSize="3000" loadFactor="0.75"/>
|
<HashDocSet maxSize="3000" loadFactor="0.75"/>
|
||||||
<boolTofilterOptimizer enabled="true" cacheSize="32" threshold=".05"/>
|
<boolTofilterOptimizer enabled="true" cacheSize="32" threshold=".05"/>
|
||||||
</query>
|
</query>
|
||||||
|
|
||||||
<requestHandler name="standard" class="solr.StandardRequestHandler" />
|
<requestHandler name="standard" class="solr.StandardRequestHandler" />
|
||||||
<requestHandler name="crazy_custom_qt" 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>
|
<admin>
|
||||||
<defaultQuery>solr</defaultQuery>
|
<defaultQuery>solr</defaultQuery>
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.apache.solr.core.Config;
|
||||||
import org.apache.solr.core.SolrCore;
|
import org.apache.solr.core.SolrCore;
|
||||||
import org.apache.solr.core.SolrException;
|
import org.apache.solr.core.SolrException;
|
||||||
import org.apache.solr.request.SolrQueryResponse;
|
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.Context;
|
||||||
import javax.naming.InitialContext;
|
import javax.naming.InitialContext;
|
||||||
|
@ -36,17 +36,17 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yonik
|
* @author yonik
|
||||||
|
* @author <a href='mailto:mbaranczak@epublishing.com'> Mike Baranczak </a>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class SolrServlet extends HttpServlet {
|
public class SolrServlet extends HttpServlet {
|
||||||
|
|
||||||
final Logger log = Logger.getLogger(SolrServlet.class.getName());
|
final Logger log = Logger.getLogger(SolrServlet.class.getName());
|
||||||
SolrCore core;
|
SolrCore core;
|
||||||
private static String CONTENT_TYPE="text/xml;charset=UTF-8";
|
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()");
|
log.info("SolrServlet.init()");
|
||||||
try {
|
try {
|
||||||
Context c = new InitialContext();
|
Context c = new InitialContext();
|
||||||
|
@ -71,7 +71,7 @@ public class SolrServlet extends HttpServlet {
|
||||||
|
|
||||||
log.info("user.dir=" + System.getProperty("user.dir"));
|
log.info("user.dir=" + System.getProperty("user.dir"));
|
||||||
core = SolrCore.getSolrCore();
|
core = SolrCore.getSolrCore();
|
||||||
xmlResponseWriter=new XMLResponseWriter();
|
|
||||||
log.info("SolrServlet.init() done");
|
log.info("SolrServlet.init() done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,14 +94,15 @@ public class SolrServlet extends HttpServlet {
|
||||||
core.execute(solrReq, solrRsp);
|
core.execute(solrReq, solrRsp);
|
||||||
if (solrRsp.getException() == null) {
|
if (solrRsp.getException() == null) {
|
||||||
response.setContentType(CONTENT_TYPE);
|
response.setContentType(CONTENT_TYPE);
|
||||||
PrintWriter writer = response.getWriter();
|
PrintWriter out = response.getWriter();
|
||||||
// if (solrReq.getStrParam("version","2").charAt(0) == '1')
|
|
||||||
xmlResponseWriter.write(writer, solrReq, solrRsp);
|
QueryResponseWriter responseWriter = core.getQueryResponseWriter(solrReq);
|
||||||
|
responseWriter.write(out, solrReq, solrRsp);
|
||||||
} else {
|
} else {
|
||||||
Exception e = solrRsp.getException();
|
Exception e = solrRsp.getException();
|
||||||
int rc=500;
|
int rc=500;
|
||||||
if (e instanceof SolrException) {
|
if (e instanceof SolrException) {
|
||||||
rc=((SolrException)e).code();
|
rc=((SolrException)e).code();
|
||||||
}
|
}
|
||||||
sendErr(rc, SolrException.toStr(e), request, response);
|
sendErr(rc, SolrException.toStr(e), request, response);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +116,6 @@ public class SolrServlet extends HttpServlet {
|
||||||
// This releases the IndexReader associated with the request
|
// This releases the IndexReader associated with the request
|
||||||
solrReq.close();
|
solrReq.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final void sendErr(int rc, String msg, HttpServletRequest request, HttpServletResponse response) {
|
final void sendErr(int rc, String msg, HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
@ -142,4 +142,4 @@ public class SolrServlet extends HttpServlet {
|
||||||
return request.getParameter(param)!=null ? true : false;
|
return request.getParameter(param)!=null ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue