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 ModifiableSolrParams _invariantParams;
|
||||||
protected ResponseParser _processor;
|
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 SolrRequestParsers parser;
|
||||||
protected final String coreName; // use MultiCore registry
|
protected final String coreName; // use MultiCore registry
|
||||||
|
|
||||||
public EmbeddedSolrServer( SolrCore core )
|
public EmbeddedSolrServer( SolrCore core )
|
||||||
{
|
{
|
||||||
|
if ( core == null ) {
|
||||||
|
throw new NullPointerException("SolrCore instance required");
|
||||||
|
}
|
||||||
this.core = core;
|
this.core = core;
|
||||||
|
this.multicore = null;
|
||||||
this.coreName = null;
|
this.coreName = null;
|
||||||
this.parser = init();
|
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.core = null;
|
||||||
|
this.multicore = multicore;
|
||||||
this.coreName = coreName;
|
this.coreName = coreName;
|
||||||
SolrCore c = MultiCore.getRegistry().getCore( coreName );
|
SolrCore c = multicore.getCore( coreName );
|
||||||
if( c == null ) {
|
if( c == null ) {
|
||||||
throw new RuntimeException( "Unknown core: "+coreName );
|
throw new RuntimeException( "Unknown core: "+coreName );
|
||||||
}
|
}
|
||||||
|
@ -96,7 +105,6 @@ public class EmbeddedSolrServer extends SolrServer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for multicore action
|
// Check for multicore action
|
||||||
MultiCore multicore = MultiCore.getRegistry();
|
|
||||||
SolrCore core = this.core;
|
SolrCore core = this.core;
|
||||||
if( core == null ) {
|
if( core == null ) {
|
||||||
core = multicore.getCore( coreName );
|
core = multicore.getCore( coreName );
|
||||||
|
@ -126,7 +134,7 @@ public class EmbeddedSolrServer extends SolrServer
|
||||||
}
|
}
|
||||||
// Perhaps the path is to manage the cores
|
// Perhaps the path is to manage the cores
|
||||||
if( handler == null &&
|
if( handler == null &&
|
||||||
coreName != null &&
|
multicore != null &&
|
||||||
path.equals( multicore.getAdminPath() ) &&
|
path.equals( multicore.getAdminPath() ) &&
|
||||||
multicore.isEnabled() ) {
|
multicore.isEnabled() ) {
|
||||||
handler = multicore.getMultiCoreHandler();
|
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.request.UpdateRequest.ACTION;
|
||||||
import org.apache.solr.client.solrj.response.MultiCoreResponse;
|
import org.apache.solr.client.solrj.response.MultiCoreResponse;
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
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
|
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 getSolrHome() { return "../../../example/multicore/"; }
|
||||||
|
|
||||||
@Override public String getSchemaFile() { return getSolrHome()+"core0/conf/schema.xml"; }
|
@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.MultiCoreExampleTestBase;
|
||||||
import org.apache.solr.client.solrj.SolrServer;
|
import org.apache.solr.client.solrj.SolrServer;
|
||||||
import org.apache.solr.core.MultiCore;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This runs SolrServer test using
|
* This runs SolrServer test using
|
||||||
|
@ -37,24 +36,24 @@ public class MultiCoreEmbeddedTest extends MultiCoreExampleTestBase {
|
||||||
|
|
||||||
File home = new File( getSolrHome() );
|
File home = new File( getSolrHome() );
|
||||||
File f = new File( home, "multicore.xml" );
|
File f = new File( home, "multicore.xml" );
|
||||||
MultiCore.getRegistry().load( getSolrHome(), f );
|
multicore.load( getSolrHome(), f );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SolrServer getSolrCore0()
|
protected SolrServer getSolrCore0()
|
||||||
{
|
{
|
||||||
return new EmbeddedSolrServer( "core0" );
|
return new EmbeddedSolrServer( multicore, "core0" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SolrServer getSolrCore1()
|
protected SolrServer getSolrCore1()
|
||||||
{
|
{
|
||||||
return new EmbeddedSolrServer( "core1" );
|
return new EmbeddedSolrServer( multicore, "core1" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SolrServer getSolrAdmin()
|
protected SolrServer getSolrAdmin()
|
||||||
{
|
{
|
||||||
return new EmbeddedSolrServer( "core0" );
|
return new EmbeddedSolrServer( multicore, "core0" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,30 +49,33 @@ import org.xml.sax.SAXException;
|
||||||
*/
|
*/
|
||||||
public class MultiCore
|
public class MultiCore
|
||||||
{
|
{
|
||||||
private static Logger log = Logger.getLogger(MultiCore.class.getName());
|
protected static Logger log = Logger.getLogger(MultiCore.class.getName());
|
||||||
private static final MultiCore instance = new MultiCore();
|
|
||||||
|
|
||||||
// Synchronized map of all cores
|
protected final Map<String, CoreDescriptor> cores = new LinkedHashMap<String, CoreDescriptor>();
|
||||||
private 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;
|
public MultiCore() {
|
||||||
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() { }
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Initialization / Cleanup
|
// 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 {
|
public void load(String dir, File configFile ) throws ParserConfigurationException, IOException, SAXException {
|
||||||
this.configFile = configFile;
|
this.configFile = configFile;
|
||||||
|
@ -94,7 +97,7 @@ public class MultiCore
|
||||||
}
|
}
|
||||||
|
|
||||||
if( adminPath != null ) {
|
if( adminPath != null ) {
|
||||||
multiCoreHandler = new MultiCoreHandler();
|
multiCoreHandler = this.createMultiCoreHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList nodes = (NodeList)cfg.evaluate("multicore/core", XPathConstants.NODESET);
|
NodeList nodes = (NodeList)cfg.evaluate("multicore/core", XPathConstants.NODESET);
|
||||||
|
@ -135,7 +138,9 @@ public class MultiCore
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stops all cores. */
|
/**
|
||||||
|
* Stops all cores.
|
||||||
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
synchronized(cores) {
|
synchronized(cores) {
|
||||||
for(Map.Entry<String,CoreDescriptor> e : cores.entrySet()) {
|
for(Map.Entry<String,CoreDescriptor> e : cores.entrySet()) {
|
||||||
|
@ -154,15 +159,11 @@ public class MultiCore
|
||||||
shutdown();
|
shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
/**
|
||||||
//
|
* 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
|
||||||
/** Get the singleton */
|
*/
|
||||||
public static MultiCore getRegistry() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CoreDescriptor register( CoreDescriptor descr ) {
|
public CoreDescriptor register( CoreDescriptor descr ) {
|
||||||
if( descr == null ) {
|
if( descr == null ) {
|
||||||
throw new RuntimeException( "Can not register a null core." );
|
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) {
|
public void swap(CoreDescriptor c0, CoreDescriptor c1) {
|
||||||
if( c0 == null || c1 == null ) {
|
if( c0 == null || c1 == null ) {
|
||||||
throw new RuntimeException( "Can not swap a null core." );
|
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
|
* While the new core is loading, requests will continue to be dispatched to
|
||||||
* and processed by the old core
|
* and processed by the old core
|
||||||
*
|
*
|
||||||
* @param core
|
* @param core the SolrCore to reload
|
||||||
* @throws ParserConfigurationException
|
* @throws ParserConfigurationException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws SAXException
|
* @throws SAXException
|
||||||
|
@ -314,6 +322,49 @@ public class MultiCore
|
||||||
this.adminPath = adminPath;
|
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() {
|
public MultiCoreHandler getMultiCoreHandler() {
|
||||||
return multiCoreHandler;
|
return multiCoreHandler;
|
||||||
}
|
}
|
||||||
|
@ -439,4 +490,5 @@ public class MultiCore
|
||||||
throw xforward;
|
throw xforward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
|
@ -467,6 +467,10 @@ public final class SolrCore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isClosed() {
|
||||||
|
return _searcher == null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() { close(); }
|
protected void finalize() { close(); }
|
||||||
|
|
||||||
|
@ -926,7 +930,7 @@ public final class SolrCore {
|
||||||
synchronized (searcherLock) {
|
synchronized (searcherLock) {
|
||||||
if (_searcher != null) {
|
if (_searcher != null) {
|
||||||
_searcher.decref(); // dec refcount for this._searcher
|
_searcher.decref(); // dec refcount for this._searcher
|
||||||
_searcher=null;
|
_searcher=null; // isClosed() does check this
|
||||||
infoRegistry.remove("currentSearcher");
|
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$
|
* @version $Id$
|
||||||
* @since solr 1.3
|
* @since solr 1.3
|
||||||
*/
|
*/
|
||||||
public class MultiCoreHandler extends RequestHandlerBase
|
public abstract class MultiCoreHandler extends RequestHandlerBase
|
||||||
{
|
{
|
||||||
public MultiCoreHandler()
|
public MultiCoreHandler()
|
||||||
{
|
{
|
||||||
|
@ -56,11 +56,18 @@ public class MultiCoreHandler extends RequestHandlerBase
|
||||||
"it is a special Handler configured directly by the RequestDispatcher" );
|
"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
|
@Override
|
||||||
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
|
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
|
||||||
{
|
{
|
||||||
// Make sure the manager is enabled
|
// Make sure the manager is enabled
|
||||||
MultiCore manager = MultiCore.getRegistry();
|
MultiCore manager = getMultiCore();
|
||||||
if( !manager.isEnabled() ) {
|
if( !manager.isEnabled() ) {
|
||||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
|
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
|
||||||
"MultiCore support must be enabled at startup." );
|
"MultiCore support must be enabled at startup." );
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
@ -74,23 +73,12 @@ public class SolrDispatchFilter implements Filter
|
||||||
this.pathPrefix = config.getInitParameter( "path-prefix" );
|
this.pathPrefix = config.getInitParameter( "path-prefix" );
|
||||||
this.solrConfigFilename = config.getInitParameter("solrconfig-filename");
|
this.solrConfigFilename = config.getInitParameter("solrconfig-filename");
|
||||||
|
|
||||||
multicore = MultiCore.getRegistry();
|
// multicore instantiation
|
||||||
if( multicore.isEnabled() ) {
|
this.multicore = initMultiCore(config);
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(multicore != null && multicore.isEnabled() ) {
|
||||||
abortOnConfigurationError = false;
|
abortOnConfigurationError = false;
|
||||||
if( multicore.isEnabled() ) {
|
|
||||||
singlecore = null;
|
singlecore = null;
|
||||||
|
|
||||||
// if any core aborts on startup, then abort
|
// if any core aborts on startup, then abort
|
||||||
for( SolrCore c : multicore.getCores() ) {
|
for( SolrCore c : multicore.getCores() ) {
|
||||||
if( c.getSolrConfig().getBool( "abortOnConfigurationError",false) ) {
|
if( c.getSolrConfig().getBool( "abortOnConfigurationError",false) ) {
|
||||||
|
@ -100,11 +88,10 @@ public class SolrDispatchFilter implements Filter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.solrConfigFilename==null) {
|
SolrConfig cfg = this.solrConfigFilename == null? new SolrConfig() : new SolrConfig(this.solrConfigFilename);
|
||||||
singlecore = new SolrCore( null, null, new SolrConfig(), null );
|
singlecore = new SolrCore( null, null, cfg, null );
|
||||||
} else {
|
abortOnConfigurationError = cfg.getBool(
|
||||||
singlecore = new SolrCore( null, null, new SolrConfig(this.solrConfigFilename), null);
|
"abortOnConfigurationError", abortOnConfigurationError);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
log.info("user.dir=" + System.getProperty("user.dir"));
|
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( "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( "If you want solr to continue after configuration errors, change: \n");
|
||||||
out.println( " <abortOnConfigurationError>false</abortOnConfigurationError>\n" );
|
out.println( " <abortOnConfigurationError>false</abortOnConfigurationError>\n" );
|
||||||
if( multicore.isEnabled() ) {
|
if (multicore != null && multicore.isEnabled()) {
|
||||||
out.println( "in multicore.xml\n" );
|
out.println( "in multicore.xml\n" );
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
out.println( "in solrconfig.xml\n" );
|
out.println( "in solrconfig.xml\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,24 +134,53 @@ public class SolrDispatchFilter implements Filter
|
||||||
log.info("SolrDispatchFilter.init() done");
|
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() {
|
public void destroy() {
|
||||||
|
if (multicore != null) {
|
||||||
multicore.shutdown();
|
multicore.shutdown();
|
||||||
|
multicore = null;
|
||||||
|
}
|
||||||
if( singlecore != null ) {
|
if( singlecore != null ) {
|
||||||
singlecore.close();
|
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 ) {
|
if( abortErrorMessage != null ) {
|
||||||
((HttpServletResponse)response).sendError( 500, abortErrorMessage );
|
((HttpServletResponse)response).sendError( 500, abortErrorMessage );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( request instanceof HttpServletRequest) {
|
if( request instanceof HttpServletRequest) {
|
||||||
SolrQueryRequest solrReq = null;
|
|
||||||
HttpServletRequest req = (HttpServletRequest)request;
|
HttpServletRequest req = (HttpServletRequest)request;
|
||||||
HttpServletResponse resp = (HttpServletResponse)response;
|
HttpServletResponse resp = (HttpServletResponse)response;
|
||||||
|
SolrRequestHandler handler = null;
|
||||||
|
SolrQueryRequest solrReq = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String path = req.getServletPath();
|
String path = req.getServletPath();
|
||||||
if( req.getPathInfo() != null ) {
|
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.
|
// By default use the single core. If multicore is enabled, look for one.
|
||||||
SolrRequestHandler handler = null;
|
final SolrCore core;
|
||||||
SolrCore core = singlecore;
|
if (multicore != null && multicore.isEnabled()) {
|
||||||
if( core == null ) {
|
// if this is the multi-core admin page, it will handle it
|
||||||
// Perhaps this is a multi-core admin page?
|
|
||||||
if( path.equals( "/" ) ) {
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if( path.equals( multicore.getAdminPath() ) ) {
|
if( path.equals( multicore.getAdminPath() ) ) {
|
||||||
handler = multicore.getMultiCoreHandler();
|
handler = multicore.getMultiCoreHandler();
|
||||||
|
// pick a core to use for output generation
|
||||||
// pick a core to use for output
|
core = multicore.getAdminCore();
|
||||||
Collection<SolrCore> cores = multicore.getCores();
|
|
||||||
if( cores != null && cores.size() > 0 ) {
|
|
||||||
core = cores.iterator().next();
|
|
||||||
}
|
|
||||||
if( core == null ) {
|
if( core == null ) {
|
||||||
throw new RuntimeException( "Can not find a valid core for the multicore admin handler" );
|
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 );
|
idx = path.indexOf( "/", 1 );
|
||||||
if( idx <= 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 );
|
||||||
// try to get the corename as a request parameter first
|
core = multicore.getCore( corename );
|
||||||
String corename = path.substring( 1, idx );
|
} else {
|
||||||
path = path.substring( idx );
|
core = null;
|
||||||
core = multicore.getCore( corename );
|
|
||||||
|
|
||||||
if( path.length() == 0 ) {
|
|
||||||
path = "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
if( core == null ) {
|
|
||||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown core: "+corename );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
else {
|
||||||
req.setAttribute("org.apache.solr.SolrCore", core);
|
core = singlecore;
|
||||||
|
}
|
||||||
// Let each core have its own admin page...
|
|
||||||
if( singlecore == null && path.startsWith( "/admin" ) ) {
|
// With a valid core...
|
||||||
req.getRequestDispatcher( path ).forward( request, response );
|
if( core != null ) {
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
log.info("no handler or core retrieved for " + path + ", follow through...");
|
||||||
catch( Throwable ex ) {
|
} catch (Throwable ex) {
|
||||||
sendError( (HttpServletResponse)response, ex );
|
sendError( (HttpServletResponse)response, ex );
|
||||||
return;
|
return;
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
if( solrReq != null ) {
|
if( solrReq != null ) {
|
||||||
solrReq.close();
|
solrReq.close();
|
||||||
}
|
}
|
||||||
|
@ -326,8 +326,7 @@ public class SolrDispatchFilter implements Filter
|
||||||
sreq.getCore().execute( handler, sreq, rsp );
|
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;
|
int code=500;
|
||||||
String trace = "";
|
String trace = "";
|
||||||
if( ex instanceof SolrException ) {
|
if( ex instanceof SolrException ) {
|
||||||
|
|
Loading…
Reference in New Issue