Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

moved SolrCore config related stuff out

-- messy messy messy
-- NOTE this does not pass all the tests

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/branches/sandbox@701592 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
commit d9b78178a47e61bf651cd3520384f49e3b07cd55 1 parent c0df15a
Ryan McKinley authored
Showing with 1,547 additions and 1,119 deletions.
  1. +2 −2 ryan/contrib/dataimporthandler/src/main/java/org/apache/solr/handler/dataimport/DataImportHandler.java
  2. +1 −1  ryan/contrib/dataimporthandler/src/main/java/org/apache/solr/handler/dataimport/DataImporter.java
  3. +2 −1  ryan/src/java/org/apache/solr/{core → config}/Config.java
  4. +5 −3 ryan/src/java/org/apache/solr/{core → config}/CoreDescriptor.java
  5. +576 −0 ryan/src/java/org/apache/solr/config/CoreInitalizer.java
  6. +148 −0 ryan/src/java/org/apache/solr/config/CoreVars.java
  7. +34 −0 ryan/src/java/org/apache/solr/config/HttpCachingConfiguration.java
  8. +14 −0 ryan/src/java/org/apache/solr/config/JmxConfiguration.java
  9. +26 −0 ryan/src/java/org/apache/solr/config/RequestDispatcherConfiguration.java
  10. +193 −0 ryan/src/java/org/apache/solr/config/SolrConfig.java
  11. +254 −0 ryan/src/java/org/apache/solr/config/SolrConfiguraion.java
  12. +1 −2  ryan/src/java/org/apache/solr/{update → config}/SolrIndexConfig.java
  13. +4 −3 ryan/src/java/org/apache/solr/{core → config}/SolrResourceLoader.java
  14. +1 −4 ryan/src/java/org/apache/solr/core/AbstractSolrEventListener.java
  15. +10 −3 ryan/src/java/org/apache/solr/core/CoreContainer.java
  16. +2 −2 ryan/src/java/org/apache/solr/core/JmxMonitoredMap.java
  17. +4 −3 ryan/src/java/org/apache/solr/core/QuerySenderListener.java
  18. +7 −84 ryan/src/java/org/apache/solr/core/RequestHandlers.java
  19. +1 −3 ryan/src/java/org/apache/solr/core/RunExecutableListener.java
  20. +0 −249 ryan/src/java/org/apache/solr/core/SolrConfig.java
  21. +139 −556 ryan/src/java/org/apache/solr/core/SolrCore.java
  22. +1 −1  ryan/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
  23. +1 −1  ryan/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java
  24. +1 −1  ryan/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
  25. +6 −7 ryan/src/java/org/apache/solr/handler/component/SearchComponent.java
  26. +2 −2 ryan/src/java/org/apache/solr/handler/component/SpellCheckComponent.java
  27. +1 −1  ryan/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java
  28. +1 −1  ryan/src/java/org/apache/solr/highlight/SolrHighlighter.java
  29. +1 −1  ryan/src/java/org/apache/solr/request/XSLTResponseWriter.java
  30. +13 −5 ryan/src/java/org/apache/solr/schema/IndexSchema.java
  31. +2 −2 ryan/src/java/org/apache/solr/search/CacheConfig.java
  32. +1 −1  ryan/src/java/org/apache/solr/search/DisMaxQParserPlugin.java
  33. +3 −2 ryan/src/java/org/apache/solr/search/QueryParsing.java
  34. +29 −21 ryan/src/java/org/apache/solr/search/SolrIndexSearcher.java
  35. +1 −1  ryan/src/java/org/apache/solr/spelling/FileBasedSpellChecker.java
  36. +6 −2 ryan/src/java/org/apache/solr/update/DirectUpdateHandler2.java
  37. +1 −0  ryan/src/java/org/apache/solr/update/SolrIndexWriter.java
  38. +13 −48 ryan/src/java/org/apache/solr/update/UpdateHandler.java
  39. +1 −1  ryan/src/java/org/apache/solr/util/AbstractSolrTestCase.java
  40. +7 −5 ryan/src/java/org/apache/solr/util/TestHarness.java
  41. +1 −1  ryan/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java
  42. +1 −1  ryan/src/java/org/apache/solr/util/xslt/TransformerProvider.java
  43. +2 −2 ryan/src/test/org/apache/solr/BasicFunctionalityTest.java
  44. +1 −1  ryan/src/test/org/apache/solr/analysis/AnalysisTestCase.java
  45. +1 −0  ryan/src/test/org/apache/solr/core/ResourceLoaderTest.java
  46. +1 −0  ryan/src/test/org/apache/solr/core/TestBadConfig.java
  47. +1 −15 ryan/src/test/org/apache/solr/core/TestConfig.java
  48. +1 −1  ryan/src/test/org/apache/solr/core/TestJmxMonitoredMap.java
  49. +1 −1  ryan/src/test/org/apache/solr/highlight/DummyHighlighter.java
  50. +1 −1  ryan/src/test/org/apache/solr/schema/BadIndexSchemaTest.java
  51. +1 −1  ryan/src/test/org/apache/solr/servlet/SolrRequestParserTest.java
  52. +1 −49 ryan/src/webapp/src/org/apache/solr/servlet/DirectSolrConnection.java
  53. +4 −2 ryan/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java
  54. +6 −12 ryan/src/webapp/src/org/apache/solr/servlet/SolrRequestParsers.java
  55. +5 −5 ryan/src/webapp/src/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java
  56. +2 −2 ryan/src/webapp/web/admin/_info.jsp
  57. +2 −6 ryan/src/webapp/web/admin/index.jsp
View
4 ryan/contrib/dataimporthandler/src/main/java/org/apache/solr/handler/dataimport/DataImportHandler.java
@@ -24,9 +24,9 @@
import org.apache.solr.common.params.UpdateParams;
import org.apache.solr.common.util.ContentStreamBase;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.core.SolrConfig;
+import org.apache.solr.config.SolrConfig;
+import org.apache.solr.config.SolrResourceLoader;
import org.apache.solr.core.SolrCore;
-import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.RequestHandlerUtils;
import org.apache.solr.request.RawResponseWriter;
View
2  ryan/contrib/dataimporthandler/src/main/java/org/apache/solr/handler/dataimport/DataImporter.java
@@ -17,7 +17,7 @@
package org.apache.solr.handler.dataimport;
-import org.apache.solr.core.SolrConfig;
+import org.apache.solr.config.SolrConfig;
import org.apache.solr.core.SolrCore;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.IndexSchema;
View
3  ryan/src/java/org/apache/solr/core/Config.java → ryan/src/java/org/apache/solr/config/Config.java
@@ -15,13 +15,14 @@
* limitations under the License.
*/
-package org.apache.solr.core;
+package org.apache.solr.config;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.DOMUtil;
+
import javax.xml.parsers.*;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
View
8 ...src/java/org/apache/solr/core/CoreDescriptor.java → ...c/java/org/apache/solr/config/CoreDescriptor.java
@@ -15,10 +15,12 @@
* limitations under the License.
*/
-package org.apache.solr.core;
+package org.apache.solr.config;
import java.util.Properties;
+import org.apache.solr.core.CoreContainer;
+
/**
* A Solr core descriptor
*
@@ -117,7 +119,7 @@ public CoreContainer getCoreContainer() {
return coreContainer;
}
- Properties getCoreProperties() {
+ public Properties getCoreProperties() {
return coreProperties;
}
@@ -129,7 +131,7 @@ Properties getCoreProperties() {
*
* @param coreProperties
*/
- void setCoreProperties(Properties coreProperties) {
+ public void setCoreProperties(Properties coreProperties) {
if (this.coreProperties == null) {
Properties p = initImplicitProperties();
this.coreProperties = new Properties(p);
View
576 ryan/src/java/org/apache/solr/config/CoreInitalizer.java
@@ -0,0 +1,576 @@
+package org.apache.solr.config;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.apache.lucene.index.IndexDeletionPolicy;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.solr.common.ResourceLoader;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.DOMUtil;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.IndexDeletionPolicyWrapper;
+import org.apache.solr.core.JmxMonitoredMap;
+import org.apache.solr.core.RequestHandlers;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.SolrDeletionPolicy;
+import org.apache.solr.core.SolrEventListener;
+import org.apache.solr.core.SolrInfoMBean;
+import org.apache.solr.handler.StandardRequestHandler;
+import org.apache.solr.handler.component.DebugComponent;
+import org.apache.solr.handler.component.FacetComponent;
+import org.apache.solr.handler.component.HighlightComponent;
+import org.apache.solr.handler.component.MoreLikeThisComponent;
+import org.apache.solr.handler.component.QueryComponent;
+import org.apache.solr.handler.component.SearchComponent;
+import org.apache.solr.highlight.DefaultSolrHighlighter;
+import org.apache.solr.highlight.SolrHighlighter;
+import org.apache.solr.request.BinaryResponseWriter;
+import org.apache.solr.request.JSONResponseWriter;
+import org.apache.solr.request.PythonResponseWriter;
+import org.apache.solr.request.QueryResponseWriter;
+import org.apache.solr.request.RawResponseWriter;
+import org.apache.solr.request.RubyResponseWriter;
+import org.apache.solr.request.SolrRequestHandler;
+import org.apache.solr.request.XMLResponseWriter;
+import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.search.QParserPlugin;
+import org.apache.solr.search.ValueSourceParser;
+import org.apache.solr.update.UpdateHandler;
+import org.apache.solr.update.processor.LogUpdateProcessorFactory;
+import org.apache.solr.update.processor.RunUpdateProcessorFactory;
+import org.apache.solr.update.processor.UpdateRequestProcessorChain;
+import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
+import org.apache.solr.util.plugin.AbstractPluginLoader;
+import org.apache.solr.util.plugin.NamedListInitializedPlugin;
+import org.apache.solr.util.plugin.NamedListPluginLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+public class CoreInitalizer
+{
+ public static Logger log = LoggerFactory.getLogger(CoreInitalizer.class);
+ private final SolrConfig solrConfig;
+ private final CoreDescriptor coreDescriptor;
+ private final CoreVars vars;
+
+ public CoreInitalizer(String dataDir, IndexSchema schema) throws ParserConfigurationException, IOException, SAXException {
+ this(null, dataDir, new SolrConfig(), schema, null );
+ }
+
+ /**
+ * Creates a new core and register it in the list of cores.
+ * If a core with the same name already exists, it will be stopped and replaced by this one.
+ *@param dataDir the index directory
+ *@param config a solr config instance
+ *@param schema a solr schema instance
+ *
+ *@since solr 1.3
+ */
+ public CoreInitalizer(String name, String dataDir, SolrConfig config, IndexSchema schema, CoreDescriptor cd)
+ {
+ vars = new CoreVars();
+ vars.initalizer = this;
+ this.solrConfig = config;
+ vars.configuration = config.vars;
+ this.coreDescriptor = cd;
+
+ SolrResourceLoader loader = config.getResourceLoader();
+ if (dataDir == null)
+ dataDir = config.get("dataDir",loader.getInstanceDir()+"data/");
+ vars.configuration.dataDir = SolrResourceLoader.normalizeDir(dataDir);
+
+
+// updateHandler = createUpdateHandler(
+// solrConfig.get("updateHandler/@class", DirectUpdateHandler2.class.getName())
+// );
+
+ if (vars.configuration.getJmxConfig().enabled) {
+ vars.infoRegistry = new JmxMonitoredMap<String, SolrInfoMBean>(name, vars.configuration.getJmxConfig() );
+ }
+ else {
+ log.info("JMX monitoring not detected for core: " + name);
+ vars.infoRegistry = new LinkedHashMap<String, SolrInfoMBean>();
+ }
+
+ vars.highlighter = createHighlighter(
+ solrConfig.get("highlighting/@class", DefaultSolrHighlighter.class.getName())
+ );
+ vars.highlighter.initalize( solrConfig );
+
+ if( schema == null ) {
+ vars.schema = new IndexSchema(config, config.vars, IndexSchema.DEFAULT_SCHEMA_FILE, null);
+ }
+ else {
+ vars.schema = schema;
+ }
+
+
+ // set the cache regenerators...
+ org.apache.solr.search.SolrIndexSearcher.initRegenerators(vars.configuration);
+
+ vars.reqHandlers = initHandlersFromConfig(config);
+
+ initWriters();
+ initQParsers();
+ initValueSourceParsers();
+ parseListeners();
+ vars.solrDelPolicy = initDeletionPolicy();
+ parseEventListeners();
+
+ vars.searchComponents = loadSearchComponents( config );
+
+ // Processors initialized before the handlers
+ vars.updateProcessorChains = loadUpdateProcessorChains();
+
+ }
+
+ public SolrCore initalizeCore( String name )
+ {
+ SolrCore core = new SolrCore( name, vars );
+
+ // now go through and inform everything...
+
+ // Finally tell anyone who wants to know
+ SolrResourceLoader loader = solrConfig.getResourceLoader();
+ loader.inform( loader );
+ loader.inform( core );
+
+ return core;
+ }
+
+
+
+ static int boolean_query_max_clause_count = Integer.MIN_VALUE;
+ // only change the BooleanQuery maxClauseCount once for ALL cores...
+ void booleanQueryMaxClauseCount() {
+ synchronized(CoreVars.class) {
+ if (boolean_query_max_clause_count == Integer.MIN_VALUE) {
+ boolean_query_max_clause_count = vars.configuration.booleanQueryMaxClauseCount;
+ BooleanQuery.setMaxClauseCount(boolean_query_max_clause_count);
+ } else if (boolean_query_max_clause_count != vars.configuration.booleanQueryMaxClauseCount ) {
+ log.debug("BooleanQuery.maxClauseCount= " +boolean_query_max_clause_count+
+ ", ignoring " +vars.configuration.booleanQueryMaxClauseCount);
+ }
+ }
+ }
+
+
+ /** Creates an instance by trying a constructor that accepts a SolrCore before
+ * trying the default (no arg) constructor.
+ *@param className the instance class to create
+ *@cast the class or interface that the instance should extend or implement
+ *@param msg a message helping compose the exception error if any occurs.
+ *@return the desired instance
+ *@throws SolrException if the object could not be instantiated
+ */
+ private <T extends Object> T createInstance(String className, Class<T> cast, String msg) {
+ Class clazz = null;
+ if (msg == null) msg = "SolrCore Object";
+ try {
+ try {
+ clazz = solrConfig.getResourceLoader().findClass(className);
+ if (cast != null && !cast.isAssignableFrom(clazz))
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,"Error Instantiating "+msg+", "+className+ " is not a " +cast.getName());
+
+ java.lang.reflect.Constructor cons = clazz.getConstructor(new Class[]{SolrCore.class});
+ return (T) cons.newInstance(new Object[]{this});
+ } catch(NoSuchMethodException xnomethod) {
+ return (T) clazz.newInstance();
+ }
+ } catch (SolrException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,"Error Instantiating "+msg+", "+className+ " failed to instantiate " +cast.getName(), e);
+ }
+ }
+
+ public SolrEventListener createEventListener(String className) {
+ return createInstance(className, SolrEventListener.class, "Event Listener");
+ }
+
+ public SolrRequestHandler createRequestHandler(String className) {
+ return createInstance(className, SolrRequestHandler.class, "Request Handler");
+ }
+
+ private UpdateHandler createUpdateHandler(String className) {
+ return createInstance(className, UpdateHandler.class, "Update Handler");
+ }
+
+ private SolrHighlighter createHighlighter(String className) {
+ return createInstance(className, SolrHighlighter.class, "Highlighter");
+ }
+
+
+ /**
+ * Load the request processors configured in solrconfig.xml
+ */
+ private Map<String,UpdateRequestProcessorChain> loadUpdateProcessorChains() {
+ final Map<String,UpdateRequestProcessorChain> map = new HashMap<String, UpdateRequestProcessorChain>();
+
+ final String parsingErrorText = "Parsing Update Request Processor Chain";
+ UpdateRequestProcessorChain def = null;
+
+ // This is kinda ugly, but at least it keeps the xpath logic in one place
+ // away from the Processors themselves.
+ XPath xpath = solrConfig.getXPath();
+ NodeList nodes = (NodeList)solrConfig.evaluate("updateRequestProcessorChain", XPathConstants.NODESET);
+ boolean requireName = nodes.getLength() > 1;
+ if (nodes !=null ) {
+ for (int i=0; i<nodes.getLength(); i++) {
+ Node node = nodes.item(i);
+ String name = DOMUtil.getAttr(node,"name", requireName?parsingErrorText:null);
+ boolean isDefault = "true".equals( DOMUtil.getAttr(node,"default", null ) );
+
+ NodeList links = null;
+ try {
+ links = (NodeList)xpath.evaluate("processor", node, XPathConstants.NODESET);
+ }
+ catch (XPathExpressionException e) {
+ throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Error reading processors",e,false);
+ }
+ if( links == null || links.getLength() < 1 ) {
+ throw new RuntimeException( "updateRequestProcessorChain require at least one processor");
+ }
+
+ // keep a list of the factories...
+ final ArrayList<UpdateRequestProcessorFactory> factories = new ArrayList<UpdateRequestProcessorFactory>(links.getLength());
+ // Load and initialize the plugin chain
+ AbstractPluginLoader<UpdateRequestProcessorFactory> loader
+ = new AbstractPluginLoader<UpdateRequestProcessorFactory>( "processor chain", false, false ) {
+ @Override
+ protected void init(UpdateRequestProcessorFactory plugin, Node node) throws Exception {
+ plugin.init( (node==null)?null:DOMUtil.childNodesToNamedList(node) );
+ }
+
+ @Override
+ protected UpdateRequestProcessorFactory register(String name, UpdateRequestProcessorFactory plugin) throws Exception {
+ factories.add( plugin );
+ return null;
+ }
+ };
+ loader.load( solrConfig.getResourceLoader(), links );
+
+
+ UpdateRequestProcessorChain chain = new UpdateRequestProcessorChain(
+ factories.toArray( new UpdateRequestProcessorFactory[factories.size()] ) );
+ if( isDefault || nodes.getLength()==1 ) {
+ def = chain;
+ }
+ if( name != null ) {
+ map.put(name, chain);
+ }
+ }
+ }
+
+ if( def == null ) {
+ // construct the default chain
+ UpdateRequestProcessorFactory[] factories = new UpdateRequestProcessorFactory[] {
+ new RunUpdateProcessorFactory(),
+ new LogUpdateProcessorFactory()
+ };
+ def = new UpdateRequestProcessorChain( factories );
+ }
+ map.put( null, def );
+ map.put( "", def );
+ return map;
+ }
+
+
+ /**
+ * Register the default search components
+ */
+ private static Map<String, SearchComponent> loadSearchComponents( SolrConfig config )
+ {
+ Map<String, SearchComponent> components = new HashMap<String, SearchComponent>();
+
+ String xpath = "searchComponent";
+ NamedListPluginLoader<SearchComponent> loader = new NamedListPluginLoader<SearchComponent>( xpath, components );
+ loader.load( config.getResourceLoader(), (NodeList)config.evaluate( xpath, XPathConstants.NODESET ) );
+
+ final Map<String,Class<? extends SearchComponent>> standardcomponents
+ = new HashMap<String, Class<? extends SearchComponent>>();
+ standardcomponents.put( QueryComponent.COMPONENT_NAME, QueryComponent.class );
+ standardcomponents.put( FacetComponent.COMPONENT_NAME, FacetComponent.class );
+ standardcomponents.put( MoreLikeThisComponent.COMPONENT_NAME, MoreLikeThisComponent.class );
+ standardcomponents.put( HighlightComponent.COMPONENT_NAME, HighlightComponent.class );
+ standardcomponents.put( DebugComponent.COMPONENT_NAME, DebugComponent.class );
+ for( Map.Entry<String, Class<? extends SearchComponent>> entry : standardcomponents.entrySet() ) {
+ if( components.get( entry.getKey() ) == null ) {
+ try {
+ SearchComponent comp = entry.getValue().newInstance();
+ comp.init( null ); // default components initialized with nothing
+ components.put( entry.getKey(), comp );
+ }
+ catch (Exception e) {
+ SolrConfig.severeErrors.add( e );
+ SolrException.logOnce(log,null,e);
+ }
+ }
+ }
+ return components;
+ }
+
+
+ private IndexDeletionPolicyWrapper initDeletionPolicy() {
+ String className = solrConfig.get("mainIndex/deletionPolicy/@class", SolrDeletionPolicy.class.getName());
+ IndexDeletionPolicy delPolicy = createInstance(className, IndexDeletionPolicy.class, "Deletion Policy for SOLR");
+
+ Node node = (Node) solrConfig.evaluate("mainIndex/deletionPolicy", XPathConstants.NODE);
+ if (node != null) {
+ if (delPolicy instanceof NamedListInitializedPlugin)
+ ((NamedListInitializedPlugin) delPolicy).init(DOMUtil.childNodesToNamedList(node));
+ }
+ return new IndexDeletionPolicyWrapper(delPolicy);
+ }
+
+ public List<SolrEventListener> parseListener(String path) {
+ List<SolrEventListener> lst = new ArrayList<SolrEventListener>();
+ log.info( "Searching for listeners: " +path);
+ NodeList nodes = (NodeList)solrConfig.evaluate(path, XPathConstants.NODESET);
+ if (nodes!=null) {
+ for (int i=0; i<nodes.getLength(); i++) {
+ Node node = nodes.item(i);
+ String className = DOMUtil.getAttr(node,"class");
+ SolrEventListener listener = createEventListener(className);
+ listener.init(DOMUtil.childNodesToNamedList(node));
+ lst.add(listener);
+ log.info( "Added SolrEventListener: " + listener);
+ }
+ }
+ return lst;
+ }
+
+
+ private void parseListeners() {
+ vars.firstSearcherListeners = parseListener("//listener[@event=\"firstSearcher\"]");
+ vars.newSearcherListeners = parseListener("//listener[@event=\"newSearcher\"]");
+ }
+
+
+ /** Configure the query response writers. There will always be a default writer; additional
+ * writers may also be configured. */
+ private void initWriters() {
+ String xpath = "queryResponseWriter";
+ NodeList nodes = (NodeList) solrConfig.evaluate(xpath, XPathConstants.NODESET);
+
+ NamedListPluginLoader<QueryResponseWriter> loader =
+ new NamedListPluginLoader<QueryResponseWriter>( "[solrconfig.xml] "+xpath, vars.responseWriters );
+
+ vars.defaultResponseWriter = loader.load( solrConfig.getResourceLoader(), nodes );
+
+ // configure the default response writer; this one should never be null
+ if (vars.defaultResponseWriter == null) {
+ vars.defaultResponseWriter = vars.responseWriters.get("standard");
+ if( vars.defaultResponseWriter == null ) {
+ vars.defaultResponseWriter = new XMLResponseWriter();
+ }
+ }
+
+ // make JSON response writers available by default
+ if (vars.responseWriters.get("json")==null) {
+ vars.responseWriters.put("json", new JSONResponseWriter());
+ }
+ if (vars.responseWriters.get("python")==null) {
+ vars.responseWriters.put("python", new PythonResponseWriter());
+ }
+ if (vars.responseWriters.get("ruby")==null) {
+ vars.responseWriters.put("ruby", new RubyResponseWriter());
+ }
+ if (vars.responseWriters.get("raw")==null) {
+ vars.responseWriters.put("raw", new RawResponseWriter());
+ }
+ if (vars.responseWriters.get("javabin") == null) {
+ vars.responseWriters.put("javabin", new BinaryResponseWriter());
+ }
+ }
+
+
+ /** Configure the query parsers. */
+ private void initQParsers() {
+ String xpath = "queryParser";
+ NodeList nodes = (NodeList) solrConfig.evaluate(xpath, XPathConstants.NODESET);
+
+ NamedListPluginLoader<QParserPlugin> loader =
+ new NamedListPluginLoader<QParserPlugin>( "[solrconfig.xml] "+xpath, vars.qParserPlugins);
+
+ loader.load( solrConfig.getResourceLoader(), nodes );
+
+ // default parsers
+ for (int i=0; i<QParserPlugin.standardPlugins.length; i+=2) {
+ try {
+ String name = (String)QParserPlugin.standardPlugins[i];
+ if (null == vars.qParserPlugins.get(name)) {
+ Class<QParserPlugin> clazz = (Class<QParserPlugin>)QParserPlugin.standardPlugins[i+1];
+ QParserPlugin plugin = clazz.newInstance();
+ vars.qParserPlugins.put(name, plugin);
+ plugin.init(null);
+ }
+ } catch (Exception e) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
+ }
+ }
+ }
+
+
+
+ /** Configure the ValueSource (function) plugins */
+ private void initValueSourceParsers() {
+ String xpath = "valueSourceParser";
+ NodeList nodes = (NodeList) solrConfig.evaluate(xpath, XPathConstants.NODESET);
+
+ NamedListPluginLoader<ValueSourceParser> loader =
+ new NamedListPluginLoader<ValueSourceParser>( "[solrconfig.xml] "+xpath, vars.valueSourceParsers);
+
+ loader.load( solrConfig.getResourceLoader(), nodes );
+
+ // default value source parsers
+ for (Map.Entry<String, ValueSourceParser> entry : ValueSourceParser.standardValueSourceParsers.entrySet()) {
+ try {
+ String name = entry.getKey();
+ if (null == vars.valueSourceParsers.get(name)) {
+ ValueSourceParser valueSourceParser = entry.getValue();
+ vars.valueSourceParsers.put(name, valueSourceParser);
+ valueSourceParser.init(null);
+ }
+ } catch (Exception e) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
+ }
+ }
+ }
+
+
+ /**
+ * Read solrconfig.xml and register the appropriate handlers
+ *
+ * This function should <b>only</b> be called from the SolrCore constructor. It is
+ * not intended as a public API.
+ *
+ * While the normal runtime registration contract is that handlers MUST be initialized
+ * before they are registered, this function does not do that exactly.
+ *
+ * This function registers all handlers first and then calls init() for each one.
+ *
+ * This is OK because this function is only called at startup and there is no chance that
+ * a handler could be asked to handle a request before it is initialized.
+ *
+ * The advantage to this approach is that handlers can know what path they are registered
+ * to and what other handlers are available at startup.
+ *
+ * Handlers will be registered and initialized in the order they appear in solrconfig.xml
+ */
+ private RequestHandlers initHandlersFromConfig( final Config config )
+ {
+ final RequestHandlers handlers = new RequestHandlers( vars.infoRegistry );
+ AbstractPluginLoader<SolrRequestHandler> loader =
+ new AbstractPluginLoader<SolrRequestHandler>( "[solrconfig.xml] requestHandler", true, true )
+ {
+ @Override
+ protected SolrRequestHandler create( ResourceLoader config, String name, String className, Node node ) throws Exception
+ {
+ String startup = DOMUtil.getAttr( node, "startup" );
+ if( startup != null ) {
+ if( "lazy".equals( startup ) ) {
+ log.info("adding lazy requestHandler: " + className );
+ NamedList args = DOMUtil.childNodesToNamedList(node);
+ log.error( "Can't handler lazy loading yet...." );
+ return super.create( config, name, className, node );
+ //return new LazyRequestHandlerWrapper( core, className, args );
+ }
+ else {
+ throw new Exception( "Unknown startup value: '"+startup+"' for: "+className );
+ }
+ }
+ return super.create( config, name, className, node );
+ }
+
+ @Override
+ protected SolrRequestHandler register(String name, SolrRequestHandler plugin) throws Exception {
+ return handlers.register( name, plugin );
+ }
+
+ @Override
+ protected void init(SolrRequestHandler plugin, Node node ) throws Exception {
+ plugin.init( DOMUtil.childNodesToNamedList(node) );
+ }
+ };
+
+ NodeList nodes = (NodeList)config.evaluate("requestHandler", XPathConstants.NODESET);
+
+ // Load the handlers and get the default one
+ SolrRequestHandler defaultHandler = loader.load( config.getResourceLoader(), nodes );
+ if( defaultHandler == null ) {
+ defaultHandler = handlers.get(RequestHandlers.DEFAULT_HANDLER_NAME);
+ if( defaultHandler == null ) {
+ defaultHandler = new StandardRequestHandler();
+ handlers.register(RequestHandlers.DEFAULT_HANDLER_NAME, defaultHandler);
+ }
+ }
+ handlers.register(null, defaultHandler);
+ handlers.register("", defaultHandler);
+ return handlers;
+ }
+
+
+
+ // FROM UPDATE HANDLER
+ private void parseEventListeners() {
+ NodeList nodes = (NodeList) solrConfig.evaluate("updateHandler/listener[@event=\"postCommit\"]", XPathConstants.NODESET);
+ if (nodes!=null) {
+ for (int i=0; i<nodes.getLength(); i++) {
+ Node node = nodes.item(i);
+ try {
+ String className = DOMUtil.getAttr(node,"class");
+ SolrEventListener listener = createEventListener(className);
+ listener.init(DOMUtil.childNodesToNamedList(node));
+ // listener.init(DOMUtil.toMapExcept(node.getAttributes(),"class","synchronized"));
+ vars.commitCallbacks.add(listener);
+ log.info("added SolrEventListener for postCommit: " + listener);
+ } catch (Exception e) {
+ throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"error parsing event listevers", e, false);
+ }
+ }
+ }
+ nodes = (NodeList) solrConfig.evaluate("updateHandler/listener[@event=\"postOptimize\"]", XPathConstants.NODESET);
+ if (nodes!=null) {
+ for (int i=0; i<nodes.getLength(); i++) {
+ Node node = nodes.item(i);
+ try {
+ String className = DOMUtil.getAttr(node,"class");
+ SolrEventListener listener = createEventListener(className);
+ listener.init(DOMUtil.childNodesToNamedList(node));
+ vars.optimizeCallbacks.add(listener);
+ log.info("added SolarEventListener for postOptimize: " + listener);
+ } catch (Exception e) {
+ throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"error parsing event listeners", e, false);
+ }
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------------
+ //--------------------------------------------------------------------------
+
+
+ public SolrConfig getSolrConfig() {
+ return solrConfig;
+ }
+
+
+ public CoreDescriptor getCoreDescriptor() {
+ return coreDescriptor;
+ }
+}
View
148 ryan/src/java/org/apache/solr/config/CoreVars.java
@@ -0,0 +1,148 @@
+package org.apache.solr.config;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.solr.core.IndexDeletionPolicyWrapper;
+import org.apache.solr.core.RequestHandlers;
+import org.apache.solr.core.SolrEventListener;
+import org.apache.solr.core.SolrInfoMBean;
+import org.apache.solr.handler.component.SearchComponent;
+import org.apache.solr.highlight.SolrHighlighter;
+import org.apache.solr.request.QueryResponseWriter;
+import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.search.QParserPlugin;
+import org.apache.solr.search.ValueSourceParser;
+import org.apache.solr.update.processor.UpdateRequestProcessorChain;
+
+public class CoreVars {
+ CoreInitalizer initalizer;
+ SolrConfiguraion configuration;
+ IndexSchema schema;
+
+ RequestHandlers reqHandlers;
+ SolrHighlighter highlighter;
+ Map<String,SearchComponent> searchComponents;
+ Map<String,UpdateRequestProcessorChain> updateProcessorChains;
+ Map<String, SolrInfoMBean> infoRegistry;
+ IndexDeletionPolicyWrapper solrDelPolicy;
+ QueryResponseWriter defaultResponseWriter;
+
+ Map<String, QueryResponseWriter> responseWriters = new HashMap<String, QueryResponseWriter>();
+ Map<String, QParserPlugin> qParserPlugins = new HashMap<String, QParserPlugin>();
+ HashMap<String, ValueSourceParser> valueSourceParsers = new HashMap<String, ValueSourceParser>();
+
+ List<SolrEventListener> firstSearcherListeners;
+ List<SolrEventListener> newSearcherListeners;
+
+ List<SolrEventListener> commitCallbacks = new ArrayList<SolrEventListener>();
+ List<SolrEventListener> optimizeCallbacks = new ArrayList<SolrEventListener>();
+
+
+ public RequestHandlers getReqHandlers() {
+ return reqHandlers;
+ }
+ public void setReqHandlers(RequestHandlers reqHandlers) {
+ this.reqHandlers = reqHandlers;
+ }
+ public SolrHighlighter getHighlighter() {
+ return highlighter;
+ }
+ public void setHighlighter(SolrHighlighter highlighter) {
+ this.highlighter = highlighter;
+ }
+ public Map<String, SearchComponent> getSearchComponents() {
+ return searchComponents;
+ }
+ public void setSearchComponents(Map<String, SearchComponent> searchComponents) {
+ this.searchComponents = searchComponents;
+ }
+ public Map<String, UpdateRequestProcessorChain> getUpdateProcessorChains() {
+ return updateProcessorChains;
+ }
+ public void setUpdateProcessorChains(
+ Map<String, UpdateRequestProcessorChain> updateProcessorChains) {
+ this.updateProcessorChains = updateProcessorChains;
+ }
+ public Map<String, SolrInfoMBean> getInfoRegistry() {
+ return infoRegistry;
+ }
+ public void setInfoRegistry(Map<String, SolrInfoMBean> infoRegistry) {
+ this.infoRegistry = infoRegistry;
+ }
+ public IndexDeletionPolicyWrapper getSolrDelPolicy() {
+ return solrDelPolicy;
+ }
+ public void setSolrDelPolicy(IndexDeletionPolicyWrapper solrDelPolicy) {
+ this.solrDelPolicy = solrDelPolicy;
+ }
+ public QueryResponseWriter getDefaultResponseWriter() {
+ return defaultResponseWriter;
+ }
+ public void setDefaultResponseWriter(QueryResponseWriter defaultResponseWriter) {
+ this.defaultResponseWriter = defaultResponseWriter;
+ }
+ public CoreInitalizer getInitalizer() {
+ return initalizer;
+ }
+ public void setInitalizer(CoreInitalizer initalizer) {
+ this.initalizer = initalizer;
+ }
+ public SolrConfiguraion getConfiguration() {
+ return configuration;
+ }
+ public void setConfiguration(SolrConfiguraion configuration) {
+ this.configuration = configuration;
+ }
+ public IndexSchema getSchema() {
+ return schema;
+ }
+ public void setSchema(IndexSchema schema) {
+ this.schema = schema;
+ }
+ public Map<String, QueryResponseWriter> getResponseWriters() {
+ return responseWriters;
+ }
+ public void setResponseWriters(Map<String, QueryResponseWriter> responseWriters) {
+ this.responseWriters = responseWriters;
+ }
+ public Map<String, QParserPlugin> getQParserPlugins() {
+ return qParserPlugins;
+ }
+ public void setQParserPlugins(Map<String, QParserPlugin> parserPlugins) {
+ qParserPlugins = parserPlugins;
+ }
+ public HashMap<String, ValueSourceParser> getValueSourceParsers() {
+ return valueSourceParsers;
+ }
+ public void setValueSourceParsers(
+ HashMap<String, ValueSourceParser> valueSourceParsers) {
+ this.valueSourceParsers = valueSourceParsers;
+ }
+ public List<SolrEventListener> getFirstSearcherListeners() {
+ return firstSearcherListeners;
+ }
+ public void setFirstSearcherListeners(
+ List<SolrEventListener> firstSearcherListeners) {
+ this.firstSearcherListeners = firstSearcherListeners;
+ }
+ public List<SolrEventListener> getNewSearcherListeners() {
+ return newSearcherListeners;
+ }
+ public void setNewSearcherListeners(List<SolrEventListener> newSearcherListeners) {
+ this.newSearcherListeners = newSearcherListeners;
+ }
+ public List<SolrEventListener> getCommitCallbacks() {
+ return commitCallbacks;
+ }
+ public void setCommitCallbacks(List<SolrEventListener> commitCallbacks) {
+ this.commitCallbacks = commitCallbacks;
+ }
+ public List<SolrEventListener> getOptimizeCallbacks() {
+ return optimizeCallbacks;
+ }
+ public void setOptimizeCallbacks(List<SolrEventListener> optimizeCallbacks) {
+ this.optimizeCallbacks = optimizeCallbacks;
+ }
+}
View
34 ryan/src/java/org/apache/solr/config/HttpCachingConfiguration.java
@@ -0,0 +1,34 @@
+package org.apache.solr.config;
+
+import org.apache.solr.core.SolrCore;
+
+public class HttpCachingConfiguration
+{
+ public static enum LastModFrom {
+ OPENTIME, DIRLASTMOD, BOGUS;
+
+ /** Input must not be null */
+ public static LastModFrom parse(final String s) {
+ try {
+ return valueOf(s.toUpperCase());
+ } catch (Exception e) {
+ SolrCore.log.warn( "Unrecognized value for lastModFrom: " + s, e);
+ return BOGUS;
+ }
+ }
+ }
+
+ boolean never304;
+ String etagSeed;
+ String cacheControlHeader;
+ Long maxAge;
+ LastModFrom lastModFrom;
+
+ public boolean isNever304() { return never304; }
+ public String getEtagSeed() { return etagSeed; }
+ /** null if no Cache-Control header */
+ public String getCacheControlHeader() { return cacheControlHeader; }
+ /** null if no max age limitation */
+ public Long getMaxAge() { return maxAge; }
+ public LastModFrom getLastModFrom() { return lastModFrom; }
+}
View
14 ryan/src/java/org/apache/solr/config/JmxConfiguration.java
@@ -0,0 +1,14 @@
+package org.apache.solr.config;
+
+public class JmxConfiguration
+{
+ public final boolean enabled;
+ public final String agentId;
+ public final String serviceUrl;
+
+ public JmxConfiguration(boolean enabled, String agentId, String serviceUrl) {
+ this.enabled = enabled;
+ this.agentId = agentId;
+ this.serviceUrl = serviceUrl;
+ }
+}
View
26 ryan/src/java/org/apache/solr/config/RequestDispatcherConfiguration.java
@@ -0,0 +1,26 @@
+package org.apache.solr.config;
+
+public class RequestDispatcherConfiguration {
+ long uploadLimitKB = Long.MAX_VALUE;
+ boolean enableRemoteStreams = true;
+ boolean handleSelect = true;
+
+ public long getUploadLimitKB() {
+ return uploadLimitKB;
+ }
+ public void setUploadLimitKB(long uploadLimitKB) {
+ this.uploadLimitKB = uploadLimitKB;
+ }
+ public boolean isEnableRemoteStreams() {
+ return enableRemoteStreams;
+ }
+ public void setEnableRemoteStreams(boolean enableRemoteStreams) {
+ this.enableRemoteStreams = enableRemoteStreams;
+ }
+ public boolean isHandleSelect() {
+ return handleSelect;
+ }
+ public void setHandleSelect(boolean handleSelect) {
+ this.handleSelect = handleSelect;
+ }
+}
View
193 ryan/src/java/org/apache/solr/config/SolrConfig.java
@@ -0,0 +1,193 @@
+/**
+ * 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.config;
+
+import org.apache.solr.config.HttpCachingConfiguration.LastModFrom;
+import org.apache.solr.search.CacheConfig;
+import org.apache.lucene.search.BooleanQuery;
+
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * Provides a static reference to a Config object modeling the main
+ * configuration data for a a Solr instance -- typically found in
+ * "solrconfig.xml".
+ *
+ * @version $Id$
+ */
+public class SolrConfig extends Config {
+
+ public static final String DEFAULT_CONF_FILE = "solrconfig.xml";
+
+ /**
+ * Singleton keeping track of configuration errors
+ */
+ public static final Collection<Throwable> severeErrors = new HashSet<Throwable>();
+ public final SolrConfiguraion vars = new SolrConfiguraion();
+
+ /** Creates a default instance from the solrconfig.xml. */
+ public SolrConfig()
+ throws ParserConfigurationException, IOException, SAXException {
+ this( (SolrResourceLoader) null, DEFAULT_CONF_FILE, null );
+ }
+
+ /** Creates a configuration instance from a configuration name.
+ * A default resource loader will be created (@see SolrResourceLoader)
+ *@param name the configuration name used by the loader
+ */
+ public SolrConfig(String name)
+ throws ParserConfigurationException, IOException, SAXException {
+ this( (SolrResourceLoader) null, name, null);
+ }
+
+ /** Creates a configuration instance from a configuration name and stream.
+ * A default resource loader will be created (@see SolrResourceLoader).
+ * If the stream is null, the resource loader will open the configuration stream.
+ * If the stream is not null, no attempt to load the resource will occur (the name is not used).
+ *@param name the configuration name
+ *@param is the configuration stream
+ */
+ public SolrConfig(String name, InputStream is)
+ throws ParserConfigurationException, IOException, SAXException {
+ this( (SolrResourceLoader) null, name, is );
+ }
+
+ /** Creates a configuration instance from an instance directory, configuration name and stream.
+ *@param instanceDir the directory used to create the resource loader
+ *@param name the configuration name used by the loader if the stream is null
+ *@param is the configuration stream
+ */
+ public SolrConfig(String instanceDir, String name, InputStream is)
+ throws ParserConfigurationException, IOException, SAXException {
+ this(new SolrResourceLoader(instanceDir), name, is);
+ }
+
+ /** Creates a configuration instance from a resource loader, a configuration name and a stream.
+ * If the stream is null, the resource loader will open the configuration stream.
+ * If the stream is not null, no attempt to load the resource will occur (the name is not used).
+ *@param loader the resource loader
+ *@param name the configuration name
+ *@param is the configuration stream
+ */
+ public SolrConfig(SolrResourceLoader loader, String name, InputStream is)
+ throws ParserConfigurationException, IOException, SAXException {
+ super(loader, name, is, "/config/");
+
+ vars.defaultIndexConfig = new SolrIndexConfig(this, null, null);
+ vars.mainIndexConfig = new SolrIndexConfig(this, "mainIndex", vars.defaultIndexConfig);
+
+ vars.booleanQueryMaxClauseCount = getInt("query/maxBooleanClauses", BooleanQuery.getMaxClauseCount());
+ vars.filtOptEnabled = getBool("query/boolTofilterOptimizer/@enabled", false);
+ vars.filtOptCacheSize = getInt("query/boolTofilterOptimizer/@cacheSize",32);
+ vars.filtOptThreshold = getFloat("query/boolTofilterOptimizer/@threshold",.05f);
+
+ vars.useFilterForSortedQuery = getBool("query/useFilterForSortedQuery", false);
+ vars.queryResultWindowSize = getInt("query/queryResultWindowSize", 1);
+ vars.queryResultMaxDocsCached = getInt("query/queryResultMaxDocsCached", Integer.MAX_VALUE);
+ vars.enableLazyFieldLoading = getBool("query/enableLazyFieldLoading", false);
+
+
+ vars.filterCacheConfig = CacheConfig.getConfig(this, "query/filterCache");
+ vars.queryResultCacheConfig = CacheConfig.getConfig(this, "query/queryResultCache");
+ vars.documentCacheConfig = CacheConfig.getConfig(this, "query/documentCache");
+ vars.userCacheConfigs = CacheConfig.getMultipleConfigs(this, "query/cache");
+
+ vars.hashSetInverseLoadFactor = 1.0f / getFloat("//HashDocSet/@loadFactor",0.75f);
+ vars.hashDocSetMaxSize= getInt("//HashDocSet/@maxSize",3000);
+
+ vars.useColdSearcher = getBool("query/useColdSearcher",false);
+ vars.maxWarmingSearchers = getInt("query/maxWarmingSearchers",Integer.MAX_VALUE);
+
+ vars.unlockOnStartup = getBool("mainIndex/unlockOnStartup", false);
+
+ RequestDispatcherConfiguration rdc = new RequestDispatcherConfiguration();
+ rdc.uploadLimitKB = getInt(
+ "requestDispatcher/requestParsers/@multipartUploadLimitInKB", (int)rdc.uploadLimitKB );
+
+ rdc.enableRemoteStreams = getBool(
+ "requestDispatcher/requestParsers/@enableRemoteStreaming", false );
+
+ // Let this filter take care of /select?xxx format
+ rdc.handleSelect = getBool(
+ "requestDispatcher/@handleSelect", rdc.handleSelect );
+ vars.dispatcherConfig = rdc;
+
+
+ // load HTTP
+ vars.httpCachingConfig = loadHttpCachingConfig();
+
+ Node jmx = getNode("jmx", false);
+ if (jmx != null) {
+ vars.jmxConfig = new JmxConfiguration(
+ true,
+ get("jmx/@agentId", null),
+ get("jmx/@serviceUrl", null) );
+ } else {
+ vars.jmxConfig = new JmxConfiguration(false, null, null);
+ }
+
+ Config.log.info("Loaded SolrConfig: " + name);
+ }
+
+ HttpCachingConfiguration loadHttpCachingConfig()
+ {
+ /** config xpath prefix for getting HTTP Caching options */
+ final String CACHE_PRE
+ = "requestDispatcher/httpCaching/";
+
+ /** For extracting Expires "ttl" from <cacheControl> config */
+ final Pattern MAX_AGE
+ = Pattern.compile("\\bmax-age=(\\d+)");
+
+
+ HttpCachingConfiguration cfg = new HttpCachingConfiguration();
+
+ cfg.never304 = this.getBool(CACHE_PRE+"@never304", false);
+ cfg.etagSeed = this.get(CACHE_PRE+"@etagSeed", "Solr");
+ cfg.lastModFrom = LastModFrom.parse( this.get(CACHE_PRE+"@lastModFrom","openTime") );
+ cfg.cacheControlHeader = this.get(CACHE_PRE+"cacheControl",null);
+
+ Long tmp = null; // maxAge
+ if (null != cfg.cacheControlHeader) {
+ try {
+ final Matcher ttlMatcher = MAX_AGE.matcher(cfg.cacheControlHeader);
+ final String ttlStr = ttlMatcher.find() ? ttlMatcher.group(1) : null;
+ tmp = (null != ttlStr && !"".equals(ttlStr))
+ ? Long.valueOf(ttlStr)
+ : null;
+ } catch (Exception e) {
+ log.warn( "Ignoring exception while attempting to " +
+ "extract max-age from cacheControl config: " +
+ cfg.cacheControlHeader, e);
+ }
+ }
+ cfg.maxAge = tmp;
+ return cfg;
+ }
+}
View
254 ryan/src/java/org/apache/solr/config/SolrConfiguraion.java
@@ -0,0 +1,254 @@
+/**
+ * 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.config;
+
+import org.apache.solr.search.CacheConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This should not care about XML!
+ *
+ * @version $Id: SolrConfig.java 701539 2008-10-03 21:26:50Z ryan $
+ */
+public class SolrConfiguraion {
+ public static Logger log = LoggerFactory.getLogger(SolrConfiguraion.class);
+
+ String dataDir;
+ int maxWarmingSearchers = Integer.MAX_VALUE;
+ boolean useColdSearcher = false;
+ boolean unlockOnStartup = false;
+
+ /* The set of materialized parameters: */
+ int booleanQueryMaxClauseCount;
+ // SolrIndexSearcher - nutch optimizer
+ boolean filtOptEnabled;
+ int filtOptCacheSize;
+ float filtOptThreshold;
+ // SolrIndexSearcher - caches configurations
+ CacheConfig filterCacheConfig ;
+ CacheConfig queryResultCacheConfig;
+ CacheConfig documentCacheConfig;
+ CacheConfig[] userCacheConfigs;
+ // SolrIndexSearcher - more...
+ boolean useFilterForSortedQuery;
+ int queryResultWindowSize;
+ int queryResultMaxDocsCached;
+ boolean enableLazyFieldLoading;
+ // DocSet
+ float hashSetInverseLoadFactor;
+ int hashDocSetMaxSize;
+ // default & main index configurations
+ SolrIndexConfig defaultIndexConfig;
+ SolrIndexConfig mainIndexConfig;
+
+ //JMX configuration
+ JmxConfiguration jmxConfig;
+
+ //HTTP config
+ HttpCachingConfiguration httpCachingConfig;
+ RequestDispatcherConfiguration dispatcherConfig;
+
+ //---------------------------------------------------------------------------------------
+ //---------------------------------------------------------------------------------------
+
+ public int getBooleanQueryMaxClauseCount() {
+ return booleanQueryMaxClauseCount;
+ }
+
+ public void setBooleanQueryMaxClauseCount(int booleanQueryMaxClauseCount) {
+ this.booleanQueryMaxClauseCount = booleanQueryMaxClauseCount;
+ }
+
+ public boolean isFiltOptEnabled() {
+ return filtOptEnabled;
+ }
+
+ public void setFiltOptEnabled(boolean filtOptEnabled) {
+ this.filtOptEnabled = filtOptEnabled;
+ }
+
+ public int getFiltOptCacheSize() {
+ return filtOptCacheSize;
+ }
+
+ public void setFiltOptCacheSize(int filtOptCacheSize) {
+ this.filtOptCacheSize = filtOptCacheSize;
+ }
+
+ public float getFiltOptThreshold() {
+ return filtOptThreshold;
+ }
+
+ public void setFiltOptThreshold(float filtOptThreshold) {
+ this.filtOptThreshold = filtOptThreshold;
+ }
+
+ public CacheConfig getFilterCacheConfig() {
+ return filterCacheConfig;
+ }
+
+ public void setFilterCacheConfig(CacheConfig filterCacheConfig) {
+ this.filterCacheConfig = filterCacheConfig;
+ }
+
+ public CacheConfig getQueryResultCacheConfig() {
+ return queryResultCacheConfig;
+ }
+
+ public void setQueryResultCacheConfig(CacheConfig queryResultCacheConfig) {
+ this.queryResultCacheConfig = queryResultCacheConfig;
+ }
+
+ public CacheConfig getDocumentCacheConfig() {
+ return documentCacheConfig;
+ }
+
+ public void setDocumentCacheConfig(CacheConfig documentCacheConfig) {
+ this.documentCacheConfig = documentCacheConfig;
+ }
+
+ public CacheConfig[] getUserCacheConfigs() {
+ return userCacheConfigs;
+ }
+
+ public void setUserCacheConfigs(CacheConfig[] userCacheConfigs) {
+ this.userCacheConfigs = userCacheConfigs;
+ }
+
+ public boolean isUseFilterForSortedQuery() {
+ return useFilterForSortedQuery;
+ }
+
+ public void setUseFilterForSortedQuery(boolean useFilterForSortedQuery) {
+ this.useFilterForSortedQuery = useFilterForSortedQuery;
+ }
+
+ public int getQueryResultWindowSize() {
+ return queryResultWindowSize;
+ }
+
+ public void setQueryResultWindowSize(int queryResultWindowSize) {
+ this.queryResultWindowSize = queryResultWindowSize;
+ }
+
+ public int getQueryResultMaxDocsCached() {
+ return queryResultMaxDocsCached;
+ }
+
+ public void setQueryResultMaxDocsCached(int queryResultMaxDocsCached) {
+ this.queryResultMaxDocsCached = queryResultMaxDocsCached;
+ }
+
+ public boolean isEnableLazyFieldLoading() {
+ return enableLazyFieldLoading;
+ }
+
+ public void setEnableLazyFieldLoading(boolean enableLazyFieldLoading) {
+ this.enableLazyFieldLoading = enableLazyFieldLoading;
+ }
+
+ public float getHashSetInverseLoadFactor() {
+ return hashSetInverseLoadFactor;
+ }
+
+ public void setHashSetInverseLoadFactor(float hashSetInverseLoadFactor) {
+ this.hashSetInverseLoadFactor = hashSetInverseLoadFactor;
+ }
+
+ public int getHashDocSetMaxSize() {
+ return hashDocSetMaxSize;
+ }
+
+ public void setHashDocSetMaxSize(int hashDocSetMaxSize) {
+ this.hashDocSetMaxSize = hashDocSetMaxSize;
+ }
+
+ public SolrIndexConfig getDefaultIndexConfig() {
+ return defaultIndexConfig;
+ }
+
+ public void setDefaultIndexConfig(SolrIndexConfig defaultIndexConfig) {
+ this.defaultIndexConfig = defaultIndexConfig;
+ }
+
+ public SolrIndexConfig getMainIndexConfig() {
+ return mainIndexConfig;
+ }
+
+ public void setMainIndexConfig(SolrIndexConfig mainIndexConfig) {
+ this.mainIndexConfig = mainIndexConfig;
+ }
+
+ public JmxConfiguration getJmxConfig() {
+ return jmxConfig;
+ }
+
+ public void setJmxConfig(JmxConfiguration jmxConfig) {
+ this.jmxConfig = jmxConfig;
+ }
+
+ public HttpCachingConfiguration getHttpCachingConfig() {
+ return httpCachingConfig;
+ }
+
+ public void setHttpCachingConfig(HttpCachingConfiguration httpCachingConfig) {
+ this.httpCachingConfig = httpCachingConfig;
+ }
+
+ public String getDataDir() {
+ return dataDir;
+ }
+
+ public void setDataDir(String dataDir) {
+ this.dataDir = dataDir;
+ }
+
+ public int getMaxWarmingSearchers() {
+ return maxWarmingSearchers;
+ }
+
+ public void setMaxWarmingSearchers(int maxWarmingSearchers) {
+ this.maxWarmingSearchers = maxWarmingSearchers;
+ }
+
+ public boolean isUseColdSearcher() {
+ return useColdSearcher;
+ }
+
+ public void setUseColdSearcher(boolean useColdSearcher) {
+ this.useColdSearcher = useColdSearcher;
+ }
+
+ public boolean isUnlockOnStartup() {
+ return unlockOnStartup;
+ }
+
+ public void setUnlockOnStartup(boolean unlockOnStartup) {
+ this.unlockOnStartup = unlockOnStartup;
+ }
+
+ public RequestDispatcherConfiguration getDispatcherConfig() {
+ return dispatcherConfig;
+ }
+
+ public void setDispatcherConfig(RequestDispatcherConfiguration dispatcherConfig) {
+ this.dispatcherConfig = dispatcherConfig;
+ }
+}
View
3  .../java/org/apache/solr/update/SolrIndexConfig.java → .../java/org/apache/solr/config/SolrIndexConfig.java
@@ -15,9 +15,8 @@
* limitations under the License.
*/
-package org.apache.solr.update;
+package org.apache.solr.config;
-import org.apache.solr.core.SolrConfig;
import org.apache.lucene.index.LogByteSizeMergePolicy;
import org.apache.lucene.index.ConcurrentMergeScheduler;
View
7 ...java/org/apache/solr/core/SolrResourceLoader.java → ...va/org/apache/solr/config/SolrResourceLoader.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.solr.core;
+package org.apache.solr.config;
import java.io.BufferedReader;
import java.io.File;
@@ -40,6 +40,7 @@
import org.apache.solr.analysis.TokenizerFactory;
import org.apache.solr.common.ResourceLoader;
import org.apache.solr.common.SolrException;
+import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.component.SearchComponent;
import org.apache.solr.request.QueryResponseWriter;
import org.apache.solr.request.SolrRequestHandler;
@@ -102,7 +103,7 @@ public SolrResourceLoader( String instanceDir, ClassLoader parent )
this(instanceDir, parent, null);
}
- static ClassLoader createClassLoader(File f, ClassLoader loader) {
+ public static ClassLoader createClassLoader(File f, ClassLoader loader) {
if( loader == null ) {
loader = Thread.currentThread().getContextClassLoader();
}
@@ -404,7 +405,7 @@ public String getInstanceDir() {
/**
* Utility function to throw an exception if the class is invalid
*/
- void assertAwareCompatibility( Class aware, Object obj )
+ public void assertAwareCompatibility( Class aware, Object obj )
{
Class[] valid = awareCompatibility.get( aware );
if( valid == null ) {
View
5 ryan/src/java/org/apache/solr/core/AbstractSolrEventListener.java
@@ -23,10 +23,7 @@
/**
*/
class AbstractSolrEventListener implements SolrEventListener {
- protected final SolrCore core;
- public AbstractSolrEventListener(SolrCore core) {
- this.core = core;
- }
+
protected NamedList args;
public void init(NamedList args) {
View
13 ryan/src/java/org/apache/solr/core/CoreContainer.java
@@ -38,6 +38,11 @@
import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.XML;
import org.apache.solr.common.util.StrUtils;
+import org.apache.solr.config.Config;
+import org.apache.solr.config.CoreDescriptor;
+import org.apache.solr.config.CoreInitalizer;
+import org.apache.solr.config.SolrConfig;
+import org.apache.solr.config.SolrResourceLoader;
import org.apache.solr.handler.admin.CoreAdminHandler;
import org.apache.solr.schema.IndexSchema;
import org.w3c.dom.Node;
@@ -117,7 +122,8 @@ public CoreContainer initialize() throws IOException, ParserConfigurationExcepti
cores = new CoreContainer(new SolrResourceLoader(instanceDir));
SolrConfig cfg = solrConfigFilename == null ? new SolrConfig() : new SolrConfig(solrConfigFilename);
CoreDescriptor dcore = new CoreDescriptor(cores, "", ".");
- SolrCore singlecore = new SolrCore(null, null, cfg, null, dcore);
+ CoreInitalizer initilizer = new CoreInitalizer(null, null, cfg, null, dcore);
+ SolrCore singlecore = initilizer.initalizeCore( "core" );
abortOnConfigurationError = cfg.getBool(
"abortOnConfigurationError", abortOnConfigurationError);
cores.register("", singlecore, false);
@@ -332,8 +338,9 @@ public SolrCore create(CoreDescriptor dcore) throws ParserConfigurationExceptio
// Initialize the solr config
SolrResourceLoader solrLoader = new SolrResourceLoader(instanceDir, libLoader, dcore.getCoreProperties());
SolrConfig config = new SolrConfig(solrLoader, dcore.getConfigName(), null);
- IndexSchema schema = new IndexSchema(config, dcore.getSchemaName(), null);
- SolrCore core = new SolrCore(dcore.getName(), null, config, schema, dcore);
+ IndexSchema schema = new IndexSchema(config, config.vars, dcore.getSchemaName(), null);
+ CoreInitalizer initalizer = new CoreInitalizer( dcore.getName(), null, config, schema, dcore);
+ SolrCore core = initalizer.initalizeCore(dcore.getName());
return core;
}
View
4 ryan/src/java/org/apache/solr/core/JmxMonitoredMap.java
@@ -18,7 +18,7 @@
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.core.SolrConfig.JmxConfiguration;
+import org.apache.solr.config.JmxConfiguration;
import javax.management.*;
import javax.management.remote.JMXConnectorServer;
@@ -41,7 +41,7 @@
* </p>
*
* @version $Id$
- * @see org.apache.solr.core.SolrConfig.JmxConfiguration
+ * @see org.apache.solr.config.SolrConfig.JmxConfiguration
* @since solr 1.3
*/
public class JmxMonitoredMap<K, V> extends
View
7 ryan/src/java/org/apache/solr/core/QuerySenderListener.java
@@ -30,14 +30,15 @@
/**
* @version $Id$
*/
-class QuerySenderListener extends AbstractSolrEventListener {
- public QuerySenderListener(SolrCore core) {
- super(core);
+public class QuerySenderListener extends AbstractSolrEventListener {
+ public QuerySenderListener() {
+ super();
}
@Override
public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher currentSearcher) {
final SolrIndexSearcher searcher = newSearcher;
+ final SolrCore core = newSearcher.getCore();
log.info("QuerySenderListener sending requests to " + newSearcher);
for (NamedList nlst : (List<NamedList>)args.get("queries")) {
try {
View
91 ryan/src/java/org/apache/solr/core/RequestHandlers.java
@@ -24,30 +24,22 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.xml.xpath.XPathConstants;
-
-import org.apache.solr.common.ResourceLoader;
import org.apache.solr.common.SolrException;
-import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.handler.StandardRequestHandler;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
import org.apache.solr.request.SolrRequestHandler;
-import org.apache.solr.util.plugin.AbstractPluginLoader;
import org.apache.solr.util.plugin.ResourceLoaderAware;
import org.apache.solr.util.plugin.SolrCoreAware;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Node;
/**
*/
-final class RequestHandlers {
+public final class RequestHandlers {
public static Logger log = LoggerFactory.getLogger(RequestHandlers.class);
public static final String DEFAULT_HANDLER_NAME="standard";
- protected final SolrCore core;
+ protected final Map<String, SolrInfoMBean> infoRegistry;
// Use a synchronized map - since the handlers can be changed at runtime,
// the map implementation should be thread safe
private final Map<String, SolrRequestHandler> handlers = Collections.synchronizedMap(
@@ -70,8 +62,8 @@ private static String normalize( String p )
return p;
}
- public RequestHandlers(SolrCore core) {
- this.core = core;
+ public RequestHandlers(Map<String, SolrInfoMBean> infoRegistry) {
+ this.infoRegistry = infoRegistry;
}
/**
@@ -97,7 +89,7 @@ public SolrRequestHandler register( String handlerName, SolrRequestHandler handl
SolrRequestHandler old = handlers.put(norm, handler);
if (handlerName != null && handlerName != "") {
if (handler instanceof SolrInfoMBean) {
- core.getInfoRegistry().put(handlerName, handler);
+ infoRegistry.put(handlerName, handler);
}
}
return old;
@@ -109,76 +101,7 @@ public SolrRequestHandler register( String handlerName, SolrRequestHandler handl
public Map<String,SolrRequestHandler> getRequestHandlers() {
return Collections.unmodifiableMap( handlers );
}
-
-
- /**
- * Read solrconfig.xml and register the appropriate handlers
- *
- * This function should <b>only</b> be called from the SolrCore constructor. It is
- * not intended as a public API.
- *
- * While the normal runtime registration contract is that handlers MUST be initialized
- * before they are registered, this function does not do that exactly.
- *
- * This function registers all handlers first and then calls init() for each one.
- *
- * This is OK because this function is only called at startup and there is no chance that
- * a handler could be asked to handle a request before it is initialized.
- *
- * The advantage to this approach is that handlers can know what path they are registered
- * to and what other handlers are available at startup.
- *
- * Handlers will be registered and initialized in the order they appear in solrconfig.xml
- */
- void initHandlersFromConfig( final Config config )
- {
- final RequestHandlers handlers = this;
- AbstractPluginLoader<SolrRequestHandler> loader =
- new AbstractPluginLoader<SolrRequestHandler>( "[solrconfig.xml] requestHandler", true, true )
- {
- @Override
- protected SolrRequestHandler create( ResourceLoader config, String name, String className, Node node ) throws Exception
- {
- String startup = DOMUtil.getAttr( node, "startup" );
- if( startup != null ) {
- if( "lazy".equals( startup ) ) {
- log.info("adding lazy requestHandler: " + className );
- NamedList args = DOMUtil.childNodesToNamedList(node);
- return new LazyRequestHandlerWrapper( core, className, args );
- }
- else {
- throw new Exception( "Unknown startup value: '"+startup+"' for: "+className );
- }
- }
- return super.create( config, name, className, node );
- }
-
- @Override
- protected SolrRequestHandler register(String name, SolrRequestHandler plugin) throws Exception {
- return handlers.register( name, plugin );
- }
-
- @Override
- protected void init(SolrRequestHandler plugin, Node node ) throws Exception {
- plugin.init( DOMUtil.childNodesToNamedList(node) );
- }
- };
-
- NodeList nodes = (NodeList)config.evaluate("requestHandler", XPathConstants.NODESET);
-
- // Load the handlers and get the default one
- SolrRequestHandler defaultHandler = loader.load( config.getResourceLoader(), nodes );
- if( defaultHandler == null ) {
- defaultHandler = get(RequestHandlers.DEFAULT_HANDLER_NAME);
- if( defaultHandler == null ) {
- defaultHandler = new StandardRequestHandler();
- register(RequestHandlers.DEFAULT_HANDLER_NAME, defaultHandler);
- }
- }
- register(null, defaultHandler);
- register("", defaultHandler);
- }
-
+
/**
* The <code>LazyRequestHandlerWrapper</core> wraps any {@link SolrRequestHandler}.
@@ -233,7 +156,7 @@ public synchronized SolrRequestHandler getWrappedHandler()
{
if( _handler == null ) {
try {
- _handler = core.createRequestHandler(_className);
+ _handler = core.getInitalizer().createRequestHandler(_className);
_handler.init( _args );
if( _handler instanceof ResourceLoaderAware ) {
View
4 ryan/src/java/org/apache/solr/core/RunExecutableListener.java
@@ -29,9 +29,7 @@
/**
*/
class RunExecutableListener extends AbstractSolrEventListener {
- public RunExecutableListener(SolrCore core) {
- super(core);
- }
+
protected String[] cmd;
protected File dir;
protected String[] envp;
View
249 ryan/src/java/org/apache/solr/core/SolrConfig.java
@@ -1,249 +0,0 @@
-/**
- * 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;
-
-import org.apache.solr.search.CacheConfig;
-import org.apache.solr.update.SolrIndexConfig;
-import org.apache.lucene.search.BooleanQuery;
-
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import java.io.IOException;
-import java.io.InputStream;
-
-
-/**
- * Provides a static reference to a Config object modeling the main
- * configuration data for a a Solr instance -- typically found in
- * "solrconfig.xml".
- *
- * @version $Id$
- */
-public class SolrConfig extends Config {
-
- public static final String DEFAULT_CONF_FILE = "solrconfig.xml";
-
- /**
- * Singleton keeping track of configuration errors
- */
- public static final Collection<Throwable> severeErrors = new HashSet<Throwable>();
-
- /** Creates a default instance from the solrconfig.xml. */
- public SolrConfig()
- throws ParserConfigurationException, IOException, SAXException {
- this( (SolrResourceLoader) null, DEFAULT_CONF_FILE, null );
- }
-
- /** Creates a configuration instance from a configuration name.
- * A default resource loader will be created (@see SolrResourceLoader)
- *@param name the configuration name used by the loader
- */
- public SolrConfig(String name)
- throws ParserConfigurationException, IOException, SAXException {
- this( (SolrResourceLoader) null, name, null);
- }
-
- /** Creates a configuration instance from a configuration name and stream.
- * A default resource loader will be created (@see SolrResourceLoader).
- * If the stream is null, the resource loader will open the configuration stream.
- * If the stream is not null, no attempt to load the resource will occur (the name is not used).
- *@param name the configuration name
- *@param is the configuration stream
- */
- public SolrConfig(String name, InputStream is)
- throws ParserConfigurationException, IOException, SAXException {
- this( (SolrResourceLoader) null, name, is );
- }
-
- /** Creates a configuration instance from an instance directory, configuration name and stream.
- *@param instanceDir the directory used to create the resource loader
- *@param name the configuration name used by the loader if the stream is null
- *@param is the configuration stream
- */
- public SolrConfig(String instanceDir, String name, InputStream is)
- throws ParserConfigurationException, IOException, SAXException {
- this(new SolrResourceLoader(instanceDir), name, is);
- }
-
- /** Creates a configuration instance from a resource loader, a configuration name and a stream.
- * If the stream is null, the resource loader will open the configuration stream.
- * If the stream is not null, no attempt to load the resource will occur (the name is not used).
- *@param loader the resource loader
- *@param name the configuration name
- *@param is the configuration stream
- */
- SolrConfig(SolrResourceLoader loader, String name, InputStream is)
- throws ParserConfigurationException, IOException, SAXException {
- super(loader, name, is, "/config/");
- defaultIndexConfig = new SolrIndexConfig(this, null, null);
- mainIndexConfig = new SolrIndexConfig(this, "mainIndex", defaultIndexConfig);
-
- booleanQueryMaxClauseCount = getInt("query/maxBooleanClauses", BooleanQuery.getMaxClauseCount());
- filtOptEnabled = getBool("query/boolTofilterOptimizer/@enabled", false);
- filtOptCacheSize = getInt("query/boolTofilterOptimizer/@cacheSize",32);
- filtOptThreshold = getFloat("query/boolTofilterOptimizer/@threshold",.05f);
-
- useFilterForSortedQuery = getBool("query/useFilterForSortedQuery", false);
- queryResultWindowSize = getInt("query/queryResultWindowSize", 1);
- queryResultMaxDocsCached = getInt("query/queryResultMaxDocsCached", Integer.MAX_VALUE);
- enableLazyFieldLoading = getBool("query/enableLazyFieldLoading", false);
-
-
- filterCacheConfig = CacheConfig.getConfig(this, "query/filterCache");
- queryResultCacheConfig = CacheConfig.getConfig(this, "query/queryResultCache");
- documentCacheConfig = CacheConfig.getConfig(this, "query/documentCache");
- userCacheConfigs = CacheConfig.getMultipleConfigs(this, "query/cache");
- org.apache.solr.search.SolrIndexSearcher.initRegenerators(this);
-
- hashSetInverseLoadFactor = 1.0f / getFloat("//HashDocSet/@loadFactor",0.75f);
- hashDocSetMaxSize= getInt("//HashDocSet/@maxSize",3000);
-
- httpCachingConfig = new HttpCachingConfig(this);
-
- Node jmx = getNode("jmx", false);
- if (jmx != null) {
- jmxConfig = new JmxConfiguration(true, get("jmx/@agentId", null), get(
- "jmx/@serviceUrl", null));
- } else {
- jmxConfig = new JmxConfiguration(false, null, null);
- }
-
- Config.log.info("Loaded SolrConfig: " + name);
- }
-
- /* The set of materialized parameters: */
- public final int booleanQueryMaxClauseCount;
- // SolrIndexSearcher - nutch optimizer
- public final boolean filtOptEnabled;
- public final int filtOptCacheSize;
- public final float filtOptThreshold;
- // SolrIndexSearcher - caches configurations
- public final CacheConfig filterCacheConfig ;
- public final CacheConfig queryResultCacheConfig;
- public final CacheConfig documentCacheConfig;
- public final CacheConfig[] userCacheConfigs;
- // SolrIndexSearcher - more...
- public final boolean useFilterForSortedQuery;
- public final int queryResultWindowSize;
- public final int queryResultMaxDocsCached;
- public final boolean enableLazyFieldLoading;
- // DocSet
- public final float hashSetInverseLoadFactor;
- public final int hashDocSetMaxSize;
- // default & main index configurations
- public final SolrIndexConfig defaultIndexConfig;
- public final SolrIndexConfig mainIndexConfig;
-
- //JMX configuration
- public final JmxConfiguration jmxConfig;
-
- private final HttpCachingConfig httpCachingConfig;
- public HttpCachingConfig getHttpCachingConfig() {
- return httpCachingConfig;
- }
-
- public static class JmxConfiguration {
- public boolean enabled = false;
-
- public String agentId;
-
- public String serviceUrl;
-
- public JmxConfiguration(boolean enabled, String agentId, String serviceUrl) {
- this.enabled = enabled;
- this.agentId = agentId;
- this.serviceUrl = serviceUrl;
- }
- }
-
- public static class HttpCachingConfig {
-
- /** config xpath prefix for getting HTTP Caching options */
- private final static String CACHE_PRE
- = "requestDispatcher/httpCaching/";
-
- /** For extracting Expires "ttl" from <cacheControl> config */
- private final static Pattern MAX_AGE
- = Pattern.compile("\\bmax-age=(\\d+)");
-
- public static enum LastModFrom {
- OPENTIME, DIRLASTMOD, BOGUS;
-
- /** Input must not be null */
- public static LastModFrom parse(final String s) {
- try {
- return valueOf(s.toUpperCase());
- } catch (Exception e) {
- log.warn( "Unrecognized value for lastModFrom: " + s, e);
- return BOGUS;
- }
- }
- }
-
- private final boolean never304;
- private final String etagSeed;
- private final String cacheControlHeader;
- private final Long maxAge;
- private final LastModFrom lastModFrom;
-
- private HttpCachingConfig(SolrConfig conf) {
-
- never304 = conf.getBool(CACHE_PRE+"@never304", false);
-
- etagSeed = conf.get(CACHE_PRE+"@etagSeed", "Solr");
-
-
- lastModFrom = LastModFrom.parse(conf.get(CACHE_PRE+"@lastModFrom",
- "openTime"));
-
- cacheControlHeader = conf.get(CACHE_PRE+"cacheControl",null);
-
- Long tmp = null; // maxAge
- if (null != cacheControlHeader) {
- try {
- final Matcher ttlMatcher = MAX_AGE.matcher(cacheControlHeader);
- final String ttlStr = ttlMatcher.find() ? ttlMatcher.group(1) : null;
- tmp = (null != ttlStr && !"".equals(ttlStr))
- ? Long.valueOf(ttlStr)
- : null;
- } catch (Exception e) {
- log.warn( "Ignoring exception while attempting to " +
- "extract max-age from cacheControl config: " +
- cacheControlHeader, e);
- }
- }
- maxAge = tmp;
-
- }
-
- public boolean isNever304() { return never304; }
- public String getEtagSeed() { return etagSeed; }
- /** null if no Cache-Control header */
- public String getCacheControlHeader() { return cacheControlHeader; }
- /** null if no max age limitation */
- public Long getMaxAge() { return maxAge; }
- public LastModFrom getLastModFrom() { return lastModFrom; }
- }
-}
View
695 ryan/src/java/org/apache/solr/core/SolrCore.java
@@ -17,22 +17,23 @@
package org.apache.solr.core;
-import org.apache.lucene.index.IndexDeletionPolicy;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.CommonParams.EchoParamStyle;
import org.apache.solr.common.params.SolrParams;
-import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.handler.admin.ShowFileRequestHandler;
+import org.apache.solr.config.CoreDescriptor;
+import org.apache.solr.config.CoreInitalizer;
+import org.apache.solr.config.CoreVars;
+import org.apache.solr.config.SolrConfig;
+import org.apache.solr.config.SolrConfiguraion;
+import org.apache.solr.config.SolrResourceLoader;
import org.apache.solr.handler.component.*;
-import org.apache.solr.highlight.DefaultSolrHighlighter;
import org.apache.solr.highlight.SolrHighlighter;
import org.apache.solr.request.*;
import org.apache.solr.schema.IndexSchema;
@@ -42,24 +43,9 @@
import org.apache.solr.update.DirectUpdateHandler2;
import org.apache.solr.update.SolrIndexWriter;
import org.apache.solr.update.UpdateHandler;
-import org.apache.solr.update.processor.LogUpdateProcessorFactory;
-import org.apache.solr.update.processor.RunUpdateProcessorFactory;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
-import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
import org.apache.solr.util.RefCounted;
-import org.apache.solr.util.plugin.AbstractPluginLoader;
-import org.apache.solr.util.plugin.NamedListInitializedPlugin;
-import org.apache.solr.util.plugin.NamedListPluginLoader;
import org.apache.solr.util.plugin.SolrCoreAware;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathExpressionException;
-
import java.io.File;
import java.io.IOException;
import java.util.*;
@@ -78,92 +64,69 @@
public static Logger log = LoggerFactory.getLogger(SolrCore.class);
+ // TODO -- get rid of me...
+ private final CoreInitalizer initalizer;
+ private final SolrConfiguraion configuration;
+
+ @Deprecated
+ public static SolrCore INSTANCE;
+
private String name;
- private String logid; // used to show what name is set
- private final CoreDescriptor coreDescriptor;
+ private String logid;
- private final SolrConfig solrConfig;
private final IndexSchema schema;
private final String dataDir;
private final UpdateHandler updateHandler;
- private final long startTime;
+
private final RequestHandlers reqHandlers;
private final SolrHighlighter highlighter;
private final Map<String,SearchComponent> searchComponents;
private final Map<String,UpdateRequestProcessorChain> updateProcessorChains;
private final Map<String, SolrInfoMBean> infoRegistry;
- private IndexDeletionPolicyWrapper solrDelPolicy;
+ private final IndexDeletionPolicyWrapper solrDelPolicy;
+ private final QueryResponseWriter defaultResponseWriter;
- public long getStartTime() { return startTime; }
+ private final Map<String, QueryResponseWriter> responseWriters;
+ private final Map<String, QParserPlugin> qParserPlugins;
+ private final HashMap<String, ValueSourceParser> valueSourceParsers;
+
+ final List<SolrEventListener> firstSearcherListeners;
+ final List<SolrEventListener> newSearcherListeners;
+
+
+ private final long startTime = System.currentTimeMillis();
- /**
- * @deprecated Use {@link CoreContainer#getCore(String)} instead.
- */
- @Deprecated
- private static SolrCore instance;
-
- static int boolean_query_max_clause_count = Integer.MIN_VALUE;
- // only change the BooleanQuery maxClauseCount once for ALL cores...
- void booleanQueryMaxClauseCount() {
- synchronized(SolrCore.class) {
- if (boolean_query_max_clause_count == Integer.MIN_VALUE) {
- boolean_query_max_clause_count = solrConfig.booleanQueryMaxClauseCount;
- BooleanQuery.setMaxClauseCount(boolean_query_max_clause_count);
- } else if (boolean_query_max_clause_count != solrConfig.booleanQueryMaxClauseCount ) {
- log.debug("BooleanQuery.maxClauseCount= " +boolean_query_max_clause_count+ ", ignoring " +solrConfig.booleanQueryMaxClauseCount);
- }
- }
- }
+
+ private List<CloseHook> closeHooks = null;
/**
* The SolrResourceLoader used to load all resources for this core.
* @since solr 1.3
*/
+ @Deprecated
public SolrResourceLoader getResourceLoader() {
- return solrConfig.getResourceLoader();
- }
-
- /**
- * Gets the configuration resource name used by this core instance.
- * @since solr 1.3
- */
- public String getConfigResource() {
- return solrConfig.getResourceName();
+ return initalizer.getSolrConfig().getResourceLoader();
}
/**
- * Gets the configuration resource name used by this core instance.
- * @deprecated Use {@link #getConfigResource()} instead.
- */
- @Deprecated
- public String getConfigFile() {
- return solrConfig.getResourceName();
- }
- /**
* Gets the configuration object used by this core instance.
*/
+ @Deprecated
public SolrConfig getSolrConfig() {
- return solrConfig;
- }
-
- /**
- * Gets the schema resource name used by this core instance.
- * @since solr 1.3
- */
- public String getSchemaResource() {
- return schema.getResourceName();
+ return initalizer.getSolrConfig();
}
+
/**
- * Gets the schema resource name used by this core instance.
- * @deprecated Use {@link #getSchemaResource()} instead.
+ * Gets the configuration object used by this core instance.
*/
@Deprecated
- public String getSchemaFile() {
- return schema.getResourceName();
+ public CoreInitalizer getInitalizer() {
+ return initalizer;
}
+
/**
* Gets the schema object used by this core instance.
*/
@@ -201,41 +164,7 @@ public String getLogId()
return infoRegistry;
}
- private void initDeletionPolicy() {
- String className = solrConfig.get("mainIndex/deletionPolicy/@class", SolrDeletionPolicy.class.getName());
- IndexDeletionPolicy delPolicy = createInstance(className, IndexDeletionPolicy.class, "Deletion Policy for SOLR");
-
- Node node = (Node) solrConfig.evaluate("mainIndex/deletionPolicy", XPathConstants.NODE);
- if (node != null) {
- if (delPolicy instanceof NamedListInitializedPlugin)
- ((NamedListInitializedPlugin) delPolicy).init(DOMUtil.childNodesToNamedList(node));
- }
- solrDelPolicy = new IndexDeletionPolicyWrapper(delPolicy);
- }
-
- public List<SolrEventListener> parseListener(String path) {
- List<SolrEventListener> lst = new ArrayList<SolrEventListener>();
- log.info( logid+"Searching for listeners: " +path);
- NodeList nodes = (NodeList)solrConfig.evaluate(path, XPathConstants.NODESET);
- if (nodes!=null) {
- for (int i=0; i<nodes.getLength(); i++) {
- Node node = nodes.item(i);
- String className = DOMUtil.getAttr(node,"class");
- SolrEventListener listener = createEventListener(className);
- listener.init(DOMUtil.childNodesToNamedList(node));
- lst.add(listener);
- log.info( logid+"Added SolrEventListener: " + listener);
- }
- }
- return lst;
- }
- List<SolrEventListener> firstSearcherListeners;
- List<SolrEventListener> newSearcherListeners;
- private void parseListeners() {
- firstSearcherListeners = parseListener("//listener[@event=\"firstSearcher\"]");
- newSearcherListeners = parseListener("//listener[@event=\"newSearcher\"]");
- }
/**
* NOTE: this function is not thread safe. However, it is safe to call within the
@@ -268,11 +197,10 @@ public void registerNewSearcherListener( SolrEventListener listener )
*
* @see SolrCoreAware
*/
- public void registerResponseWriter( String name, QueryResponseWriter responseWriter ){
- responseWriters.put(name, responseWriter);
+ public QueryResponseWriter registerResponseWriter( String name, QueryResponseWriter responseWriter ){
+ return responseWriters.put(name, responseWriter);
}
-
// gets a non-caching searcher
public SolrIndexSearcher newSearcher(String name) throws IOException {
return newSearcher(name, false);
@@ -284,20 +212,97 @@ public SolrIndexSearcher newSearcher(String name, boolean readOnly) throws IOExc
}
+
+
+ /**
+ * Creates a new core and register it in the list of cores.
+ * If a core with the same name already exists, it will be stopped and replaced by this one.
+ *@param dataDir the index directory
+ *@param config a solr config instance
+ *@param schema a solr schema instance
+ *
+ *@since solr 1.3
+ */
+ public SolrCore(String name, CoreVars vars ) {
+ INSTANCE = this;
+ this.initalizer = vars.getInitalizer();
+ this.configuration = vars.getConfiguration();
+ this.setName( name );
+
+ this.dataDir = configuration.getDataDir();
+ log.info(logid+"Opening new SolrCore at: " + dataDir);
+
+
+ //Initialize JMX
+ this.schema = vars.getSchema();
+ if (schema==null) {
+ throw new NullPointerException( "schema can't be null" );
+ }
+
+ this.reqHandlers = vars.getReqHandlers();
+ this.highlighter = vars.getHighlighter();
+ this.searchComponents = vars.getSearchComponents();
+ this.updateProcessorChains = vars.getUpdateProcessorChains();
+ this.infoRegistry = vars.getInfoRegistry();
+ this.solrDelPolicy = vars.getSolrDelPolicy();
+ this.defaultResponseWriter = vars.getDefaultResponseWriter();
+
+ this.responseWriters = vars.getResponseWriters();
+ this.qParserPlugins = vars.getQParserPlugins();
+ this.valueSourceParsers = vars.getValueSourceParsers();
+
+ this.firstSearcherListeners = vars.getFirstSearcherListeners();
+ this.newSearcherListeners = vars.getNewSearcherListeners();
+
+ initIndex();
+
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ try {
+ // cause the executor to stall so firstSearcher events won't fire
+ // until after inform() has been called for all components.
+ // searchExecutor must be single-threaded for this to work
+ searcherExecutor.submit(new Callable() {
+ public Object call() throws Exception {
+ latch.await();
+ return null;
+ }
+ });
+
+ // Open the searcher *before* the update handler so we don't end up opening
+ // one in the middle.
+ // With lockless commits in Lucene now, this probably shouldn't be an issue anymore
+ getSearcher(false,false,null);
+
+ // HACK -- for now, this is hard coded since it needs the update handler...
+ updateHandler = new DirectUpdateHandler2(this,
+ vars.getCommitCallbacks(), vars.getOptimizeCallbacks() );
+ infoRegistry.put("updateHandler", updateHandler);
+ }
+ catch (IOException e) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
+ }
+ finally {
+ // allow firstSearcher events to fire
+ latch.countDown();
+ }
+ infoRegistry.put("core", this);
+ }
+
+
// protect via synchronized(SolrCore.class)
private static Set<String> dirs = new HashSet<String>();
-
+
// currently only called with SolrCore.class lock held
void initIndex() {
try {
File dirFile = new File(getIndexDir());
boolean indexExists = dirFile.canRead();
boolean firstTime = dirs.add(dirFile.getCanonicalPath());
- boolean removeLocks = solrConfig.getBool("mainIndex/unlockOnStartup", false);
- if (indexExists && firstTime && removeLocks) {
+ if (indexExists && firstTime && configuration.isUnlockOnStartup() ) {
// to remove locks, the directory must already exist... so we create it
// if it didn't exist already...
- Directory dir = SolrIndexWriter.getDirectory(getIndexDir(), solrConfig.mainIndexConfig);
+ Directory dir = SolrIndexWriter.getDirectory(getIndexDir(), configuration.getMainIndexConfig() );
if (dir != null && IndexWriter.isLocked(dir)) {
log.warn(logid+"WARNING: Solr index directory '" + getIndexDir() + "' is locked. Unlocking...");
IndexWriter.unlock(dir);
@@ -309,7 +314,9 @@ void initIndex() {
log.warn(logid+"Solr index directory '" + dirFile + "' doesn't exist."
+ " Creating new index...");
- SolrIndexWriter writer = new SolrIndexWriter("SolrCore.initIndex",getIndexDir(), true, schema, solrConfig.mainIndexConfig);
+ SolrIndexWriter writer = new SolrIndexWriter(
+ "SolrCore.initIndex",getIndexDir(), true, schema,
+ configuration.getMainIndexConfig() );
writer.close();
}
@@ -317,270 +324,8 @@ void initIndex() {
throw new RuntimeException(e);
}
}
-
- /** Creates an instance by trying a constructor that accepts a SolrCore before
- * trying the default (no arg) constructor.
- *@param className the instance class to create
- *@cast the class or interface that the instance should extend or implement
- *@param msg a message helping compose the exception error if any occurs.
- *@return the desired instance
- *@throws SolrException if the object could not be instantiated
- */
- private <T extends Object> T createInstance(String className, Class<T> cast, String msg) {
- Class clazz = null;
- if (msg == null) msg = "SolrCore Object";
- try {
- try {
- clazz = solrConfig.getResourceLoader().findClass(className);
- if (cast != null && !cast.isAssignableFrom(clazz))
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,"Error Instantiating "+msg+", "+className+ " is not a " +cast.getName());
-
- java.lang.reflect.Constructor cons = clazz.getConstructor(new Class[]{SolrCore.class});
- return (T) cons.newInstance(new Object[]{this});
- } catch(NoSuchMethodException xnomethod) {
- return (T) clazz.newInstance();
- }
- } catch (SolrException e) {
- throw e;
- } catch (Exception e) {
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,"Error Instantiating "+msg+", "+className+ " failed to instantiate " +cast.getName(), e);
- }
- }
-
- public SolrEventListener createEventListener(String className) {
- return createInstance(className, SolrEventListener.class, "Event Listener");
- }
-
- public SolrRequestHandler createRequestHandler(String className) {
- return createInstance(className, SolrRequestHandler.class, "Request Handler");
- }
-
- private UpdateHandler createUpdateHandler(String className) {
- return createInstance(className, UpdateHandler.class, "Update Handler");
- }
-
- private SolrHighlighter createHighlighter(String className) {
- return createInstance(className, SolrHighlighter.class, "Highlighter");
- }
- /**
- * @return the last core initialized. If you are using multiple cores,
- * this is not a function to use.
- *
- * @deprecated Use {@link CoreContainer#getCore(String)} instead.
- */
- @Deprecated
- public static SolrCore getSolrCore() {
- synchronized( SolrCore.class ) {
- if( instance == null ) {
- try {
- // sets 'instance' to the latest solr core
- instance = new SolrCore( null, null, new SolrConfig(), null, null);
- } catch(Exception xany) {
- throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
- "error creating core", xany );
- }
- }
- }
- return instance;
- }