From da634f42eb270fc6d2f3fef068949a28a73ff585 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Sat, 26 Jul 2008 00:20:44 +0000 Subject: [PATCH] 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 --- example/solr/conf/solrconfig.xml | 16 +-- src/java/org/apache/solr/core/SolrCore.java | 108 ++++++++++++----- .../apache/solr/core/SolrResourceLoader.java | 4 +- .../solr/handler/CSVRequestHandler.java | 7 +- .../solr/handler/XmlUpdateRequestHandler.java | 14 +-- .../ChainedUpdateProcessorFactory.java | 109 ------------------ .../processor/LogUpdateProcessorFactory.java | 11 +- .../update/processor/NoOpUpdateProcessor.java | 63 ---------- .../processor/RunUpdateProcessorFactory.java | 10 +- .../processor/UpdateRequestProcessor.java | 29 ++++- .../UpdateRequestProcessorChain.java | 61 ++++++++++ .../UpdateRequestProcessorFactory.java | 13 ++- .../CustomUpdateRequestProcessorFactory.java | 9 +- .../UpdateRequestProcessorFactoryTest.java | 23 ++-- .../solr/conf/solrconfig-transformers.xml | 42 +++---- 15 files changed, 225 insertions(+), 294 deletions(-) delete mode 100644 src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java delete mode 100644 src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java create mode 100644 src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java diff --git a/example/solr/conf/solrconfig.xml b/example/solr/conf/solrconfig.xml index c913badb01b..bc4e4139d4b 100755 --- a/example/solr/conf/solrconfig.xml +++ b/example/solr/conf/solrconfig.xml @@ -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. --> - - - + - - - + + diff --git a/src/java/org/apache/solr/core/SolrCore.java b/src/java/org/apache/solr/core/SolrCore.java index 9266f90359d..9dfdd3c4fae 100644 --- a/src/java/org/apache/solr/core/SolrCore.java +++ b/src/java/org/apache/solr/core/SolrCore.java @@ -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 searchComponents; - private final Map updateProcessors; + private final Map updateProcessorChains; private final Map infoRegistry = new java.util.HashMap(); 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 loadUpdateProcessors() { - final Map map = new HashMap(); + private Map loadUpdateProcessorChains() { + final Map map = new HashMap(); - // If this is a more general use-case, this could be a regular type - final SolrCore thiscore = this; - AbstractPluginLoader loader - = new AbstractPluginLoader( "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 factories = new ArrayList(links.getLength()); + // Load and initialize the plugin chain + AbstractPluginLoader loader + = new AbstractPluginLoader( "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; } /** diff --git a/src/java/org/apache/solr/core/SolrResourceLoader.java b/src/java/org/apache/solr/core/SolrResourceLoader.java index 91fc97d18a3..ce900b1ce90 100644 --- a/src/java/org/apache/solr/core/SolrResourceLoader.java +++ b/src/java/org/apache/solr/core/SolrResourceLoader.java @@ -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 } ); diff --git a/src/java/org/apache/solr/handler/CSVRequestHandler.java b/src/java/org/apache/solr/handler/CSVRequestHandler.java index 0f7255cee9f..4eacca32cf9 100755 --- a/src/java/org/apache/solr/handler/CSVRequestHandler.java +++ b/src/java/org/apache/solr/handler/CSVRequestHandler.java @@ -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); diff --git a/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java b/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java index 93f9a8d4320..9e584957d48 100644 --- a/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java +++ b/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java @@ -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 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() ); 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(""); diff --git a/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java b/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java deleted file mode 100644 index 911bf01ed6a..00000000000 --- a/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java +++ /dev/null @@ -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: - * - * - * - * - * - * - * 100 - * - * - * - * - * - * @since solr 1.3 - */ -public class ChainedUpdateProcessorFactory extends UpdateRequestProcessorFactory -{ - protected UpdateRequestProcessorFactory[] factory; - - @Override - public void init( final SolrCore core, final Node node ) { - final ArrayList factories = new ArrayList(); - if( node != null ) { - // Load and initialize the plugin chain - AbstractPluginLoader loader - = new AbstractPluginLoader( "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; - } -} diff --git a/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java b/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java index c6d78845794..da98bb8fe22 100644 --- a/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java +++ b/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java @@ -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 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 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 diff --git a/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java b/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java deleted file mode 100644 index bb3d6153f4b..00000000000 --- a/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java +++ /dev/null @@ -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(); - } -} - - diff --git a/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java b/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java index e60d7ea706a..a5e2c6d0e1e 100644 --- a/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java +++ b/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java @@ -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; diff --git a/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java b/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java index 053a306f3ed..da998b46b16 100644 --- a/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java +++ b/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java @@ -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(); + } } diff --git a/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java b/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java new file mode 100644 index 00000000000..0c1d7bbbb20 --- /dev/null +++ b/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java @@ -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: + * + * + * + * + * + * 100 + * + * + * + * + * @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; + } +} diff --git a/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java b/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java index da3c8cf12ae..05150853465 100644 --- a/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java +++ b/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java @@ -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 } diff --git a/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java b/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java index a1e3a39f2e8..de0de6f714a 100644 --- a/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java +++ b/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java @@ -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 diff --git a/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java b/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java index 75f38d496c0..434dc132f88 100644 --- a/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java +++ b/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java @@ -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() ); } } diff --git a/src/test/test-files/solr/conf/solrconfig-transformers.xml b/src/test/test-files/solr/conf/solrconfig-transformers.xml index 14bda55fc50..5b7d97fc619 100644 --- a/src/test/test-files/solr/conf/solrconfig-transformers.xml +++ b/src/test/test-files/solr/conf/solrconfig-transformers.xml @@ -19,31 +19,31 @@ - - - - 100 - - - - x1 - x2 - - - - - xA - xA - - - + + + 100 + + + + x1 + x2 + + + + + xA + xA + + + - + + 88 99 - - + +