- by default, a (empty) solr storage instance is created at SEGMENTS/solr_36 - the index is written if in /IndexFederated_p.html the flag "embedded solr search index" is switched on - a standard solr query interface is available now with a new servlet at http://127.0.0.1:8090/solr/select To test this, do the following: - switch to webportal mode - switch on the feature as described - do a crawl. this fills the solr index. The normal YaCy search will NOT work now! - do a solr query, like: http://127.0.0.1:8090/solr/select?q=*:* http://127.0.0.1:8090/solr/select?q=text_t:Help play with different search fields as you can see in /IndexFederated_p.html You can use the standard solr query attributes as described in http://wiki.apache.org/solr/SearchHandlerpull/1/head
parent
f0a079ac9f
commit
97b7bcf2a6
@ -0,0 +1,73 @@
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import net.yacy.cora.document.UTF8;
|
||||
import net.yacy.cora.protocol.RequestHeader;
|
||||
import net.yacy.kelondro.logging.Log;
|
||||
import net.yacy.search.Switchboard;
|
||||
import net.yacy.search.solr.EmbeddedSolrConnector;
|
||||
import net.yacy.search.solr.SolrServlet;
|
||||
|
||||
import org.apache.solr.common.util.FastWriter;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.response.QueryResponseWriter;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.response.XMLResponseWriter;
|
||||
|
||||
import de.anomic.server.serverObjects;
|
||||
import de.anomic.server.serverSwitch;
|
||||
|
||||
public class select {
|
||||
|
||||
private static SolrServlet solrServlet = new SolrServlet();
|
||||
private static final QueryResponseWriter responseWriter = new XMLResponseWriter();
|
||||
|
||||
static {
|
||||
try {solrServlet.init(null);} catch (ServletException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* a query to solr, for documentation of parameters see:
|
||||
* http://lucene.apache.org/solr/api-3_6_0/doc-files/tutorial.html
|
||||
* and
|
||||
* http://wiki.apache.org/solr/SolrQuerySyntax
|
||||
* @param header
|
||||
* @param post
|
||||
* @param env
|
||||
* @param out
|
||||
* @return
|
||||
*/
|
||||
public static serverObjects respond(@SuppressWarnings("unused") final RequestHeader header, final serverObjects post, final serverSwitch env, final OutputStream out) {
|
||||
|
||||
// this uses the methods in the jetty servlet environment and can be removed if jetty in implemented
|
||||
Switchboard sb = (Switchboard) env;
|
||||
EmbeddedSolrConnector connector = (EmbeddedSolrConnector) sb.index.getLocalSolr();
|
||||
if (connector == null) return null;
|
||||
if (post == null) return null;
|
||||
if (!post.containsKey("df")) post.put("df", "text_t"); // set default field to all fields
|
||||
SolrQueryRequest req = connector.request(post.toSolrParams());
|
||||
SolrQueryResponse response = connector.query(req);
|
||||
Exception e = response.getException();
|
||||
if (e != null) {
|
||||
Log.logException(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// write the result directly to the output stream
|
||||
Writer ow = new FastWriter(new OutputStreamWriter(out, UTF8.charset));
|
||||
try {
|
||||
responseWriter.write(ow, req, response);
|
||||
ow.flush();
|
||||
} catch (IOException e1) {
|
||||
} finally {
|
||||
req.close();
|
||||
try {ow.close();} catch (IOException e1) {}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,237 @@
|
||||
package net.yacy.search.solr;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.yacy.cora.document.UTF8;
|
||||
import net.yacy.kelondro.logging.Log;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.util.FastWriter;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.request.ServletSolrParams;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.request.SolrRequestInfo;
|
||||
import org.apache.solr.response.QueryResponseWriter;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.response.XMLResponseWriter;
|
||||
import org.apache.solr.search.DocIterator;
|
||||
import org.apache.solr.search.DocList;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.servlet.cache.HttpCacheHeaderUtil;
|
||||
import org.apache.solr.servlet.cache.Method;
|
||||
import org.mortbay.jetty.Handler;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.Context;
|
||||
import org.mortbay.jetty.servlet.FilterHolder;
|
||||
|
||||
|
||||
public class SolrServlet implements Filter {
|
||||
|
||||
private static final QueryResponseWriter responseWriter = new XMLResponseWriter();
|
||||
private static EmbeddedSolrConnector connector;
|
||||
|
||||
public SolrServlet() {
|
||||
}
|
||||
|
||||
public static void initCore(EmbeddedSolrConnector c) {
|
||||
connector = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig config) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
if (!(request instanceof HttpServletRequest)) {
|
||||
if (chain != null) chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
HttpServletRequest hrequest = (HttpServletRequest) request;
|
||||
HttpServletResponse hresponse = (HttpServletResponse) response;
|
||||
SolrQueryRequest req = null;
|
||||
|
||||
// check if this servlet was called correctly
|
||||
String pathInfo = hrequest.getPathInfo();
|
||||
String path = pathInfo == null ? hrequest.getServletPath() : hrequest.getServletPath() + pathInfo; // should be "/select" after this
|
||||
|
||||
if (!EmbeddedSolrConnector.SELECT.equals(path)) {
|
||||
// this is not for this servlet
|
||||
if (chain != null) chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
if (!EmbeddedSolrConnector.CONTEXT.equals(hrequest.getContextPath())) {
|
||||
// this is not for this servlet
|
||||
if (chain != null) chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// reject POST which is not supported here
|
||||
final Method reqMethod = Method.getMethod(hrequest.getMethod());
|
||||
if (reqMethod == null || (reqMethod != Method.GET && reqMethod != Method.HEAD)) {
|
||||
throw new ServletException("Unsupported method: " + hrequest.getMethod());
|
||||
}
|
||||
|
||||
try {
|
||||
SolrCore core = connector.getCore();
|
||||
if (core == null) {
|
||||
throw new UnsupportedOperationException("core not initialized");
|
||||
}
|
||||
|
||||
// prepare request to solr
|
||||
hrequest.setAttribute("org.apache.solr.CoreContainer", core);
|
||||
req = connector.request(new ServletSolrParams(hrequest));
|
||||
|
||||
SolrQueryResponse rsp = connector.query(req);
|
||||
|
||||
// prepare response
|
||||
hresponse.setHeader("Cache-Control", "no-cache");
|
||||
HttpCacheHeaderUtil.checkHttpCachingVeto(rsp, hresponse, reqMethod);
|
||||
|
||||
// check error
|
||||
if (rsp.getException() != null) {
|
||||
sendError(hresponse, rsp.getException());
|
||||
return;
|
||||
}
|
||||
|
||||
// write response header
|
||||
final String contentType = responseWriter.getContentType(req, rsp);
|
||||
if (null != contentType) response.setContentType(contentType);
|
||||
|
||||
if (Method.HEAD == reqMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
// write response body
|
||||
Writer out = new FastWriter(new OutputStreamWriter(response.getOutputStream(), UTF8.charset));
|
||||
|
||||
//debug
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterator<Map.Entry<String, Object>> ie = rsp.getValues().iterator();
|
||||
Map.Entry<String, Object> e;
|
||||
while (ie.hasNext()) {
|
||||
e = ie.next();
|
||||
System.out.println("Field: " + e.getKey() + ", value: " + e.getValue().getClass().getName());
|
||||
//Field: responseHeader, value: org.apache.solr.common.util.SimpleOrderedMap
|
||||
//Field: response, value: org.apache.solr.search.DocSlice
|
||||
if (e.getValue() instanceof DocList) {
|
||||
DocList ids = (DocList) e.getValue();
|
||||
SolrIndexSearcher searcher = req.getSearcher();
|
||||
DocIterator iterator = ids.iterator();
|
||||
int sz = ids.size();
|
||||
for (int i = 0; i < sz; i++) {
|
||||
int id = iterator.nextDoc();
|
||||
Document doc = searcher.doc(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
responseWriter.write(out, req, rsp);
|
||||
out.flush();
|
||||
return;
|
||||
|
||||
} catch (Throwable ex) {
|
||||
sendError(hresponse, ex);
|
||||
return;
|
||||
} finally {
|
||||
if (req != null) {
|
||||
req.close();
|
||||
}
|
||||
SolrRequestInfo.clearRequestInfo();
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendError(HttpServletResponse hresponse, Throwable ex) throws IOException {
|
||||
int code = (ex instanceof SolrException) ? ((SolrException) ex).code() : 500;
|
||||
StringWriter sw = new StringWriter();
|
||||
ex.printStackTrace(new PrintWriter(sw));
|
||||
hresponse.sendError((code < 100) ? 500 : code, ex.getMessage() + "\n\n" + sw.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* from org.apache.solr.client.solrj.embedded.JettySolrRunner
|
||||
*/
|
||||
public static Server startServer(String context, int port, EmbeddedSolrConnector c) {
|
||||
//this.context = context;
|
||||
Server server = new Server(port);
|
||||
/*
|
||||
SocketConnector connector = new SocketConnector();
|
||||
connector.setPort(port);
|
||||
connector.setReuseAddress(true);
|
||||
this.server.setConnectors(new Connector[] { connector });
|
||||
this.server.setSessionIdManager(new HashSessionIdManager(new Random()));
|
||||
*/
|
||||
server.setStopAtShutdown(true);
|
||||
Context root = new Context(server, context, Context.SESSIONS);
|
||||
root.addServlet(Servlet404.class, "/*");
|
||||
|
||||
// attach org.apache.solr.response.XMLWriter to search requests
|
||||
SolrServlet.initCore(c);
|
||||
FilterHolder dispatchFilter = root.addFilter(SolrServlet.class, "*", Handler.REQUEST);
|
||||
|
||||
if (!server.isRunning()) {
|
||||
try {
|
||||
server.start();
|
||||
waitForSolr(context, port);
|
||||
} catch (Exception e) {
|
||||
Log.logException(e);
|
||||
}
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
public static void waitForSolr(String context, int port) throws Exception {
|
||||
// A raw term query type doesn't check the schema
|
||||
URL url = new URL("http://127.0.0.1:" + port + context + "/select?q={!raw+f=test_query}ping");
|
||||
|
||||
Exception ex=null;
|
||||
// Wait for a total of 20 seconds: 100 tries, 200 milliseconds each
|
||||
for (int i = 0; i < 600; i++) {
|
||||
try {
|
||||
InputStream stream = url.openStream();
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
ex=e;
|
||||
Thread.sleep(200);
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Jetty/Solr unresponsive", ex);
|
||||
}
|
||||
|
||||
public static class Servlet404 extends HttpServlet {
|
||||
private static final long serialVersionUID=-4497069674942245148L;
|
||||
@Override
|
||||
public void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
|
||||
res.sendError(404, "Can not find: " + req.getRequestURI());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue