diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index ef172696315..c0887b4a752 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -333,6 +333,10 @@ Bug Fixes
in strings since those characters are not valid in javascript strings
(although they are valid in JSON strings). (yonik)
+* SOLR-2536: Add ReloadCacheRequestHandler to fix ExternalFileField bug (if reopenReaders
+ set to true and no index segments have been changed, commit cannot trigger reload
+ external file). (koji)
+
Other Changes
----------------------
diff --git a/solr/src/java/org/apache/solr/search/function/FileFloatSource.java b/solr/src/java/org/apache/solr/search/function/FileFloatSource.java
index daeb10c3a94..3e25cd301c7 100755
--- a/solr/src/java/org/apache/solr/search/function/FileFloatSource.java
+++ b/solr/src/java/org/apache/solr/search/function/FileFloatSource.java
@@ -16,23 +16,38 @@
*/
package org.apache.solr.search.function;
-import org.apache.lucene.index.IndexReader;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.MultiFields;
+import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
import org.apache.lucene.index.IndexReader.ReaderContext;
-import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.index.MultiFields;
+import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.ReaderUtil;
import org.apache.lucene.util.StringHelper;
-import org.apache.lucene.util.BytesRef;
import org.apache.solr.core.SolrCore;
-import org.apache.solr.schema.SchemaField;
+import org.apache.solr.handler.RequestHandlerBase;
+import org.apache.solr.handler.RequestHandlerUtils;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.QParser;
+import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.solr.util.VersionedFile;
-
-import java.io.*;
-import java.util.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Obtains float field values from an external file.
@@ -99,6 +114,10 @@ public class FileFloatSource extends ValueSource {
+ ",defVal="+defVal+",dataDir="+dataDir+")";
}
+
+ public static void resetCache(){
+ floatCache.resetCache();
+ }
private final float[] getCachedFloats(IndexReader reader) {
return (float[])floatCache.get(reader, new Entry(this));
@@ -150,6 +169,14 @@ public class FileFloatSource extends ValueSource {
return value;
}
+
+ public void resetCache(){
+ synchronized(readerCache){
+ // Map.clear() is optional and can throw UnsipportedOperationException,
+ // but readerCache is WeakHashMap and it supports clear().
+ readerCache.clear();
+ }
+ }
}
static Object onlyForTesting; // set to the last value
@@ -272,5 +299,44 @@ public class FileFloatSource extends ValueSource {
return vals;
}
+ public static class ReloadCacheRequestHandler extends RequestHandlerBase {
+
+ static final Logger log = LoggerFactory.getLogger(ReloadCacheRequestHandler.class);
+ @Override
+ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp)
+ throws Exception {
+ FileFloatSource.resetCache();
+ log.debug("readerCache has been reset.");
+
+ UpdateRequestProcessor processor =
+ req.getCore().getUpdateProcessingChain(null).createProcessor(req, rsp);
+ try{
+ RequestHandlerUtils.handleCommit(req, processor, req.getParams(), true);
+ }
+ finally{
+ processor.finish();
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Reload readerCache request handler";
+ }
+
+ @Override
+ public String getSource() {
+ return "$URL$";
+ }
+
+ @Override
+ public String getSourceId() {
+ return "$Id$";
+ }
+
+ @Override
+ public String getVersion() {
+ return "$Revision$";
+ }
+ }
}
diff --git a/solr/src/test-files/solr/conf/solrconfig-functionquery.xml b/solr/src/test-files/solr/conf/solrconfig-functionquery.xml
index 0276195c762..461b31713c5 100755
--- a/solr/src/test-files/solr/conf/solrconfig-functionquery.xml
+++ b/solr/src/test-files/solr/conf/solrconfig-functionquery.xml
@@ -30,6 +30,9 @@
+
+
0.0
diff --git a/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java b/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java
index 28f427f82d6..1bf6dd8edfc 100755
--- a/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java
+++ b/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java
@@ -22,6 +22,8 @@ import org.apache.lucene.search.DefaultSimilarity;
import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.Similarity;
import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.NamedList;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.Ignore;
@@ -191,7 +193,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
}
@Test
- public void testExternalField() {
+ public void testExternalField() throws Exception {
String field = "foo_extf";
float[] ids = {100,-4,0,10,25,5,77,23,55,-78,-45,-24,63,78,94,22,34,54321,261,-627};
@@ -210,8 +212,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
assertTrue(orig == FileFloatSource.onlyForTesting);
makeExternalFile(field, "0=1","UTF-8");
- assertU(adoc("id", "10000")); // will get same reader if no index change
- assertU(commit());
+ assertU(h.query("/reloadCache",lrf.makeRequest("","")));
singleTest(field, "sqrt(\0)");
assertTrue(orig != FileFloatSource.onlyForTesting);
@@ -247,8 +248,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
makeExternalFile(field, sb.toString(),"UTF-8");
// make it visible
- assertU(adoc("id", "10001")); // will get same reader if no index change
- assertU(commit());
+ assertU(h.query("/reloadCache",lrf.makeRequest("","")));
// test it
float[] answers = new float[ids.length*2];