SOLR-660 -- simplify the UpdateRequestProcessorFactory framework and use standard initialization techniques

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@679936 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ryan McKinley 2008-07-26 00:20:44 +00:00
parent 645fd551f6
commit da634f42eb
15 changed files with 225 additions and 294 deletions

View File

@ -610,25 +610,15 @@
The response format differs from solr1.1 formatting and returns a standard error code.
To enable solr1.1 behavior, remove the /update handler or change its path
"update.processor.class" is the class name for the UpdateRequestProcessor. It is initalized
only once. This can not be changed for each request.
-->
<requestHandler name="/update" class="solr.XmlUpdateRequestHandler" >
<!--
<str name="update.processor.class">org.apache.solr.handler.UpdateRequestProcessor</str>
-->
</requestHandler>
<requestHandler name="/update" class="solr.XmlUpdateRequestHandler" />
<!--
Analysis request handler. Since Solr 1.3. Use to returnhow a document is analyzed. Useful
for debugging and as a token server for other types of applications
-->
<requestHandler name="/analysis" class="solr.AnalysisRequestHandler" >
<!--
<str name="update.processor.class">org.apache.solr.handler.UpdateRequestProcessor</str>
-->
</requestHandler>
<requestHandler name="/analysis" class="solr.AnalysisRequestHandler" />
<!-- CSV update handler, loaded on demand -->
<requestHandler name="/update/csv" class="solr.CSVRequestHandler" startup="lazy" />

View File

@ -40,7 +40,9 @@ import org.apache.solr.search.ValueSourceParser;
import org.apache.solr.update.DirectUpdateHandler;
import org.apache.solr.update.SolrIndexWriter;
import org.apache.solr.update.UpdateHandler;
import org.apache.solr.update.processor.ChainedUpdateProcessorFactory;
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;
@ -52,6 +54,9 @@ 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.*;
@ -79,7 +84,7 @@ public final class SolrCore {
private final RequestHandlers reqHandlers;
private final SolrHighlighter highlighter;
private final Map<String,SearchComponent> searchComponents;
private final Map<String,UpdateRequestProcessorFactory> updateProcessors;
private final Map<String,UpdateRequestProcessorChain> updateProcessorChains;
private final Map<String,SolrInfoMBean> infoRegistry = new java.util.HashMap<String,SolrInfoMBean>();
public long getStartTime() { return startTime; }
@ -408,7 +413,7 @@ public final class SolrCore {
this.searchComponents = loadSearchComponents( config );
// Processors initialized before the handlers
updateProcessors = loadUpdateProcessors();
updateProcessorChains = loadUpdateProcessorChains();
reqHandlers = new RequestHandlers(this);
reqHandlers.initHandlersFromConfig( solrConfig );
@ -458,30 +463,71 @@ public final class SolrCore {
/**
* Load the request processors configured in solrconfig.xml
*/
private Map<String, UpdateRequestProcessorFactory> loadUpdateProcessors() {
final Map<String,UpdateRequestProcessorFactory> map = new HashMap<String, UpdateRequestProcessorFactory>();
private Map<String,UpdateRequestProcessorChain> loadUpdateProcessorChains() {
final Map<String,UpdateRequestProcessorChain> map = new HashMap<String, UpdateRequestProcessorChain>();
// If this is a more general use-case, this could be a regular type
final SolrCore thiscore = this;
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>( "updateRequestProcessor" ) {
= new AbstractPluginLoader<UpdateRequestProcessorFactory>( "processor chain", false, false ) {
@Override
protected void init(UpdateRequestProcessorFactory plugin, Node node) throws Exception {
plugin.init( thiscore, node );
plugin.init( (node==null)?null:DOMUtil.childNodesToNamedList(node) );
}
@Override
protected UpdateRequestProcessorFactory register(String name, UpdateRequestProcessorFactory plugin) throws Exception {
return map.put( name, plugin );
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);
}
}
}
NodeList nodes = (NodeList)solrConfig.evaluate("updateRequestProcessor/factory", XPathConstants.NODESET);
UpdateRequestProcessorFactory def = loader.load( solrConfig.getResourceLoader(), nodes );
if( def == null ) {
def = new ChainedUpdateProcessorFactory(); // the default
def.init( thiscore, null );
// construct the default chain
UpdateRequestProcessorFactory[] factories = new UpdateRequestProcessorFactory[] {
new RunUpdateProcessorFactory(),
new LogUpdateProcessorFactory()
};
def = new UpdateRequestProcessorChain( factories );
}
map.put( null, def );
map.put( "", def );
@ -489,16 +535,16 @@ public final class SolrCore {
}
/**
* @return an update processor registered to the given name. Throw an exception if this factory is undefined
* @return an update processor registered to the given name. Throw an exception if this chain is undefined
*/
public UpdateRequestProcessorFactory getUpdateProcessorFactory( String name )
public UpdateRequestProcessorChain getUpdateProcessingChain( final String name )
{
UpdateRequestProcessorFactory factory = updateProcessors.get( name );
if( factory == null ) {
UpdateRequestProcessorChain chain = updateProcessorChains.get( name );
if( chain == null ) {
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
"unknown UpdateProcessorFactory: "+name );
"unknown UpdateRequestProcessorChain: "+name );
}
return factory;
return chain;
}
/**

View File

@ -47,6 +47,7 @@ import org.apache.solr.handler.component.SearchComponent;
import org.apache.solr.request.QueryResponseWriter;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.schema.FieldType;
import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
import org.apache.solr.util.plugin.ResourceLoaderAware;
import org.apache.solr.util.plugin.SolrCoreAware;
import org.apache.solr.spelling.SpellingQueryConverter;
@ -370,7 +371,8 @@ public class SolrResourceLoader implements ResourceLoader
SolrCoreAware.class, new Class[] {
SolrRequestHandler.class,
QueryResponseWriter.class,
SearchComponent.class
SearchComponent.class,
UpdateRequestProcessorFactory.class
}
);

View File

@ -28,6 +28,7 @@ import org.apache.solr.common.util.StrUtils;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.update.*;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.commons.csv.CSVStrategy;
@ -47,10 +48,10 @@ public class CSVRequestHandler extends RequestHandlerBase {
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
SolrParams params = req.getParams();
UpdateRequestProcessorFactory processorFactory =
req.getCore().getUpdateProcessorFactory( params.get( UpdateParams.UPDATE_PROCESSOR ) );
UpdateRequestProcessorChain processorChain =
req.getCore().getUpdateProcessingChain( params.get( UpdateParams.UPDATE_PROCESSOR ) );
UpdateRequestProcessor processor = processorFactory.getInstance(req, rsp, null);
UpdateRequestProcessor processor = processorChain.createProcessor(req, rsp);
try {
CSVLoader loader = new SingleThreadedCSVLoader(req, processor);

View File

@ -50,8 +50,8 @@ import org.apache.solr.request.SolrQueryResponse;
import org.apache.solr.update.AddUpdateCommand;
import org.apache.solr.update.CommitUpdateCommand;
import org.apache.solr.update.DeleteUpdateCommand;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
/**
* Add documents to solr using the STAX XML parser.
@ -96,7 +96,7 @@ public class XmlUpdateRequestHandler extends RequestHandlerBase
catch( IllegalArgumentException ex ) {
// Other implementations will likely throw this exception since "reuse-instance"
// isimplementation specific.
log.fine( "Unable to set the 'reuse-instance' property for the input factory: "+inputFactory );
log.fine( "Unable to set the 'reuse-instance' property for the input chain: "+inputFactory );
}
}
@ -106,10 +106,10 @@ public class XmlUpdateRequestHandler extends RequestHandlerBase
RequestHandlerUtils.addExperimentalFormatWarning( rsp );
SolrParams params = req.getParams();
UpdateRequestProcessorFactory processorFactory =
req.getCore().getUpdateProcessorFactory( params.get( UpdateParams.UPDATE_PROCESSOR ) );
UpdateRequestProcessorChain processingChain =
req.getCore().getUpdateProcessingChain( params.get( UpdateParams.UPDATE_PROCESSOR ) );
UpdateRequestProcessor processor = processorFactory.getInstance(req, rsp, null);
UpdateRequestProcessor processor = processingChain.createProcessor(req, rsp);
Iterable<ContentStream> streams = req.getContentStreams();
if( streams == null ) {
if( !RequestHandlerUtils.handleCommit(processor, params, false) ) {
@ -381,13 +381,13 @@ public class XmlUpdateRequestHandler extends RequestHandlerBase
SolrCore core = SolrCore.getSolrCore();
// Old style requests do not choose a custom handler
UpdateRequestProcessorFactory processorFactory = core.getUpdateProcessorFactory( null );
UpdateRequestProcessorChain processorFactory = core.getUpdateProcessingChain( null );
SolrParams params = new MapSolrParams( new HashMap<String, String>() );
SolrQueryRequestBase req = new SolrQueryRequestBase( core, params ) {};
SolrQueryResponse rsp = new SolrQueryResponse(); // ignored
XMLStreamReader parser = inputFactory.createXMLStreamReader(input);
UpdateRequestProcessor processor = processorFactory.getInstance(req, rsp, null);
UpdateRequestProcessor processor = processorFactory.createProcessor(req, rsp);
this.processUpdate( processor, parser );
processor.finish();
output.write("<result status=\"0\"></result>");

View File

@ -1,109 +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.update.processor;
import java.util.ArrayList;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.solr.common.SolrException;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
import org.apache.solr.util.plugin.AbstractPluginLoader;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* An UpdateRequestProcessorFactory that constructs a chain of UpdateRequestProcessor.
*
* This is the default implementation and can be configured via solrconfig.xml with:
*
* <updateRequestProcessor>
* <factory name="standard" class="solr.ChainedUpdateProcessorFactory" >
* <chain class="PathToClass1" />
* <chain class="PathToClass2" />
* <chain class="solr.LogUpdateProcessorFactory" >
* <int name="maxNumToLog">100</int>
* </chain>
* <chain class="solr.RunUpdateProcessorFactory" />
* </factory>
* </updateRequestProcessor>
*
* @since solr 1.3
*/
public class ChainedUpdateProcessorFactory extends UpdateRequestProcessorFactory
{
protected UpdateRequestProcessorFactory[] factory;
@Override
public void init( final SolrCore core, final Node node ) {
final ArrayList<UpdateRequestProcessorFactory> factories = new ArrayList<UpdateRequestProcessorFactory>();
if( node != null ) {
// 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( core, node );
}
@Override
protected UpdateRequestProcessorFactory register(String name, UpdateRequestProcessorFactory plugin) throws Exception {
factories.add( plugin );
return null;
}
};
XPath xpath = XPathFactory.newInstance().newXPath();
try {
loader.load( core.getResourceLoader(), (NodeList) xpath.evaluate( "chain", node, XPathConstants.NODESET ) );
}
catch (XPathExpressionException e) {
throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
"Error loading processor chain: " + node,e,false);
}
}
// If not configured, make sure it has the default settings
if( factories.size() < 1 ) {
factories.add( new RunUpdateProcessorFactory() );
factories.add( new LogUpdateProcessorFactory() );
}
factory = factories.toArray( new UpdateRequestProcessorFactory[factories.size()] );
}
@Override
public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next)
{
UpdateRequestProcessor processor = null;
UpdateRequestProcessor last = null;
for (int i = factory.length-1; i>=0; i--) {
processor = factory[i].getInstance(req, rsp, last);
last = processor == null ? last : processor;
}
return last;
}
public UpdateRequestProcessorFactory[] getFactories() {
return factory;
}
}

View File

@ -23,16 +23,13 @@ import java.util.List;
import java.util.logging.Level;
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.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
import org.apache.solr.update.AddUpdateCommand;
import org.apache.solr.update.CommitUpdateCommand;
import org.apache.solr.update.DeleteUpdateCommand;
import org.w3c.dom.Node;
/**
* A logging processor. This keeps track of all commands that have passed through
@ -47,9 +44,8 @@ public class LogUpdateProcessorFactory extends UpdateRequestProcessorFactory {
int maxNumToLog = 8;
@Override
public void init( final SolrCore core, final Node node ) {
if( node != null ) {
NamedList<Object> args = DOMUtil.childNodesToNamedList( node );
public void init( final NamedList args ) {
if( args != null ) {
SolrParams params = SolrParams.toSolrParams( args );
maxNumToLog = params.getInt( "maxNumToLog", maxNumToLog );
}
@ -70,7 +66,6 @@ public class LogUpdateProcessorFactory extends UpdateRequestProcessorFactory {
class LogUpdateProcessor extends UpdateRequestProcessor {
private final SolrQueryRequest req;
private final SolrQueryResponse rsp;
private final UpdateRequestProcessor next;
private final NamedList<Object> toLog;
int numAdds;
@ -83,9 +78,9 @@ class LogUpdateProcessor extends UpdateRequestProcessor {
private final int maxNumToLog;
public LogUpdateProcessor(SolrQueryRequest req, SolrQueryResponse rsp, LogUpdateProcessorFactory factory, UpdateRequestProcessor next) {
super( next );
this.req = req;
this.rsp = rsp;
this.next = next;
maxNumToLog = factory.maxNumToLog; // TODO: make configurable
// TODO: make log level configurable as well, or is that overkill?
// (ryan) maybe? I added it mostly to show that it *can* be configurable

View File

@ -1,63 +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.update.processor;
import java.io.IOException;
import org.apache.solr.update.AddUpdateCommand;
import org.apache.solr.update.CommitUpdateCommand;
import org.apache.solr.update.DeleteUpdateCommand;
/**
* A simple processor that does nothing but passes on the command to the next
* processor in the chain.
*
* @since solr 1.3
*/
public abstract class NoOpUpdateProcessor extends UpdateRequestProcessor
{
protected final UpdateRequestProcessor next;
public NoOpUpdateProcessor( UpdateRequestProcessor next) {
this.next = next;
}
@Override
public void processAdd(AddUpdateCommand cmd) throws IOException {
if (next != null) next.processAdd(cmd);
}
@Override
public void processDelete(DeleteUpdateCommand cmd) throws IOException {
if (next != null) next.processDelete(cmd);
}
@Override
public void processCommit(CommitUpdateCommand cmd) throws IOException
{
if (next != null) next.processCommit(cmd);
}
@Override
public void finish() throws IOException {
if (next != null) next.finish();
}
}

View File

@ -19,7 +19,6 @@ package org.apache.solr.update.processor;
import java.io.IOException;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
import org.apache.solr.update.AddUpdateCommand;
@ -27,8 +26,6 @@ import org.apache.solr.update.CommitUpdateCommand;
import org.apache.solr.update.DeleteUpdateCommand;
import org.apache.solr.update.DocumentBuilder;
import org.apache.solr.update.UpdateHandler;
import org.w3c.dom.Node;
/**
@ -38,11 +35,6 @@ import org.w3c.dom.Node;
*/
public class RunUpdateProcessorFactory extends UpdateRequestProcessorFactory
{
@Override
public void init( final SolrCore core, final Node node ) {
}
@Override
public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next)
{
@ -50,7 +42,7 @@ public class RunUpdateProcessorFactory extends UpdateRequestProcessorFactory
}
}
class RunUpdateProcessor extends NoOpUpdateProcessor
class RunUpdateProcessor extends UpdateRequestProcessor
{
private final SolrQueryRequest req;
private final UpdateHandler updateHandler;

View File

@ -33,17 +33,34 @@ import org.apache.solr.update.DeleteUpdateCommand;
* Perhaps you continue adding an error message (without indexing the document)...
* perhaps you throw an error and halt indexing (remove anything already indexed??)
*
* This implementation (the default) passes the request command (as is) to the updateHandler
* and adds debug info to the response.
* By default, this just passes the request to the next processor in the chain.
*
* @since solr 1.3
*/
public abstract class UpdateRequestProcessor {
protected static Logger log = Logger.getLogger(UpdateRequestProcessor.class.getName());
public abstract void processAdd(AddUpdateCommand cmd) throws IOException;
public abstract void processDelete(DeleteUpdateCommand cmd) throws IOException;
public abstract void processCommit(CommitUpdateCommand cmd) throws IOException;
public abstract void finish() throws IOException;
protected final UpdateRequestProcessor next;
public UpdateRequestProcessor( UpdateRequestProcessor next) {
this.next = next;
}
public void processAdd(AddUpdateCommand cmd) throws IOException {
if (next != null) next.processAdd(cmd);
}
public void processDelete(DeleteUpdateCommand cmd) throws IOException {
if (next != null) next.processDelete(cmd);
}
public void processCommit(CommitUpdateCommand cmd) throws IOException
{
if (next != null) next.processCommit(cmd);
}
public void finish() throws IOException {
if (next != null) next.finish();
}
}

View File

@ -0,0 +1,61 @@
/**
* 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.update.processor;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
/**
* An UpdateRequestProcessorFactory that constructs a chain of UpdateRequestProcessor.
*
* This is the default implementation and can be configured via solrconfig.xml with:
*
* <updateRequestProcessors name="key" default="true">
* <processor class="PathToClass1" />
* <processor class="PathToClass2" />
* <processor class="solr.LogUpdateProcessorFactory" >
* <int name="maxNumToLog">100</int>
* </processor>
* <processor class="solr.RunUpdateProcessorFactory" />
* </updateRequestProcessors>
*
* @since solr 1.3
*/
public final class UpdateRequestProcessorChain
{
final UpdateRequestProcessorFactory[] chain;
public UpdateRequestProcessorChain( UpdateRequestProcessorFactory[] chain ) {
this.chain = chain;
}
public UpdateRequestProcessor createProcessor(SolrQueryRequest req, SolrQueryResponse rsp)
{
UpdateRequestProcessor processor = null;
UpdateRequestProcessor last = null;
for (int i = chain.length-1; i>=0; i--) {
processor = chain[i].getInstance(req, rsp, last);
last = processor == null ? last : processor;
}
return last;
}
public UpdateRequestProcessorFactory[] getFactories() {
return chain;
}
}

View File

@ -17,19 +17,24 @@
package org.apache.solr.update.processor;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
import org.w3c.dom.Node;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
import org.apache.solr.util.plugin.SolrCoreAware;
/**
* A factory to generate UpdateRequestProcessors for each request.
* A factory to generate an UpdateRequestProcessor for each request.
*
* If the factory needs access to {@link SolrCore} in initialization, it could
* implement {@link SolrCoreAware}
*
* @since solr 1.3
*/
public abstract class UpdateRequestProcessorFactory
public abstract class UpdateRequestProcessorFactory implements NamedListInitializedPlugin
{
public void init( final SolrCore core, final Node node )
public void init( NamedList args )
{
// could process the Node
}

View File

@ -17,14 +17,11 @@
package org.apache.solr.update.processor;
import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
import org.w3c.dom.Node;
/**
@ -35,11 +32,9 @@ public class CustomUpdateRequestProcessorFactory extends UpdateRequestProcessorF
public NamedList args = null;
@Override
public void init( final SolrCore core, final Node node )
public void init( NamedList args )
{
if( node != null ) {
args = DOMUtil.childNodesToNamedList( node );
}
this.args = args;
}
@Override

View File

@ -18,7 +18,7 @@
package org.apache.solr.update.processor;
import org.apache.solr.core.SolrCore;
import org.apache.solr.update.processor.ChainedUpdateProcessorFactory;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.apache.solr.util.AbstractSolrTestCase;
/**
@ -35,22 +35,21 @@ public class UpdateRequestProcessorFactoryTest extends AbstractSolrTestCase {
SolrCore core = h.getCore();
// make sure it loaded the factories
ChainedUpdateProcessorFactory chained =
(ChainedUpdateProcessorFactory)core.getUpdateProcessorFactory( "standard" );
UpdateRequestProcessorChain chained = core.getUpdateProcessingChain( "standard" );
// Make sure it got 3 items and configured the Log factory ok
assertEquals( 3, chained.factory.length );
LogUpdateProcessorFactory log = (LogUpdateProcessorFactory)chained.factory[0];
// Make sure it got 3 items and configured the Log chain ok
assertEquals( 3, chained.chain.length );
LogUpdateProcessorFactory log = (LogUpdateProcessorFactory)chained.chain[0];
assertEquals( 100, log.maxNumToLog );
CustomUpdateRequestProcessorFactory custom =
(CustomUpdateRequestProcessorFactory)core.getUpdateProcessorFactory( null );
UpdateRequestProcessorChain custom = core.getUpdateProcessingChain( null );
CustomUpdateRequestProcessorFactory link = (CustomUpdateRequestProcessorFactory) custom.chain[0];
assertEquals( custom, core.getUpdateProcessorFactory( "" ) );
assertEquals( custom, core.getUpdateProcessorFactory( "custom" ) );
assertEquals( custom, core.getUpdateProcessingChain( "" ) );
assertEquals( custom, core.getUpdateProcessingChain( "custom" ) );
// Make sure the NamedListArgs got through ok
assertEquals( "{name={n8=88,n9=99}}", custom.args.toString() );
assertEquals( "{name={n8=88,n9=99}}", link.args.toString() );
}
}

View File

@ -19,31 +19,31 @@
<config>
<updateRequestProcessor>
<factory name="standard" class="solr.ChainedUpdateProcessorFactory" >
<chain class="solr.LogUpdateProcessorFactory" >
<updateRequestProcessorChain name="standard">
<processor class="solr.LogUpdateProcessorFactory" >
<int name="maxNumToLog">100</int>
</chain>
<chain class="solr.CustomUpdateRequestProcessorFactory" >
</processor>
<processor class="solr.CustomUpdateRequestProcessorFactory" >
<lst name="name">
<str name="n1">x1</str>
<str name="n2">x2</str>
</lst>
</chain>
<chain class="solr.CustomUpdateRequestProcessorFactory" >
</processor>
<processor class="solr.CustomUpdateRequestProcessorFactory" >
<lst name="name">
<str name="nA">xA</str>
<str name="nA">xA</str>
</lst>
</chain>
</factory>
</processor>
</updateRequestProcessorChain>
<factory name="custom" class="solr.CustomUpdateRequestProcessorFactory" default="true" >
<updateRequestProcessorChain name="custom" default="true" >
<processor class="solr.CustomUpdateRequestProcessorFactory">
<lst name="name">
<str name="n8">88</str>
<str name="n9">99</str>
</lst>
</factory>
</updateRequestProcessor>
</processor>
</updateRequestProcessorChain>
</config>