mirror of https://github.com/apache/lucene.git
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:
parent
645fd551f6
commit
da634f42eb
|
@ -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" />
|
||||
|
|
|
@ -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;
|
||||
AbstractPluginLoader<UpdateRequestProcessorFactory> loader
|
||||
= new AbstractPluginLoader<UpdateRequestProcessorFactory>( "updateRequestProcessor" ) {
|
||||
|
||||
@Override
|
||||
protected void init(UpdateRequestProcessorFactory plugin, Node node) throws Exception {
|
||||
plugin.init( thiscore, node );
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UpdateRequestProcessorFactory register(String name, UpdateRequestProcessorFactory plugin) throws Exception {
|
||||
return map.put( name, plugin );
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
*/
|
||||
public UpdateRequestProcessorFactory getUpdateProcessorFactory( String name )
|
||||
* @return an update processor registered to the given name. Throw an exception if this chain is undefined
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
assertEquals( custom, core.getUpdateProcessorFactory( "" ) );
|
||||
assertEquals( custom, core.getUpdateProcessorFactory( "custom" ) );
|
||||
UpdateRequestProcessorChain custom = core.getUpdateProcessingChain( null );
|
||||
CustomUpdateRequestProcessorFactory link = (CustomUpdateRequestProcessorFactory) custom.chain[0];
|
||||
|
||||
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() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,31 +19,31 @@
|
|||
|
||||
<config>
|
||||
|
||||
<updateRequestProcessor>
|
||||
<factory name="standard" class="solr.ChainedUpdateProcessorFactory" >
|
||||
<chain class="solr.LogUpdateProcessorFactory" >
|
||||
<int name="maxNumToLog">100</int>
|
||||
</chain>
|
||||
<chain class="solr.CustomUpdateRequestProcessorFactory" >
|
||||
<lst name="name">
|
||||
<str name="n1">x1</str>
|
||||
<str name="n2">x2</str>
|
||||
</lst>
|
||||
</chain>
|
||||
<chain class="solr.CustomUpdateRequestProcessorFactory" >
|
||||
<lst name="name">
|
||||
<str name="nA">xA</str>
|
||||
<str name="nA">xA</str>
|
||||
</lst>
|
||||
</chain>
|
||||
</factory>
|
||||
<updateRequestProcessorChain name="standard">
|
||||
<processor class="solr.LogUpdateProcessorFactory" >
|
||||
<int name="maxNumToLog">100</int>
|
||||
</processor>
|
||||
<processor class="solr.CustomUpdateRequestProcessorFactory" >
|
||||
<lst name="name">
|
||||
<str name="n1">x1</str>
|
||||
<str name="n2">x2</str>
|
||||
</lst>
|
||||
</processor>
|
||||
<processor class="solr.CustomUpdateRequestProcessorFactory" >
|
||||
<lst name="name">
|
||||
<str name="nA">xA</str>
|
||||
<str name="nA">xA</str>
|
||||
</lst>
|
||||
</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>
|
||||
|
|
Loading…
Reference in New Issue