SOLR-6864: Support registering searcher listeners in SolrCoreAware.inform(SolrCore) method

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1646577 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tomas Eduardo Fernandez Lobbe 2014-12-18 23:24:30 +00:00
parent 57bfad4861
commit 869ac14ac4
4 changed files with 180 additions and 7 deletions

View File

@ -330,6 +330,9 @@ Bug Fixes
component. Increased test coverage of expand component with docValues.
(Christine Poerschke, Per Steffensen, shalin)
* SOLR-6864: Support registering searcher listeners in SolrCoreAware.inform(SolrCore)
method. Existing components rely on this. (Tomás Fernández Löbbe)
Optimizations
----------------------

View File

@ -1755,7 +1755,7 @@ public final class SolrCore implements SolrInfoMBean, Closeable {
});
}
if (currSearcher == null && firstSearcherListeners.size() > 0) {
if (currSearcher == null) {
future = searcherExecutor.submit(new Callable() {
@Override
public Object call() throws Exception {
@ -1774,7 +1774,7 @@ public final class SolrCore implements SolrInfoMBean, Closeable {
});
}
if (currSearcher != null && newSearcherListeners.size() > 0) {
if (currSearcher != null) {
future = searcherExecutor.submit(new Callable() {
@Override
public Object call() throws Exception {

View File

@ -0,0 +1,47 @@
<?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>
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}"/>
<luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion>
<xi:include href="solrconfig.snippet.randomindexconfig.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<queryResponseWriter name="xml" default="true"
class="solr.XMLResponseWriter" />
<requestHandler name="standard" class="solr.StandardRequestHandler"/>
<searchComponent name="mock" class="org.apache.solr.search.TestIndexSearcher$MockSearchComponent"/>
</config>

View File

@ -16,22 +16,34 @@
*/
package org.apache.solr.search;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.LogDocMergePolicy;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrEventListener;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.handler.component.SearchComponent;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.servlet.DirectSolrConnection;
import org.apache.solr.util.plugin.SolrCoreAware;
import org.junit.BeforeClass;
import java.util.List;
import java.util.Map;
import java.io.IOException;
public class TestIndexSearcher extends SolrTestCaseJ4 {
@BeforeClass
@ -171,4 +183,115 @@ public class TestIndexSearcher extends SolrTestCaseJ4 {
}
}
public void testSearcherListeners() throws Exception {
MockSearchComponent.registerFirstSearcherListener = false;
MockSearchComponent.registerNewSearcherListener = false;
createCoreAndValidateListeners(0, 0, 0, 0);
MockSearchComponent.registerFirstSearcherListener = true;
MockSearchComponent.registerNewSearcherListener = false;
createCoreAndValidateListeners(1, 1, 1, 1);
MockSearchComponent.registerFirstSearcherListener = true;
MockSearchComponent.registerNewSearcherListener = true;
createCoreAndValidateListeners(1, 1, 2, 1);
}
private void createCoreAndValidateListeners(int numTimesCalled, int numTimesCalledFirstSearcher,
int numTimesCalledAfterGetSearcher, int numTimesCalledFirstSearcherAfterGetSearcher) throws Exception {
CoreContainer cores = h.getCoreContainer();
CoreDescriptor cd = h.getCore().getCoreDescriptor();
SolrCore newCore = null;
// reset counters
MockSearcherListener.numberOfTimesCalled = new AtomicInteger();
MockSearcherListener.numberOfTimesCalledFirstSearcher = new AtomicInteger();
try {
CoreDescriptor newCd = new CoreDescriptor(cores, "core1", cd.getInstanceDir(), "config", "solrconfig-searcher-listeners1.xml");
// Create a new core, this should call all the firstSearcherListeners
newCore = cores.create(newCd);
//validate that the new core was created with the correct solrconfig
assertNotNull(newCore.getSearchComponent("mock"));
assertEquals(MockSearchComponent.class, newCore.getSearchComponent("mock").getClass());
assertEquals(numTimesCalled, MockSearcherListener.numberOfTimesCalled.get());
assertEquals(numTimesCalledFirstSearcher, MockSearcherListener.numberOfTimesCalledFirstSearcher.get());
addDummyDoc(newCore);
// Open a new searcher, this should call the newSearcherListeners
Future<?>[] future = new Future[1];
newCore.getSearcher(true, false, future);
future[0].get();
assertEquals(numTimesCalledAfterGetSearcher, MockSearcherListener.numberOfTimesCalled.get());
assertEquals(numTimesCalledFirstSearcherAfterGetSearcher, MockSearcherListener.numberOfTimesCalledFirstSearcher.get());
} finally {
if (newCore != null) {
cores.unload("core1");
}
}
}
private void addDummyDoc(SolrCore core) throws Exception {
DirectSolrConnection connection = new DirectSolrConnection(core);
SolrRequestHandler handler = core.getRequestHandler("/update");
connection.request(handler, null, adoc("id", "1"));
}
public static class MockSearchComponent extends SearchComponent implements SolrCoreAware {
static boolean registerFirstSearcherListener = false;
static boolean registerNewSearcherListener = false;
@Override
public void prepare(ResponseBuilder rb) throws IOException {}
@Override
public void process(ResponseBuilder rb) throws IOException {}
@Override
public String getDescription() {
return "MockSearchComponent";
}
@Override
public void inform(SolrCore core) {
if (registerFirstSearcherListener) {
core.registerFirstSearcherListener(new MockSearcherListener());
}
if (registerNewSearcherListener) {
core.registerNewSearcherListener(new MockSearcherListener());
}
}
}
static class MockSearcherListener implements SolrEventListener {
static AtomicInteger numberOfTimesCalled;
static AtomicInteger numberOfTimesCalledFirstSearcher;
@Override
public void init(NamedList args) {}
@Override
public void postCommit() {}
@Override
public void postSoftCommit() {}
@Override
public void newSearcher(SolrIndexSearcher newSearcher,
SolrIndexSearcher currentSearcher) {
numberOfTimesCalled.incrementAndGet();
if (currentSearcher == null) {
numberOfTimesCalledFirstSearcher.incrementAndGet();
}
}
}
}