mirror of https://github.com/apache/lucene.git
SOLR-350 -- make MultiCore subclassable so to allow custom persistance methods (for example, SQL)
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@635334 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
705cade858
commit
0d633bdcea
|
@ -54,22 +54,31 @@ public class EmbeddedSolrServer extends SolrServer
|
|||
protected ModifiableSolrParams _invariantParams;
|
||||
protected ResponseParser _processor;
|
||||
|
||||
protected final SolrCore core;
|
||||
protected final MultiCore multicore; // either multicore
|
||||
protected final SolrCore core; // or single core
|
||||
protected final SolrRequestParsers parser;
|
||||
protected final String coreName; // use MultiCore registry
|
||||
|
||||
public EmbeddedSolrServer( SolrCore core )
|
||||
{
|
||||
if ( core == null ) {
|
||||
throw new NullPointerException("SolrCore instance required");
|
||||
}
|
||||
this.core = core;
|
||||
this.multicore = null;
|
||||
this.coreName = null;
|
||||
this.parser = init();
|
||||
}
|
||||
|
||||
public EmbeddedSolrServer( String coreName )
|
||||
public EmbeddedSolrServer( MultiCore multicore, String coreName )
|
||||
{
|
||||
if ( multicore == null ) {
|
||||
throw new NullPointerException("MultiCore instance required");
|
||||
}
|
||||
this.core = null;
|
||||
this.multicore = multicore;
|
||||
this.coreName = coreName;
|
||||
SolrCore c = MultiCore.getRegistry().getCore( coreName );
|
||||
SolrCore c = multicore.getCore( coreName );
|
||||
if( c == null ) {
|
||||
throw new RuntimeException( "Unknown core: "+coreName );
|
||||
}
|
||||
|
@ -96,7 +105,6 @@ public class EmbeddedSolrServer extends SolrServer
|
|||
}
|
||||
|
||||
// Check for multicore action
|
||||
MultiCore multicore = MultiCore.getRegistry();
|
||||
SolrCore core = this.core;
|
||||
if( core == null ) {
|
||||
core = multicore.getCore( coreName );
|
||||
|
@ -126,7 +134,7 @@ public class EmbeddedSolrServer extends SolrServer
|
|||
}
|
||||
// Perhaps the path is to manage the cores
|
||||
if( handler == null &&
|
||||
coreName != null &&
|
||||
multicore != null &&
|
||||
path.equals( multicore.getAdminPath() ) &&
|
||||
multicore.isEnabled() ) {
|
||||
handler = multicore.getMultiCoreHandler();
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.apache.solr.client.solrj.request.UpdateRequest;
|
|||
import org.apache.solr.client.solrj.request.UpdateRequest.ACTION;
|
||||
import org.apache.solr.client.solrj.response.MultiCoreResponse;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.core.MultiCore;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,9 @@ import org.apache.solr.core.SolrCore;
|
|||
*/
|
||||
public abstract class MultiCoreExampleTestBase extends SolrExampleTestBase
|
||||
{
|
||||
@SuppressWarnings("deprecation")
|
||||
protected static final MultiCore multicore = org.apache.solr.core.SolrMultiCore.getInstance();
|
||||
|
||||
@Override public String getSolrHome() { return "../../../example/multicore/"; }
|
||||
|
||||
@Override public String getSchemaFile() { return getSolrHome()+"core0/conf/schema.xml"; }
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.io.File;
|
|||
|
||||
import org.apache.solr.client.solrj.MultiCoreExampleTestBase;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.core.MultiCore;
|
||||
|
||||
/**
|
||||
* This runs SolrServer test using
|
||||
|
@ -37,24 +36,24 @@ public class MultiCoreEmbeddedTest extends MultiCoreExampleTestBase {
|
|||
|
||||
File home = new File( getSolrHome() );
|
||||
File f = new File( home, "multicore.xml" );
|
||||
MultiCore.getRegistry().load( getSolrHome(), f );
|
||||
multicore.load( getSolrHome(), f );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SolrServer getSolrCore0()
|
||||
{
|
||||
return new EmbeddedSolrServer( "core0" );
|
||||
return new EmbeddedSolrServer( multicore, "core0" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SolrServer getSolrCore1()
|
||||
{
|
||||
return new EmbeddedSolrServer( "core1" );
|
||||
return new EmbeddedSolrServer( multicore, "core1" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SolrServer getSolrAdmin()
|
||||
{
|
||||
return new EmbeddedSolrServer( "core0" );
|
||||
return new EmbeddedSolrServer( multicore, "core0" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,30 +49,33 @@ import org.xml.sax.SAXException;
|
|||
*/
|
||||
public class MultiCore
|
||||
{
|
||||
private static Logger log = Logger.getLogger(MultiCore.class.getName());
|
||||
private static final MultiCore instance = new MultiCore();
|
||||
protected static Logger log = Logger.getLogger(MultiCore.class.getName());
|
||||
|
||||
// Synchronized map of all cores
|
||||
private final Map<String, CoreDescriptor> cores = new LinkedHashMap<String, CoreDescriptor>();
|
||||
protected final Map<String, CoreDescriptor> cores = new LinkedHashMap<String, CoreDescriptor>();
|
||||
protected boolean enabled = false;
|
||||
protected boolean persistent = false;
|
||||
protected String adminPath = null;
|
||||
protected MultiCoreHandler multiCoreHandler = null;
|
||||
protected File configFile = null;
|
||||
protected String libDir = null;
|
||||
protected ClassLoader libLoader = null;
|
||||
protected SolrResourceLoader loader = null;
|
||||
protected java.lang.ref.WeakReference<SolrCore> adminCore = null;
|
||||
|
||||
private boolean enabled = false;
|
||||
private boolean persistent = false;
|
||||
private String adminPath = null;
|
||||
private MultiCoreHandler multiCoreHandler = null;
|
||||
private File configFile = null;
|
||||
private String libDir = null;
|
||||
private ClassLoader libLoader = null;
|
||||
private SolrResourceLoader loader = null;
|
||||
|
||||
// no one else can make the registry
|
||||
private MultiCore() { }
|
||||
public MultiCore() {
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Initialization / Cleanup
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Load a config file listing the available solr cores
|
||||
* Load a config file listing the available solr cores.
|
||||
* @param dir the home directory of all resources.
|
||||
* @param configFile the configuration file
|
||||
* @throws javax.xml.parsers.ParserConfigurationException
|
||||
* @throws java.io.IOException
|
||||
* @throws org.xml.sax.SAXException
|
||||
*/
|
||||
public void load(String dir, File configFile ) throws ParserConfigurationException, IOException, SAXException {
|
||||
this.configFile = configFile;
|
||||
|
@ -94,7 +97,7 @@ public class MultiCore
|
|||
}
|
||||
|
||||
if( adminPath != null ) {
|
||||
multiCoreHandler = new MultiCoreHandler();
|
||||
multiCoreHandler = this.createMultiCoreHandler();
|
||||
}
|
||||
|
||||
NodeList nodes = (NodeList)cfg.evaluate("multicore/core", XPathConstants.NODESET);
|
||||
|
@ -135,7 +138,9 @@ public class MultiCore
|
|||
enabled = true;
|
||||
}
|
||||
|
||||
/** Stops all cores. */
|
||||
/**
|
||||
* Stops all cores.
|
||||
*/
|
||||
public void shutdown() {
|
||||
synchronized(cores) {
|
||||
for(Map.Entry<String,CoreDescriptor> e : cores.entrySet()) {
|
||||
|
@ -154,15 +159,11 @@ public class MultiCore
|
|||
shutdown();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
/** Get the singleton */
|
||||
public static MultiCore getRegistry() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a SolrCore descriptor in the registry.
|
||||
* @param descr the Solr core descriptor
|
||||
* @return a previous descriptor having the same name if it existed, null otherwise
|
||||
*/
|
||||
public CoreDescriptor register( CoreDescriptor descr ) {
|
||||
if( descr == null ) {
|
||||
throw new RuntimeException( "Can not register a null core." );
|
||||
|
@ -186,6 +187,12 @@ public class MultiCore
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Swaps two SolrCore descriptors.
|
||||
* @param c0
|
||||
* @param c1
|
||||
*/
|
||||
public void swap(CoreDescriptor c0, CoreDescriptor c1) {
|
||||
if( c0 == null || c1 == null ) {
|
||||
throw new RuntimeException( "Can not swap a null core." );
|
||||
|
@ -235,10 +242,11 @@ public class MultiCore
|
|||
}
|
||||
|
||||
/**
|
||||
* Recreates a SolrCore.
|
||||
* While the new core is loading, requests will continue to be dispatched to
|
||||
* and processed by the old core
|
||||
*
|
||||
* @param core
|
||||
* @param core the SolrCore to reload
|
||||
* @throws ParserConfigurationException
|
||||
* @throws IOException
|
||||
* @throws SAXException
|
||||
|
@ -314,6 +322,49 @@ public class MultiCore
|
|||
this.adminPath = adminPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred core used to handle MultiCore admin tasks.
|
||||
* Note that getAdminCore is not symmetrical to this method since
|
||||
* it will allways return an opened SolrCore.
|
||||
* This however can be useful implementing a "metacore" (a core of cores).
|
||||
*/
|
||||
public void setAdminCore(SolrCore core) {
|
||||
adminCore = new java.lang.ref.WeakReference<SolrCore>(core);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a core to handle MultiCore admin tasks (@see SolrDispatchFilter).
|
||||
* This makes the best attempt to reuse the same opened SolrCore accross calls.
|
||||
*/
|
||||
public SolrCore getAdminCore() {
|
||||
SolrCore core = adminCore != null ? adminCore.get() : null;
|
||||
if (core == null || core.isClosed()) {
|
||||
for (CoreDescriptor descr : this.cores.values()) {
|
||||
core = descr.getCore();
|
||||
if (core == null || core.isClosed()) {
|
||||
core = null;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
setAdminCore(core);
|
||||
}
|
||||
return core;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a MultiCoreHandler for this MultiCore.
|
||||
* @return a MultiCoreHandler
|
||||
*/
|
||||
public MultiCoreHandler createMultiCoreHandler() {
|
||||
return new MultiCoreHandler() {
|
||||
@Override
|
||||
public MultiCore getMultiCore() {
|
||||
return MultiCore.this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public MultiCoreHandler getMultiCoreHandler() {
|
||||
return multiCoreHandler;
|
||||
}
|
||||
|
@ -439,4 +490,5 @@ public class MultiCore
|
|||
throw xforward;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
|
|
@ -467,6 +467,10 @@ public final class SolrCore {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return _searcher == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() { close(); }
|
||||
|
||||
|
@ -926,7 +930,7 @@ public final class SolrCore {
|
|||
synchronized (searcherLock) {
|
||||
if (_searcher != null) {
|
||||
_searcher.decref(); // dec refcount for this._searcher
|
||||
_searcher=null;
|
||||
_searcher=null; // isClosed() does check this
|
||||
infoRegistry.remove("currentSearcher");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.apache.solr.core;
|
||||
|
||||
/**
|
||||
* A MultiCore singleton.
|
||||
* Marked as deprecated to avoid usage proliferation of core code that would
|
||||
* assume MultiCore being a singleton. In solr 2.0, the MultiCore factory
|
||||
* should be popluated with a standard tool like spring. Until then, this is
|
||||
* a simple static factory that should not be used widely.
|
||||
*
|
||||
* @version $Id$
|
||||
* @since solr 1.3
|
||||
*/
|
||||
@Deprecated
|
||||
public final class SolrMultiCore extends MultiCore
|
||||
{
|
||||
private static MultiCore instance = null;
|
||||
|
||||
// no one else can make the registry
|
||||
private SolrMultiCore() {}
|
||||
|
||||
/** Returns a default MultiCore singleton.
|
||||
* @return
|
||||
*/
|
||||
public static synchronized MultiCore getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new SolrMultiCore();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ import org.apache.solr.util.RefCounted;
|
|||
* @version $Id$
|
||||
* @since solr 1.3
|
||||
*/
|
||||
public class MultiCoreHandler extends RequestHandlerBase
|
||||
public abstract class MultiCoreHandler extends RequestHandlerBase
|
||||
{
|
||||
public MultiCoreHandler()
|
||||
{
|
||||
|
@ -56,11 +56,18 @@ public class MultiCoreHandler extends RequestHandlerBase
|
|||
"it is a special Handler configured directly by the RequestDispatcher" );
|
||||
}
|
||||
|
||||
/**
|
||||
* The instance of multicore this handler handles.
|
||||
* This should be the MultiCore instance that created this handler.
|
||||
* @return a MultiCore instance
|
||||
*/
|
||||
public abstract MultiCore getMultiCore();
|
||||
|
||||
@Override
|
||||
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
|
||||
{
|
||||
// Make sure the manager is enabled
|
||||
MultiCore manager = MultiCore.getRegistry();
|
||||
MultiCore manager = getMultiCore();
|
||||
if( !manager.isEnabled() ) {
|
||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
|
||||
"MultiCore support must be enabled at startup." );
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
|
@ -74,23 +73,12 @@ public class SolrDispatchFilter implements Filter
|
|||
this.pathPrefix = config.getInitParameter( "path-prefix" );
|
||||
this.solrConfigFilename = config.getInitParameter("solrconfig-filename");
|
||||
|
||||
multicore = MultiCore.getRegistry();
|
||||
if( multicore.isEnabled() ) {
|
||||
log.info( "Using existing multicore configuration" );
|
||||
}
|
||||
else {
|
||||
String instanceDir = SolrResourceLoader.locateInstanceDir();
|
||||
File multiconfig = new File( instanceDir, "multicore.xml" );
|
||||
log.info( "looking for multicore.xml: "+multiconfig.getAbsolutePath() );
|
||||
if( multiconfig.exists() ) {
|
||||
multicore.load( instanceDir, multiconfig );
|
||||
}
|
||||
}
|
||||
// multicore instantiation
|
||||
this.multicore = initMultiCore(config);
|
||||
|
||||
if(multicore != null && multicore.isEnabled() ) {
|
||||
abortOnConfigurationError = false;
|
||||
if( multicore.isEnabled() ) {
|
||||
singlecore = null;
|
||||
|
||||
// if any core aborts on startup, then abort
|
||||
for( SolrCore c : multicore.getCores() ) {
|
||||
if( c.getSolrConfig().getBool( "abortOnConfigurationError",false) ) {
|
||||
|
@ -100,11 +88,10 @@ public class SolrDispatchFilter implements Filter
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (this.solrConfigFilename==null) {
|
||||
singlecore = new SolrCore( null, null, new SolrConfig(), null );
|
||||
} else {
|
||||
singlecore = new SolrCore( null, null, new SolrConfig(this.solrConfigFilename), null);
|
||||
}
|
||||
SolrConfig cfg = this.solrConfigFilename == null? new SolrConfig() : new SolrConfig(this.solrConfigFilename);
|
||||
singlecore = new SolrCore( null, null, cfg, null );
|
||||
abortOnConfigurationError = cfg.getBool(
|
||||
"abortOnConfigurationError", abortOnConfigurationError);
|
||||
}
|
||||
log.info("user.dir=" + System.getProperty("user.dir"));
|
||||
}
|
||||
|
@ -123,10 +110,9 @@ public class SolrDispatchFilter implements Filter
|
|||
out.println( "Check your log files for more detailed information on what may be wrong.\n" );
|
||||
out.println( "If you want solr to continue after configuration errors, change: \n");
|
||||
out.println( " <abortOnConfigurationError>false</abortOnConfigurationError>\n" );
|
||||
if( multicore.isEnabled() ) {
|
||||
if (multicore != null && multicore.isEnabled()) {
|
||||
out.println( "in multicore.xml\n" );
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
out.println( "in solrconfig.xml\n" );
|
||||
}
|
||||
|
||||
|
@ -148,24 +134,53 @@ public class SolrDispatchFilter implements Filter
|
|||
log.info("SolrDispatchFilter.init() done");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the multicore instance.
|
||||
* @param config the filter configuration
|
||||
* @return the multicore instance or null
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
protected MultiCore initMultiCore(FilterConfig config) throws Exception {
|
||||
@SuppressWarnings("deprecation") // since SolrDispatchFilter can be derived & initMultiCore can be overriden
|
||||
MultiCore mcore = org.apache.solr.core.SolrMultiCore.getInstance();
|
||||
if (mcore.isEnabled()) {
|
||||
log.info("Using existing multicore configuration");
|
||||
} else {
|
||||
// multicore load
|
||||
String instanceDir = SolrResourceLoader.locateInstanceDir();
|
||||
File fconf = new File(instanceDir, "multicore.xml");
|
||||
log.info("looking for multicore.xml: " + fconf.getAbsolutePath());
|
||||
if (fconf.exists()) {
|
||||
mcore.load(instanceDir, fconf);
|
||||
}
|
||||
}
|
||||
return mcore;
|
||||
}
|
||||
|
||||
|
||||
public void destroy() {
|
||||
if (multicore != null) {
|
||||
multicore.shutdown();
|
||||
multicore = null;
|
||||
}
|
||||
if( singlecore != null ) {
|
||||
singlecore.close();
|
||||
singlecore = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
|
||||
{
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
if( abortErrorMessage != null ) {
|
||||
((HttpServletResponse)response).sendError( 500, abortErrorMessage );
|
||||
return;
|
||||
}
|
||||
|
||||
if( request instanceof HttpServletRequest) {
|
||||
SolrQueryRequest solrReq = null;
|
||||
HttpServletRequest req = (HttpServletRequest)request;
|
||||
HttpServletResponse resp = (HttpServletResponse)response;
|
||||
SolrRequestHandler handler = null;
|
||||
SolrQueryRequest solrReq = null;
|
||||
|
||||
try {
|
||||
String path = req.getServletPath();
|
||||
if( req.getPathInfo() != null ) {
|
||||
|
@ -183,133 +198,118 @@ public class SolrDispatchFilter implements Filter
|
|||
}
|
||||
|
||||
// By default use the single core. If multicore is enabled, look for one.
|
||||
SolrRequestHandler handler = null;
|
||||
SolrCore core = singlecore;
|
||||
if( core == null ) {
|
||||
// Perhaps this is a multi-core admin page?
|
||||
if( path.equals( "/" ) ) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
final SolrCore core;
|
||||
if (multicore != null && multicore.isEnabled()) {
|
||||
// if this is the multi-core admin page, it will handle it
|
||||
if( path.equals( multicore.getAdminPath() ) ) {
|
||||
handler = multicore.getMultiCoreHandler();
|
||||
|
||||
// pick a core to use for output
|
||||
Collection<SolrCore> cores = multicore.getCores();
|
||||
if( cores != null && cores.size() > 0 ) {
|
||||
core = cores.iterator().next();
|
||||
}
|
||||
// pick a core to use for output generation
|
||||
core = multicore.getAdminCore();
|
||||
if( core == null ) {
|
||||
throw new RuntimeException( "Can not find a valid core for the multicore admin handler" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//otherwise, we should find a core from the path
|
||||
idx = path.indexOf( "/", 1 );
|
||||
if( idx <= 1 ) {
|
||||
idx = path.length();
|
||||
}
|
||||
|
||||
// try to get the corename as a request parameter first
|
||||
String corename = path.substring( 1, idx );
|
||||
path = path.substring( idx );
|
||||
core = multicore.getCore( corename );
|
||||
|
||||
if( path.length() == 0 ) {
|
||||
path = "/";
|
||||
}
|
||||
|
||||
if( core == null ) {
|
||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown core: "+corename );
|
||||
if( idx > 1 ) {
|
||||
// try to get the corename as a request parameter first
|
||||
String corename = path.substring( 1, idx );
|
||||
path = path.substring( idx );
|
||||
core = multicore.getCore( corename );
|
||||
} else {
|
||||
core = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SolrRequestParsers parser = parsers.get( core );
|
||||
if( parser == null ) {
|
||||
parser = new SolrRequestParsers( core.getSolrConfig() );
|
||||
parsers.put( core, parser );
|
||||
}
|
||||
|
||||
// Only try to parse the handler *if* a valid core exists
|
||||
// when multi-core is enabled, the path can lead to a null core.
|
||||
if( handler == null && path.length() > 1 ) { // don't match "" or "/" as valid path
|
||||
handler = core.getRequestHandler( path );
|
||||
}
|
||||
if( handler == null && parser.isHandleSelect() ) {
|
||||
if( "/select".equals( path ) || "/select/".equals( path ) ) {
|
||||
solrReq = parser.parse( core, path, req );
|
||||
String qt = solrReq.getParams().get( CommonParams.QT );
|
||||
if( qt != null && qt.startsWith( "/" ) ) {
|
||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Invalid query type. Do not use /select to access: "+qt);
|
||||
}
|
||||
handler = core.getRequestHandler( qt );
|
||||
if( handler == null ) {
|
||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+qt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( handler != null ) {
|
||||
if( solrReq == null ) {
|
||||
solrReq = parser.parse( core, path, req );
|
||||
}
|
||||
|
||||
final SolrConfig conf = core.getSolrConfig();
|
||||
final Method reqMethod = Method.getMethod(req.getMethod());
|
||||
|
||||
if (Method.POST != reqMethod) {
|
||||
HttpCacheHeaderUtil.setCacheControlHeader(conf, resp);
|
||||
}
|
||||
|
||||
// unless we have been explicitly told not to, do cache validation
|
||||
if (!conf.getHttpCachingConfig().isNever304()) {
|
||||
// if we've confirmed cache validation, return immediately
|
||||
if (HttpCacheHeaderUtil.doCacheHeaderValidation(solrReq, req,resp)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SolrQueryResponse solrRsp = new SolrQueryResponse();
|
||||
/* even for HEAD requests, we need to execute the handler to
|
||||
* ensure we don't get an error (and to make sure the correct
|
||||
* QueryResponseWriter is selectedand we get the correct
|
||||
* Content-Type)
|
||||
*/
|
||||
this.execute( req, handler, solrReq, solrRsp );
|
||||
if( solrRsp.getException() != null ) {
|
||||
sendError( (HttpServletResponse)response, solrRsp.getException() );
|
||||
return;
|
||||
}
|
||||
|
||||
// Now write it out
|
||||
QueryResponseWriter responseWriter = core.getQueryResponseWriter(solrReq);
|
||||
response.setContentType(responseWriter.getContentType(solrReq, solrRsp));
|
||||
if (Method.HEAD == Method.getMethod(req.getMethod())) {
|
||||
// nothing to write out, waited this long just to get ContentType
|
||||
return;
|
||||
}
|
||||
|
||||
PrintWriter out = response.getWriter();
|
||||
responseWriter.write(out, solrReq, solrRsp);
|
||||
return;
|
||||
}
|
||||
// otherwise, let's ensure the core is in the SolrCore request attribute so
|
||||
// the servlet/jsp can retrieve it
|
||||
else {
|
||||
req.setAttribute("org.apache.solr.SolrCore", core);
|
||||
|
||||
// Let each core have its own admin page...
|
||||
if( singlecore == null && path.startsWith( "/admin" ) ) {
|
||||
req.getRequestDispatcher( path ).forward( request, response );
|
||||
return;
|
||||
core = singlecore;
|
||||
}
|
||||
|
||||
// With a valid core...
|
||||
if( core != null ) {
|
||||
final SolrConfig config = core.getSolrConfig();
|
||||
// get or create/cache the parser for the core
|
||||
SolrRequestParsers parser = null;
|
||||
parser = parsers.get(core);
|
||||
if( parser == null ) {
|
||||
parser = new SolrRequestParsers(config);
|
||||
parsers.put( core, parser );
|
||||
}
|
||||
|
||||
// Determine the handler from the url path if not set
|
||||
// (we might already have selected the multicore handler)
|
||||
if( handler == null && path.length() > 1 ) { // don't match "" or "/" as valid path
|
||||
handler = core.getRequestHandler( path );
|
||||
// no handler yet but allowed to handle select; let's check
|
||||
if( handler == null && parser.isHandleSelect() ) {
|
||||
if( "/select".equals( path ) || "/select/".equals( path ) ) {
|
||||
solrReq = parser.parse( core, path, req );
|
||||
String qt = solrReq.getParams().get( CommonParams.QT );
|
||||
if( qt != null && qt.startsWith( "/" ) ) {
|
||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Invalid query type. Do not use /select to access: "+qt);
|
||||
}
|
||||
handler = core.getRequestHandler( qt );
|
||||
if( handler == null ) {
|
||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+qt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// With a valid handler and a valid core...
|
||||
if( handler != null ) {
|
||||
// if not a /select, create the request
|
||||
if( solrReq == null ) {
|
||||
solrReq = parser.parse( core, path, req );
|
||||
}
|
||||
|
||||
final Method reqMethod = Method.getMethod(req.getMethod());
|
||||
if (Method.POST != reqMethod) {
|
||||
HttpCacheHeaderUtil.setCacheControlHeader(config, resp);
|
||||
}
|
||||
// unless we have been explicitly told not to, do cache validation
|
||||
// if we fail cache validation, execute the query
|
||||
if (config.getHttpCachingConfig().isNever304() ||
|
||||
!HttpCacheHeaderUtil.doCacheHeaderValidation(solrReq, req, resp)) {
|
||||
SolrQueryResponse solrRsp = new SolrQueryResponse();
|
||||
/* even for HEAD requests, we need to execute the handler to
|
||||
* ensure we don't get an error (and to make sure the correct
|
||||
* QueryResponseWriter is selectedand we get the correct
|
||||
* Content-Type)
|
||||
*/
|
||||
this.execute( req, handler, solrReq, solrRsp );
|
||||
if( solrRsp.getException() != null ) {
|
||||
sendError( (HttpServletResponse)response, solrRsp.getException() );
|
||||
}
|
||||
else {
|
||||
// Now write it out
|
||||
QueryResponseWriter responseWriter = core.getQueryResponseWriter(solrReq);
|
||||
response.setContentType(responseWriter.getContentType(solrReq, solrRsp));
|
||||
if (Method.HEAD != Method.getMethod(req.getMethod())) {
|
||||
PrintWriter out = response.getWriter();
|
||||
responseWriter.write(out, solrReq, solrRsp);
|
||||
}
|
||||
//else http HEAD request, nothing to write out, waited this long just to get ContentType
|
||||
}
|
||||
}
|
||||
return; // we are done with a valid handler
|
||||
}
|
||||
// otherwise (we have a core), let's ensure the core is in the SolrCore request attribute so
|
||||
// a servlet/jsp can retrieve it
|
||||
else {
|
||||
req.setAttribute("org.apache.solr.SolrCore", core);
|
||||
// Modify the request so each core gets its own /admin
|
||||
if( singlecore == null && path.startsWith( "/admin" ) ) {
|
||||
req.getRequestDispatcher( path ).forward( request, response );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Throwable ex ) {
|
||||
log.info("no handler or core retrieved for " + path + ", follow through...");
|
||||
} catch (Throwable ex) {
|
||||
sendError( (HttpServletResponse)response, ex );
|
||||
return;
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
if( solrReq != null ) {
|
||||
solrReq.close();
|
||||
}
|
||||
|
@ -326,8 +326,7 @@ public class SolrDispatchFilter implements Filter
|
|||
sreq.getCore().execute( handler, sreq, rsp );
|
||||
}
|
||||
|
||||
protected void sendError(HttpServletResponse res, Throwable ex) throws IOException
|
||||
{
|
||||
protected void sendError(HttpServletResponse res, Throwable ex) throws IOException {
|
||||
int code=500;
|
||||
String trace = "";
|
||||
if( ex instanceof SolrException ) {
|
||||
|
|
Loading…
Reference in New Issue