You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ja...@apache.org on 2013/05/30 09:53:46 UTC
svn commit: r1487777 [42/50] - in /lucene/dev/branches/security: ./
dev-tools/ dev-tools/eclipse/dot.settings/ dev-tools/idea/.idea/
dev-tools/idea/.idea/libraries/ dev-tools/idea/lucene/replicator/
dev-tools/maven/ dev-tools/maven/lucene/ dev-tools/ma...
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java Thu May 30 07:53:18 2013
@@ -20,7 +20,17 @@ package org.apache.solr.search;
import java.io.Closeable;
import java.io.IOException;
import java.net.URL;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.lucene.document.Document;
@@ -33,23 +43,55 @@ import org.apache.lucene.document.LazyDo
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
-import org.apache.lucene.index.*;
-import org.apache.lucene.search.*;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.FieldInfos;
+import org.apache.lucene.index.Fields;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.MultiDocsEnum;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.index.StorableField;
+import org.apache.lucene.index.StoredDocument;
+import org.apache.lucene.index.StoredFieldVisitor;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TimeLimitingCollector;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.search.TopDocsCollector;
+import org.apache.lucene.search.TopFieldCollector;
+import org.apache.lucene.search.TopScoreDocCollector;
+import org.apache.lucene.search.Weight;
import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.FSDirectory;
-import org.apache.lucene.store.NRTCachingDirectory;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.OpenBitSet;
import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.DirectoryFactory;
+import org.apache.solr.core.DirectoryFactory.DirContext;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrInfoMBean;
-import org.apache.solr.core.DirectoryFactory.DirContext;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
@@ -57,6 +99,7 @@ import org.apache.solr.request.UnInverte
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
+import org.apache.solr.spelling.QueryConverter;
import org.apache.solr.update.SolrIndexConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -117,26 +160,43 @@ public class SolrIndexSearcher extends I
private DirectoryFactory directoryFactory;
private final AtomicReader atomicReader;
- private String path;
+ private String path;
+ private final boolean reserveDirectory;
+ private final boolean createdDirectory;
+
+ private static DirectoryReader getReader(SolrCore core, SolrIndexConfig config, DirectoryFactory directoryFactory, String path) throws IOException {
+ DirectoryReader reader = null;
+ Directory dir = directoryFactory.get(path, DirContext.DEFAULT, config.lockType);
+ try {
+ reader = core.getIndexReaderFactory().newReader(dir, core);
+ } catch (Throwable t) {
+ directoryFactory.release(dir);
+ throw new SolrException(ErrorCode.SERVER_ERROR, "Error opening Reader", t);
+ }
+ return reader;
+ }
public SolrIndexSearcher(SolrCore core, String path, IndexSchema schema, SolrIndexConfig config, String name, boolean enableCache, DirectoryFactory directoryFactory) throws IOException {
// we don't need to reserve the directory because we get it from the factory
- this(core, path, schema,name, core.getIndexReaderFactory().newReader(directoryFactory.get(path, DirContext.DEFAULT, config.lockType), core), true, enableCache, false, directoryFactory);
+ this(core, path, schema, config, name, null, true, enableCache, false, directoryFactory);
}
- public SolrIndexSearcher(SolrCore core, String path, IndexSchema schema, String name, DirectoryReader r, boolean closeReader, boolean enableCache, boolean reserveDirectory, DirectoryFactory directoryFactory) throws IOException {
- super(r);
+ public SolrIndexSearcher(SolrCore core, String path, IndexSchema schema, SolrIndexConfig config, String name, DirectoryReader r, boolean closeReader, boolean enableCache, boolean reserveDirectory, DirectoryFactory directoryFactory) throws IOException {
+ super(r == null ? getReader(core, config, directoryFactory, path) : r);
+
this.path = path;
this.directoryFactory = directoryFactory;
- this.reader = r;
- this.atomicReader = SlowCompositeReaderWrapper.wrap(r);
+ this.reader = (DirectoryReader) super.readerContext.reader();
+ this.atomicReader = SlowCompositeReaderWrapper.wrap(this.reader);
this.core = core;
this.schema = schema;
this.name = "Searcher@" + Integer.toHexString(hashCode()) + (name!=null ? " "+name : "");
log.info("Opening " + this.name);
- Directory dir = r.directory();
+ Directory dir = this.reader.directory();
+ this.reserveDirectory = reserveDirectory;
+ this.createdDirectory = r == null;
if (reserveDirectory) {
// keep the directory from being released while we use it
directoryFactory.incRef(dir);
@@ -281,8 +341,12 @@ public class SolrIndexSearcher extends I
cache.close();
}
-
- directoryFactory.release(getIndexReader().directory());
+ if (reserveDirectory) {
+ directoryFactory.release(getIndexReader().directory());
+ }
+ if (createdDirectory) {
+ directoryFactory.release(getIndexReader().directory());
+ }
// do this at the end so it only gets done if there are no exceptions
@@ -1172,7 +1236,7 @@ public class SolrIndexSearcher extends I
public static final int GET_DOCSET = 0x40000000;
static final int NO_CHECK_FILTERCACHE = 0x20000000;
static final int NO_SET_QCACHE = 0x10000000;
-
+ public static final int TERMINATE_EARLY = 0x04;
public static final int GET_DOCLIST = 0x02; // get the documents actually returned in a response
public static final int GET_SCORES = 0x01;
@@ -1331,7 +1395,8 @@ public class SolrIndexSearcher extends I
float[] scores;
boolean needScores = (cmd.getFlags() & GET_SCORES) != 0;
-
+ boolean terminateEarly = (cmd.getFlags() & TERMINATE_EARLY) == TERMINATE_EARLY;
+
Query query = QueryUtils.makeQueryable(cmd.getQuery());
ProcessedFilter pf = getProcessedFilter(cmd.getFilter(), cmd.getFilterList());
@@ -1383,7 +1448,9 @@ public class SolrIndexSearcher extends I
}
};
}
-
+ if (terminateEarly) {
+ collector = new EarlyTerminatingCollector(collector, cmd.len);
+ }
if( timeAllowed > 0 ) {
collector = new TimeLimitingCollector(collector, TimeLimitingCollector.getGlobalCounter(), timeAllowed);
}
@@ -1418,6 +1485,9 @@ public class SolrIndexSearcher extends I
topCollector = TopFieldCollector.create(weightSort(cmd.getSort()), len, false, needScores, needScores, true);
}
Collector collector = topCollector;
+ if (terminateEarly) {
+ collector = new EarlyTerminatingCollector(collector, cmd.len);
+ }
if( timeAllowed > 0 ) {
collector = new TimeLimitingCollector(collector, TimeLimitingCollector.getGlobalCounter(), timeAllowed);
}
@@ -1466,6 +1536,7 @@ public class SolrIndexSearcher extends I
DocSet set;
boolean needScores = (cmd.getFlags() & GET_SCORES) != 0;
+ boolean terminateEarly = (cmd.getFlags() & TERMINATE_EARLY) == TERMINATE_EARLY;
int maxDoc = maxDoc();
int smallSetSize = maxDoc>>6;
@@ -1505,7 +1576,9 @@ public class SolrIndexSearcher extends I
}
});
}
-
+ if (terminateEarly) {
+ collector = new EarlyTerminatingCollector(collector, cmd.len);
+ }
if( timeAllowed > 0 ) {
collector = new TimeLimitingCollector(collector, TimeLimitingCollector.getGlobalCounter(), timeAllowed);
}
@@ -1541,7 +1614,9 @@ public class SolrIndexSearcher extends I
DocSetCollector setCollector = new DocSetDelegateCollector(maxDoc>>6, maxDoc, topCollector);
Collector collector = setCollector;
-
+ if (terminateEarly) {
+ collector = new EarlyTerminatingCollector(collector, cmd.len);
+ }
if( timeAllowed > 0 ) {
collector = new TimeLimitingCollector(collector, TimeLimitingCollector.getGlobalCounter(), timeAllowed );
}
@@ -2307,6 +2382,11 @@ class FilterImpl extends Filter {
public int advance(int target) throws IOException {
return doNext(first.advance(target));
}
+
+ @Override
+ public long cost() {
+ return first.cost();
+ }
}
private static class DualFilterIterator extends DocIdSetIterator {
@@ -2344,6 +2424,11 @@ class FilterImpl extends Filter {
if (other == doc) return doc;
}
}
+
+ @Override
+ public long cost() {
+ return Math.min(a.cost(), b.cost());
+ }
}
}
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java Thu May 30 07:53:18 2013
@@ -52,14 +52,14 @@ public class SolrReturnFields extends Re
private final List<String> globs = new ArrayList<String>(1);
// The lucene field names to request from the SolrIndexSearcher
- // Order is important for CSVResponseWriter
- private final Set<String> fields = new LinkedHashSet<String>();
+ private final Set<String> fields = new HashSet<String>();
// Field names that are OK to include in the response.
// This will include pseudo fields, lucene fields, and matching globs
private Set<String> okFieldNames = new HashSet<String>();
// The list of explicitly requested fields
+ // Order is important for CSVResponseWriter
private Set<String> reqFieldNames = null;
protected DocTransformer transformer;
@@ -122,7 +122,7 @@ public class SolrReturnFields extends Re
if(from.equals(rename.getName(j))) {
rename.setName(j, to); // copy from the current target
if(reqFieldNames==null) {
- reqFieldNames = new HashSet<String>();
+ reqFieldNames = new LinkedHashSet<String>();
}
reqFieldNames.add(to); // don't rename our current target
}
@@ -360,12 +360,16 @@ public class SolrReturnFields extends Re
private void addField(String field, String key, DocTransformers augmenters, SolrQueryRequest req)
{
+ if(reqFieldNames==null) {
+ reqFieldNames = new LinkedHashSet<String>();
+ }
+
if(key==null) {
- if(reqFieldNames==null) {
- reqFieldNames = new HashSet<String>();
- }
reqFieldNames.add(field);
}
+ else {
+ reqFieldNames.add(key);
+ }
fields.add(field); // need to put in the map to maintain order for things like CSVResponseWriter
okFieldNames.add( field );
@@ -386,6 +390,19 @@ public class SolrReturnFields extends Re
}
@Override
+ public Set<String> getRequestedFieldNames() {
+ if(_wantsAllFields || reqFieldNames==null || reqFieldNames.isEmpty()) {
+ return null;
+ }
+ return reqFieldNames;
+ }
+
+ @Override
+ public boolean hasPatternMatching() {
+ return !globs.isEmpty();
+ }
+
+ @Override
public boolean wantsField(String name)
{
if( _wantsAllFields || okFieldNames.contains( name ) ){
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java Thu May 30 07:53:18 2013
@@ -755,6 +755,10 @@ public class SortedIntDocSet extends Doc
}
}
+ @Override
+ public long cost() {
+ return docs.length;
+ }
};
}
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SwitchQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SwitchQParserPlugin.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SwitchQParserPlugin.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/SwitchQParserPlugin.java Thu May 30 07:53:18 2013
@@ -82,6 +82,57 @@ import org.apache.commons.lang.StringUti
* v=$shipping}</str>
* </lst>
* </requestHandler></pre>
+ *
+ * <p>
+ * A slightly more interesting variant of the <code>shipping</code> example above, would be
+ * to combine the switch parser with the frange parser, to allow the client to specify an
+ * arbitrary "max shipping" amount that will be used to build a filter if and only if a
+ * value is specified. Example:
+ * </p>
+ * <pre class="prettyprint">
+ * <requestHandler name="/select" class="solr.SearchHandler">
+ * <lst name="invariants">
+ * <str name="shipping_fq">{!frange u=$shipping}shipping_cost</str>
+ * </lst>
+ * <lst name="defaults">
+ * <str name="shipping">any</str>
+ * </lst>
+ * <lst name="appends">
+ * <str name="fq">{!switch case='*:*'
+ * case.any='*:*'
+ * default=$shipping_fq
+ * v=$shipping}</str>
+ * </lst>
+ * </requestHandler></pre>
+ *
+ * <p>
+ * With the above configuration a client that specifies <code>shipping=any</code>, or
+ * does not specify a <code>shipping</code> param at all, will not have the results
+ * filtered. But if a client specifies a numeric value (ie: <code>shipping=10</code>,
+ * <code>shipping=5</code>, etc..) then the results will be limited to documents whose
+ * <code>shipping_cost</code> field has a value less then that number.
+ * </p>
+ *
+ * <p>
+ * A similar use case would be to combine the switch parser with the bbox parser to
+ * support an optional geographic filter that is applied if and only if the client
+ * specifies a <code>location</code> param containing a lat,lon pair to be used as
+ * the center of the bounding box:
+ * </p>
+ * <pre class="prettyprint">
+ * <requestHandler name="/select" class="solr.SearchHandler">
+ * <lst name="invariants">
+ * <str name="bbox_fq">{!bbox pt=$location sfield=geo d=$dist}</str>
+ * </lst>
+ * <lst name="defaults">
+ * <str name="dist">100</str>
+ * </lst>
+ * <lst name="appends">
+ * <str name="fq">{!switch case='*:*'
+ * default=$bbox_fq
+ * v=$location}</str>
+ * </lst>
+ * </requestHandler></pre>
*/
public class SwitchQParserPlugin extends QParserPlugin {
public static String NAME = "switch";
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/distributed/requestfactory/TopGroupsShardRequestFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/distributed/requestfactory/TopGroupsShardRequestFactory.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/distributed/requestfactory/TopGroupsShardRequestFactory.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/distributed/requestfactory/TopGroupsShardRequestFactory.java Thu May 30 07:53:18 2013
@@ -27,6 +27,7 @@ import org.apache.solr.common.params.Sha
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.handler.component.ShardRequest;
import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.IndexSchema;
import org.apache.solr.search.Grouping;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.search.grouping.distributed.ShardRequestFactory;
@@ -112,12 +113,13 @@ public class TopGroupsShardRequestFactor
}
sreq.params.set(GroupParams.GROUP_DISTRIBUTED_SECOND, "true");
+ final IndexSchema schema = rb.req.getSearcher().getSchema();
for (Map.Entry<String, Collection<SearchGroup<BytesRef>>> entry : rb.mergedSearchGroups.entrySet()) {
for (SearchGroup<BytesRef> searchGroup : entry.getValue()) {
String groupValue;
if (searchGroup.groupValue != null) {
String rawGroupValue = searchGroup.groupValue.utf8ToString();
- FieldType fieldType = rb.req.getSearcher().getSchema().getField(entry.getKey()).getType();
+ FieldType fieldType = schema.getField(entry.getKey()).getType();
groupValue = fieldType.indexedToReadable(rawGroupValue);
} else {
groupValue = GROUP_NULL_VALUE;
@@ -127,9 +129,9 @@ public class TopGroupsShardRequestFactor
}
if ((rb.getFieldFlags() & SolrIndexSearcher.GET_SCORES) != 0 || rb.getSortSpec().includesScore()) {
- sreq.params.set(CommonParams.FL, rb.req.getSchema().getUniqueKeyField().getName() + ",score");
+ sreq.params.set(CommonParams.FL, schema.getUniqueKeyField().getName() + ",score");
} else {
- sreq.params.set(CommonParams.FL, rb.req.getSchema().getUniqueKeyField().getName());
+ sreq.params.set(CommonParams.FL, schema.getUniqueKeyField().getName());
}
int origTimeAllowed = sreq.params.getInt(CommonParams.TIME_ALLOWED, -1);
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java Thu May 30 07:53:18 2013
@@ -32,6 +32,7 @@ import org.apache.solr.common.util.Named
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.handler.component.ShardDoc;
import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.grouping.Command;
import org.apache.solr.search.grouping.distributed.command.QueryCommand;
@@ -66,11 +67,12 @@ public class TopGroupsResultTransformer
@Override
public NamedList transform(List<Command> data) throws IOException {
NamedList<NamedList> result = new NamedList<NamedList>();
+ final IndexSchema schema = rb.req.getSearcher().getSchema();
for (Command command : data) {
NamedList commandResult;
if (TopGroupsFieldCommand.class.isInstance(command)) {
TopGroupsFieldCommand fieldCommand = (TopGroupsFieldCommand) command;
- SchemaField groupField = rb.req.getSearcher().getSchema().getField(fieldCommand.getKey());
+ SchemaField groupField = schema.getField(fieldCommand.getKey());
commandResult = serializeTopGroups(fieldCommand.result(), groupField);
} else if (QueryCommand.class.isInstance(command)) {
QueryCommand queryCommand = (QueryCommand) command;
@@ -184,7 +186,8 @@ public class TopGroupsResultTransformer
}
CharsRef spare = new CharsRef();
- SchemaField uniqueField = rb.req.getSearcher().getSchema().getUniqueKeyField();
+ final IndexSchema schema = rb.req.getSearcher().getSchema();
+ SchemaField uniqueField = schema.getUniqueKeyField();
for (GroupDocs<BytesRef> searchGroup : data.groups) {
NamedList<Object> groupResult = new NamedList<Object>();
groupResult.add("totalHits", searchGroup.totalHits);
@@ -211,7 +214,7 @@ public class TopGroupsResultTransformer
for (int j = 0; j < fieldDoc.fields.length; j++) {
Object sortValue = fieldDoc.fields[j];
Sort sortWithinGroup = rb.getGroupingSpec().getSortWithinGroup();
- SchemaField field = sortWithinGroup.getSort()[j].getField() != null ? rb.req.getSearcher().getSchema().getFieldOrNull(sortWithinGroup.getSort()[j].getField()) : null;
+ SchemaField field = sortWithinGroup.getSort()[j].getField() != null ? schema.getFieldOrNull(sortWithinGroup.getSort()[j].getField()) : null;
if (field != null) {
FieldType fieldType = field.getType();
if (sortValue instanceof BytesRef) {
@@ -244,7 +247,8 @@ public class TopGroupsResultTransformer
List<NamedList> documents = new ArrayList<NamedList>();
queryResult.add("documents", documents);
- SchemaField uniqueField = rb.req.getSearcher().getSchema().getUniqueKeyField();
+ final IndexSchema schema = rb.req.getSearcher().getSchema();
+ SchemaField uniqueField = schema.getUniqueKeyField();
CharsRef spare = new CharsRef();
for (ScoreDoc scoreDoc : result.getTopDocs().scoreDocs) {
NamedList<Object> document = new NamedList<Object>();
@@ -264,7 +268,8 @@ public class TopGroupsResultTransformer
for (int j = 0; j < fieldDoc.fields.length; j++) {
Object sortValue = fieldDoc.fields[j];
Sort groupSort = rb.getGroupingSpec().getGroupSort();
- SchemaField field = groupSort.getSort()[j].getField() != null ? rb.req.getSearcher().getSchema().getFieldOrNull(groupSort.getSort()[j].getField()) : null;
+ SchemaField field = groupSort.getSort()[j].getField() != null
+ ? schema.getFieldOrNull(groupSort.getSort()[j].getField()) : null;
if (field != null) {
FieldType fieldType = field.getType();
if (sortValue instanceof BytesRef) {
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java Thu May 30 07:53:18 2013
@@ -50,7 +50,7 @@ public class GroupedEndResultTransformer
*/
@Override
public void transform(Map<String, ?> result, ResponseBuilder rb, SolrDocumentSource solrDocumentSource) {
- NamedList<Object> commands = new NamedList<Object>();
+ NamedList<Object> commands = new SimpleOrderedMap<Object>();
for (Map.Entry<String, ?> entry : result.entrySet()) {
Object value = entry.getValue();
if (TopGroups.class.isInstance(value)) {
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java Thu May 30 07:53:18 2013
@@ -20,14 +20,15 @@ package org.apache.solr.search.similarit
import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.apache.lucene.search.similarities.PerFieldSimilarityWrapper;
import org.apache.lucene.search.similarities.Similarity;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.core.SolrCore;
import org.apache.solr.schema.FieldType;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.SchemaAware;
import org.apache.solr.schema.SimilarityFactory;
+import org.apache.solr.util.plugin.SolrCoreAware;
/**
* SimilarityFactory that returns a {@link PerFieldSimilarityWrapper}
- * that delegates to the field type, if its configured, otherwise
+ * that delegates to the field type, if it's configured, otherwise
* {@link DefaultSimilarity}.
*
* <p>
@@ -42,16 +43,23 @@ import org.apache.solr.schema.Similarity
*
* @see FieldType#getSimilarity
*/
-public class SchemaSimilarityFactory extends SimilarityFactory implements SchemaAware {
+public class SchemaSimilarityFactory extends SimilarityFactory implements SolrCoreAware {
private Similarity similarity;
private Similarity defaultSimilarity = new DefaultSimilarity();
+ private volatile SolrCore core;
+
+ @Override
+ public void inform(SolrCore core) {
+ this.core = core;
+ }
@Override
- public void inform(final IndexSchema schema) {
+ public void init(SolrParams args) {
+ super.init(args);
similarity = new PerFieldSimilarityWrapper() {
@Override
public Similarity get(String name) {
- FieldType fieldType = schema.getFieldTypeNoEx(name);
+ FieldType fieldType = core.getLatestSchema().getFieldTypeNoEx(name);
if (fieldType == null) {
return defaultSimilarity;
} else {
@@ -64,7 +72,7 @@ public class SchemaSimilarityFactory ext
@Override
public Similarity getSimilarity() {
- assert similarity != null : "inform must be called first";
+ assert core != null : "inform must be called first";
return similarity;
}
}
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/LoadAdminUiServlet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/LoadAdminUiServlet.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/LoadAdminUiServlet.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/LoadAdminUiServlet.java Thu May 30 07:53:18 2013
@@ -30,6 +30,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
/**
* A simple servlet to load the Solr Admin UI
@@ -53,14 +54,17 @@ public final class LoadAdminUiServlet ex
Writer out = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
String html = IOUtils.toString(in, "UTF-8");
+ Package pack = SolrCore.class.getPackage();
String[] search = new String[] {
"${contextPath}",
- "${adminPath}"
+ "${adminPath}",
+ "${version}"
};
String[] replace = new String[] {
StringEscapeUtils.escapeJavaScript(request.getContextPath()),
- StringEscapeUtils.escapeJavaScript(cores.getAdminPath())
+ StringEscapeUtils.escapeJavaScript(cores.getAdminPath()),
+ StringEscapeUtils.escapeJavaScript(pack.getSpecificationVersion())
};
out.write( StringUtils.replaceEach(html, search, replace) );
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java Thu May 30 07:53:18 2013
@@ -17,8 +17,6 @@
package org.apache.solr.servlet;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -31,6 +29,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -42,7 +41,6 @@ import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
@@ -50,6 +48,8 @@ import javax.servlet.http.HttpServletRes
import org.apache.commons.io.IOUtils;
import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.cloud.Aliases;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
@@ -58,10 +58,12 @@ import org.apache.solr.common.cloud.ZkNo
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.MapSolrParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.ContentStreamBase;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.common.util.StrUtils;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrCore;
@@ -86,7 +88,7 @@ import org.slf4j.LoggerFactory;
*/
public class SolrDispatchFilter implements Filter
{
- final Logger log = LoggerFactory.getLogger(SolrDispatchFilter.class);
+ final Logger log;
protected volatile CoreContainer cores;
@@ -96,6 +98,19 @@ public class SolrDispatchFilter implemen
private static final Charset UTF8 = Charset.forName("UTF-8");
+ public SolrDispatchFilter() {
+ try {
+ log = LoggerFactory.getLogger(SolrDispatchFilter.class);
+ } catch (NoClassDefFoundError e) {
+ throw new SolrException(
+ ErrorCode.SERVER_ERROR,
+ "Could not find necessary SLF4j logging jars. If using Jetty, the SLF4j logging jars need to go in "
+ +"the jetty lib/ext directory. For other containers, the corresponding directory should be used. "
+ +"For more information, see: http://wiki.apache.org/solr/SolrLogging",
+ e);
+ }
+ }
+
@Override
public void init(FilterConfig config) throws ServletException
{
@@ -134,9 +149,13 @@ public class SolrDispatchFilter implemen
cores = null;
}
}
-
+
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ doFilter(request, response, chain, false);
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain, boolean retry) throws IOException, ServletException {
if( abortErrorMessage != null ) {
((HttpServletResponse)response).sendError( 500, abortErrorMessage );
return;
@@ -149,12 +168,14 @@ public class SolrDispatchFilter implemen
CoreContainer cores = this.cores;
SolrCore core = null;
SolrQueryRequest solrReq = null;
+ Aliases aliases = null;
if( request instanceof HttpServletRequest) {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
SolrRequestHandler handler = null;
String corename = "";
+ String origCorename = null;
try {
// put the core container in request attribute
req.setAttribute("org.apache.solr.CoreContainer", cores);
@@ -185,6 +206,8 @@ public class SolrDispatchFilter implemen
handleAdminRequest(req, response, handler, solrReq);
return;
}
+ boolean usingAliases = false;
+ List<String> collectionsList = null;
// Check for the core admin collections url
if( path.equals( "/admin/collections" ) ) {
handler = cores.getCollectionsHandler();
@@ -198,7 +221,24 @@ public class SolrDispatchFilter implemen
if( idx > 1 ) {
// try to get the corename as a request parameter first
corename = path.substring( 1, idx );
+
+ // look at aliases
+ if (cores.isZooKeeperAware()) {
+ origCorename = corename;
+ ZkStateReader reader = cores.getZkController().getZkStateReader();
+ aliases = reader.getAliases();
+ if (aliases != null && aliases.collectionAliasSize() > 0) {
+ usingAliases = true;
+ String alias = aliases.getCollectionAlias(corename);
+ if (alias != null) {
+ collectionsList = StrUtils.splitSmart(alias, ",", true);
+ corename = collectionsList.get(0);
+ }
+ }
+ }
+
core = cores.getCore(corename);
+
if (core != null) {
path = path.substring( idx );
}
@@ -221,11 +261,21 @@ public class SolrDispatchFilter implemen
// if we couldn't find it locally, look on other nodes
if (core == null && idx > 0) {
- String coreUrl = getRemotCoreUrl(cores, corename);
+ String coreUrl = getRemotCoreUrl(cores, corename, origCorename);
if (coreUrl != null) {
path = path.substring( idx );
remoteQuery(coreUrl + path, req, solrReq, resp);
return;
+ } else {
+ if (!retry) {
+ // we couldn't find a core to work with, try reloading aliases
+ // TODO: it would be nice if admin ui elements skipped this...
+ ZkStateReader reader = cores.getZkController()
+ .getZkStateReader();
+ reader.updateAliases();
+ doFilter(request, response, chain, true);
+ return;
+ }
}
}
@@ -289,6 +339,10 @@ public class SolrDispatchFilter implemen
solrReq = parser.parse( core, path, req );
}
+ if (usingAliases) {
+ processAliases(solrReq, aliases, collectionsList);
+ }
+
final Method reqMethod = Method.getMethod(req.getMethod());
HttpCacheHeaderUtil.setCacheControlHeader(config, resp, reqMethod);
// unless we have been explicitly told not to, do cache validation
@@ -328,6 +382,7 @@ public class SolrDispatchFilter implemen
}
finally {
if( solrReq != null ) {
+ log.debug("Closing out SolrRequest: {}", solrReq);
solrReq.close();
}
if (core != null) {
@@ -341,9 +396,44 @@ public class SolrDispatchFilter implemen
chain.doFilter(request, response);
}
+ private void processAliases(SolrQueryRequest solrReq, Aliases aliases,
+ List<String> collectionsList) {
+ String collection = solrReq.getParams().get("collection");
+ if (collection != null) {
+ collectionsList = StrUtils.splitSmart(collection, ",", true);
+ }
+ if (collectionsList != null) {
+ Set<String> newCollectionsList = new HashSet<String>(
+ collectionsList.size());
+ for (String col : collectionsList) {
+ String al = aliases.getCollectionAlias(col);
+ if (al != null) {
+ List<String> aliasList = StrUtils.splitSmart(al, ",", true);
+ newCollectionsList.addAll(aliasList);
+ } else {
+ newCollectionsList.add(col);
+ }
+ }
+ if (newCollectionsList.size() > 0) {
+ StringBuilder collectionString = new StringBuilder();
+ Iterator<String> it = newCollectionsList.iterator();
+ int sz = newCollectionsList.size();
+ for (int i = 0; i < sz; i++) {
+ collectionString.append(it.next());
+ if (i < newCollectionsList.size() - 1) {
+ collectionString.append(",");
+ }
+ }
+ ModifiableSolrParams params = new ModifiableSolrParams(
+ solrReq.getParams());
+ params.set("collection", collectionString.toString());
+ solrReq.setParams(params);
+ }
+ }
+ }
+
private void remoteQuery(String coreUrl, HttpServletRequest req,
SolrQueryRequest solrReq, HttpServletResponse resp) throws IOException {
-
try {
String urlstr = coreUrl;
@@ -372,6 +462,7 @@ public class SolrDispatchFilter implemen
os = con.getOutputStream(); // side effect: method is switched to POST
try {
IOUtils.copyLarge(is, os);
+ os.flush();
} finally {
IOUtils.closeQuietly(os);
IOUtils.closeQuietly(is); // TODO: I thought we weren't supposed to explicitly close servlet streams
@@ -394,6 +485,7 @@ public class SolrDispatchFilter implemen
os = resp.getOutputStream();
try {
IOUtils.copyLarge(is, os);
+ os.flush();
} finally {
IOUtils.closeQuietly(os); // TODO: I thought we weren't supposed to explicitly close servlet streams
IOUtils.closeQuietly(is);
@@ -409,9 +501,9 @@ public class SolrDispatchFilter implemen
}
- private String getRemotCoreUrl(CoreContainer cores, String collectionName) {
+ private String getRemotCoreUrl(CoreContainer cores, String collectionName, String origCorename) {
ClusterState clusterState = cores.getZkController().getClusterState();
- Collection<Slice> slices = clusterState.getSlices(collectionName);
+ Collection<Slice> slices = clusterState.getActiveSlices(collectionName);
boolean byCoreName = false;
if (slices == null) {
// look by core name
@@ -419,7 +511,7 @@ public class SolrDispatchFilter implemen
Set<String> collections = clusterState.getCollections();
for (String collection : collections) {
slices = new ArrayList<Slice>();
- slices.addAll(clusterState.getSlices(collection));
+ slices.addAll(clusterState.getActiveSlices(collection));
}
}
@@ -444,9 +536,14 @@ public class SolrDispatchFilter implemen
// don't count a local core
continue;
}
- String coreUrl = coreNodeProps.getCoreUrl();
- if (coreUrl.endsWith("/")) {
- coreUrl = coreUrl.substring(0, coreUrl.length() - 1);
+ String coreUrl;
+ if (origCorename != null) {
+ coreUrl = coreNodeProps.getBaseUrl() + "/" + origCorename;
+ } else {
+ coreUrl = coreNodeProps.getCoreUrl();
+ if (coreUrl.endsWith("/")) {
+ coreUrl = coreUrl.substring(0, coreUrl.length() - 1);
+ }
}
return coreUrl;
@@ -461,7 +558,7 @@ public class SolrDispatchFilter implemen
ZkStateReader zkStateReader = cores.getZkController().getZkStateReader();
ClusterState clusterState = zkStateReader.getClusterState();
- Map<String,Slice> slices = clusterState.getSlicesMap(collection);
+ Map<String,Slice> slices = clusterState.getActiveSlicesMap(collection);
if (slices == null) {
return null;
}
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java Thu May 30 07:53:18 2013
@@ -44,6 +44,7 @@ import org.apache.commons.fileupload.dis
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.lucene.util.IOUtils;
import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.MultiMapSolrParams;
import org.apache.solr.common.params.SolrParams;
@@ -72,7 +73,8 @@ public class SolrRequestParsers
private final boolean enableRemoteStreams;
private StandardRequestParser standard;
private boolean handleSelect = true;
-
+ private boolean addHttpRequestToContext;
+
/** Default instance for e.g. admin requests. Limits to 2 MB uploads and does not allow remote streams. */
public static final SolrRequestParsers DEFAULT = new SolrRequestParsers();
@@ -86,6 +88,7 @@ public class SolrRequestParsers
multipartUploadLimitKB = formUploadLimitKB = Integer.MAX_VALUE;
enableRemoteStreams = true;
handleSelect = true;
+ addHttpRequestToContext = false;
} else {
multipartUploadLimitKB = globalConfig.getInt(
"requestDispatcher/requestParsers/@multipartUploadLimitInKB", 2048 );
@@ -99,6 +102,9 @@ public class SolrRequestParsers
// Let this filter take care of /select?xxx format
handleSelect = globalConfig.getBool(
"requestDispatcher/@handleSelect", true );
+
+ addHttpRequestToContext = globalConfig.getBool(
+ "requestDispatcher/requestParsers/@addHttpRequestToContext", false );
}
init(multipartUploadLimitKB, formUploadLimitKB);
}
@@ -106,6 +112,7 @@ public class SolrRequestParsers
private SolrRequestParsers() {
enableRemoteStreams = false;
handleSelect = false;
+ addHttpRequestToContext = false;
init(2048, 2048);
}
@@ -139,6 +146,10 @@ public class SolrRequestParsers
// Handlers and login will want to know the path. If it contains a ':'
// the handler could use it for RESTful URLs
sreq.getContext().put( "path", path );
+
+ if(addHttpRequestToContext) {
+ sreq.getContext().put("httpRequest", req);
+ }
return sreq;
}
@@ -151,7 +162,7 @@ public class SolrRequestParsers
String[] strs = params.getParams( CommonParams.STREAM_URL );
if( strs != null ) {
if( !enableRemoteStreams ) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Remote Streaming is disabled." );
+ throw new SolrException( ErrorCode.BAD_REQUEST, "Remote Streaming is disabled." );
}
for( final String url : strs ) {
ContentStreamBase stream = new ContentStreamBase.URLStream( new URL(url) );
@@ -166,7 +177,7 @@ public class SolrRequestParsers
strs = params.getParams( CommonParams.STREAM_FILE );
if( strs != null ) {
if( !enableRemoteStreams ) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Remote Streaming is disabled." );
+ throw new SolrException( ErrorCode.BAD_REQUEST, "Remote Streaming is disabled." );
}
for( final String file : strs ) {
ContentStreamBase stream = new ContentStreamBase.FileStream( new File(file) );
@@ -222,7 +233,7 @@ public class SolrRequestParsers
if (pos < len) {
final char ch = queryString.charAt(pos);
if (ch > 127) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "URLDecoder: The query string contains a not-%-escaped byte > 127 at position " + pos);
+ throw new SolrException(ErrorCode.BAD_REQUEST, "URLDecoder: The query string contains a not-%-escaped byte > 127 at position " + pos);
}
pos++;
return ch;
@@ -233,7 +244,7 @@ public class SolrRequestParsers
};
parseFormDataContent(in, Long.MAX_VALUE, IOUtils.CHARSET_UTF_8, map);
} catch (IOException ioe) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, ioe);
+ throw new SolrException(ErrorCode.BAD_REQUEST, ioe);
}
}
}
@@ -263,7 +274,7 @@ public class SolrRequestParsers
final String key = decodeChars(keyStream, keyPos, charsetDecoder), value = decodeChars(valueStream, valuePos, charsetDecoder);
MultiMapSolrParams.addParam(key, value, map);
} else if (valueStream.size() > 0) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "application/x-www-form-urlencoded invalid: missing key");
+ throw new SolrException(ErrorCode.BAD_REQUEST, "application/x-www-form-urlencoded invalid: missing key");
}
keyStream.reset();
valueStream.reset();
@@ -295,7 +306,7 @@ public class SolrRequestParsers
}
len++;
if (len > maxLen) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "application/x-www-form-urlencoded content exceeds upload limit of " + (maxLen/1024L) + " KB");
+ throw new SolrException(ErrorCode.BAD_REQUEST, "application/x-www-form-urlencoded content exceeds upload limit of " + (maxLen/1024L) + " KB");
}
}
return len;
@@ -305,7 +316,7 @@ public class SolrRequestParsers
try {
return charsetDecoder.decode(ByteBuffer.wrap(stream.buffer(), 0, stream.size())).toString();
} catch (CharacterCodingException cce) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+ throw new SolrException(ErrorCode.BAD_REQUEST,
"URLDecoder: Invalid character encoding detected after position " + position +
" of query string / form data (while parsing as " + charsetDecoder.charset().name() + ")"
);
@@ -321,7 +332,7 @@ public class SolrRequestParsers
private static int digit16(int b) {
if (b == -1) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "URLDecoder: Incomplete trailing escape (%) pattern");
+ throw new SolrException(ErrorCode.BAD_REQUEST, "URLDecoder: Incomplete trailing escape (%) pattern");
}
if (b >= '0' && b <= '9') {
return b - '0';
@@ -332,7 +343,7 @@ public class SolrRequestParsers
if (b >= 'a' && b <= 'f') {
return b - ('a' - 10);
}
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "URLDecoder: Invalid digit (" + ((char) b) + ") in escape (%) pattern");
+ throw new SolrException(ErrorCode.BAD_REQUEST, "URLDecoder: Invalid digit (" + ((char) b) + ") in escape (%) pattern");
}
public boolean isHandleSelect() {
@@ -342,6 +353,14 @@ public class SolrRequestParsers
public void setHandleSelect(boolean handleSelect) {
this.handleSelect = handleSelect;
}
+
+ public boolean isAddRequestHeadersToContext() {
+ return addHttpRequestToContext;
+ }
+
+ public void setAddRequestHeadersToContext(boolean addRequestHeadersToContext) {
+ this.addHttpRequestToContext = addRequestHeadersToContext;
+ }
}
//-----------------------------------------------------------------
@@ -453,7 +472,7 @@ class MultipartRequestParser implements
final HttpServletRequest req, ArrayList<ContentStream> streams ) throws Exception
{
if( !ServletFileUpload.isMultipartContent(req) ) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Not multipart content! "+req.getContentType() );
+ throw new SolrException( ErrorCode.BAD_REQUEST, "Not multipart content! "+req.getContentType() );
}
MultiMapSolrParams params = SolrRequestParsers.parseQueryString( req.getQueryString() );
@@ -508,7 +527,7 @@ class FormDataRequestParser implements S
final HttpServletRequest req, ArrayList<ContentStream> streams ) throws Exception
{
if (!isFormData(req)) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Not application/x-www-form-urlencoded content: "+req.getContentType() );
+ throw new SolrException( ErrorCode.BAD_REQUEST, "Not application/x-www-form-urlencoded content: "+req.getContentType() );
}
final Map<String,String[]> map = new HashMap<String, String[]>();
@@ -523,7 +542,7 @@ class FormDataRequestParser implements S
final long totalLength = req.getContentLength();
final long maxLength = ((long) uploadLimitKB) * 1024L;
if (totalLength > maxLength) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "application/x-www-form-urlencoded content length (" +
+ throw new SolrException(ErrorCode.BAD_REQUEST, "application/x-www-form-urlencoded content length (" +
totalLength + " bytes) exceeds upload limit of " + uploadLimitKB + " KB");
}
@@ -538,7 +557,7 @@ class FormDataRequestParser implements S
throw getParameterIncompatibilityException();
}
} catch (IOException ioe) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, ioe);
+ throw new SolrException(ErrorCode.BAD_REQUEST, ioe);
} catch (IllegalStateException ise) {
throw (SolrException) getParameterIncompatibilityException().initCause(ise);
} finally {
@@ -549,7 +568,7 @@ class FormDataRequestParser implements S
}
private SolrException getParameterIncompatibilityException() {
- return new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+ return new SolrException(ErrorCode.SERVER_ERROR,
"Solr requires that request parameters sent using application/x-www-form-urlencoded " +
"content-type can be read through the request input stream. Unfortunately, the " +
"stream was empty / not available. This may be caused by another servlet filter calling " +
@@ -595,7 +614,8 @@ class StandardRequestParser implements S
final HttpServletRequest req, ArrayList<ContentStream> streams ) throws Exception
{
String method = req.getMethod().toUpperCase(Locale.ROOT);
- if ("GET".equals(method) || "HEAD".equals(method)) {
+ if ("GET".equals(method) || "HEAD".equals(method)
+ || ("PUT".equals(method) && req.getRequestURI().contains("/schema"))) {
return SolrRequestParsers.parseQueryString(req.getQueryString());
}
if ("POST".equals( method ) ) {
@@ -607,7 +627,7 @@ class StandardRequestParser implements S
}
return raw.parseParamsAndFillStreams(req, streams);
}
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Unsupported method: "+method );
+ throw new SolrException(ErrorCode.BAD_REQUEST, "Unsupported method: " + method + " for request " + req);
}
}
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/ZookeeperInfoServlet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/ZookeeperInfoServlet.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/ZookeeperInfoServlet.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/servlet/ZookeeperInfoServlet.java Thu May 30 07:53:18 2013
@@ -32,8 +32,8 @@ import javax.servlet.http.HttpServletRes
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.IOUtils;
-import org.apache.noggit.CharArr;
-import org.apache.noggit.JSONWriter;
+import org.noggit.CharArr;
+import org.noggit.JSONWriter;
import org.apache.solr.cloud.ZkController;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.SolrZkClient;
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/FileBasedSpellChecker.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/FileBasedSpellChecker.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/FileBasedSpellChecker.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/FileBasedSpellChecker.java Thu May 30 07:53:18 2013
@@ -21,7 +21,13 @@ import java.io.InputStreamReader;
import java.util.List;
import org.apache.lucene.document.Field;
-import org.apache.lucene.index.*;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.LogByteSizeMergePolicy;
+import org.apache.lucene.index.LogMergePolicy;
+import org.apache.solr.schema.IndexSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,7 +66,7 @@ public class FileBasedSpellChecker exten
@Override
public void build(SolrCore core, SolrIndexSearcher searcher) throws IOException {
- loadExternalFileDictionary(core);
+ loadExternalFileDictionary(core, searcher);
spellChecker.clearIndex();
// TODO: you should be able to specify the IWC params?
// TODO: if we enable this, codec gets angry since field won't exist in the schema
@@ -76,12 +82,12 @@ public class FileBasedSpellChecker exten
return null;
}
- private void loadExternalFileDictionary(SolrCore core) {
+ private void loadExternalFileDictionary(SolrCore core, SolrIndexSearcher searcher) {
try {
-
+ IndexSchema schema = null == searcher ? core.getLatestSchema() : searcher.getSchema();
// Get the field's analyzer
- if (fieldTypeName != null && core.getSchema().getFieldTypeNoEx(fieldTypeName) != null) {
- FieldType fieldType = core.getSchema().getFieldTypes().get(fieldTypeName);
+ if (fieldTypeName != null && schema.getFieldTypeNoEx(fieldTypeName) != null) {
+ FieldType fieldType = schema.getFieldTypes().get(fieldTypeName);
// Do index-time analysis using the given fieldType's analyzer
RAMDirectory ramDir = new RAMDirectory();
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/SolrSpellChecker.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/SolrSpellChecker.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/SolrSpellChecker.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/SolrSpellChecker.java Thu May 30 07:53:18 2013
@@ -29,6 +29,7 @@ import org.apache.solr.common.util.Named
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.component.SpellCheckMergeData;
import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.IndexSchema;
import org.apache.solr.search.SolrIndexSearcher;
import java.io.IOException;
@@ -63,12 +64,13 @@ public abstract class SolrSpellChecker {
name = DEFAULT_DICTIONARY_NAME;
}
field = (String)config.get(FIELD);
- if (field != null && core.getSchema().getFieldTypeNoEx(field) != null) {
- analyzer = core.getSchema().getFieldType(field).getQueryAnalyzer();
+ IndexSchema schema = core.getLatestSchema();
+ if (field != null && schema.getFieldTypeNoEx(field) != null) {
+ analyzer = schema.getFieldType(field).getQueryAnalyzer();
}
fieldTypeName = (String) config.get(FIELD_TYPE);
- if (core.getSchema().getFieldTypes().containsKey(fieldTypeName)) {
- FieldType fieldType = core.getSchema().getFieldTypes().get(fieldTypeName);
+ if (schema.getFieldTypes().containsKey(fieldTypeName)) {
+ FieldType fieldType = schema.getFieldTypes().get(fieldTypeName);
analyzer = fieldType.getQueryAnalyzer();
}
if (analyzer == null) {
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/SpellCheckCollator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/SpellCheckCollator.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/SpellCheckCollator.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/SpellCheckCollator.java Thu May 30 07:53:18 2013
@@ -22,7 +22,9 @@ import java.util.Iterator;
import java.util.List;
import org.apache.lucene.analysis.Token;
+import org.apache.lucene.index.IndexReader;
import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.DisMaxParams;
import org.apache.solr.common.params.GroupParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
@@ -33,15 +35,22 @@ import org.apache.solr.handler.component
import org.apache.solr.handler.component.SearchComponent;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.search.EarlyTerminatingCollectorException;
+import org.apache.solr.search.SolrIndexSearcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SpellCheckCollator {
private static final Logger LOG = LoggerFactory.getLogger(SpellCheckCollator.class);
-
- public List<SpellCheckCollation> collate(SpellingResult result, String originalQuery, ResponseBuilder ultimateResponse,
- int maxCollations, int maxTries, int maxEvaluations, boolean suggestionsMayOverlap) {
- List<SpellCheckCollation> collations = new ArrayList<SpellCheckCollation>();
+ private int maxCollations = 1;
+ private int maxCollationTries = 0;
+ private int maxCollationEvaluations = 10000;
+ private boolean suggestionsMayOverlap = false;
+ private int docCollectionLimit = 0;
+
+ public List<SpellCheckCollation> collate(SpellingResult result,
+ String originalQuery, ResponseBuilder ultimateResponse) {
+ List<SpellCheckCollation> collations = new ArrayList<SpellCheckCollation>();
QueryComponent queryComponent = null;
if (ultimateResponse.components != null) {
@@ -54,6 +63,7 @@ public class SpellCheckCollator {
}
boolean verifyCandidateWithQuery = true;
+ int maxTries = maxCollationTries;
int maxNumberToIterate = maxTries;
if (maxTries < 1) {
maxTries = 1;
@@ -65,10 +75,17 @@ public class SpellCheckCollator {
maxTries = 1;
verifyCandidateWithQuery = false;
}
+ docCollectionLimit = docCollectionLimit > 0 ? docCollectionLimit : 0;
+ int maxDocId = -1;
+ if (verifyCandidateWithQuery && docCollectionLimit > 0) {
+ IndexReader reader = ultimateResponse.req.getSearcher().getIndexReader();
+ maxDocId = reader.maxDoc();
+ }
int tryNo = 0;
int collNo = 0;
- PossibilityIterator possibilityIter = new PossibilityIterator(result.getSuggestions(), maxNumberToIterate, maxEvaluations, suggestionsMayOverlap);
+ PossibilityIterator possibilityIter = new PossibilityIterator(result.getSuggestions(),
+ maxNumberToIterate, maxCollationEvaluations, suggestionsMayOverlap);
while (tryNo < maxTries && collNo < maxCollations && possibilityIter.hasNext()) {
PossibilityIterator.RankedSpellPossibility possibility = possibilityIter.next();
@@ -96,12 +113,25 @@ public class SpellCheckCollator {
}
params.set(CommonParams.Q, collationQueryStr);
params.remove(CommonParams.START);
+ params.set(CommonParams.ROWS, "" + docCollectionLimit);
+ // we don't want any stored fields
params.set(CommonParams.FL, "id");
- params.set(CommonParams.ROWS, "0");
+ // we'll sort by doc id to ensure no scoring is done.
+ params.set(CommonParams.SORT, "_docid_ asc");
+ // If a dismax query, don't add unnecessary clauses for scoring
+ params.remove(DisMaxParams.TIE);
+ params.remove(DisMaxParams.PF);
+ params.remove(DisMaxParams.PF2);
+ params.remove(DisMaxParams.PF3);
+ params.remove(DisMaxParams.BQ);
+ params.remove(DisMaxParams.BF);
+ // Collate testing does not support Grouping (see SOLR-2577)
params.remove(GroupParams.GROUP);
// creating a request here... make sure to close it!
- ResponseBuilder checkResponse = new ResponseBuilder(new LocalSolrQueryRequest(ultimateResponse.req.getCore(), params),new SolrQueryResponse(), Arrays.<SearchComponent>asList(queryComponent));
+ ResponseBuilder checkResponse = new ResponseBuilder(
+ new LocalSolrQueryRequest(ultimateResponse.req.getCore(), params),
+ new SolrQueryResponse(), Arrays.<SearchComponent> asList(queryComponent));
checkResponse.setQparser(ultimateResponse.getQparser());
checkResponse.setFilters(ultimateResponse.getFilters());
checkResponse.setQueryString(collationQueryStr);
@@ -109,8 +139,19 @@ public class SpellCheckCollator {
try {
queryComponent.prepare(checkResponse);
+ if (docCollectionLimit > 0) {
+ int f = checkResponse.getFieldFlags();
+ checkResponse.setFieldFlags(f |= SolrIndexSearcher.TERMINATE_EARLY);
+ }
queryComponent.process(checkResponse);
hits = (Integer) checkResponse.rsp.getToLog().get("hits");
+ } catch (EarlyTerminatingCollectorException etce) {
+ assert (docCollectionLimit > 0);
+ if (etce.getLastDocId() + 1 == maxDocId) {
+ hits = docCollectionLimit;
+ } else {
+ hits = maxDocId / ((etce.getLastDocId() + 1) / docCollectionLimit);
+ }
} catch (Exception e) {
LOG.warn("Exception trying to re-query to check if a spell check possibility would return any hits.", e);
} finally {
@@ -191,6 +232,27 @@ public class SpellCheckCollator {
offset += corr.length() - oneForReqOrProhib - (tok.endOffset() - tok.startOffset());
}
return collation.toString();
- }
-
+ }
+ public SpellCheckCollator setMaxCollations(int maxCollations) {
+ this.maxCollations = maxCollations;
+ return this;
+ }
+ public SpellCheckCollator setMaxCollationTries(int maxCollationTries) {
+ this.maxCollationTries = maxCollationTries;
+ return this;
+ }
+ public SpellCheckCollator setMaxCollationEvaluations(
+ int maxCollationEvaluations) {
+ this.maxCollationEvaluations = maxCollationEvaluations;
+ return this;
+ }
+ public SpellCheckCollator setSuggestionsMayOverlap(
+ boolean suggestionsMayOverlap) {
+ this.suggestionsMayOverlap = suggestionsMayOverlap;
+ return this;
+ }
+ public SpellCheckCollator setDocCollectionLimit(int docCollectionLimit) {
+ this.docCollectionLimit = docCollectionLimit;
+ return this;
+ }
}
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java Thu May 30 07:53:18 2013
@@ -77,7 +77,7 @@ public class AnalyzingLookupFactory exte
if (fieldTypeName == null) {
throw new IllegalArgumentException("Error in configuration: " + QUERY_ANALYZER + " parameter is mandatory");
}
- FieldType ft = core.getSchema().getFieldTypeByName(fieldTypeName.toString());
+ FieldType ft = core.getLatestSchema().getFieldTypeByName(fieldTypeName.toString());
Analyzer indexAnalyzer = ft.getAnalyzer();
Analyzer queryAnalyzer = ft.getQueryAnalyzer();
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/suggest/fst/FuzzyLookupFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/suggest/fst/FuzzyLookupFactory.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/suggest/fst/FuzzyLookupFactory.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/spelling/suggest/fst/FuzzyLookupFactory.java Thu May 30 07:53:18 2013
@@ -67,7 +67,7 @@ public class FuzzyLookupFactory extends
throw new IllegalArgumentException("Error in configuration: " + AnalyzingLookupFactory.QUERY_ANALYZER + " parameter is mandatory");
}
// retrieve index and query analyzers for the field
- FieldType ft = core.getSchema().getFieldTypeByName(fieldTypeName.toString());
+ FieldType ft = core.getLatestSchema().getFieldTypeByName(fieldTypeName.toString());
Analyzer indexAnalyzer = ft.getAnalyzer();
Analyzer queryAnalyzer = ft.getQueryAnalyzer();
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java Thu May 30 07:53:18 2013
@@ -22,9 +22,9 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.store.AlreadyClosedException;
import org.apache.solr.cloud.RecoveryStrategy;
import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.DirectoryFactory;
@@ -48,7 +48,6 @@ public final class DefaultSolrCoreState
private volatile boolean recoveryRunning;
private RecoveryStrategy recoveryStrat;
- private volatile boolean closed = false;
private RefCounted<IndexWriter> refCntWriter;
@@ -71,6 +70,7 @@ public final class DefaultSolrCoreState
log.info("closing IndexWriter...");
indexWriter.close();
}
+ indexWriter = null;
} catch (Throwable t) {
log.error("Error during shutdown of writer.", t);
}
@@ -79,17 +79,9 @@ public final class DefaultSolrCoreState
@Override
public RefCounted<IndexWriter> getIndexWriter(SolrCore core)
throws IOException {
-
- if (closed) {
- throw new RuntimeException("SolrCoreState already closed");
- }
-
synchronized (writerPauseLock) {
- if (core == null) {
- // core == null is a signal to just return the current writer, or null
- // if none.
- if (refCntWriter != null) refCntWriter.incref();
- return refCntWriter;
+ if (closed) {
+ throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "SolrCoreState already closed");
}
while (pauseWriter) {
@@ -98,12 +90,24 @@ public final class DefaultSolrCoreState
} catch (InterruptedException e) {}
if (closed) {
- throw new RuntimeException("Already closed");
+ throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Already closed");
}
}
+ if (core == null) {
+ // core == null is a signal to just return the current writer, or null
+ // if none.
+ initRefCntWriter();
+ if (refCntWriter == null) return null;
+ writerFree = false;
+ writerPauseLock.notifyAll();
+ if (refCntWriter != null) refCntWriter.incref();
+
+ return refCntWriter;
+ }
+
if (indexWriter == null) {
- indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2", false);
+ indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2");
}
initRefCntWriter();
writerFree = false;
@@ -114,7 +118,7 @@ public final class DefaultSolrCoreState
}
private void initRefCntWriter() {
- if (refCntWriter == null) {
+ if (refCntWriter == null && indexWriter != null) {
refCntWriter = new RefCounted<IndexWriter>(indexWriter) {
@Override
public void close() {
@@ -128,13 +132,14 @@ public final class DefaultSolrCoreState
}
@Override
- public synchronized void newIndexWriter(SolrCore core, boolean rollback, boolean forceNewDir) throws IOException {
- if (closed) {
- throw new AlreadyClosedException("SolrCoreState already closed");
- }
+ public synchronized void newIndexWriter(SolrCore core, boolean rollback) throws IOException {
log.info("Creating new IndexWriter...");
String coreName = core.getName();
synchronized (writerPauseLock) {
+ if (closed) {
+ throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Already closed");
+ }
+
// we need to wait for the Writer to fall out of use
// first lets stop it from being lent out
pauseWriter = true;
@@ -147,7 +152,7 @@ public final class DefaultSolrCoreState
} catch (InterruptedException e) {}
if (closed) {
- throw new RuntimeException("SolrCoreState already closed");
+ throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "SolrCoreState already closed");
}
}
@@ -171,7 +176,7 @@ public final class DefaultSolrCoreState
}
}
}
- indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2", forceNewDir);
+ indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2");
log.info("New IndexWriter is ready to be used.");
// we need to null this so it picks up the new writer next get call
refCntWriter = null;
@@ -185,13 +190,13 @@ public final class DefaultSolrCoreState
@Override
public synchronized void rollbackIndexWriter(SolrCore core) throws IOException {
- newIndexWriter(core, true, true);
+ newIndexWriter(core, true);
}
- protected SolrIndexWriter createMainIndexWriter(SolrCore core, String name, boolean forceNewDirectory) throws IOException {
+ protected SolrIndexWriter createMainIndexWriter(SolrCore core, String name) throws IOException {
return SolrIndexWriter.create(name, core.getNewIndexDir(),
- core.getDirectoryFactory(), false, core.getSchema(),
- core.getSolrConfig().indexConfig, core.getDeletionPolicy(), core.getCodec(), forceNewDirectory);
+ core.getDirectoryFactory(), false, core.getLatestSchema(),
+ core.getSolrConfig().indexConfig, core.getDeletionPolicy(), core.getCodec());
}
@Override
@@ -206,12 +211,18 @@ public final class DefaultSolrCoreState
return;
}
+ // check before we grab the lock
if (cc.isShutDown()) {
log.warn("Skipping recovery because Solr is shutdown");
return;
}
synchronized (recoveryLock) {
+ // to be air tight we must also check after lock
+ if (cc.isShutDown()) {
+ log.warn("Skipping recovery because Solr is shutdown");
+ return;
+ }
log.info("Running recovery - first canceling any ongoing recovery");
cancelRecovery();
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java Thu May 30 07:53:18 2013
@@ -51,6 +51,7 @@ import org.apache.solr.request.LocalSolr
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.FunctionRangeQuery;
import org.apache.solr.search.QParser;
@@ -110,7 +111,7 @@ public class DirectUpdateHandler2 extend
}
public DirectUpdateHandler2(SolrCore core, UpdateHandler updateHandler) {
- super(core);
+ super(core, updateHandler.getUpdateLog());
solrCoreState = core.getSolrCoreState();
UpdateHandlerInfo updateHandlerInfo = core.getSolrConfig()
@@ -123,11 +124,6 @@ public class DirectUpdateHandler2 extend
int softCommitTimeUpperBound = updateHandlerInfo.autoSoftCommmitMaxTime; // getInt("updateHandler/autoSoftCommit/maxTime", -1);
softCommitTracker = new CommitTracker("Soft", core, softCommitDocsUpperBound, softCommitTimeUpperBound, updateHandlerInfo.openSearcher, true);
- this.ulog = updateHandler.getUpdateLog();
- if (this.ulog != null) {
- this.ulog.init(this, core);
- }
-
commitWithinSoftCommit = updateHandlerInfo.commitWithinSoftCommit;
}
@@ -162,6 +158,7 @@ public class DirectUpdateHandler2 extend
}
try {
+ IndexSchema schema = cmd.getReq().getSchema();
if (cmd.overwrite) {
@@ -401,7 +398,7 @@ public class DirectUpdateHandler2 extend
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
IndexWriter writer = iw.get();
- writer.updateDocument(idTerm, luceneDocument, core.getSchema()
+ writer.updateDocument(idTerm, luceneDocument, cmd.getReq().getSchema()
.getAnalyzer());
for (Query q : dbqList) {
@@ -616,8 +613,8 @@ public class DirectUpdateHandler2 extend
}
@Override
- public void newIndexWriter(boolean rollback, boolean forceNewDir) throws IOException {
- solrCoreState.newIndexWriter(core, rollback, forceNewDir);
+ public void newIndexWriter(boolean rollback) throws IOException {
+ solrCoreState.newIndexWriter(core, rollback);
}
/**
@@ -749,7 +746,7 @@ public class DirectUpdateHandler2 extend
@Override
public void split(SplitIndexCommand cmd) throws IOException {
- // TODO: do a commit first?
+ commit(new CommitUpdateCommand(cmd.req, false));
SolrIndexSplitter splitter = new SolrIndexSplitter(cmd);
splitter.split();
}
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DocumentBuilder.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DocumentBuilder.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DocumentBuilder.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/DocumentBuilder.java Thu May 30 07:53:18 2013
@@ -17,8 +17,6 @@
package org.apache.solr.update;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import org.apache.lucene.document.Document;
@@ -27,154 +25,23 @@ import org.apache.lucene.index.StorableF
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField;
-import org.apache.solr.schema.*;
+import org.apache.solr.schema.CopyField;
+import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.schema.SchemaField;
+
/**
*
*/
-
-
-// Not thread safe - by design. Create a new builder for each thread.
public class DocumentBuilder {
- private final IndexSchema schema;
- private Document doc;
- private HashMap<String,String> map;
-
- public DocumentBuilder(IndexSchema schema) {
- this.schema = schema;
- }
-
- public void startDoc() {
- doc = new Document();
- map = new HashMap<String,String>();
- }
-
- protected void addSingleField(SchemaField sfield, String val, float boost) {
- //System.out.println("###################ADDING FIELD "+sfield+"="+val);
-
- // we don't check for a null val ourselves because a solr.FieldType
- // might actually want to map it to something. If createField()
- // returns null, then we don't store the field.
- List<StorableField> fields = sfield.createFields(val, boost);
- if (!fields.isEmpty()) {
- if (!sfield.multiValued()) {
- String oldValue = map.put(sfield.getName(), val);
- if (oldValue != null) {
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "ERROR: multiple values encountered for non multiValued field " + sfield.getName()
- + ": first='" + oldValue + "' second='" + val + "'");
- }
- }
- // Add each field
- for (StorableField field : fields) {
- doc.add((Field) field);
- }
- }
-
- }
-
- /**
- * Add the specified {@link org.apache.solr.schema.SchemaField} to the document. Does not invoke the copyField mechanism.
- * @param sfield The {@link org.apache.solr.schema.SchemaField} to add
- * @param val The value to add
- * @param boost The boost factor
- *
- * @see #addField(String, String)
- * @see #addField(String, String, float)
- * @see #addSingleField(org.apache.solr.schema.SchemaField, String, float)
- */
- public void addField(SchemaField sfield, String val, float boost) {
- addSingleField(sfield,val,boost);
- }
-
- /**
- * Add the Field and value to the document, invoking the copyField mechanism
- * @param name The name of the field
- * @param val The value to add
- *
- * @see #addField(String, String, float)
- * @see #addField(org.apache.solr.schema.SchemaField, String, float)
- * @see #addSingleField(org.apache.solr.schema.SchemaField, String, float)
- */
- public void addField(String name, String val) {
- addField(name, val, 1.0f);
- }
-
- /**
- * Add the Field and value to the document with the specified boost, invoking the copyField mechanism
- * @param name The name of the field.
- * @param val The value to add
- * @param boost The boost
- *
- * @see #addField(String, String)
- * @see #addField(org.apache.solr.schema.SchemaField, String, float)
- * @see #addSingleField(org.apache.solr.schema.SchemaField, String, float)
- *
- */
- public void addField(String name, String val, float boost) {
- SchemaField sfield = schema.getFieldOrNull(name);
- if (sfield != null) {
- addField(sfield,val,boost);
- }
-
- // Check if we should copy this field to any other fields.
- // This could happen whether it is explicit or not.
- final List<CopyField> copyFields = schema.getCopyFieldsList(name);
- if (copyFields != null) {
- for(CopyField cf : copyFields) {
- addSingleField(cf.getDestination(), cf.getLimitedValue( val ), boost);
- }
- }
-
- // error if this field name doesn't match anything
- if (sfield==null && (copyFields==null || copyFields.size()==0)) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,"ERROR:unknown field '" + name + "'");
- }
- }
-
- public void endDoc() {
- }
-
- // specific to this type of document builder
- public Document getDoc() throws IllegalArgumentException {
-
- // Check for all required fields -- Note, all fields with a
- // default value are defacto 'required' fields.
- List<String> missingFields = null;
- for (SchemaField field : schema.getRequiredFields()) {
- if (doc.getField(field.getName() ) == null) {
- if (field.getDefaultValue() != null) {
- addField(doc, field, field.getDefaultValue(), 1.0f);
- } else {
- if (missingFields==null) {
- missingFields = new ArrayList<String>(1);
- }
- missingFields.add(field.getName());
- }
- }
- }
-
- if (missingFields != null) {
- StringBuilder builder = new StringBuilder();
- // add the uniqueKey if possible
- if( schema.getUniqueKeyField() != null ) {
- String n = schema.getUniqueKeyField().getName();
- String v = doc.getField( n ).stringValue();
- builder.append( "Document ["+n+"="+v+"] " );
- }
- builder.append("missing required fields: " );
- for (String field : missingFields) {
- builder.append(field);
- builder.append(" ");
- }
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, builder.toString());
- }
-
- Document ret = doc; doc=null;
- return ret;
- }
-
private static void addField(Document doc, SchemaField field, Object val, float boost) {
+ if (val instanceof StorableField) {
+ // set boost to the calculated compound boost
+ ((Field)val).setBoost(boost);
+ doc.add((Field)val);
+ return;
+ }
for (StorableField f : field.getType().createFields(field, val, boost)) {
if (f != null) doc.add((Field) f); // null fields are not added
}
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/PeerSync.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/PeerSync.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/PeerSync.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/PeerSync.java Thu May 30 07:53:18 2013
@@ -51,6 +51,7 @@ import org.apache.solr.response.SolrQuer
import org.apache.solr.update.processor.DistributedUpdateProcessorFactory;
import org.apache.solr.update.processor.RunUpdateProcessorFactory;
import org.apache.solr.update.processor.UpdateRequestProcessor;
+import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -447,13 +448,8 @@ public class PeerSync {
SolrQueryRequest req = new LocalSolrQueryRequest(uhandler.core, params);
SolrQueryResponse rsp = new SolrQueryResponse();
- // TODO: use the standard update processor chain now that it has support to skip processors before the DistributedUpdateProcessor?
- RunUpdateProcessorFactory runFac = new RunUpdateProcessorFactory();
- DistributedUpdateProcessorFactory magicFac = new DistributedUpdateProcessorFactory();
- runFac.init(new NamedList());
- magicFac.init(new NamedList());
-
- UpdateRequestProcessor proc = magicFac.getInstance(req, rsp, runFac.getInstance(req, rsp, null));
+ UpdateRequestProcessorChain processorChain = req.getCore().getUpdateProcessingChain(null);
+ UpdateRequestProcessor proc = processorChain.createProcessor(req, rsp);
Collections.sort(updates, updateRecordComparator);
Modified: lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/SolrCoreState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/SolrCoreState.java?rev=1487777&r1=1487776&r2=1487777&view=diff
==============================================================================
--- lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/SolrCoreState.java (original)
+++ lucene/dev/branches/security/solr/core/src/java/org/apache/solr/update/SolrCoreState.java Thu May 30 07:53:18 2013
@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
public abstract class SolrCoreState {
public static Logger log = LoggerFactory.getLogger(SolrCoreState.class);
+ protected boolean closed = false;
private final Object deleteLock = new Object();
public Object getUpdateLock() {
@@ -44,10 +45,6 @@ public abstract class SolrCoreState {
}
private int solrCoreStateRefCnt = 1;
-
- public synchronized int getSolrCoreStateRefCnt() {
- return solrCoreStateRefCnt;
- }
public void increfSolrCoreState() {
synchronized (this) {
@@ -58,11 +55,13 @@ public abstract class SolrCoreState {
}
}
- public void decrefSolrCoreState(IndexWriterCloser closer) {
+ public boolean decrefSolrCoreState(IndexWriterCloser closer) {
boolean close = false;
synchronized (this) {
solrCoreStateRefCnt--;
+ assert solrCoreStateRefCnt >= 0;
if (solrCoreStateRefCnt == 0) {
+ closed = true;
close = true;
}
}
@@ -75,6 +74,7 @@ public abstract class SolrCoreState {
log.error("Error closing SolrCoreState", t);
}
}
+ return close;
}
public abstract Lock getCommitLock();
@@ -86,7 +86,7 @@ public abstract class SolrCoreState {
* @param rollback close IndexWriter if false, else rollback
* @throws IOException If there is a low-level I/O error.
*/
- public abstract void newIndexWriter(SolrCore core, boolean rollback, boolean forceNewDir) throws IOException;
+ public abstract void newIndexWriter(SolrCore core, boolean rollback) throws IOException;
/**
* Get the current IndexWriter. If a new IndexWriter must be created, use the