You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-commits@lucene.apache.org by ry...@apache.org on 2008/03/09 20:29:07 UTC
svn commit: r635334 - in /lucene/solr/trunk:
client/java/solrj/src/org/apache/solr/client/solrj/embedded/
client/java/solrj/test/org/apache/solr/client/solrj/
client/java/solrj/test/org/apache/solr/client/solrj/embedded/
src/java/org/apache/solr/core/ ...
Author: ryan
Date: Sun Mar 9 12:29:04 2008
New Revision: 635334
URL: http://svn.apache.org/viewvc?rev=635334&view=rev
Log:
SOLR-350 -- make MultiCore subclassable so to allow custom persistance methods (for example, SQL)
Added:
lucene/solr/trunk/src/java/org/apache/solr/core/SolrMultiCore.java
Modified:
lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java
lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/embedded/MultiCoreEmbeddedTest.java
lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java
lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java
lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java
lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java
Modified: lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java?rev=635334&r1=635333&r2=635334&view=diff
==============================================================================
--- lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java (original)
+++ lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java Sun Mar 9 12:29:04 2008
@@ -54,22 +54,31 @@
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 @@
}
// Check for multicore action
- MultiCore multicore = MultiCore.getRegistry();
SolrCore core = this.core;
if( core == null ) {
core = multicore.getCore( coreName );
@@ -126,7 +134,7 @@
}
// Perhaps the path is to manage the cores
if( handler == null &&
- coreName != null &&
+ multicore != null &&
path.equals( multicore.getAdminPath() ) &&
multicore.isEnabled() ) {
handler = multicore.getMultiCoreHandler();
Modified: lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java?rev=635334&r1=635333&r2=635334&view=diff
==============================================================================
--- lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java (original)
+++ lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java Sun Mar 9 12:29:04 2008
@@ -25,7 +25,7 @@
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 @@
*/
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"; }
Modified: lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/embedded/MultiCoreEmbeddedTest.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/embedded/MultiCoreEmbeddedTest.java?rev=635334&r1=635333&r2=635334&view=diff
==============================================================================
--- lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/embedded/MultiCoreEmbeddedTest.java (original)
+++ lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/embedded/MultiCoreEmbeddedTest.java Sun Mar 9 12:29:04 2008
@@ -21,7 +21,6 @@
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 @@
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" );
}
}
Modified: lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java?rev=635334&r1=635333&r2=635334&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java Sun Mar 9 12:29:04 2008
@@ -49,30 +49,33 @@
*/
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 @@
}
if( adminPath != null ) {
- multiCoreHandler = new MultiCoreHandler();
+ multiCoreHandler = this.createMultiCoreHandler();
}
NodeList nodes = (NodeList)cfg.evaluate("multicore/core", XPathConstants.NODESET);
@@ -135,7 +138,9 @@
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 @@
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 @@
}
}
+
+ /**
+ * 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 @@
}
/**
+ * 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 @@
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 @@
throw xforward;
}
}
+
}
Modified: lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java?rev=635334&r1=635333&r2=635334&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java Sun Mar 9 12:29:04 2008
@@ -32,7 +32,6 @@
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;
Modified: lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java?rev=635334&r1=635333&r2=635334&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java Sun Mar 9 12:29:04 2008
@@ -467,6 +467,10 @@
}
}
+ public boolean isClosed() {
+ return _searcher == null;
+ }
+
@Override
protected void finalize() { close(); }
@@ -926,7 +930,7 @@
synchronized (searcherLock) {
if (_searcher != null) {
_searcher.decref(); // dec refcount for this._searcher
- _searcher=null;
+ _searcher=null; // isClosed() does check this
infoRegistry.remove("currentSearcher");
}
}
Added: lucene/solr/trunk/src/java/org/apache/solr/core/SolrMultiCore.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrMultiCore.java?rev=635334&view=auto
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/SolrMultiCore.java (added)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrMultiCore.java Sun Mar 9 12:29:04 2008
@@ -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;
+ }
+}
Modified: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java?rev=635334&r1=635333&r2=635334&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java Sun Mar 9 12:29:04 2008
@@ -39,7 +39,7 @@
* @version $Id$
* @since solr 1.3
*/
-public class MultiCoreHandler extends RequestHandlerBase
+public abstract class MultiCoreHandler extends RequestHandlerBase
{
public MultiCoreHandler()
{
@@ -56,11 +56,18 @@
"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." );
Modified: lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java?rev=635334&r1=635333&r2=635334&view=diff
==============================================================================
--- lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java (original)
+++ lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java Sun Mar 9 12:29:04 2008
@@ -21,7 +21,6 @@
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 @@
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 @@
}
}
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 @@
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 @@
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 @@
}
// 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);
- }
- }
+ else {
+ core = singlecore;
}
- if( handler != null ) {
- if( solrReq == null ) {
- solrReq = parser.parse( core, path, req );
+ // 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 );
}
- 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;
+ // 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);
+ }
+ }
}
}
- 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;
+ // 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
}
-
- 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;
+ // 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 @@
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 ) {
Re: svn commit: r635334 - in /lucene/solr/trunk: client/java/solrj/src/org/apache/solr/client/solrj/embedded/ client/java/solrj/test/org/apache/solr/client/solrj/ client/java/solrj/test/org/apache/solr/client/solrj/embedded/ src/java/org/apache/solr/core/ ...
Posted by Grant Ingersoll <gs...@apache.org>.
I'm getting:
HTTP ERROR: 500
PWC6033: Unable to compile class for JSP
PWC6197: An error occurred at line: 50 in the jsp file: /admin/index.jsp
PWC6199: Generated servlet error:
The method getRegistry() is undefined for the type MultiCore
RequestURI=/solr/admin/
Caused by:
org.apache.jasper.JasperException: PWC6033: Unable to compile class
for JSP
PWC6197: An error occurred at line: 50 in the jsp file: /admin/index.jsp
PWC6199: Generated servlet error:
The method getRegistry() is undefined for the type MultiCore
at
org
.apache
.jasper
.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:94)
Looks like getRegistry() was removed. I'm not sure on the
replacement, just yet, but can look into it if no one else sees it
right off hand..
-Grant
On Mar 9, 2008, at 3:29 PM, ryan@apache.org wrote:
> Author: ryan
> Date: Sun Mar 9 12:29:04 2008
> New Revision: 635334
>
> URL: http://svn.apache.org/viewvc?rev=635334&view=rev
> Log:
> SOLR-350 -- make MultiCore subclassable so to allow custom
> persistance methods (for example, SQL)
>
> Added:
> lucene/solr/trunk/src/java/org/apache/solr/core/SolrMultiCore.java
> Modified:
> lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/
> solrj/embedded/EmbeddedSolrServer.java
> lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/
> solrj/MultiCoreExampleTestBase.java
> lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/
> solrj/embedded/MultiCoreEmbeddedTest.java
> lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java
> lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
> lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java
> lucene/solr/trunk/src/java/org/apache/solr/handler/admin/
> MultiCoreHandler.java
> lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/
> SolrDispatchFilter.java
>
> Modified: lucene/solr/trunk/client/java/solrj/src/org/apache/solr/
> client/solrj/embedded/EmbeddedSolrServer.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java?rev=635334&r1=635333&r2=635334&view=diff
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/
> solrj/embedded/EmbeddedSolrServer.java (original)
> +++ lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/
> solrj/embedded/EmbeddedSolrServer.java Sun Mar 9 12:29:04 2008
> @@ -54,22 +54,31 @@
> 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 @@
> }
>
> // Check for multicore action
> - MultiCore multicore = MultiCore.getRegistry();
> SolrCore core = this.core;
> if( core == null ) {
> core = multicore.getCore( coreName );
> @@ -126,7 +134,7 @@
> }
> // Perhaps the path is to manage the cores
> if( handler == null &&
> - coreName != null &&
> + multicore != null &&
> path.equals( multicore.getAdminPath() ) &&
> multicore.isEnabled() ) {
> handler = multicore.getMultiCoreHandler();
>
> Modified: lucene/solr/trunk/client/java/solrj/test/org/apache/solr/
> client/solrj/MultiCoreExampleTestBase.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java?rev=635334&r1=635333&r2=635334&view=diff
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/
> solrj/MultiCoreExampleTestBase.java (original)
> +++ lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/
> solrj/MultiCoreExampleTestBase.java Sun Mar 9 12:29:04 2008
> @@ -25,7 +25,7 @@
> 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 @@
> */
> 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"; }
>
> Modified: lucene/solr/trunk/client/java/solrj/test/org/apache/solr/
> client/solrj/embedded/MultiCoreEmbeddedTest.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/embedded/MultiCoreEmbeddedTest.java?rev=635334&r1=635333&r2=635334&view=diff
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/
> solrj/embedded/MultiCoreEmbeddedTest.java (original)
> +++ lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/
> solrj/embedded/MultiCoreEmbeddedTest.java Sun Mar 9 12:29:04 2008
> @@ -21,7 +21,6 @@
>
> 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 @@
>
> 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" );
> }
> }
>
> Modified: lucene/solr/trunk/src/java/org/apache/solr/core/
> MultiCore.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java?rev=635334&r1=635333&r2=635334&view=diff
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java
> (original)
> +++ lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java
> Sun Mar 9 12:29:04 2008
> @@ -49,30 +49,33 @@
> */
> 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 @@
> }
>
> if( adminPath != null ) {
> - multiCoreHandler = new MultiCoreHandler();
> + multiCoreHandler = this.createMultiCoreHandler();
> }
>
> NodeList nodes = (NodeList)cfg.evaluate("multicore/core",
> XPathConstants.NODESET);
> @@ -135,7 +138,9 @@
> 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 @@
> 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 @@
> }
> }
>
> +
> + /**
> + * 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 @@
> }
>
> /**
> + * 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 @@
> 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 @@
> throw xforward;
> }
> }
> +
> }
>
> Modified: lucene/solr/trunk/src/java/org/apache/solr/core/
> SolrConfig.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java?rev=635334&r1=635333&r2=635334&view=diff
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
> (original)
> +++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
> Sun Mar 9 12:29:04 2008
> @@ -32,7 +32,6 @@
> 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;
>
> Modified: lucene/solr/trunk/src/java/org/apache/solr/core/
> SolrCore.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java?rev=635334&r1=635333&r2=635334&view=diff
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java
> (original)
> +++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java
> Sun Mar 9 12:29:04 2008
> @@ -467,6 +467,10 @@
> }
> }
>
> + public boolean isClosed() {
> + return _searcher == null;
> + }
> +
> @Override
> protected void finalize() { close(); }
>
> @@ -926,7 +930,7 @@
> synchronized (searcherLock) {
> if (_searcher != null) {
> _searcher.decref(); // dec refcount for this._searcher
> - _searcher=null;
> + _searcher=null; // isClosed() does check this
> infoRegistry.remove("currentSearcher");
> }
> }
>
> Added: lucene/solr/trunk/src/java/org/apache/solr/core/
> SolrMultiCore.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrMultiCore.java?rev=635334&view=auto
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/src/java/org/apache/solr/core/
> SolrMultiCore.java (added)
> +++ lucene/solr/trunk/src/java/org/apache/solr/core/
> SolrMultiCore.java Sun Mar 9 12:29:04 2008
> @@ -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;
> + }
> +}
>
> Modified: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/
> MultiCoreHandler.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java?rev=635334&r1=635333&r2=635334&view=diff
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/
> MultiCoreHandler.java (original)
> +++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/
> MultiCoreHandler.java Sun Mar 9 12:29:04 2008
> @@ -39,7 +39,7 @@
> * @version $Id$
> * @since solr 1.3
> */
> -public class MultiCoreHandler extends RequestHandlerBase
> +public abstract class MultiCoreHandler extends RequestHandlerBase
> {
> public MultiCoreHandler()
> {
> @@ -56,11 +56,18 @@
> "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." );
>
> Modified: lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/
> SolrDispatchFilter.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java?rev=635334&r1=635333&r2=635334&view=diff
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/
> SolrDispatchFilter.java (original)
> +++ lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/
> SolrDispatchFilter.java Sun Mar 9 12:29:04 2008
> @@ -21,7 +21,6 @@
> 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 @@
> 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 @@
> }
> }
> 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 @@
> 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 @@
> 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 @@
> }
>
> // 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);
> - }
> - }
> + else {
> + core = singlecore;
> }
>
> - if( handler != null ) {
> - if( solrReq == null ) {
> - solrReq = parser.parse( core, path, req );
> + // 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 );
> }
>
> - 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;
> + // 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);
> + }
> + }
> }
> }
>
> - 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;
> + // 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
> }
> -
> - 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;
> + // 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 @@
> 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 ) {
>
>
--------------------------
Grant Ingersoll
http://www.lucenebootcamp.com
Next Training: April 7, 2008 at ApacheCon Europe in Amsterdam
Lucene Helpful Hints:
http://wiki.apache.org/lucene-java/BasicsOfPerformance
http://wiki.apache.org/lucene-java/LuceneFAQ