SOLR-4175: SearchComponent chain can't contain two components of the same class and use debugQuery

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1426569 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Erik Hatcher 2012-12-28 16:29:37 +00:00
parent e78141a82c
commit 11c4ce617c
7 changed files with 204 additions and 5 deletions

View File

@ -379,6 +379,9 @@ Bug Fixes
* SOLR-4223: "maxFormContentSize" in jetty.xml is not picked up by jetty 8
so set it via solr webapp context file. (shalin)
* SOLR-4175:SearchComponent chain can't contain two components of the
same class and use debugQuery. (Tomás Fernández Löbbe via ehatcher)
Other Changes
----------------------

View File

@ -565,6 +565,9 @@ public final class SolrCore implements SolrInfoMBean {
} else if (o instanceof NamedListInitializedPlugin) {
((NamedListInitializedPlugin) o).init(info.initArgs);
}
if(o instanceof SearchComponent) {
((SearchComponent) o).setName(info.name);
}
return o;
}
@ -1170,7 +1173,10 @@ public final class SolrCore implements SolrInfoMBean {
if(!registry.containsKey(name)){
T searchComp = resourceLoader.newInstance(c.getName(), c);
if (searchComp instanceof NamedListInitializedPlugin){
((NamedListInitializedPlugin)searchComp).init( new NamedList() );
((NamedListInitializedPlugin)searchComp).init( new NamedList<String>() );
}
if(searchComp instanceof SearchComponent) {
((SearchComponent)searchComp).setName(name);
}
registry.put(name, searchComp);
if (searchComp instanceof SolrInfoMBean){

View File

@ -21,7 +21,6 @@ import java.io.IOException;
import java.net.URL;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.SolrInfoMBean;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
@ -33,6 +32,10 @@ import org.apache.solr.util.plugin.NamedListInitializedPlugin;
*/
public abstract class SearchComponent implements SolrInfoMBean, NamedListInitializedPlugin
{
/**
* The name given to this component in solrconfig.xml file
*/
private String name = this.getClass().getName();
/**
* Prepare the response. Guaranteed to be called before any SearchComponent {@link #process(org.apache.solr.handler.component.ResponseBuilder)} method.
* Called for every incoming request.
@ -71,6 +74,14 @@ public abstract class SearchComponent implements SolrInfoMBean, NamedListInitial
*/
public void finishStage(ResponseBuilder rb) {
}
/**
* Sets the name of the SearchComponent. The name of the component is usually
* the name defined for it in the configuration.
*/
public void setName(String name) {
this.name = name;
}
//////////////////////// NamedListInitializedPlugin methods //////////////////////
@ -84,7 +95,7 @@ public abstract class SearchComponent implements SolrInfoMBean, NamedListInitial
@Override
public String getName() {
return this.getClass().getName();
return name;
}
@Override

View File

@ -0,0 +1,84 @@
<?xml version="1.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.
-->
<!-- This is a "kitchen sink" config file that tests can use.
When writting a new test, feel free to add *new* items (plugins,
config options, etc...) as long as they don't break any existing
tests. if you need to test something esoteric please add a new
"solrconfig-your-esoteric-purpose.xml" config file.
Note in particular that this test is used by MinimalSchemaTest so
Anything added to this file needs to work correctly even if there
is now uniqueKey or defaultSearch Field.
-->
<config>
<jmx />
<!-- Used to specify an alternate directory to hold all index data.
It defaults to "index" if not present, and should probably
not be changed if replication is in use. -->
<dataDir>${solr.data.dir:}</dataDir>
<!-- The DirectoryFactory to use for indexes.
solr.StandardDirectoryFactory, the default, is filesystem based.
solr.RAMDirectoryFactory is memory based and not persistent. -->
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}"/>
<luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
<updateHandler class="solr.DirectUpdateHandler2"></updateHandler>
<queryResponseWriter name="xml" default="true"
class="solr.XMLResponseWriter" />
<requestHandler name="standard" class="solr.StandardRequestHandler">
<bool name="httpCaching">true</bool>
<arr name="first-components">
<str>component1</str>
</arr>
<arr name="last-components">
<str>component2</str>
</arr>
</requestHandler>
<requestHandler name="/update" class="solr.UpdateRequestHandler" />
<!-- enable streaming for testing... -->
<requestDispatcher handleSelect="true" >
<requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="2048" />
<httpCaching lastModifiedFrom="openTime" etagSeed="Solr" never304="false">
<cacheControl>max-age=30, public</cacheControl>
</httpCaching>
</requestDispatcher>
<admin>
<defaultQuery>solr</defaultQuery>
<gettableFiles>solrconfig.xml scheam.xml admin-extra.html</gettableFiles>
</admin>
<searchComponent name="component1" class="org.apache.solr.search.MockSearchComponent">
<str name="testParam">foo</str>
</searchComponent>
<searchComponent name="component2" class="org.apache.solr.search.MockSearchComponent">
<str name="testParam">bar</str>
</searchComponent>
</config>

View File

@ -227,10 +227,10 @@ public class SolrCoreTest extends SolrTestCaseJ4 {
Map<String, SolrInfoMBean> infoRegistry = core.getInfoRegistry();
assertTrue("infoRegistry Size: " + infoRegistry.size() + " is not greater than: " + 0, infoRegistry.size() > 0);
//try out some that we know are in the config
SolrInfoMBean bean = infoRegistry.get(SpellCheckComponent.class.getName());
SolrInfoMBean bean = infoRegistry.get(SpellCheckComponent.COMPONENT_NAME);
assertNotNull("bean not registered", bean);
//try a default one
bean = infoRegistry.get(QueryComponent.class.getName());
bean = infoRegistry.get(QueryComponent.COMPONENT_NAME);
assertNotNull("bean not registered", bean);
//try a Req Handler, which are stored by name, not clas
bean = infoRegistry.get("standard");

View File

@ -0,0 +1,39 @@
package org.apache.solr.search;
import java.io.IOException;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.handler.component.SearchComponent;
public class MockSearchComponent extends SearchComponent {
private String testParam = null;
@Override
public void init(NamedList args) {
super.init(args);
testParam = (String) args.get("testParam");
}
@Override
public void prepare(ResponseBuilder rb) throws IOException {
}
@Override
public void process(ResponseBuilder rb) throws IOException {
rb.rsp.add(this.getName(), this.testParam);
}
@Override
public String getDescription() {
return "Mock search component for tests";
}
@Override
public String getSource() {
return "";
}
}

View File

@ -0,0 +1,56 @@
package org.apache.solr.search;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.handler.component.DebugComponent;
import org.apache.solr.handler.component.FacetComponent;
import org.apache.solr.handler.component.MoreLikeThisComponent;
import org.apache.solr.handler.component.QueryComponent;
import org.apache.solr.handler.component.StatsComponent;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestComponentsName extends SolrTestCaseJ4{
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig-components-name.xml","schema.xml");
}
@Override
public void tearDown() throws Exception {
super.tearDown();
assertU(delQ("*:*"));
assertU((commit()));
}
@Test
public void testComponentsName() {
assertU(adoc("id", "0", "name", "Zapp Brannigan"));
assertU(adoc("id", "1", "name", "The Zapper"));
assertU((commit()));
assertQ("match all docs query",
req("q","*:*")
,"//result[@numFound='2']",
"/response/str[@name='component1'][.='foo']",
"/response/str[@name='component2'][.='bar']");
assertQ("use debugQuery",
req("q","*:*",
"debugQuery", "true")
,"//result[@numFound='2']",
"/response/str[@name='component1'][.='foo']",
"/response/str[@name='component2'][.='bar']",
"/response/lst[@name='debug']/lst[@name='timing']/lst[@name='prepare']/lst[@name='component1']",
"/response/lst[@name='debug']/lst[@name='timing']/lst[@name='prepare']/lst[@name='" + QueryComponent.COMPONENT_NAME + "']",
"/response/lst[@name='debug']/lst[@name='timing']/lst[@name='prepare']/lst[@name='" + FacetComponent.COMPONENT_NAME + "']",
"/response/lst[@name='debug']/lst[@name='timing']/lst[@name='prepare']/lst[@name='" + MoreLikeThisComponent.COMPONENT_NAME + "']",
"/response/lst[@name='debug']/lst[@name='timing']/lst[@name='prepare']/lst[@name='" + StatsComponent.COMPONENT_NAME + "']",
"/response/lst[@name='debug']/lst[@name='timing']/lst[@name='prepare']/lst[@name='" + DebugComponent.COMPONENT_NAME + "']",
"/response/lst[@name='debug']/lst[@name='timing']/lst[@name='prepare']/lst[@name='component2']");
}
}